Skip to content

Commit f5bbc7f

Browse files
authored
Merge pull request #701 from RustPython/coolreader18/fix-wasm-import-json
Fix the WASM build
2 parents 6c660c9 + ed60b19 commit f5bbc7f

4 files changed

Lines changed: 46 additions & 45 deletions

File tree

vm/src/stdlib/json.rs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -188,44 +188,45 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
188188
}
189189
}
190190

191+
pub fn ser_pyobject(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyResult<String> {
192+
let serializer = PyObjectSerializer { pyobject: obj, vm };
193+
serde_json::to_string(&serializer).map_err(|err| vm.new_type_error(err.to_string()))
194+
}
195+
196+
pub fn de_pyobject(vm: &mut VirtualMachine, s: &str) -> PyResult {
197+
let de = PyObjectDeserializer { vm };
198+
// TODO: Support deserializing string sub-classes
199+
de.deserialize(&mut serde_json::Deserializer::from_str(s))
200+
.map_err(|err| {
201+
let json_decode_error = vm
202+
.sys_module
203+
.get_item("modules")
204+
.unwrap()
205+
.get_item("json")
206+
.unwrap()
207+
.get_item("JSONDecodeError")
208+
.unwrap();
209+
let exc = vm.new_exception(json_decode_error, format!("{}", err));
210+
vm.ctx.set_attr(&exc, "lineno", vm.ctx.new_int(err.line()));
211+
vm.ctx.set_attr(&exc, "colno", vm.ctx.new_int(err.column()));
212+
exc
213+
})
214+
}
215+
191216
/// Implement json.dumps
192217
fn json_dumps(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
193218
// TODO: Implement non-trivial serialisation case
194219
arg_check!(vm, args, required = [(obj, None)]);
195-
let res = {
196-
let serializer = PyObjectSerializer { pyobject: obj, vm };
197-
serde_json::to_string(&serializer)
198-
};
199-
let string = res.map_err(|err| vm.new_type_error(format!("{}", err)))?;
220+
let string = ser_pyobject(vm, obj)?;
200221
Ok(vm.context().new_str(string))
201222
}
202223

203224
/// Implement json.loads
204225
fn json_loads(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
205226
// TODO: Implement non-trivial deserialization case
206227
arg_check!(vm, args, required = [(string, Some(vm.ctx.str_type()))]);
207-
let res = {
208-
let de = PyObjectDeserializer { vm };
209-
// TODO: Support deserializing string sub-classes
210-
de.deserialize(&mut serde_json::Deserializer::from_str(&objstr::get_value(
211-
&string,
212-
)))
213-
};
214-
215-
res.map_err(|err| {
216-
let json_decode_error = vm
217-
.sys_module
218-
.get_item("modules")
219-
.unwrap()
220-
.get_item("json")
221-
.unwrap()
222-
.get_item("JSONDecodeError")
223-
.unwrap();
224-
let exc = vm.new_exception(json_decode_error, format!("{}", err));
225-
vm.ctx.set_attr(&exc, "lineno", vm.ctx.new_int(err.line()));
226-
vm.ctx.set_attr(&exc, "colno", vm.ctx.new_int(err.column()));
227-
exc
228-
})
228+
229+
de_pyobject(vm, &objstr::get_value(&string))
229230
}
230231

231232
pub fn make_module(ctx: &PyContext) -> PyObjectRef {

vm/src/stdlib/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
mod ast;
22
mod dis;
3-
mod json;
3+
pub(crate) mod json;
44
mod keyword;
55
mod math;
66
mod platform;

vm/src/vm.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,14 @@ impl VirtualMachine {
626626
})
627627
}
628628

629+
pub fn serialize(&mut self, obj: &PyObjectRef) -> PyResult<String> {
630+
crate::stdlib::json::ser_pyobject(self, obj)
631+
}
632+
633+
pub fn deserialize(&mut self, s: &str) -> PyResult {
634+
crate::stdlib::json::de_pyobject(self, s)
635+
}
636+
629637
pub fn _sub(&mut self, a: PyObjectRef, b: PyObjectRef) -> PyResult {
630638
self.call_or_reflection(a, b, "__sub__", "__rsub__", |vm, a, b| {
631639
Err(vm.new_unsupported_operand_error(a, b, "-"))

wasm/lib/src/convert.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,14 @@ pub fn py_to_js(vm: &mut VirtualMachine, py_obj: PyObjectRef) -> JsValue {
111111

112112
return func;
113113
}
114-
// the browser module might not be injected
115-
if let Ok(promise_type) = browser_module::import_promise_type(vm) {
116-
if objtype::isinstance(&py_obj, &promise_type) {
117-
return browser_module::get_promise_value(&py_obj).into();
118-
}
114+
}
115+
// the browser module might not be injected
116+
if let Ok(promise_type) = browser_module::import_promise_type(vm) {
117+
if objtype::isinstance(&py_obj, &promise_type) {
118+
return browser_module::get_promise_value(&py_obj).into();
119119
}
120120
}
121+
121122
if objtype::isinstance(&py_obj, &vm.ctx.bytes_type())
122123
|| objtype::isinstance(&py_obj, &vm.ctx.bytearray_type())
123124
{
@@ -129,12 +130,8 @@ pub fn py_to_js(vm: &mut VirtualMachine, py_obj: PyObjectRef) -> JsValue {
129130
}
130131
arr.into()
131132
} else {
132-
let dumps = vm.class("json", "dumps");
133-
match vm.invoke(dumps, PyFuncArgs::new(vec![py_obj], vec![])) {
134-
Ok(value) => {
135-
let json = vm.to_pystr(&value).unwrap();
136-
js_sys::JSON::parse(&json).unwrap_or(JsValue::UNDEFINED)
137-
}
133+
match vm.serialize(&py_obj) {
134+
Ok(json) => js_sys::JSON::parse(&json).unwrap_or(JsValue::UNDEFINED),
138135
Err(_) => JsValue::UNDEFINED,
139136
}
140137
}
@@ -226,15 +223,10 @@ pub fn js_to_py(vm: &mut VirtualMachine, js_val: JsValue) -> PyObjectRef {
226223
// Because `JSON.stringify(undefined)` returns undefined
227224
vm.get_none()
228225
} else {
229-
let loads = vm.class("json", "dumps");
230226
let json = match js_sys::JSON::stringify(&js_val) {
231227
Ok(json) => String::from(json),
232228
Err(_) => return vm.get_none(),
233229
};
234-
let py_json = vm.new_str(json);
235-
236-
vm.invoke(loads, PyFuncArgs::new(vec![py_json], vec![]))
237-
// can safely unwrap because we know it's valid JSON
238-
.unwrap()
230+
vm.deserialize(&json).unwrap_or_else(|_| vm.get_none())
239231
}
240232
}

0 commit comments

Comments
 (0)