[JAEGER] Added JSOP_NAME.
authorDavid Anderson <danderson@mozilla.com>
Fri, 28 May 2010 00:54:01 -0700
changeset 52615 e62d41ce373de374b973e51b429d974c8dadc8ec
parent 52614 a96f70dac68d2078ea88cfd0912647628db30f51
child 52616 c355cffd66678e8e6dcd805d492cd0931bfbd4c7
push idunknown
push userunknown
push dateunknown
milestone1.9.3a5pre
[JAEGER] Added JSOP_NAME.
js/src/methodjit/Compiler.cpp
js/src/methodjit/StubCalls.cpp
js/src/methodjit/StubCalls.h
js/src/methodjit/nunbox/FrameState.h
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -268,16 +268,23 @@ mjit::Compiler::generateMethod()
             Jump j = masm.jump();
             jumpInScript(j, PC + GET_JUMP_OFFSET(PC));
           }
           END_CASE(JSOP_GOTO)
 
           BEGIN_CASE(JSOP_TRACE)
           END_CASE(JSOP_TRACE)
 
+          BEGIN_CASE(JSOP_NAME)
+            prepareStubCall();
+            masm.move(Imm32(fullAtomIndex(PC)), Registers::ArgReg1);
+            stubCall(stubs::Name, Uses(0), Defs(1));
+            frame.push();
+          END_CASE(JSOP_NAME)
+
           BEGIN_CASE(JSOP_DOUBLE)
           {
             uint32 index = fullAtomIndex(PC);
             JSAtom *atom = script->getAtom(index);
             double d = *ATOM_TO_DOUBLE(atom);
             frame.push(Value(DoubleTag(d)));
           }
           END_CASE(JSOP_DOUBLE)
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -311,16 +311,32 @@ ValueToObject(JSContext *cx, Value *vp)
 {
     if (vp->isObject())
         return &vp->asObject();
     if (!js_ValueToNonNullObject(cx, *vp, vp))
         return NULL;
     return &vp->asObject();
 }
 
+#define NATIVE_GET(cx,obj,pobj,sprop,getHow,vp)                               \
+    JS_BEGIN_MACRO                                                            \
+        if (sprop->hasDefaultGetter()) {                                      \
+            /* Fast path for Object instance properties. */                   \
+            JS_ASSERT((sprop)->slot != SPROP_INVALID_SLOT ||                  \
+                      !sprop->hasDefaultSetter());                            \
+            if (((sprop)->slot != SPROP_INVALID_SLOT))                        \
+                *(vp) = (pobj)->lockedGetSlot((sprop)->slot);                 \
+            else                                                              \
+                (vp)->setUndefined();                                         \
+        } else {                                                              \
+            if (!js_NativeGet(cx, obj, pobj, sprop, getHow, vp))              \
+                THROW();                                                      \
+        }                                                                     \
+    JS_END_MACRO
+
 void JS_FASTCALL
 mjit::stubs::SetName(VMFrame &f, uint32 index)
 {
     JSContext *cx = f.cx;
 
     Value &rref = f.regs.sp[-1];
     Value &lref = f.regs.sp[-2];
     JSObject *obj = ValueToObject(cx, &lref);
@@ -519,8 +535,79 @@ mjit::stubs::SetName(VMFrame &f, uint32 
             if (!obj->setProperty(cx, id, &rref))
                 THROW();
         }
     } while (0);
 
     f.regs.sp[-2] = f.regs.sp[-1];
 }
 
