Explorar el Código

Invalidate cached scopes in the call stack on Function.caller. Prevent a cached scope's variables from being cleared out if the function that escapes via Function.caller can access them.

Paul Leathers hace 9 años
padre
commit
f0c4150309

+ 15 - 1
lib/Runtime/Library/JavascriptFunction.cpp

@@ -2655,8 +2655,22 @@ LABEL1:
             }
             if (ScriptFunction::Is(funcCaller))
             {
-                // Is this is the internal function of a generator function then return the original generator function
+                // If this is the internal function of a generator function then return the original generator function
                 funcCaller = ScriptFunction::FromVar(funcCaller)->GetRealFunctionObject();
+
+                // This function is escaping, so make sure there isn't some caller that has a cached scope.
+                JavascriptFunction * func;
+                while (walker.GetCaller(&func))
+                {
+                    if (ScriptFunction::Is(func))
+                    {
+                        ActivationObjectEx * obj = ScriptFunction::FromVar(func)->GetCachedScope();
+                        if (obj)
+                        {
+                            obj->InvalidateCachedScope();
+                        }
+                    }
+                }
             }
         }
 

+ 1 - 0
test/Closures/invalcachedscope-caller.baseline

@@ -0,0 +1 @@
+0,-1

+ 29 - 0
test/Closures/invalcachedscope-caller.js

@@ -0,0 +1,29 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+var GiantPrintArray = [];
+var obj0 = {};
+var func2 = function () {
+  obj0.method0 = func2.caller;
+};
+var ary = Array();
+ary[0] = -285904746.9;
+var protoObj0 = Object(obj0);
+(function (argMath7) {
+  for (var _strvar1 in ary) {
+    arguments[1];
+    function v0() {
+      var v2 = Array();
+      var v4 = {};
+      func2();
+      v4.z = -_strvar1++;
+      v2[0] = v4;
+      GiantPrintArray.push(v2[0].z);
+    }
+    v0();
+  }
+}());
+protoObj0.method0();
+WScript.Echo(GiantPrintArray);

+ 6 - 0
test/Closures/rlexe.xml

@@ -129,6 +129,12 @@
       <tags>exclude_fre</tags>
     </default>
   </test>
+  <test>
+    <default>
+      <files>invalcachedscope-caller.js</files>
+      <baseline>invalcachedscope-caller.baseline</baseline>
+    </default>
+  </test>
   <test>
     <default>
       <files>bug_OS_2299723.js</files>