diff options
author | Jack Karamanian <karamanian.jack@gmail.com> | 2020-04-01 22:28:48 -0500 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-02 08:50:28 +0200 |
commit | bb15b372283230814e82da8e398dbbf3a0572849 (patch) | |
tree | 542f34df7d48524e6d96033dfe80a04aa13f407b /Libraries/LibJS | |
parent | 8f08ec5038bbee43621af6cd9ef088448d044ee3 (diff) | |
download | serenity-bb15b372283230814e82da8e398dbbf3a0572849.zip |
LibJS: Evaluate CallExpression arguments before pushing a CallFrame
Diffstat (limited to 'Libraries/LibJS')
-rw-r--r-- | Libraries/LibJS/AST.cpp | 8 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/function-this-in-arguments.js | 17 |
2 files changed, 23 insertions, 2 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 23baf14d23..407ecd8caa 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -101,16 +101,20 @@ Value CallExpression::execute(Interpreter& interpreter) const auto& function = static_cast<Function&>(callee.as_object()); - auto& call_frame = interpreter.push_call_frame(); + Vector<Value> arguments; + arguments.ensure_capacity(m_arguments.size()); for (size_t i = 0; i < m_arguments.size(); ++i) { auto value = m_arguments[i].execute(interpreter); if (interpreter.exception()) return {}; - call_frame.arguments.append(value); + arguments.append(value); if (interpreter.exception()) return {}; } + auto& call_frame = interpreter.push_call_frame(); + call_frame.arguments = move(arguments); + Object* new_object = nullptr; Value result; if (is_new_expression()) { diff --git a/Libraries/LibJS/Tests/function-this-in-arguments.js b/Libraries/LibJS/Tests/function-this-in-arguments.js new file mode 100644 index 0000000000..23bf80937c --- /dev/null +++ b/Libraries/LibJS/Tests/function-this-in-arguments.js @@ -0,0 +1,17 @@ +function assert(x) { if (!x) throw 1; } + +try { + assert(typeof this === "object"); + assert(this === global); + + function Foo() { + this.x = 5; + assert(typeof this === "object"); + assert(this.x === 5); + } + + new Foo(); + console.log("PASS"); +} catch (err) { + console.log("FAIL: " + err); +} |