diff --git a/boa_engine/src/vm/mod.rs b/boa_engine/src/vm/mod.rs index f17a0089281..3685570651e 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.is_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..cd1b1108c07 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 proto = { + m() { return "super"; } + }; + let obj = { + v() { return super.m(); } + }; + 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")) + ) +}