Bug 795574 - name lookup in JSOP_IMPLICITTHIS should default to the global (r=waldo,a=bajaj)
authorLuke Wagner <luke@mozilla.com>
Tue, 02 Oct 2012 10:51:10 -0700
changeset 107069 28ef082de058889014a0b2f0acb3245ea1b7a36e
parent 107068 06ebc898a9c30929b1b224e084d1fdd82682d400
child 107070 ff90431f32c39fe62ffba1327556fc1e85453824
push id2210
push userlwagner@mozilla.com
push dateFri, 05 Oct 2012 23:10:13 +0000
treeherdermozilla-aurora@28ef082de058 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo, bajaj
bugs795574
milestone17.0a2
Bug 795574 - name lookup in JSOP_IMPLICITTHIS should default to the global (r=waldo,a=bajaj)
js/src/jit-test/tests/basic/testImplicitThisMiss.js
js/src/jsinterp.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/methodjit/PolyIC.cpp
js/src/methodjit/StubCalls.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testImplicitThisMiss.js
@@ -0,0 +1,2 @@
+// |jit-test| error:TypeError
+Function("Object.defineProperty(this, 'x', { configurable:true, get:function() { delete this['x'] } }); x()")();
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1826,18 +1826,19 @@ END_CASE(JSOP_BINDGNAME)
 BEGIN_CASE(JSOP_BINDNAME)
 {
     RootedObject &scopeChain = rootObject0;
     scopeChain = regs.fp()->scopeChain();
 
     RootedPropertyName &name = rootName0;
     name = script->getName(regs.pc);
 
+    /* Assigning to an undeclared name adds a property to the global object. */
     RootedObject &scope = rootObject1;
-    if (!LookupNameForSet(cx, name, scopeChain, &scope))
+    if (!LookupNameWithGlobalDefault(cx, name, scopeChain, &scope))
         goto error;
 
     PUSH_OBJECT(*scope);
 }
 END_CASE(JSOP_BINDNAME)
 
 #define BITWISE_OP(OP)                                                        \
     JS_BEGIN_MACRO                                                            \
@@ -2491,19 +2492,17 @@ BEGIN_CASE(JSOP_IMPLICITTHIS)
 {
     RootedPropertyName &name = rootName0;
     name = script->getName(regs.pc);
 
     RootedObject &scopeObj = rootObject0;
     scopeObj = cx->stack.currentScriptedScopeChain();
 
     RootedObject &scope = rootObject1;
-    RootedObject &pobj = rootObject2;
-    RootedShape &prop = rootShape0;
-    if (!LookupName(cx, name, scopeObj, &scope, &pobj, &prop))
+    if (!LookupNameWithGlobalDefault(cx, name, scopeObj, &scope))
         goto error;
 
     Value v;
     if (!ComputeImplicitThis(cx, scope, &v))
         goto error;
     PUSH_COPY(v);
 }
 END_CASE(JSOP_IMPLICITTHIS)
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -4405,18 +4405,18 @@ js::LookupName(JSContext *cx, HandleProp
 
     objp.set(NULL);
     pobjp.set(NULL);
     propp.set(NULL);
     return true;
 }
 
 bool
-js::LookupNameForSet(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
-                     MutableHandleObject objp)
+js::LookupNameWithGlobalDefault(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
+                                MutableHandleObject objp)
 {
     RootedId id(cx, NameToId(name));
 
     RootedObject pobj(cx);
     RootedShape prop(cx);
 
     RootedObject scope(cx, scopeChain);
     for (; !scope->isGlobal(); scope = scope->enclosingScope()) {
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1251,25 +1251,24 @@ static const unsigned RESOLVE_INFER = 0x
 
 /* Read the name using a dynamic lookup on the scopeChain. */
 extern bool
 LookupName(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
            MutableHandleObject objp, MutableHandleObject pobjp, MutableHandleShape propp);
 
 /*
  * Like LookupName except returns the global object if 'name' is not found in
- * any preceding non-global scope. This is because assigning to an undeclared
- * name will add a property to the global object.
+ * any preceding non-global scope.
  *
  * Additionally, pobjp and propp are not needed by callers so they are not
  * returned.
  */
 extern bool
-LookupNameForSet(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
-                 MutableHandleObject objp);
+LookupNameWithGlobalDefault(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
+                            MutableHandleObject objp);
 
 }
 
 extern JSObject *
 js_FindVariableScope(JSContext *cx, JSFunction **funp);
 
 /* JSGET_CACHE_RESULT is the analogue of DNP_CACHE_RESULT for GetMethod. */
 const unsigned JSGET_CACHE_RESULT = 1; // from a caching interpreter opcode
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -1909,17 +1909,17 @@ class BindNameCompiler : public PICStubC
         return Lookup_Cacheable;
     }
 
     JSObject *update()
     {
         RecompilationMonitor monitor(cx);
 
         RootedObject scope(cx);
-        if (!LookupNameForSet(cx, name, scopeChain, &scope))
+        if (!LookupNameWithGlobalDefault(cx, name, scopeChain, &scope))
             return NULL;
 
         if (monitor.recompiled())
             return scope;
 
         if (!pic.hit) {
             spew("first hit", "nop");
             pic.hit = true;
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -51,17 +51,17 @@ using namespace js::mjit;
 using namespace js::types;
 using namespace JSC;
 
 void JS_FASTCALL
 stubs::BindName(VMFrame &f, PropertyName *name_)
 {
     RootedPropertyName name(f.cx, name_);
     RootedObject scope(f.cx);
-    if (!LookupNameForSet(f.cx, name, f.fp()->scopeChain(), &scope))
+    if (!LookupNameWithGlobalDefault(f.cx, name, f.fp()->scopeChain(), &scope))
         THROW();
     f.regs.sp[0].setObject(*scope);
 }
 
 JSObject * JS_FASTCALL
 stubs::BindGlobalName(VMFrame &f)
 {
     return &f.fp()->global();
@@ -176,19 +176,18 @@ stubs::ToId(VMFrame &f)
 }
 
 void JS_FASTCALL
 stubs::ImplicitThis(VMFrame &f, PropertyName *name_)
 {
     RootedObject scopeObj(f.cx, f.cx->stack.currentScriptedScopeChain());
     RootedPropertyName name(f.cx, name_);
 
-    RootedObject obj(f.cx), obj2(f.cx);
-    RootedShape prop(f.cx);
-    if (!LookupName(f.cx, name, scopeObj, &obj, &obj2, &prop))
+    RootedObject obj(f.cx);
+    if (!LookupNameWithGlobalDefault(f.cx, name, scopeObj, &obj))
         THROW();
 
     if (!ComputeImplicitThis(f.cx, obj, &f.regs.sp[0]))
         THROW();
 }
 
 void JS_FASTCALL
 stubs::BitOr(VMFrame &f)