Browse Source

Make sure the arguments are moved to stash if the context is dynamic

Dmitry Panov 4 years ago
parent
commit
22dce4853e
2 changed files with 19 additions and 2 deletions
  1. 5 2
      compiler_expr.go
  2. 14 0
      compiler_test.go

+ 5 - 2
compiler_expr.go

@@ -856,8 +856,11 @@ func (e *compiledFunctionLiteral) emitGetter(putOnStack bool) {
 		preambleLen += 2
 	}
 
-	if s.argsNeeded {
+	if (s.argsNeeded || s.isDynamic()) && !s.argsInStash {
 		s.moveArgsToStash()
+	}
+
+	if s.argsNeeded {
 		pos := preambleLen - 2
 		delta += 2
 		if s.strict {
@@ -881,7 +884,7 @@ func (e *compiledFunctionLiteral) emitGetter(putOnStack bool) {
 	delta++
 	delta = preambleLen - delta
 	var enter instruction
-	if stashSize > 0 || s.argsInStash || s.isDynamic() {
+	if stashSize > 0 || s.argsInStash {
 		enter1 := enterFunc{
 			numArgs:     uint32(paramsCount),
 			argsToStash: s.argsInStash,

+ 14 - 0
compiler_test.go

@@ -3448,6 +3448,20 @@ func TestAssignAfterStackExpand(t *testing.T) {
 	testScript1(SCRIPT, _undefined, t)
 }
 
+func TestArgAccessFromDynamicStash(t *testing.T) {
+	const SCRIPT = `
+	function f(arg) {
+		function test() {
+			eval("");
+			return a;
+		}
+		return arg;
+	}
+	f(true);
+	`
+	testScript1(SCRIPT, valueTrue, t)
+}
+
 /*
 func TestBabel(t *testing.T) {
 	src, err := ioutil.ReadFile("babel7.js")