Skip to content

Commit

Permalink
fix computed property methods can call super methods (#2274)
Browse files Browse the repository at this point in the history
<!---
Thank you for contributing to Boa! Please fill out the template below, and remove or add any
information as you feel neccesary.
--->

This Pull Request fixes: https://github.com/tc39/test262/blob/79e3bc5176b6f29a5aed3b7164a9c623a3a9a63b/test/language/computed-property-names/object/method/super.js

This PR solves the bug of using the `super` keyword in the method attribute of object. When the environment is `None`, the `vm` gets the top element  of `vm.stack` as `this`, such as:
```js
var a = {
    f() {
        return super.m();
    }
};

var b = {
    m() {
        retrun "super";
    }
};

Object.setPrototypeOf(a, b);

a.f(); // the top of stack is `a`
let f = a.f;
f(); // the top of stack is `global_this`, so `super` cannot be used
```

### Can be improved

What I think is that when I use `object.method()`, the engine should bind `this_object`  to the `environment`, instead of using `vm.stack.last()...`.

### TODOS
1. `super` need to look for properties all the way to the end.

Co-authored-by: creampnx_x <2270436024@qq.com>
  • Loading branch information
creampnx-x and creampnx-x committed Sep 11, 2022
1 parent 2072f51 commit c43539a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
12 changes: 11 additions & 1 deletion boa_engine/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
};
Expand Down
45 changes: 45 additions & 0 deletions boa_engine/src/vm/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
)
}

0 comments on commit c43539a

Please sign in to comment.