+static void
+ReportAtomNotDefined(JSContext *cx, JSAtom *atom)
+{
+    const char *printable = js_AtomToPrintableString(cx, atom);
+    if (printable)
+        js_ReportIsNotDefined(cx, printable);
+}
+
+void JS_FASTCALL
+stubs::Name(VMFrame &f, uint32 index)
+{
+    JSContext *cx = f.cx;
+    JSStackFrame *fp = f.fp;
+    JSObject *obj = fp->scopeChain;
+
+    JSScopeProperty *sprop;
+    Value rval;
+
+    PropertyCacheEntry *entry;
+    JSObject *obj2;
+    JSAtom *atom;
+    JS_PROPERTY_CACHE(cx).test(cx, f.regs.pc, obj, obj2, entry, atom);
+    if (!atom) {
+        if (entry->vword.isFunObj()) {
+            f.regs.sp[-1].setFunObj(entry->vword.toFunObj());
+            return;
+        }
+
+        if (entry->vword.isSlot()) {
+            uintN slot = entry->vword.toSlot();
+            JS_ASSERT(slot < obj2->scope()->freeslot);
+            f.regs.sp[-1] = obj2->lockedGetSlot(slot);
+            return;
+        }
+
+        JS_ASSERT(entry->vword.isSprop());
+        sprop = entry->vword.toSprop();
+        goto do_native_get;
+    }
+
+    jsid id;
+    id = ATOM_TO_JSID(atom);
+    JSProperty *prop;
+    if (!js_FindPropertyHelper(cx, id, true, &obj, &obj2, &prop))
+        THROW();
+    if (!prop) {
+        /* Kludge to allow (typeof foo == "undefined") tests. */
+        JSOp op2 = js_GetOpcode(cx, f.fp->script, f.regs.pc + JSOP_NAME_LENGTH);
+        if (op2 == JSOP_TYPEOF) {
+            f.regs.sp[-1].setUndefined();
+            return;
+        }
+        ReportAtomNotDefined(cx, atom);
+        THROW();
+    }
+
+    /* Take the slow path if prop was not found in a native object. */
+    if (!obj->isNative() || !obj2->isNative()) {
+        obj2->dropProperty(cx, prop);
+        if (!obj->getProperty(cx, id, &rval))
+            THROW();
+    } else {
+        sprop = (JSScopeProperty *)prop;
+  do_native_get:
+        NATIVE_GET(cx, obj, obj2, sprop, JSGET_METHOD_BARRIER, &rval);
+        obj2->dropProperty(cx, (JSProperty *) sprop);
+    }
+
+    f.regs.sp[-1] = rval;
+}
+
--- a/js/src/methodjit/StubCalls.h
+++ b/js/src/methodjit/StubCalls.h
@@ -45,16 +45,17 @@
 
 namespace js {
 namespace mjit {
 namespace stubs {
 
 void * JS_FASTCALL Return(VMFrame &f);
 JSObject * JS_FASTCALL BindName(VMFrame &f);
 void JS_FASTCALL SetName(VMFrame &f, uint32 index);
+void JS_FASTCALL Name(VMFrame &f, uint32 index);
 
 }}} /* namespace stubs,mjit,js */
 
 extern "C" void *
 js_InternalThrow(js::VMFrame &f);
 
 #endif /* jslogic_h__ */
 
--- a/js/src/methodjit/nunbox/FrameState.h
+++ b/js/src/methodjit/nunbox/FrameState.h
@@ -103,16 +103,17 @@ class FrameState
 
     void freeReg(RegisterID reg) {
         JS_ASSERT(!regstate[reg].tracked);
         regalloc.freeReg(reg);
     }
 
     void incSp() {
         sp++;
+        JS_ASSERT(sp - locals <= script->nslots);
     }
 
     void decSp() {
         sp--;
     }
 
     /*
      * Push a type register, unsycned, with unknown payload.
@@ -128,17 +129,23 @@ class FrameState
     void push(const Value &v) {
         push(Jsvalify(v));
     }
 
     void push(const jsval &v) {
         sp[0].setConstant(v);
         sp[0].copies = 0;
         incSp();
-        JS_ASSERT(sp - locals <= script->nslots);
+    }
+
+    void push() {
+        sp[0].type.setMemory();
+        sp[0].data.setMemory();
+        sp[0].copies = 0;
+        incSp();
     }
 
     void pushObject(RegisterID reg) {
         sp[0].type.setConstant();
         sp[0].v_.s.mask32 = JSVAL_MASK32_NONFUNOBJ;
         sp[0].data.setRegister(reg);
         sp[0].copies = 0;
         regstate[reg] = RegState(RegState::Part_Data, uint32(sp - base), true);