From 7cdd58c95065378b83b1bf5a43728bfd8eb8bd2d Mon Sep 17 00:00:00 2001 From: Mihail Stoykov Date: Mon, 23 Jun 2025 18:50:18 +0300 Subject: [PATCH] bugfix: this being wrong when rest arguments are used During a previous fix it seems that rest parameters weren't taken into consideration and currently `this` refers to them in the provided test. The test in question is a very simplified variation of a real code. It seems all of the following things are relevant for the bug to occur: 1. method with only a rest parameter 2. usage of `this` 3. usage of the parameter 4. All of the above within a lambda inside the method --- compiler_expr.go | 2 +- compiler_test.go | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/compiler_expr.go b/compiler_expr.go index 71fdad38..a12a335c 100644 --- a/compiler_expr.go +++ b/compiler_expr.go @@ -1701,7 +1701,7 @@ func (e *compiledFunctionLiteral) compile() (prg *Program, name unistring.String stashSize, stackSize := s.finaliseVarAlloc(0) - if needInitThis && (s.numArgs > 0 && !s.argsInStash || stackSize > 0) { + if needInitThis && ((s.numArgs > 0 || hasPatterns) && !s.argsInStash || stackSize > 0) { code[preambleLen-delta] = initStashP(code[preambleLen-delta].(initStash)) delta++ code[preambleLen-delta] = loadStack(0) diff --git a/compiler_test.go b/compiler_test.go index 97011fc0..7581de99 100644 --- a/compiler_test.go +++ b/compiler_test.go @@ -5965,6 +5965,29 @@ func TestThisInStashCtor(t *testing.T) { testScript(SCRIPT, _undefined, t) } +func TestWrongThis(t *testing.T) { + const SCRIPT = ` + class mine { + constructor (arg) { + this.field = arg + } + + f(...argument) { + if (this.field != "something") { + throw "wrong " + this.field + " Object.keys:" + Object.keys(this) + } + let s = () => { + for (const arg of argument) arg.call() + return this.field + } + } + } + const a = new mine("something") + a.f({"SomeKey": "here"}) +` + testScript(SCRIPT, _undefined, t) +} + /* func TestBabel(t *testing.T) { src, err := os.ReadFile("babel7.js")