Skip to content

Commit 4d26883

Browse files
committed
Fixed incorrect 'this' value when arguments remain on stack. Closes #670
1 parent cb187b0 commit 4d26883

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

compiler_expr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,7 @@ func (e *compiledFunctionLiteral) compile() (prg *Program, name unistring.String
17011701

17021702
stashSize, stackSize := s.finaliseVarAlloc(0)
17031703

1704-
if needInitThis && (s.numArgs > 0 && !s.argsInStash || stackSize > 0) {
1704+
if needInitThis && (!s.argsInStash || firstForwardRef != -1 || stackSize > 0) {
17051705
code[preambleLen-delta] = initStashP(code[preambleLen-delta].(initStash))
17061706
delta++
17071707
code[preambleLen-delta] = loadStack(0)

compiler_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5965,6 +5965,62 @@ func TestThisInStashCtor(t *testing.T) {
59655965
testScript(SCRIPT, _undefined, t)
59665966
}
59675967

5968+
func TestWrongThisRest(t *testing.T) {
5969+
const SCRIPT = `
5970+
class mine {
5971+
constructor (arg) {
5972+
this.field = arg
5973+
}
5974+
f(...argument) {
5975+
if (this.field != "something") {
5976+
throw "wrong " + this.field + " Object.keys:" + Object.keys(this)
5977+
}
5978+
let s = () => {
5979+
for (const arg of argument) arg.call()
5980+
return this.field
5981+
}
5982+
}
5983+
}
5984+
const a = new mine("something")
5985+
a.f({"SomeKey": "here"})
5986+
`
5987+
testScript(SCRIPT, _undefined, t)
5988+
}
5989+
5990+
func TestWrongThisExtraArg(t *testing.T) {
5991+
const SCRIPT = `
5992+
class mine {
5993+
constructor (arg) {
5994+
this.field = arg
5995+
}
5996+
f() {
5997+
if (this.field != "something") {
5998+
throw "wrong " + this.field + " Object.keys:" + Object.keys(this)
5999+
}
6000+
globalThis.x = () => this.field;
6001+
}
6002+
}
6003+
const a = new mine("something")
6004+
a.f({"SomeKey": "here"}) // pass extra arg
6005+
`
6006+
testScript(SCRIPT, _undefined, t)
6007+
}
6008+
6009+
func TestWrongThisForwardRef(t *testing.T) {
6010+
const SCRIPT = `
6011+
const expectedThis = {};
6012+
function f(a = b + 1, b) { // forward ref argument to make sure args remain on stack
6013+
if (this != expectedThis) {
6014+
throw new Error("unexpected 'this'");
6015+
}
6016+
eval("true"); // make the scope dynamic which copies args to stash
6017+
}
6018+
6019+
f.call(expectedThis, 1, 2);
6020+
`
6021+
testScript(SCRIPT, _undefined, t)
6022+
}
6023+
59686024
/*
59696025
func TestBabel(t *testing.T) {
59706026
src, err := os.ReadFile("babel7.js")

0 commit comments

Comments
 (0)