From 17c27434ee9f53e6eadb68e497e6281693b0680b Mon Sep 17 00:00:00 2001 From: creampnx_x <73047992+creampnx-x@users.noreply.github.com> Date: Fri, 9 Sep 2022 18:28:10 +0800 Subject: [PATCH 1/5] fix: get home object --- boa_engine/src/vm/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/vm/mod.rs b/boa_engine/src/vm/mod.rs index f17a0089281..b8f394ab6bc 100644 --- a/boa_engine/src/vm/mod.rs +++ b/boa_engine/src/vm/mod.rs @@ -1521,7 +1521,12 @@ impl Context { let function = function_object .as_function() .expect("must be function object"); - function.get_home_object().cloned() + let mut home_object = function.get_home_object().cloned(); + + if home_object == None { + home_object = self.vm.stack.last().expect("stack is empty").as_object().cloned(); + } + home_object } else { return self.throw_range_error("Must call super constructor in derived class before accessing 'this' or returning from derived constructor"); }; From ff2904cf600661937b5848697f0b60f88d1bab2f Mon Sep 17 00:00:00 2001 From: creampnx_x <73047992+creampnx-x@users.noreply.github.com> Date: Fri, 9 Sep 2022 18:29:10 +0800 Subject: [PATCH 2/5] test: add test --- boa_engine/src/vm/tests.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/boa_engine/src/vm/tests.rs b/boa_engine/src/vm/tests.rs index 8a5fda7be06..ed0ab7097cb 100644 --- a/boa_engine/src/vm/tests.rs +++ b/boa_engine/src/vm/tests.rs @@ -137,3 +137,29 @@ fn finally_block_binding_env() { Ok(JsValue::from("Hey hey people")) ); } + +#[test] +fn run_super_method_in_object() { + let source = r#" + let obj = { + v() { + return super.m(); + } + }; + + let proto = { + m() { + return "super"; + } + }; + + Object.setPrototypeOf(obj, proto); + + obj.v(); + "#; + + assert_eq!( + Context::default().eval(source.as_bytes()), + Ok(JsValue::from("super")) + ) +} From 0f58b1d9377ac188465201fa2b58c6f64d722983 Mon Sep 17 00:00:00 2001 From: creampnx_x <73047992+creampnx-x@users.noreply.github.com> Date: Fri, 9 Sep 2022 20:38:24 +0800 Subject: [PATCH 3/5] code-format --- boa_engine/src/vm/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/vm/mod.rs b/boa_engine/src/vm/mod.rs index b8f394ab6bc..6357859bab6 100644 --- a/boa_engine/src/vm/mod.rs +++ b/boa_engine/src/vm/mod.rs @@ -1524,7 +1524,13 @@ impl Context { let mut home_object = function.get_home_object().cloned(); if home_object == None { - home_object = self.vm.stack.last().expect("stack is empty").as_object().cloned(); + home_object = self + .vm + .stack + .last() + .expect("stack is empty") + .as_object() + .cloned(); } home_object } else { From 0bf84850890a560d570f792b1a48a937b964e1fd Mon Sep 17 00:00:00 2001 From: creampnx_x <2270436024@qq.com> Date: Sun, 11 Sep 2022 20:27:31 +0800 Subject: [PATCH 4/5] fix: get this in object method --- boa_engine/src/vm/mod.rs | 12 +++++++++- boa_engine/src/vm/tests.rs | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/boa_engine/src/vm/mod.rs b/boa_engine/src/vm/mod.rs index f17a0089281..a172f69185d 100644 --- a/boa_engine/src/vm/mod.rs +++ b/boa_engine/src/vm/mod.rs @@ -1521,7 +1521,17 @@ impl Context { let function = function_object .as_function() .expect("must be function object"); - function.get_home_object().cloned() + let mut home_object = function.get_home_object().cloned(); + + if home_object == None { + home_object = env + .get_this_binding() + .expect("can not get `this` object") + .as_object() + .cloned(); + } + + home_object } else { return self.throw_range_error("Must call super constructor in derived class before accessing 'this' or returning from derived constructor"); }; diff --git a/boa_engine/src/vm/tests.rs b/boa_engine/src/vm/tests.rs index 8a5fda7be06..3f9a1eac119 100644 --- a/boa_engine/src/vm/tests.rs +++ b/boa_engine/src/vm/tests.rs @@ -137,3 +137,48 @@ fn finally_block_binding_env() { Ok(JsValue::from("Hey hey people")) ); } + +#[test] +fn run_super_method_in_object() { + let source = r#" + let obj = { + v() { return super.m(); } + }; + let proto = { + m() { return "super"; } + }; + Object.setPrototypeOf(obj, proto); + obj.v(); + "#; + + assert_eq!( + Context::default().eval(source.as_bytes()), + Ok(JsValue::from("super")) + ) +} + +#[test] +fn get_reference_by_super() { + let source = r#" + var fromA, fromB; + var A = { fromA: 'a', fromB: 'a' }; + var B = { fromB: 'b' }; + Object.setPrototypeOf(B, A); + var obj = { + fromA: 'c', + fromB: 'c', + method() { + fromA = (() => { return super.fromA; })(); + fromB = (() => { return super.fromB; })(); + } + }; + Object.setPrototypeOf(obj, B); + obj.method(); + fromA + fromB + "#; + + assert_eq!( + Context::default().eval(source.as_bytes()), + Ok(JsValue::from("ab")) + ) +} From 56e4f2a03b66e6d90458b8d42f8cf7b45f73447a Mon Sep 17 00:00:00 2001 From: creampnx_x <73047992+creampnx-x@users.noreply.github.com> Date: Sun, 11 Sep 2022 23:18:53 +0800 Subject: [PATCH 5/5] code-format: functional style Co-authored-by: Iban Eguia --- boa_engine/src/vm/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa_engine/src/vm/mod.rs b/boa_engine/src/vm/mod.rs index a172f69185d..3685570651e 100644 --- a/boa_engine/src/vm/mod.rs +++ b/boa_engine/src/vm/mod.rs @@ -1523,7 +1523,7 @@ impl Context { .expect("must be function object"); let mut home_object = function.get_home_object().cloned(); - if home_object == None { + if home_object.is_none() { home_object = env .get_this_binding() .expect("can not get `this` object")