mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-15 17:50:51 +00:00
Fix codegen of consuming setters/getters (#2172)
Make sure they reset their internal pointer to null after we call Rust since it invalidates the Rust pointer after being called! Closes #2168
This commit is contained in:
parent
b5e377da78
commit
cc36bdc00d
@ -2190,10 +2190,9 @@ impl<'a> Context<'a> {
|
|||||||
AuxExportKind::Function(_) => {}
|
AuxExportKind::Function(_) => {}
|
||||||
AuxExportKind::StaticFunction { .. } => {}
|
AuxExportKind::StaticFunction { .. } => {}
|
||||||
AuxExportKind::Constructor(class) => builder.constructor(class),
|
AuxExportKind::Constructor(class) => builder.constructor(class),
|
||||||
AuxExportKind::Getter { .. } | AuxExportKind::Setter { .. } => {
|
AuxExportKind::Getter { consumed, .. }
|
||||||
builder.method(false)
|
| AuxExportKind::Setter { consumed, .. }
|
||||||
}
|
| AuxExportKind::Method { consumed, .. } => builder.method(*consumed),
|
||||||
AuxExportKind::Method { consumed, .. } => builder.method(*consumed),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Import(_) => {}
|
Kind::Import(_) => {}
|
||||||
@ -2257,7 +2256,7 @@ impl<'a> Context<'a> {
|
|||||||
exported.has_constructor = true;
|
exported.has_constructor = true;
|
||||||
exported.push(&docs, "constructor", "", &code, ts_sig);
|
exported.push(&docs, "constructor", "", &code, ts_sig);
|
||||||
}
|
}
|
||||||
AuxExportKind::Getter { class, field } => {
|
AuxExportKind::Getter { class, field, .. } => {
|
||||||
let ret_ty = match export.generate_typescript {
|
let ret_ty = match export.generate_typescript {
|
||||||
true => match &ts_ret_ty {
|
true => match &ts_ret_ty {
|
||||||
Some(s) => Some(s.as_str()),
|
Some(s) => Some(s.as_str()),
|
||||||
@ -2268,7 +2267,7 @@ impl<'a> Context<'a> {
|
|||||||
let exported = require_class(&mut self.exported_classes, class);
|
let exported = require_class(&mut self.exported_classes, class);
|
||||||
exported.push_getter(&docs, field, &code, ret_ty);
|
exported.push_getter(&docs, field, &code, ret_ty);
|
||||||
}
|
}
|
||||||
AuxExportKind::Setter { class, field } => {
|
AuxExportKind::Setter { class, field, .. } => {
|
||||||
let arg_ty = match export.generate_typescript {
|
let arg_ty = match export.generate_typescript {
|
||||||
true => Some(ts_arg_tys[0].as_str()),
|
true => Some(ts_arg_tys[0].as_str()),
|
||||||
false => None,
|
false => None,
|
||||||
@ -3247,20 +3246,24 @@ fn check_duplicated_getter_and_setter_names(
|
|||||||
AuxExportKind::Getter {
|
AuxExportKind::Getter {
|
||||||
class: first_class,
|
class: first_class,
|
||||||
field: first_field,
|
field: first_field,
|
||||||
|
consumed: _,
|
||||||
},
|
},
|
||||||
AuxExportKind::Getter {
|
AuxExportKind::Getter {
|
||||||
class: second_class,
|
class: second_class,
|
||||||
field: second_field,
|
field: second_field,
|
||||||
|
consumed: _,
|
||||||
},
|
},
|
||||||
) => verify_exports(first_class, first_field, second_class, second_field)?,
|
) => verify_exports(first_class, first_field, second_class, second_field)?,
|
||||||
(
|
(
|
||||||
AuxExportKind::Setter {
|
AuxExportKind::Setter {
|
||||||
class: first_class,
|
class: first_class,
|
||||||
field: first_field,
|
field: first_field,
|
||||||
|
consumed: _,
|
||||||
},
|
},
|
||||||
AuxExportKind::Setter {
|
AuxExportKind::Setter {
|
||||||
class: second_class,
|
class: second_class,
|
||||||
field: second_field,
|
field: second_field,
|
||||||
|
consumed: _,
|
||||||
},
|
},
|
||||||
) => verify_exports(first_class, first_field, second_class, second_field)?,
|
) => verify_exports(first_class, first_field, second_class, second_field)?,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -419,6 +419,7 @@ impl<'a> Context<'a> {
|
|||||||
AuxExportKind::Getter {
|
AuxExportKind::Getter {
|
||||||
class,
|
class,
|
||||||
field: f.to_string(),
|
field: f.to_string(),
|
||||||
|
consumed: export.consumed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decode::OperationKind::Setter(f) => {
|
decode::OperationKind::Setter(f) => {
|
||||||
@ -426,6 +427,7 @@ impl<'a> Context<'a> {
|
|||||||
AuxExportKind::Setter {
|
AuxExportKind::Setter {
|
||||||
class,
|
class,
|
||||||
field: f.to_string(),
|
field: f.to_string(),
|
||||||
|
consumed: export.consumed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ if op.is_static => AuxExportKind::StaticFunction {
|
_ if op.is_static => AuxExportKind::StaticFunction {
|
||||||
@ -806,6 +808,7 @@ impl<'a> Context<'a> {
|
|||||||
kind: AuxExportKind::Getter {
|
kind: AuxExportKind::Getter {
|
||||||
class: struct_.name.to_string(),
|
class: struct_.name.to_string(),
|
||||||
field: field.name.to_string(),
|
field: field.name.to_string(),
|
||||||
|
consumed: false,
|
||||||
},
|
},
|
||||||
generate_typescript: field.generate_typescript,
|
generate_typescript: field.generate_typescript,
|
||||||
},
|
},
|
||||||
@ -832,6 +835,7 @@ impl<'a> Context<'a> {
|
|||||||
kind: AuxExportKind::Setter {
|
kind: AuxExportKind::Setter {
|
||||||
class: struct_.name.to_string(),
|
class: struct_.name.to_string(),
|
||||||
field: field.name.to_string(),
|
field: field.name.to_string(),
|
||||||
|
consumed: false,
|
||||||
},
|
},
|
||||||
generate_typescript: field.generate_typescript,
|
generate_typescript: field.generate_typescript,
|
||||||
},
|
},
|
||||||
|
@ -105,12 +105,22 @@ pub enum AuxExportKind {
|
|||||||
/// This function is intended to be a getter for a field on a class. The
|
/// This function is intended to be a getter for a field on a class. The
|
||||||
/// first argument is the internal pointer and the returned value is
|
/// first argument is the internal pointer and the returned value is
|
||||||
/// expected to be the field.
|
/// expected to be the field.
|
||||||
Getter { class: String, field: String },
|
Getter {
|
||||||
|
class: String,
|
||||||
|
field: String,
|
||||||
|
// same as `consumed` in `Method`
|
||||||
|
consumed: bool,
|
||||||
|
},
|
||||||
|
|
||||||
/// This function is intended to be a setter for a field on a class. The
|
/// This function is intended to be a setter for a field on a class. The
|
||||||
/// first argument is the internal pointer and the second argument is
|
/// first argument is the internal pointer and the second argument is
|
||||||
/// expected to be the field's new value.
|
/// expected to be the field's new value.
|
||||||
Setter { class: String, field: String },
|
Setter {
|
||||||
|
class: String,
|
||||||
|
field: String,
|
||||||
|
// same as `consumed` in `Method`
|
||||||
|
consumed: bool,
|
||||||
|
},
|
||||||
|
|
||||||
/// This is a free function (ish) but scoped inside of a class name.
|
/// This is a free function (ish) but scoped inside of a class name.
|
||||||
StaticFunction { class: String, name: String },
|
StaticFunction { class: String, name: String },
|
||||||
|
@ -369,7 +369,7 @@ fn check_standard_export(export: &AuxExport) -> Result<(), Error> {
|
|||||||
name,
|
name,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
AuxExportKind::Getter { class, field } => {
|
AuxExportKind::Getter { class, field, .. } => {
|
||||||
bail!(
|
bail!(
|
||||||
"cannot export `{}::{}` getter function when generating \
|
"cannot export `{}::{}` getter function when generating \
|
||||||
a standalone WebAssembly module with no JS glue",
|
a standalone WebAssembly module with no JS glue",
|
||||||
@ -377,7 +377,7 @@ fn check_standard_export(export: &AuxExport) -> Result<(), Error> {
|
|||||||
field,
|
field,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
AuxExportKind::Setter { class, field } => {
|
AuxExportKind::Setter { class, field, .. } => {
|
||||||
bail!(
|
bail!(
|
||||||
"cannot export `{}::{}` setter function when generating \
|
"cannot export `{}::{}` setter function when generating \
|
||||||
a standalone WebAssembly module with no JS glue",
|
a standalone WebAssembly module with no JS glue",
|
||||||
|
@ -4,3 +4,21 @@ use wasm_bindgen::prelude::*;
|
|||||||
pub fn add(a: u32, b: u32) -> u32 {
|
pub fn add(a: u32, b: u32) -> u32 {
|
||||||
a + b
|
a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Answer(u32);
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Answer {
|
||||||
|
pub fn new() -> Answer {
|
||||||
|
Answer(41)
|
||||||
|
}
|
||||||
|
#[wasm_bindgen(getter)]
|
||||||
|
pub fn the_answer(self) -> u32 {
|
||||||
|
self.0 + 1
|
||||||
|
}
|
||||||
|
pub fn foo(self) -> u32 {
|
||||||
|
self.0 + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,4 +33,11 @@ exports.js_works = () => {
|
|||||||
useMoved();
|
useMoved();
|
||||||
moveMoved();
|
moveMoved();
|
||||||
methodMoved();
|
methodMoved();
|
||||||
|
|
||||||
|
const a = new wasm.Fruit('a');
|
||||||
|
a.prop;
|
||||||
|
assertMovedPtrThrows(() => a.prop);
|
||||||
|
const b = new wasm.Fruit('a');
|
||||||
|
b.prop = 3;
|
||||||
|
assertMovedPtrThrows(() => { b.prop = 4; });
|
||||||
};
|
};
|
||||||
|
@ -25,6 +25,14 @@ impl Fruit {
|
|||||||
pub fn rot(self) {
|
pub fn rot(self) {
|
||||||
drop(self);
|
drop(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(getter)]
|
||||||
|
pub fn prop(self) -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(setter)]
|
||||||
|
pub fn set_prop(self, _val: u32) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user