Bug 713183 - Make JSOP_*PROP and JSOP_*NAME store a PropertyName immediate, not a JSAtom immediate, and take advantage of this fact. r=bhackett

--HG--
extra : rebase_source : 99d199382928758983765ce87e8e4a4121c6430b
This commit is contained in:
Jeff Walden 2011-12-27 02:27:02 -06:00
Родитель ae91b1cee3
Коммит 2936d38bd0
17 изменённых файлов: 531 добавлений и 504 удалений

Просмотреть файл

@ -1284,8 +1284,8 @@ AssertValidPropertyCacheHit(JSContext *cx, JSScript *script, FrameRegs& regs,
uint32_t sample = cx->runtime->gcNumber;
PropertyCacheEntry savedEntry = *entry;
JSAtom *atom;
GET_ATOM_FROM_BYTECODE(script, regs.pc, 0, atom);
PropertyName *name;
GET_NAME_FROM_BYTECODE(script, regs.pc, 0, name);
JSObject *obj, *pobj;
JSProperty *prop;
@ -1293,10 +1293,10 @@ AssertValidPropertyCacheHit(JSContext *cx, JSScript *script, FrameRegs& regs,
if (JOF_OPMODE(*regs.pc) == JOF_NAME) {
bool global = js_CodeSpec[*regs.pc].format & JOF_GNAME;
ok = js_FindProperty(cx, ATOM_TO_JSID(atom), global, &obj, &pobj, &prop);
ok = FindProperty(cx, name, global, &obj, &pobj, &prop);
} else {
obj = start;
ok = js_LookupProperty(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop);
ok = LookupProperty(cx, obj, name, &pobj, &prop);
}
if (!ok)
return false;
@ -1497,6 +1497,13 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
atom = atoms[GET_INDEX(regs.pc + PCOFF)]; \
JS_END_MACRO
#define LOAD_NAME(PCOFF, name) \
JS_BEGIN_MACRO \
JSAtom *atom; \
LOAD_ATOM((PCOFF), atom); \
name = atom->asPropertyName(); \
JS_END_MACRO
#define GET_FULL_INDEX(PCOFF) \
(atoms - script->atoms + GET_INDEX(regs.pc + (PCOFF)))
@ -1644,7 +1651,6 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
/* State communicated between non-local jumps: */
JSBool interpReturnOK;
JSAtom *atomNotDefined;
/* Don't call the script prologue if executing between Method and Trace JIT. */
if (interpMode == JSINTERP_NORMAL) {
@ -2260,11 +2266,11 @@ END_CASE(JSOP_PICK)
BEGIN_CASE(JSOP_SETCONST)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
PropertyName *name;
LOAD_NAME(0, name);
JSObject &obj = regs.fp()->varObj();
const Value &ref = regs.sp[-1];
if (!obj.defineProperty(cx, atom->asPropertyName(), ref,
if (!obj.defineProperty(cx, name, ref,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY)) {
goto error;
@ -2320,15 +2326,14 @@ BEGIN_CASE(JSOP_BINDNAME)
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, obj, obj2, entry, atom);
if (!atom) {
PropertyName *name;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, obj, obj2, entry, name);
if (!name) {
ASSERT_VALID_PROPERTY_CACHE_HIT(obj, obj2, entry);
break;
}
jsid id = ATOM_TO_JSID(atom);
obj = js_FindIdentifierBase(cx, &regs.fp()->scopeChain(), id);
obj = FindIdentifierBase(cx, &regs.fp()->scopeChain(), name);
if (!obj)
goto error;
} while (0);
@ -2721,12 +2726,11 @@ END_CASE(JSOP_POS)
BEGIN_CASE(JSOP_DELNAME)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
jsid id = ATOM_TO_JSID(atom);
PropertyName *name;
LOAD_NAME(0, name);
JSObject *obj, *obj2;
JSProperty *prop;
if (!js_FindProperty(cx, id, false, &obj, &obj2, &prop))
if (!FindProperty(cx, name, false, &obj, &obj2, &prop))
goto error;
/* Strict mode code should never contain JSOP_DELNAME opcodes. */
@ -2735,7 +2739,7 @@ BEGIN_CASE(JSOP_DELNAME)
/* ECMA says to return true if name is undefined or inherited. */
PUSH_BOOLEAN(true);
if (prop) {
if (!obj->deleteProperty(cx, atom->asPropertyName(), &regs.sp[-1], false))
if (!obj->deleteProperty(cx, name, &regs.sp[-1], false))
goto error;
}
}
@ -2743,15 +2747,14 @@ END_CASE(JSOP_DELNAME)
BEGIN_CASE(JSOP_DELPROP)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
jsid id = ATOM_TO_JSID(atom);
PropertyName *name;
LOAD_NAME(0, name);
JSObject *obj;
FETCH_OBJECT(cx, -1, obj);
Value rval;
if (!obj->deleteGeneric(cx, id, &rval, script->strictModeCode))
if (!obj->deleteProperty(cx, name, &rval, script->strictModeCode))
goto error;
regs.sp[-1] = rval;
@ -2804,8 +2807,7 @@ BEGIN_CASE(JSOP_TYPEOF)
{
const Value &ref = regs.sp[-1];
JSType type = JS_TypeOfValue(cx, ref);
JSAtom *atom = rt->atomState.typeAtoms[type];
regs.sp[-1].setString(atom);
regs.sp[-1].setString(rt->atomState.typeAtoms[type]);
}
END_CASE(JSOP_TYPEOF)
@ -2948,22 +2950,21 @@ BEGIN_CASE(JSOP_LENGTH)
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, aobj, obj2, entry, atom);
if (!atom) {
PropertyName *name;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, aobj, obj2, entry, name);
if (!name) {
ASSERT_VALID_PROPERTY_CACHE_HIT(aobj, obj2, entry);
NATIVE_GET(cx, obj, obj2, entry->prop, JSGET_METHOD_BARRIER, &rval);
break;
}
jsid id = ATOM_TO_JSID(atom);
if (JS_LIKELY(!aobj->getOps()->getProperty)
? !js_GetPropertyHelper(cx, obj, id,
(regs.pc[JSOP_GETPROP_LENGTH] == JSOP_IFEQ)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER,
&rval)
: !obj->getGeneric(cx, id, &rval))
? !GetPropertyHelper(cx, obj, name,
(regs.pc[JSOP_GETPROP_LENGTH] == JSOP_IFEQ)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER,
&rval)
: !obj->getProperty(cx, name, &rval))
{
goto error;
}
@ -3007,50 +3008,44 @@ BEGIN_CASE(JSOP_CALLPROP)
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, aobj, obj2, entry, atom);
if (!atom) {
PropertyName *name;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, aobj, obj2, entry, name);
if (!name) {
ASSERT_VALID_PROPERTY_CACHE_HIT(aobj, obj2, entry);
NATIVE_GET(cx, &objv.toObject(), obj2, entry->prop, JSGET_NO_METHOD_BARRIER, &rval);
regs.sp[-1] = rval;
assertSameCompartment(cx, regs.sp[-1]);
PUSH_COPY(lval);
} else {
/*
* Cache miss: use the immediate atom that was loaded for us under
* PropertyCache::test.
*/
jsid id;
id = ATOM_TO_JSID(atom);
/* Cache miss: use the name loaded for us under PropertyCache::test. */
PUSH_NULL();
if (lval.isObject()) {
if (!js_GetMethod(cx, &objv.toObject(), id,
JS_LIKELY(!aobj->getOps()->getProperty)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_NO_METHOD_BARRIER,
&rval)) {
if (!GetMethod(cx, &objv.toObject(), name,
JS_LIKELY(!aobj->getOps()->getProperty)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_NO_METHOD_BARRIER,
&rval))
{
goto error;
}
regs.sp[-1] = objv;
regs.sp[-2] = rval;
assertSameCompartment(cx, regs.sp[-1], regs.sp[-2]);
} else {
JS_ASSERT(!objv.toObject().getOps()->getProperty);
if (!js_GetPropertyHelper(cx, &objv.toObject(), id,
JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER,
&rval)) {
if (!GetPropertyHelper(cx, &objv.toObject(), name,
JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER, &rval))
{
goto error;
}
regs.sp[-1] = lval;
regs.sp[-2] = rval;
assertSameCompartment(cx, regs.sp[-1], regs.sp[-2]);
}
assertSameCompartment(cx, regs.sp[-1], regs.sp[-2]);
}
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
LOAD_ATOM(0, atom);
regs.sp[-2].setString(atom);
LOAD_NAME(0, name);
regs.sp[-2].setString(name);
if (!OnUnknownMethod(cx, regs.sp - 2))
goto error;
}
@ -3097,8 +3092,8 @@ BEGIN_CASE(JSOP_SETMETHOD)
*/
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
if (cache->testForSet(cx, regs.pc, obj, &entry, &obj2, &atom)) {
PropertyName *name;
if (cache->testForSet(cx, regs.pc, obj, &entry, &obj2, &name)) {
/*
* Property cache hit, only partially confirmed by testForSet. We
* know that the entry applies to regs.pc and that obj's shape
@ -3133,12 +3128,11 @@ BEGIN_CASE(JSOP_SETMETHOD)
}
PCMETER(cache->setpcmisses++);
LOAD_ATOM(0, atom);
LOAD_NAME(0, name);
} else {
JS_ASSERT(atom);
JS_ASSERT(name);
}
jsid id = ATOM_TO_JSID(atom);
if (entry && JS_LIKELY(!obj->getOps()->setProperty)) {
uintN defineHow;
if (op == JSOP_SETMETHOD)
@ -3147,10 +3141,10 @@ BEGIN_CASE(JSOP_SETMETHOD)
defineHow = DNP_CACHE_RESULT | DNP_UNQUALIFIED;
else
defineHow = DNP_CACHE_RESULT;
if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode))
if (!SetPropertyHelper(cx, obj, name, defineHow, &rval, script->strictModeCode))
goto error;
} else {
if (!obj->setGeneric(cx, id, &rval, script->strictModeCode))
if (!obj->setProperty(cx, name, &rval, script->strictModeCode))
goto error;
}
} while (0);
@ -3458,9 +3452,9 @@ BEGIN_CASE(JSOP_CALLNAME)
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, obj, obj2, entry, atom);
if (!atom) {
PropertyName *name;
JS_PROPERTY_CACHE(cx).test(cx, regs.pc, obj, obj2, entry, name);
if (!name) {
ASSERT_VALID_PROPERTY_CACHE_HIT(obj, obj2, entry);
NATIVE_GET(cx, obj, obj2, entry->prop, JSGET_METHOD_BARRIER, &rval);
PUSH_COPY(rval);
@ -3474,9 +3468,8 @@ BEGIN_CASE(JSOP_CALLNAME)
DO_NEXT_OP(len);
}
jsid id = ATOM_TO_JSID(atom);
JSProperty *prop;
if (!js_FindPropertyHelper(cx, id, true, global, &obj, &obj2, &prop))
if (!FindPropertyHelper(cx, name, true, global, &obj, &obj2, &prop))
goto error;
if (!prop) {
/* Kludge to allow (typeof foo == "undefined") tests. */
@ -3487,13 +3480,16 @@ BEGIN_CASE(JSOP_CALLNAME)
len = JSOP_NAME_LENGTH;
DO_NEXT_OP(len);
}
atomNotDefined = atom;
goto atom_not_defined;
JSAutoByteString bytes;
if (js_AtomToPrintableString(cx, name, &bytes))
js_ReportIsNotDefined(cx, bytes.ptr());
goto error;
}
/* Take the slow path if prop was not found in a native object. */
if (!obj->isNative() || !obj2->isNative()) {
if (!obj->getGeneric(cx, id, &rval))
if (!obj->getProperty(cx, name, &rval))
goto error;
} else {
Shape *shape = (Shape *)prop;
@ -3861,7 +3857,6 @@ BEGIN_CASE(JSOP_DEFVAR)
attrs |= JSPROP_PERMANENT;
/* Lookup id in order to check for redeclaration problems. */
jsid id = ATOM_TO_JSID(name);
bool shouldDefine;
if (op == JSOP_DEFVAR) {
/*
@ -3876,7 +3871,7 @@ BEGIN_CASE(JSOP_DEFVAR)
} else {
JS_ASSERT(op == JSOP_DEFCONST);
attrs |= JSPROP_READONLY;
if (!CheckRedeclaration(cx, obj, id, attrs))
if (!CheckRedeclaration(cx, obj, name, attrs))
goto error;
/*
@ -3888,8 +3883,9 @@ BEGIN_CASE(JSOP_DEFVAR)
/* Bind a variable only if it's not yet defined. */
if (shouldDefine &&
!DefineNativeProperty(cx, obj, id, UndefinedValue(), JS_PropertyStub, JS_StrictPropertyStub,
attrs, 0, 0)) {
!DefineNativeProperty(cx, obj, name, UndefinedValue(),
JS_PropertyStub, JS_StrictPropertyStub, attrs, 0, 0))
{
goto error;
}
}
@ -3956,7 +3952,6 @@ BEGIN_CASE(JSOP_DEFFUN)
/* ES5 10.5 (NB: with subsequent errata). */
PropertyName *name = fun->atom->asPropertyName();
jsid id = ATOM_TO_JSID(name);
JSProperty *prop = NULL;
JSObject *pobj;
if (!parent->lookupProperty(cx, name, &pobj, &prop))
@ -3990,9 +3985,9 @@ BEGIN_CASE(JSOP_DEFFUN)
if (shape->isAccessorDescriptor() || !shape->writable() || !shape->enumerable()) {
JSAutoByteString bytes;
if (const char *name = js_ValueToPrintable(cx, IdToValue(id), &bytes)) {
if (js_AtomToPrintableString(cx, name, &bytes)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_REDEFINE_PROP, name);
JSMSG_CANT_REDEFINE_PROP, bytes.ptr());
}
goto error;
}
@ -4029,11 +4024,10 @@ BEGIN_CASE(JSOP_DEFFUN_FC)
JSObject &parent = regs.fp()->varObj();
jsid id = ATOM_TO_JSID(fun->atom);
if (!CheckRedeclaration(cx, &parent, id, attrs))
PropertyName *name = fun->atom->asPropertyName();
if (!CheckRedeclaration(cx, &parent, name, attrs))
goto error;
PropertyName *name = fun->atom->asPropertyName();
if ((attrs == JSPROP_ENUMERATE)
? !parent.setProperty(cx, name, &rval, script->strictModeCode)
: !parent.defineProperty(cx, name, rval, JS_PropertyStub, JS_StrictPropertyStub, attrs))
@ -4227,9 +4221,9 @@ BEGIN_CASE(JSOP_SETTER)
case JSOP_SETNAME:
case JSOP_SETPROP:
{
JSAtom *atom;
LOAD_ATOM(0, atom);
id = ATOM_TO_JSID(atom);
PropertyName *name;
LOAD_NAME(0, name);
id = ATOM_TO_JSID(name);
rval = regs.sp[-1];
i = -1;
goto gs_pop_lval;
@ -4247,9 +4241,9 @@ BEGIN_CASE(JSOP_SETTER)
JS_ASSERT(regs.sp - regs.fp()->base() >= 2);
rval = regs.sp[-1];
i = -1;
JSAtom *atom;
LOAD_ATOM(0, atom);
id = ATOM_TO_JSID(atom);
PropertyName *name;
LOAD_NAME(0, name);
id = ATOM_TO_JSID(name);
goto gs_get_lval;
}
default:
@ -4273,11 +4267,8 @@ BEGIN_CASE(JSOP_SETTER)
FETCH_ELEMENT_ID(obj, i, id);
if (!js_IsCallable(rval)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_BAD_GETTER_OR_SETTER,
(op == JSOP_GETTER)
? js_getter_str
: js_setter_str);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_GETTER_OR_SETTER,
(op == JSOP_GETTER) ? js_getter_str : js_setter_str);
goto error;
}
@ -4412,8 +4403,8 @@ BEGIN_CASE(JSOP_INITMETHOD)
*/
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
if (JS_PROPERTY_CACHE(cx).testForSet(cx, regs.pc, obj, &entry, &obj2, &atom) &&
PropertyName *name;
if (JS_PROPERTY_CACHE(cx).testForSet(cx, regs.pc, obj, &entry, &obj2, &name) &&
entry->prop->hasDefaultSetter() &&
entry->isOwnPropertyHit())
{
@ -4422,17 +4413,14 @@ BEGIN_CASE(JSOP_INITMETHOD)
obj->nativeSetSlotWithType(cx, entry->prop, rval);
} else {
PCMETER(JS_PROPERTY_CACHE(cx).inipcmisses++);
LOAD_ATOM(0, atom);
/* Get the immediate property name into id. */
jsid id = ATOM_TO_JSID(atom);
LOAD_NAME(0, name);
uintN defineHow = (op == JSOP_INITMETHOD)
? DNP_CACHE_RESULT | DNP_SET_METHOD
: DNP_CACHE_RESULT;
if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
? !js_SetPropertyHelper(cx, obj, id, defineHow, &rval, script->strictModeCode)
: !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
? !SetPropertyHelper(cx, obj, name, defineHow, &rval, script->strictModeCode)
: !DefineNativeProperty(cx, obj, name, rval, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, defineHow)) {
goto error;
}
@ -5438,12 +5426,4 @@ END_CASE(JSOP_ARRAYPUSH)
gc::VerifyBarriers(cx, true);
return interpReturnOK;
atom_not_defined:
{
JSAutoByteString printable;
if (js_AtomToPrintableString(cx, atomNotDefined, &printable))
js_ReportIsNotDefined(cx, printable.ptr());
}
goto error;
}

Просмотреть файл

@ -234,6 +234,12 @@ RunScript(JSContext *cx, JSScript *script, StackFrame *fp);
extern bool
CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs);
inline bool
CheckRedeclaration(JSContext *cx, JSObject *obj, PropertyName *name, uintN attrs)
{
return CheckRedeclaration(cx, obj, ATOM_TO_JSID(name), attrs);
}
extern bool
StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *equal);

Просмотреть файл

@ -5030,11 +5030,9 @@ js_LookupElement(JSContext *cx, JSObject *obj, uint32_t index, JSObject **objp,
return LookupPropertyWithFlagsInline(cx, obj, id, cx->resolveFlags, objp, propp);
}
namespace js {
bool
LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp, JSProperty **propp)
js::LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp, JSProperty **propp)
{
/* Convert string indices to integers if appropriate. */
id = js_CheckForStringIndex(id);
@ -5042,12 +5040,11 @@ LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
return LookupPropertyWithFlagsInline(cx, obj, id, flags, objp, propp);
}
} /* namespace js */
PropertyCacheEntry *
js_FindPropertyHelper(JSContext *cx, jsid id, bool cacheResult, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
js::FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
{
jsid id = ATOM_TO_JSID(name);
JSObject *scopeChain, *obj, *parent, *pobj;
PropertyCacheEntry *entry;
int scopeIndex;
@ -5152,15 +5149,15 @@ js_FindPropertyHelper(JSContext *cx, jsid id, bool cacheResult, bool global,
* On return, if |*pobjp| is a native object, then |*propp| is a |Shape *|.
* Otherwise, its type and meaning depends on the host object's implementation.
*/
JS_FRIEND_API(JSBool)
js_FindProperty(JSContext *cx, jsid id, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
bool
js::FindProperty(JSContext *cx, PropertyName *name, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
{
return !!js_FindPropertyHelper(cx, id, false, global, objp, pobjp, propp);
return !!FindPropertyHelper(cx, name, false, global, objp, pobjp, propp);
}
JSObject *
js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id)
js::FindIdentifierBase(JSContext *cx, JSObject *scopeChain, PropertyName *name)
{
/*
* This function should not be called for a global object or from the
@ -5184,7 +5181,7 @@ js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id)
scopeIndex++) {
JSObject *pobj;
JSProperty *prop;
if (!LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags, &pobj, &prop))
if (!LookupPropertyWithFlags(cx, obj, name, cx->resolveFlags, &pobj, &prop))
return NULL;
if (prop) {
if (!pobj->isNative()) {
@ -5208,7 +5205,7 @@ js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id)
do {
JSObject *pobj;
JSProperty *prop;
if (!obj->lookupGeneric(cx, id, &pobj, &prop))
if (!obj->lookupProperty(cx, name, &pobj, &prop))
return NULL;
if (prop)
break;
@ -5419,10 +5416,10 @@ js_GetPropertyHelperInline(JSContext *cx, JSObject *obj, JSObject *receiver, jsi
return JS_TRUE;
}
JSBool
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32_t getHow, Value *vp)
bool
js::GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32_t getHow, Value *vp)
{
return js_GetPropertyHelperInline(cx, obj, obj, id, getHow, vp);
return !!js_GetPropertyHelperInline(cx, obj, obj, id, getHow, vp);
}
JSBool
@ -5469,7 +5466,7 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, Value *vp)
#if JS_HAS_XML_SUPPORT
JS_ASSERT(!obj->isXML());
#endif
return js_GetPropertyHelper(cx, obj, id, getHow, vp);
return GetPropertyHelper(cx, obj, id, getHow, vp);
}
JS_ASSERT_IF(getHow & JSGET_CACHE_RESULT, obj->isDenseArray());
#if JS_HAS_XML_SUPPORT

Просмотреть файл

@ -50,6 +50,7 @@
* is reference counted and the slot vector is malloc'ed.
*/
#include "jsapi.h"
#include "jsatom.h"
#include "jsclass.h"
#include "jsfriendapi.h"
#include "jsinfer.h"
@ -246,6 +247,17 @@ extern JS_FRIEND_API(JSBool)
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
JSProperty **propp);
namespace js {
inline bool
LookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
JSObject **objp, JSProperty **propp)
{
return js_LookupProperty(cx, obj, ATOM_TO_JSID(name), objp, propp);
}
}
extern JS_FRIEND_API(JSBool)
js_LookupElement(JSContext *cx, JSObject *obj, uint32_t index,
JSObject **objp, JSProperty **propp);
@ -287,6 +299,17 @@ extern JSBool
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
js::Value *vp, JSBool strict);
namespace js {
inline bool
SetPropertyHelper(JSContext *cx, JSObject *obj, PropertyName *name, uintN defineHow,
Value *vp, JSBool strict)
{
return !!js_SetPropertyHelper(cx, obj, ATOM_TO_JSID(name), defineHow, vp, strict);
}
} /* namespace js */
extern JSBool
js_SetElementHelper(JSContext *cx, JSObject *obj, uint32_t index, uintN defineHow,
js::Value *vp, JSBool strict);
@ -1231,6 +1254,12 @@ struct JSObject : js::gc::Cell
JSPropertyOp getter, JSStrictPropertyOp setter,
uint32_t slot, uintN attrs,
uintN flags, intN shortid);
inline js::Shape *
putProperty(JSContext *cx, js::PropertyName *name,
JSPropertyOp getter, JSStrictPropertyOp setter,
uint32_t slot, uintN attrs, uintN flags, intN shortid) {
return putProperty(cx, js_CheckForStringIndex(ATOM_TO_JSID(name)), getter, setter, slot, attrs, flags, shortid);
}
/* Change the given property into a sibling with the same id in this scope. */
js::Shape *changeProperty(JSContext *cx, js::Shape *shape, uintN attrs, uintN mask,
@ -1730,10 +1759,19 @@ const uintN DNP_SKIP_TYPE = 0x10; /* Don't update type information */
* Return successfully added or changed shape or NULL on error.
*/
extern const Shape *
DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const js::Value &value,
DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value,
PropertyOp getter, StrictPropertyOp setter, uintN attrs,
uintN flags, intN shortid, uintN defineHow = 0);
inline const Shape *
DefineNativeProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value &value,
PropertyOp getter, StrictPropertyOp setter, uintN attrs,
uintN flags, intN shortid, uintN defineHow = 0)
{
return DefineNativeProperty(cx, obj, ATOM_TO_JSID(name), value, getter, setter, attrs, flags,
shortid, defineHow);
}
/*
* Specialized subroutine that allows caller to preset JSRESOLVE_* flags.
*/
@ -1741,6 +1779,12 @@ extern bool
LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp, JSProperty **propp);
inline bool
LookupPropertyWithFlags(JSContext *cx, JSObject *obj, PropertyName *name, uintN flags,
JSObject **objp, JSProperty **propp)
{
return LookupPropertyWithFlags(cx, obj, ATOM_TO_JSID(name), flags, objp, propp);
}
/*
* Call the [[DefineOwnProperty]] internal method of obj.
@ -1768,25 +1812,25 @@ ReadPropertyDescriptors(JSContext *cx, JSObject *props, bool checkAccessors,
*/
static const uintN RESOLVE_INFER = 0xffff;
}
/*
* If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success.
*/
extern js::PropertyCacheEntry *
js_FindPropertyHelper(JSContext *cx, jsid id, bool cacheResult, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp);
extern PropertyCacheEntry *
FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp);
/*
* Search for id either on the current scope chain or on the scope chain's
* Search for name either on the current scope chain or on the scope chain's
* global object, per the global parameter.
*/
extern JS_FRIEND_API(JSBool)
js_FindProperty(JSContext *cx, jsid id, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp);
extern bool
FindProperty(JSContext *cx, PropertyName *name, bool global,
JSObject **objp, JSObject **pobjp, JSProperty **propp);
extern JSObject *
js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id);
FindIdentifierBase(JSContext *cx, JSObject *scopeChain, PropertyName *name);
}
extern JSObject *
js_FindVariableScope(JSContext *cx, JSFunction **funp);
@ -1822,11 +1866,17 @@ extern JSBool
js_NativeSet(JSContext *cx, JSObject *obj, const js::Shape *shape, bool added,
bool strict, js::Value *vp);
extern JSBool
js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32_t getHow, js::Value *vp);
namespace js {
bool
GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uint32_t getHow, Value *vp);
inline bool
GetPropertyHelper(JSContext *cx, JSObject *obj, PropertyName *name, uint32_t getHow, Value *vp)
{
return GetPropertyHelper(cx, obj, ATOM_TO_JSID(name), getHow, vp);
}
bool
GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, PropertyDescriptor *desc);
@ -1841,6 +1891,16 @@ NewPropertyDescriptorObject(JSContext *cx, const PropertyDescriptor *desc, Value
extern JSBool
js_GetMethod(JSContext *cx, JSObject *obj, jsid id, uintN getHow, js::Value *vp);
namespace js {
inline bool
GetMethod(JSContext *cx, JSObject *obj, PropertyName *name, uintN getHow, Value *vp)
{
return js_GetMethod(cx, obj, ATOM_TO_JSID(name), getHow, vp);
}
} /* namespace js */
/*
* Change attributes for the given native property. The caller must ensure
* that obj is locked and this function always unlocks obj on return.

Просмотреть файл

@ -341,10 +341,19 @@ js_GetIndexFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff);
#define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom) \
JS_BEGIN_MACRO \
JS_ASSERT(*(pc) != JSOP_DOUBLE); \
JS_ASSERT(js_CodeSpec[*(pc)].format & JOF_ATOM); \
uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff)); \
(atom) = (script)->getAtom(index_); \
JS_END_MACRO
#define GET_NAME_FROM_BYTECODE(script, pc, pcoff, name) \
JS_BEGIN_MACRO \
JSAtom *atom_; \
GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom_); \
JS_ASSERT(js_CodeSpec[*(pc)].format & (JOF_NAME | JOF_PROP)); \
(name) = atom_->asPropertyName(); \
JS_END_MACRO
#define GET_DOUBLE_FROM_BYTECODE(script, pc, pcoff, dbl) \
JS_BEGIN_MACRO \
uintN index_ = js_GetIndexFromBytecode((script), (pc), (pcoff)); \

Просмотреть файл

@ -158,8 +158,8 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, JSObject *po
return entry;
}
static inline JSAtom *
GetAtomFromBytecode(JSContext *cx, jsbytecode *pc, JSOp op, const JSCodeSpec &cs)
static inline PropertyName *
GetNameFromBytecode(JSContext *cx, jsbytecode *pc, JSOp op, const JSCodeSpec &cs)
{
if (op == JSOP_LENGTH)
return cx->runtime->atomState.lengthAtom;
@ -171,12 +171,12 @@ GetAtomFromBytecode(JSContext *cx, jsbytecode *pc, JSOp op, const JSCodeSpec &cs
JSScript *script = cx->stack.currentScript();
ptrdiff_t pcoff = (JOF_TYPE(cs.format) == JOF_SLOTATOM) ? SLOTNO_LEN : 0;
JSAtom *atom;
GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom);
return atom;
PropertyName *name;
GET_NAME_FROM_BYTECODE(script, pc, pcoff, name);
return name;
}
JSAtom *
PropertyName *
PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject **pobjp,
PropertyCacheEntry *entry)
{
@ -196,13 +196,13 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
if (entry->kpc != pc) {
PCMETER(kpcmisses++);
JSAtom *atom = GetAtomFromBytecode(cx, pc, op, cs);
PropertyName *name = GetNameFromBytecode(cx, pc, op, cs);
#ifdef DEBUG_notme
JSAutoByteString printable;
fprintf(stderr,
"id miss for %s from %s:%u"
" (pc %u, kpc %u, kshape %p, shape %p)\n",
js_AtomToPrintableString(cx, atom, &printable),
js_AtomToPrintableString(cx, name, &printable),
script->filename,
js_PCToLineNumber(cx, script, pc),
pc - script->code,
@ -214,12 +214,12 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
JS_FALSE, stderr);
#endif
return atom;
return name;
}
if (entry->kshape != obj->lastProperty()) {
PCMETER(kshapemisses++);
return GetAtomFromBytecode(cx, pc, op, cs);
return GetNameFromBytecode(cx, pc, op, cs);
}
/*
@ -252,18 +252,15 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
if (pobj->lastProperty() == entry->pshape) {
#ifdef DEBUG
JSAtom *atom = GetAtomFromBytecode(cx, pc, op, cs);
jsid id = ATOM_TO_JSID(atom);
id = js_CheckForStringIndex(id);
JS_ASSERT(pobj->nativeContains(cx, id));
PropertyName *name = GetNameFromBytecode(cx, pc, op, cs);
JS_ASSERT(pobj->nativeContains(cx, js_CheckForStringIndex(ATOM_TO_JSID(name))));
#endif
*pobjp = pobj;
return NULL;
}
PCMETER(vcapmisses++);
return GetAtomFromBytecode(cx, pc, op, cs);
return GetNameFromBytecode(cx, pc, op, cs);
}
#ifdef DEBUG

Просмотреть файл

@ -45,6 +45,8 @@
#include "jsprvtd.h"
#include "jstypes.h"
#include "vm/String.h"
namespace js {
/*
@ -180,8 +182,9 @@ class PropertyCache
static inline bool matchShape(JSContext *cx, JSObject *obj, uint32_t shape);
JSAtom *fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp,
JSObject **pobjp, PropertyCacheEntry *entry);
PropertyName *
fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp,
JSObject **pobjp, PropertyCacheEntry *entry);
#ifdef DEBUG
void assertEmpty();
@ -192,18 +195,18 @@ class PropertyCache
public:
JS_ALWAYS_INLINE void test(JSContext *cx, jsbytecode *pc,
JSObject *&obj, JSObject *&pobj,
PropertyCacheEntry *&entry, JSAtom *&atom);
PropertyCacheEntry *&entry, PropertyName *&name);
/*
* Test for cached information about a property set on *objp at pc.
*
* On a hit, set *entryp to the entry and return true.
*
* On a miss, set *atomp to the name of the property being set and return false.
* On a miss, set *namep to the name of the property being set and return false.
*/
JS_ALWAYS_INLINE bool testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj,
PropertyCacheEntry **entryp, JSObject **obj2p,
JSAtom **atomp);
PropertyName **namep);
/*
* Fill property cache entry for key cx->fp->pc, optimized value word

Просмотреть файл

@ -54,10 +54,10 @@ using namespace js;
* same variable, since for JOF_PROP-mode opcodes, obj must not be changed
* because of a cache miss.
*
* On return, if atom is null then obj points to the scope chain element in
* which the property was found, pobj is locked, and entry is valid. If atom is
* On return, if name is null then obj points to the scope chain element in
* which the property was found, pobj is locked, and entry is valid. If name is
* non-null then no object is locked but entry is still set correctly for use,
* e.g., by PropertyCache::fill and atom should be used as the id to find.
* e.g., by PropertyCache::fill and name should be used as the id to find.
*
* We must lock pobj on a hit in order to close races with threads that might
* be deleting a property from its scope, or otherwise invalidating property
@ -65,7 +65,7 @@ using namespace js;
*/
JS_ALWAYS_INLINE void
PropertyCache::test(JSContext *cx, jsbytecode *pc, JSObject *&obj,
JSObject *&pobj, PropertyCacheEntry *&entry, JSAtom *&atom)
JSObject *&pobj, PropertyCacheEntry *&entry, PropertyName *&name)
{
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
@ -85,18 +85,18 @@ PropertyCache::test(JSContext *cx, jsbytecode *pc, JSObject *&obj,
if (pobj->lastProperty() == entry->pshape) {
PCMETER(pchits++);
PCMETER(entry->isOwnPropertyHit() || protopchits++);
atom = NULL;
name = NULL;
return;
}
}
atom = fullTest(cx, pc, &obj, &pobj, entry);
if (atom)
name = fullTest(cx, pc, &obj, &pobj, entry);
if (name)
PCMETER(misses++);
}
JS_ALWAYS_INLINE bool
PropertyCache::testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj,
PropertyCacheEntry **entryp, JSObject **obj2p, JSAtom **atomp)
PropertyCacheEntry **entryp, JSObject **obj2p, PropertyName **namep)
{
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
@ -109,13 +109,13 @@ PropertyCache::testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj,
if (entry->kpc == pc && entry->kshape == kshape)
return true;
JSAtom *atom = fullTest(cx, pc, &obj, obj2p, entry);
JS_ASSERT(atom);
PropertyName *name = fullTest(cx, pc, &obj, obj2p, entry);
JS_ASSERT(name);
PCMETER(misses++);
PCMETER(setmisses++);
*atomp = atom;
*namep = name;
return false;
}

Просмотреть файл

@ -728,6 +728,10 @@ struct JSScript : public js::gc::Cell {
return atoms[index];
}
js::PropertyName *getName(size_t index) {
return getAtom(index)->asPropertyName();
}
JSObject *getObject(size_t index) {
JSObjectArray *arr = objects();
JS_ASSERT(index < arr->length);

Просмотреть файл

@ -1966,10 +1966,10 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_DELNAME)
{
uint32_t index = fullAtomIndex(PC);
JSAtom *atom = script->getAtom(index);
PropertyName *name = script->getName(index);
prepareStubCall(Uses(0));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(stubs::DelName, REJOIN_FALLTHROUGH);
pushSyncedEntry(0);
}
@ -1978,10 +1978,10 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_DELPROP)
{
uint32_t index = fullAtomIndex(PC);
JSAtom *atom = script->getAtom(index);
PropertyName *name = script->getName(index);
prepareStubCall(Uses(1));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(STRICT_VARIANT(stubs::DelProp), REJOIN_FALLTHROUGH);
frame.pop();
pushSyncedEntry(0);
@ -2009,7 +2009,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_GETPROP)
BEGIN_CASE(JSOP_LENGTH)
if (!jsop_getprop(script->getAtom(fullAtomIndex(PC)), knownPushedType(0)))
if (!jsop_getprop(script->getName(fullAtomIndex(PC)), knownPushedType(0)))
return Compile_Error;
END_CASE(JSOP_GETPROP)
@ -2084,17 +2084,17 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_NAME)
{
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
jsop_name(atom, knownPushedType(0), false);
frame.extra(frame.peek(-1)).name = atom;
PropertyName *name = script->getName(fullAtomIndex(PC));
jsop_name(name, knownPushedType(0), false);
frame.extra(frame.peek(-1)).name = name;
}
END_CASE(JSOP_NAME)
BEGIN_CASE(JSOP_CALLNAME)
{
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
jsop_name(atom, knownPushedType(0), true);
frame.extra(frame.peek(-2)).name = atom;
PropertyName *name = script->getName(fullAtomIndex(PC));
jsop_name(name, knownPushedType(0), true);
frame.extra(frame.peek(-2)).name = name;
}
END_CASE(JSOP_CALLNAME)
@ -2402,14 +2402,14 @@ mjit::Compiler::generateMethod()
END_CASE(JSOP_LOCALDEC)
BEGIN_CASE(JSOP_BINDNAME)
jsop_bindname(script->getAtom(fullAtomIndex(PC)), true);
jsop_bindname(script->getName(fullAtomIndex(PC)), true);
END_CASE(JSOP_BINDNAME)
BEGIN_CASE(JSOP_SETPROP)
{
jsbytecode *next = &PC[JSOP_SETPROP_LENGTH];
bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
if (!jsop_setprop(script->getAtom(fullAtomIndex(PC)), true, pop))
if (!jsop_setprop(script->getName(fullAtomIndex(PC)), true, pop))
return Compile_Error;
}
END_CASE(JSOP_SETPROP)
@ -2419,7 +2419,7 @@ mjit::Compiler::generateMethod()
{
jsbytecode *next = &PC[JSOP_SETNAME_LENGTH];
bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
if (!jsop_setprop(script->getAtom(fullAtomIndex(PC)), true, pop))
if (!jsop_setprop(script->getName(fullAtomIndex(PC)), true, pop))
return Compile_Error;
}
END_CASE(JSOP_SETNAME)
@ -2506,10 +2506,10 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_DEFCONST)
{
uint32_t index = fullAtomIndex(PC);
JSAtom *atom = script->getAtom(index);
PropertyName *name = script->getName(index);
prepareStubCall(Uses(0));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(stubs::DefVarOrConst, REJOIN_FALLTHROUGH);
}
END_CASE(JSOP_DEFVAR)
@ -2517,10 +2517,10 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_SETCONST)
{
uint32_t index = fullAtomIndex(PC);
JSAtom *atom = script->getAtom(index);
PropertyName *name = script->getName(index);
prepareStubCall(Uses(1));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(stubs::SetConst, REJOIN_FALLTHROUGH);
}
END_CASE(JSOP_SETCONST)
@ -2633,7 +2633,7 @@ mjit::Compiler::generateMethod()
{
uint32_t index = fullAtomIndex(PC);
jsop_getgname(index);
frame.extra(frame.peek(-1)).name = script->getAtom(index);
frame.extra(frame.peek(-1)).name = script->getName(index);
if (op == JSOP_CALLGNAME)
jsop_callgname_epilogue();
}
@ -2643,7 +2643,7 @@ mjit::Compiler::generateMethod()
{
jsbytecode *next = &PC[JSOP_SETGNAME_LENGTH];
bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
jsop_setgname(script->getAtom(fullAtomIndex(PC)), true, pop);
jsop_setgname(script->getName(fullAtomIndex(PC)), true, pop);
}
END_CASE(JSOP_SETGNAME)
@ -2662,7 +2662,7 @@ mjit::Compiler::generateMethod()
END_CASE(JSOP_OBJECT)
BEGIN_CASE(JSOP_CALLPROP)
if (!jsop_callprop(script->getAtom(fullAtomIndex(PC))))
if (!jsop_callprop(script->getName(fullAtomIndex(PC))))
return Compile_Error;
END_CASE(JSOP_CALLPROP)
@ -2684,7 +2684,7 @@ mjit::Compiler::generateMethod()
END_CASE(JSOP_STOP)
BEGIN_CASE(JSOP_GETXPROP)
if (!jsop_xname(script->getAtom(fullAtomIndex(PC))))
if (!jsop_xname(script->getName(fullAtomIndex(PC))))
return Compile_Error;
END_CASE(JSOP_GETXPROP)
@ -4386,10 +4386,10 @@ mjit::Compiler::emitStubCmpOp(BoolStub stub, jsbytecode *target, JSOp fused)
}
void
mjit::Compiler::jsop_setprop_slow(JSAtom *atom, bool usePropCache)
mjit::Compiler::jsop_setprop_slow(PropertyName *name, bool usePropCache)
{
prepareStubCall(Uses(2));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
if (usePropCache)
INLINE_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
else
@ -4401,7 +4401,7 @@ mjit::Compiler::jsop_setprop_slow(JSAtom *atom, bool usePropCache)
}
void
mjit::Compiler::jsop_getprop_slow(JSAtom *atom, bool usePropCache)
mjit::Compiler::jsop_getprop_slow(PropertyName *name, bool usePropCache)
{
/* See ::jsop_getprop */
RejoinState rejoin = usePropCache ? REJOIN_GETTER : REJOIN_THIS_PROTOTYPE;
@ -4411,7 +4411,7 @@ mjit::Compiler::jsop_getprop_slow(JSAtom *atom, bool usePropCache)
INLINE_STUBCALL(stubs::GetProp, rejoin);
testPushedType(rejoin, -1, /* ool = */ false);
} else {
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(stubs::GetPropNoCache, rejoin);
}
@ -4423,10 +4423,10 @@ mjit::Compiler::jsop_getprop_slow(JSAtom *atom, bool usePropCache)
}
bool
mjit::Compiler::jsop_callprop_slow(JSAtom *atom)
mjit::Compiler::jsop_callprop_slow(PropertyName *name)
{
prepareStubCall(Uses(1));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
INLINE_STUBCALL(stubs::CallProp, REJOIN_FALLTHROUGH);
testPushedType(REJOIN_FALLTHROUGH, -1, /* ool = */ false);
frame.pop();
@ -4453,7 +4453,7 @@ mjit::Compiler::passICAddress(BaseICInfo *ic)
}
bool
mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
bool doTypeCheck, bool usePropCache)
{
FrameEntry *top = frame.peek(-1);
@ -4466,12 +4466,12 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
RejoinState rejoin = REJOIN_GETTER;
if (!usePropCache) {
JS_ASSERT(top->isType(JSVAL_TYPE_OBJECT) &&
atom == cx->runtime->atomState.classPrototypeAtom);
name == cx->runtime->atomState.classPrototypeAtom);
rejoin = REJOIN_THIS_PROTOTYPE;
}
/* Handle length accesses on known strings without using a PIC. */
if (atom == cx->runtime->atomState.lengthAtom &&
if (name == cx->runtime->atomState.lengthAtom &&
top->isType(JSVAL_TYPE_STRING) &&
(!cx->typeInferenceEnabled() || knownPushedType(0) == JSVAL_TYPE_INT32)) {
if (top->isConstant()) {
@ -4492,7 +4492,7 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
/* If the incoming type will never PIC, take slow path. */
if (top->isNotType(JSVAL_TYPE_OBJECT)) {
jsop_getprop_slow(atom, usePropCache);
jsop_getprop_slow(name, usePropCache);
return true;
}
@ -4586,8 +4586,7 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
/* Check if this is a property access we can make a loop invariant entry for. */
if (loop && loop->generatingInvariants() && !hasTypeBarriers(PC)) {
CrossSSAValue topv(a->inlineIndex, analysis->poppedValue(PC, 0));
FrameEntry *fe = loop->invariantProperty(topv, ATOM_TO_JSID(atom));
if (fe) {
if (FrameEntry *fe = loop->invariantProperty(topv, ATOM_TO_JSID(name))) {
if (knownType != JSVAL_TYPE_UNKNOWN && knownType != JSVAL_TYPE_DOUBLE)
frame.learnType(fe, knownType, false);
frame.pop();
@ -4603,7 +4602,7 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
* in a particular inline slot. Get the property directly in this case,
* without using an IC.
*/
jsid id = ATOM_TO_JSID(atom);
jsid id = ATOM_TO_JSID(name);
types::TypeSet *types = frame.extra(top).types;
if (types && !types->unknownObject() &&
types->getObjectCount() == 1 &&
@ -4654,7 +4653,7 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
*/
RegisterID objReg = Registers::ReturnReg;
RegisterID shapeReg = Registers::ReturnReg;
if (atom == cx->runtime->atomState.lengthAtom) {
if (name == cx->runtime->atomState.lengthAtom) {
objReg = frame.copyDataIntoReg(top);
shapeReg = frame.allocReg();
}
@ -4683,7 +4682,7 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
pic.typeReg = Registers::ReturnReg;
}
if (atom != cx->runtime->atomState.lengthAtom) {
if (name != cx->runtime->atomState.lengthAtom) {
objReg = frame.copyDataIntoReg(top);
shapeReg = frame.allocReg();
}
@ -4699,13 +4698,13 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
pic.canCallHook = pic.forcedTypeBarrier =
usePropCache &&
JSOp(*PC) == JSOP_GETPROP &&
atom != cx->runtime->atomState.lengthAtom &&
name != cx->runtime->atomState.lengthAtom &&
analysis->getCode(PC).accessGetter;
if (pic.canCallHook)
frame.syncAndKillEverything();
pic.shapeReg = shapeReg;
pic.atom = atom;
pic.name = name;
/* Guard on shape. */
masm.loadShape(objReg, shapeReg);
@ -4764,7 +4763,7 @@ mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType,
}
bool
mjit::Compiler::jsop_callprop_generic(JSAtom *atom)
mjit::Compiler::jsop_callprop_generic(PropertyName *name)
{
FrameEntry *top = frame.peek(-1);
@ -4809,7 +4808,7 @@ mjit::Compiler::jsop_callprop_generic(JSAtom *atom)
pic.hasTypeCheck = true;
pic.objReg = objReg;
pic.shapeReg = shapeReg;
pic.atom = atom;
pic.name = name;
/*
* Store the type and object back. Don't bother keeping them in registers,
@ -4887,10 +4886,10 @@ mjit::Compiler::jsop_callprop_generic(JSAtom *atom)
}
bool
mjit::Compiler::jsop_callprop_str(JSAtom *atom)
mjit::Compiler::jsop_callprop_str(PropertyName *name)
{
if (!globalObj) {
jsop_callprop_slow(atom);
jsop_callprop_slow(name);
return true;
}
@ -4906,7 +4905,7 @@ mjit::Compiler::jsop_callprop_str(JSAtom *atom)
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, reg);
/* Get the property. */
if (!jsop_getprop(atom, knownPushedType(0)))
if (!jsop_getprop(name, knownPushedType(0)))
return false;
/* Perform a swap. */
@ -4935,7 +4934,7 @@ mjit::Compiler::jsop_callprop_str(JSAtom *atom)
}
bool
mjit::Compiler::jsop_callprop_obj(JSAtom *atom)
mjit::Compiler::jsop_callprop_obj(PropertyName *name)
{
FrameEntry *top = frame.peek(-1);
@ -4956,7 +4955,7 @@ mjit::Compiler::jsop_callprop_obj(JSAtom *atom)
RegisterID shapeReg = frame.allocReg();
pic.shapeReg = shapeReg;
pic.atom = atom;
pic.name = name;
RegisterID objReg;
if (top->isConstant()) {
@ -5140,7 +5139,7 @@ mjit::Compiler::testSingletonPropertyTypes(FrameEntry *top, jsid id, bool *testO
}
bool
mjit::Compiler::jsop_callprop_dispatch(JSAtom *atom)
mjit::Compiler::jsop_callprop_dispatch(PropertyName *name)
{
/*
* Check for a CALLPROP which is a dynamic dispatch: every value it can
@ -5152,7 +5151,7 @@ mjit::Compiler::jsop_callprop_dispatch(JSAtom *atom)
if (top->isNotType(JSVAL_TYPE_OBJECT))
return false;
jsid id = ATOM_TO_JSID(atom);
jsid id = ATOM_TO_JSID(name);
if (id != types::MakeTypeId(cx, id))
return false;
@ -5274,7 +5273,7 @@ mjit::Compiler::jsop_callprop_dispatch(JSAtom *atom)
rejoins[i].linkTo(masm.label(), &masm);
stubcc.leave();
stubcc.masm.move(ImmPtr(atom), Registers::ArgReg1);
stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
OOL_STUBCALL(stubs::CallProp, REJOIN_FALLTHROUGH);
testPushedType(REJOIN_FALLTHROUGH, -1);
@ -5295,7 +5294,7 @@ mjit::Compiler::jsop_callprop_dispatch(JSAtom *atom)
}
bool
mjit::Compiler::jsop_callprop(JSAtom *atom)
mjit::Compiler::jsop_callprop(PropertyName *name)
{
FrameEntry *top = frame.peek(-1);
@ -5303,12 +5302,12 @@ mjit::Compiler::jsop_callprop(JSAtom *atom)
bool testObject;
JSObject *singleton = pushedSingleton(0);
if (singleton && singleton->isFunction() && !hasTypeBarriers(PC) &&
testSingletonPropertyTypes(top, ATOM_TO_JSID(atom), &testObject)) {
testSingletonPropertyTypes(top, ATOM_TO_JSID(name), &testObject)) {
if (testObject) {
Jump notObject = frame.testObject(Assembler::NotEqual, top);
stubcc.linkExit(notObject, Uses(1));
stubcc.leave();
stubcc.masm.move(ImmPtr(atom), Registers::ArgReg1);
stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
OOL_STUBCALL(stubs::CallProp, REJOIN_FALLTHROUGH);
testPushedType(REJOIN_FALLTHROUGH, -1);
}
@ -5335,31 +5334,31 @@ mjit::Compiler::jsop_callprop(JSAtom *atom)
/* Check for a dynamic dispatch. */
if (cx->typeInferenceEnabled()) {
if (jsop_callprop_dispatch(atom))
if (jsop_callprop_dispatch(name))
return true;
}
/* If the incoming type will never PIC, take slow path. */
if (top->isTypeKnown() && top->getKnownType() != JSVAL_TYPE_OBJECT) {
if (top->getKnownType() == JSVAL_TYPE_STRING)
return jsop_callprop_str(atom);
return jsop_callprop_slow(atom);
return jsop_callprop_str(name);
return jsop_callprop_slow(name);
}
if (top->isTypeKnown())
return jsop_callprop_obj(atom);
return jsop_callprop_generic(atom);
return jsop_callprop_obj(name);
return jsop_callprop_generic(name);
}
bool
mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed)
mjit::Compiler::jsop_setprop(PropertyName *name, bool usePropCache, bool popGuaranteed)
{
FrameEntry *lhs = frame.peek(-2);
FrameEntry *rhs = frame.peek(-1);
/* If the incoming type will never PIC, take slow path. */
if (lhs->isTypeKnown() && lhs->getKnownType() != JSVAL_TYPE_OBJECT) {
jsop_setprop_slow(atom, usePropCache);
jsop_setprop_slow(name, usePropCache);
return true;
}
@ -5369,7 +5368,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed
*/
if (cx->typeInferenceEnabled() && js_CodeSpec[*PC].format & JOF_NAME) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(atom), true);
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
if (access.nesting) {
/* Use a SavedReg so it isn't clobbered by the stub call. */
RegisterID nameReg = frame.allocReg(Registers::SavedRegs).reg();
@ -5397,7 +5396,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed
* Set the property directly if we are accessing a known object which
* always has the property in a particular inline slot.
*/
jsid id = ATOM_TO_JSID(atom);
jsid id = ATOM_TO_JSID(name);
types::TypeSet *types = frame.extra(lhs).types;
if (JSOp(*PC) == JSOP_SETPROP && id == types::MakeTypeId(cx, id) &&
types && !types->unknownObject() &&
@ -5435,7 +5434,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed
if (!isObject) {
stubcc.linkExit(notObject.get(), Uses(2));
stubcc.leave();
stubcc.masm.move(ImmPtr(atom), Registers::ArgReg1);
stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
OOL_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
}
frame.storeTo(rhs, Address(reg, JSObject::getFixedSlotOffset(slot)), popGuaranteed);
@ -5454,7 +5453,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed
#ifdef JSGC_INCREMENTAL_MJ
/* Write barrier. */
if (cx->compartment->needsBarrier() && (!types || types->propertyNeedsBarrier(cx, id))) {
jsop_setprop_slow(atom, usePropCache);
jsop_setprop_slow(name, usePropCache);
return true;
}
#endif
@ -5465,7 +5464,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed
? ic::PICInfo::SETMETHOD
: ic::PICInfo::SET;
PICGenInfo pic(kind, op, usePropCache);
pic.atom = atom;
pic.name = name;
if (monitored(PC)) {
pic.typeMonitored = true;
@ -5499,7 +5498,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed
pic.typeCheck = stubcc.linkExit(j, Uses(2));
stubcc.leave();
stubcc.masm.move(ImmPtr(atom), Registers::ArgReg1);
stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
if (usePropCache)
OOL_STUBCALL(STRICT_VARIANT(stubs::SetName), REJOIN_FALLTHROUGH);
else
@ -5581,7 +5580,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed
}
void
mjit::Compiler::jsop_name(JSAtom *atom, JSValueType type, bool isCall)
mjit::Compiler::jsop_name(PropertyName *name, JSValueType type, bool isCall)
{
/*
* If this is a NAME for a variable of a non-reentrant outer function, get
@ -5590,7 +5589,7 @@ mjit::Compiler::jsop_name(JSAtom *atom, JSValueType type, bool isCall)
*/
if (cx->typeInferenceEnabled()) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(atom), true);
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
if (access.nesting) {
Address address = frame.loadNameAddress(access);
JSValueType type = knownPushedType(0);
@ -5610,7 +5609,7 @@ mjit::Compiler::jsop_name(JSAtom *atom, JSValueType type, bool isCall)
pic.shapeReg = frame.allocReg();
pic.objReg = frame.allocReg();
pic.typeReg = Registers::ReturnReg;
pic.atom = atom;
pic.name = name;
pic.hasTypeCheck = false;
pic.fastPathStart = masm.label();
@ -5661,7 +5660,7 @@ mjit::Compiler::jsop_name(JSAtom *atom, JSValueType type, bool isCall)
}
bool
mjit::Compiler::jsop_xname(JSAtom *atom)
mjit::Compiler::jsop_xname(PropertyName *name)
{
/*
* If this is a GETXPROP for a variable of a non-reentrant outer function,
@ -5669,7 +5668,7 @@ mjit::Compiler::jsop_xname(JSAtom *atom)
*/
if (cx->typeInferenceEnabled()) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(atom), true);
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
if (access.nesting) {
frame.pop();
Address address = frame.loadNameAddress(access);
@ -5685,7 +5684,7 @@ mjit::Compiler::jsop_xname(JSAtom *atom)
FrameEntry *fe = frame.peek(-1);
if (fe->isNotType(JSVAL_TYPE_OBJECT)) {
return jsop_getprop(atom, knownPushedType(0));
return jsop_getprop(name, knownPushedType(0));
}
if (!fe->isTypeKnown()) {
@ -5700,7 +5699,7 @@ mjit::Compiler::jsop_xname(JSAtom *atom)
pic.shapeReg = frame.allocReg();
pic.objReg = frame.copyDataIntoReg(fe);
pic.typeReg = Registers::ReturnReg;
pic.atom = atom;
pic.name = name;
pic.hasTypeCheck = false;
pic.fastPathStart = masm.label();
@ -5741,7 +5740,7 @@ mjit::Compiler::jsop_xname(JSAtom *atom)
}
void
mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
mjit::Compiler::jsop_bindname(PropertyName *name, bool usePropCache)
{
/*
* If this is a BINDNAME for a variable of a non-reentrant outer function,
@ -5749,7 +5748,7 @@ mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
*/
if (cx->typeInferenceEnabled()) {
ScriptAnalysis::NameAccess access =
analysis->resolveNameAccess(cx, ATOM_TO_JSID(atom), true);
analysis->resolveNameAccess(cx, ATOM_TO_JSID(name), true);
if (access.nesting) {
RegisterID reg = frame.allocReg();
JSObject **pobj = &access.nesting->activeCall;
@ -5771,7 +5770,7 @@ mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
pic.shapeReg = frame.allocReg();
pic.objReg = frame.allocReg();
pic.typeReg = Registers::ReturnReg;
pic.atom = atom;
pic.name = name;
pic.hasTypeCheck = false;
RESERVE_IC_SPACE(masm);
@ -5810,7 +5809,7 @@ mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
#else /* !JS_POLYIC */
void
mjit::Compiler::jsop_name(JSAtom *atom, JSValueType type, bool isCall)
mjit::Compiler::jsop_name(PropertyName *name, JSValueType type, bool isCall)
{
prepareStubCall(Uses(0));
INLINE_STUBCALL(isCall ? stubs::CallName : stubs::Name, REJOIN_FALLTHROUGH);
@ -5821,34 +5820,34 @@ mjit::Compiler::jsop_name(JSAtom *atom, JSValueType type, bool isCall)
}
bool
mjit::Compiler::jsop_xname(JSAtom *atom)
mjit::Compiler::jsop_xname(PropertyName *name)
{
return jsop_getprop(atom, knownPushedType(0), pushedTypeSet(0));
return jsop_getprop(name, knownPushedType(0), pushedTypeSet(0));
}
bool
mjit::Compiler::jsop_getprop(JSAtom *atom, JSValueType knownType, types::TypeSet *typeSet,
mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType, types::TypeSet *typeSet,
bool typecheck, bool usePropCache)
{
jsop_getprop_slow(atom, usePropCache);
jsop_getprop_slow(name, usePropCache);
return true;
}
bool
mjit::Compiler::jsop_callprop(JSAtom *atom)
mjit::Compiler::jsop_callprop(PropertyName *name)
{
return jsop_callprop_slow(atom);
return jsop_callprop_slow(name);
}
bool
mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache)
mjit::Compiler::jsop_setprop(PropertyName *name, bool usePropCache)
{
jsop_setprop_slow(atom, usePropCache);
jsop_setprop_slow(name, usePropCache);
return true;
}
void
mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
mjit::Compiler::jsop_bindname(PropertyName *name, bool usePropCache)
{
RegisterID reg = frame.allocReg();
Address scopeChain(JSFrameReg, StackFrame::offsetOfScopeChain());
@ -5863,7 +5862,7 @@ mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
if (usePropCache) {
OOL_STUBCALL(stubs::BindName, REJOIN_FALLTHROUGH);
} else {
stubcc.masm.move(ImmPtr(atom), Registers::ArgReg1);
stubcc.masm.move(ImmPtr(name), Registers::ArgReg1);
OOL_STUBCALL(stubs::BindNameNoCache, REJOIN_FALLTHROUGH);
}
@ -6222,28 +6221,28 @@ void
mjit::Compiler::jsop_getgname(uint32_t index)
{
/* Optimize undefined, NaN and Infinity. */
JSAtom *atom = script->getAtom(index);
if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID]) {
PropertyName *name = script->getName(index);
if (name == cx->runtime->atomState.typeAtoms[JSTYPE_VOID]) {
frame.push(UndefinedValue());
return;
}
if (atom == cx->runtime->atomState.NaNAtom) {
if (name == cx->runtime->atomState.NaNAtom) {
frame.push(cx->runtime->NaNValue);
return;
}
if (atom == cx->runtime->atomState.InfinityAtom) {
if (name == cx->runtime->atomState.InfinityAtom) {
frame.push(cx->runtime->positiveInfinityValue);
return;
}
/* Optimize singletons like Math for JSOP_CALLPROP. */
JSObject *obj = pushedSingleton(0);
if (obj && !hasTypeBarriers(PC) && testSingletonProperty(globalObj, ATOM_TO_JSID(atom))) {
if (obj && !hasTypeBarriers(PC) && testSingletonProperty(globalObj, ATOM_TO_JSID(name))) {
frame.push(ObjectValue(*obj));
return;
}
jsid id = ATOM_TO_JSID(atom);
jsid id = ATOM_TO_JSID(name);
JSValueType type = knownPushedType(0);
if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::MakeTypeId(cx, id) &&
!globalObj->getType(cx)->unknownProperties()) {
@ -6256,7 +6255,7 @@ mjit::Compiler::jsop_getgname(uint32_t index)
* then bake its address into the jitcode and guard against future
* reallocation of the global object's slots.
*/
const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(atom));
const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
if (shape && shape->hasDefaultGetterOrIsMethod() && shape->hasSlot()) {
HeapValue *value = &globalObj->getSlotRef(shape->slot());
if (!value->isUndefined() &&
@ -6451,10 +6450,10 @@ mjit::Compiler::jsop_callgname_epilogue()
}
void
mjit::Compiler::jsop_setgname_slow(JSAtom *atom, bool usePropertyCache)
mjit::Compiler::jsop_setgname_slow(PropertyName *name, bool usePropertyCache)
{
prepareStubCall(Uses(2));
masm.move(ImmPtr(atom), Registers::ArgReg1);
masm.move(ImmPtr(name), Registers::ArgReg1);
if (usePropertyCache)
INLINE_STUBCALL(STRICT_VARIANT(stubs::SetGlobalName), REJOIN_FALLTHROUGH);
else
@ -6464,15 +6463,15 @@ mjit::Compiler::jsop_setgname_slow(JSAtom *atom, bool usePropertyCache)
}
void
mjit::Compiler::jsop_setgname(JSAtom *atom, bool usePropertyCache, bool popGuaranteed)
mjit::Compiler::jsop_setgname(PropertyName *name, bool usePropertyCache, bool popGuaranteed)
{
if (monitored(PC)) {
/* Global accesses are monitored only for a few names like __proto__. */
jsop_setgname_slow(atom, usePropertyCache);
jsop_setgname_slow(name, usePropertyCache);
return;
}
jsid id = ATOM_TO_JSID(atom);
jsid id = ATOM_TO_JSID(name);
if (cx->typeInferenceEnabled() && globalObj->isGlobal() && id == types::MakeTypeId(cx, id) &&
!globalObj->getType(cx)->unknownProperties()) {
/*
@ -6484,7 +6483,7 @@ mjit::Compiler::jsop_setgname(JSAtom *atom, bool usePropertyCache, bool popGuara
types::TypeSet *types = globalObj->getType(cx)->getProperty(cx, id, false);
if (!types)
return;
const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(atom));
const js::Shape *shape = globalObj->nativeLookup(cx, ATOM_TO_JSID(name));
if (shape && !shape->isMethod() && shape->hasDefaultSetter() &&
shape->writable() && shape->hasSlot() &&
!types->isOwnProperty(cx, globalObj->getType(cx), true)) {
@ -6512,7 +6511,7 @@ mjit::Compiler::jsop_setgname(JSAtom *atom, bool usePropertyCache, bool popGuara
#ifdef JSGC_INCREMENTAL_MJ
/* Write barrier. */
if (cx->compartment->needsBarrier()) {
jsop_setgname_slow(atom, usePropertyCache);
jsop_setgname_slow(name, usePropertyCache);
return;
}
#endif
@ -6588,7 +6587,7 @@ mjit::Compiler::jsop_setgname(JSAtom *atom, bool usePropertyCache, bool popGuara
ic.fastPathRejoin = masm.label();
setGlobalNames.append(ic);
#else
jsop_setgname_slow(atom, usePropertyCache);
jsop_setgname_slow(name, usePropertyCache);
#endif
}

Просмотреть файл

@ -248,7 +248,7 @@ class Compiler : public BaseCompiler
bool usePropCache;
Label shapeGuard;
jsbytecode *pc;
JSAtom *atom;
PropertyName *name;
bool hasTypeCheck;
bool typeMonitored;
types::TypeSet *rhsTypes;
@ -282,7 +282,7 @@ class Compiler : public BaseCompiler
ic.kind = kind;
ic.shapeReg = shapeReg;
ic.objReg = objReg;
ic.atom = atom;
ic.name = name;
ic.usePropCache = usePropCache;
if (ic.isSet()) {
ic.u.vr = vr;
@ -598,9 +598,9 @@ private:
bool jumpAndRun(Jump j, jsbytecode *target, Jump *slow = NULL, bool *trampoline = NULL);
bool startLoop(jsbytecode *head, Jump entry, jsbytecode *entryTarget);
bool finishLoop(jsbytecode *head);
void jsop_bindname(JSAtom *atom, bool usePropCache);
void jsop_bindname(PropertyName *name, bool usePropCache);
void jsop_setglobal(uint32_t index);
void jsop_getprop_slow(JSAtom *atom, bool usePropCache = true);
void jsop_getprop_slow(PropertyName *name, bool usePropCache = true);
void jsop_getarg(uint32_t slot);
void jsop_setarg(uint32_t slot, bool popped);
void jsop_this();
@ -623,25 +623,25 @@ private:
void jsop_getgname(uint32_t index);
void jsop_getgname_slow(uint32_t index);
void jsop_callgname_epilogue();
void jsop_setgname(JSAtom *atom, bool usePropertyCache, bool popGuaranteed);
void jsop_setgname_slow(JSAtom *atom, bool usePropertyCache);
void jsop_setgname(PropertyName *name, bool usePropertyCache, bool popGuaranteed);
void jsop_setgname_slow(PropertyName *name, bool usePropertyCache);
void jsop_bindgname();
void jsop_setelem_slow();
void jsop_getelem_slow();
void jsop_callelem_slow();
bool jsop_getprop(JSAtom *atom, JSValueType type,
bool jsop_getprop(PropertyName *name, JSValueType type,
bool typeCheck = true, bool usePropCache = true);
bool jsop_setprop(JSAtom *atom, bool usePropCache, bool popGuaranteed);
void jsop_setprop_slow(JSAtom *atom, bool usePropCache = true);
bool jsop_callprop_slow(JSAtom *atom);
bool jsop_callprop(JSAtom *atom);
bool jsop_callprop_obj(JSAtom *atom);
bool jsop_callprop_str(JSAtom *atom);
bool jsop_callprop_generic(JSAtom *atom);
bool jsop_callprop_dispatch(JSAtom *atom);
bool jsop_setprop(PropertyName *name, bool usePropCache, bool popGuaranteed);
void jsop_setprop_slow(PropertyName *name, bool usePropCache = true);
bool jsop_callprop_slow(PropertyName *name);
bool jsop_callprop(PropertyName *name);
bool jsop_callprop_obj(PropertyName *name);
bool jsop_callprop_str(PropertyName *name);
bool jsop_callprop_generic(PropertyName *name);
bool jsop_callprop_dispatch(PropertyName *name);
bool jsop_instanceof();
void jsop_name(JSAtom *atom, JSValueType type, bool isCall);
bool jsop_xname(JSAtom *atom);
void jsop_name(PropertyName *name, JSValueType type, bool isCall);
bool jsop_xname(PropertyName *name);
void enterBlock(JSObject *obj);
void leaveBlock();
void emitEval(uint32_t argc);

Просмотреть файл

@ -550,7 +550,7 @@ typedef JSObject * (JS_FASTCALL *JSObjStubUInt32)(VMFrame &, uint32_t);
typedef JSObject * (JS_FASTCALL *JSObjStubFun)(VMFrame &, JSFunction *);
typedef void (JS_FASTCALL *VoidStubFun)(VMFrame &, JSFunction *);
typedef JSObject * (JS_FASTCALL *JSObjStubJSObj)(VMFrame &, JSObject *);
typedef void (JS_FASTCALL *VoidStubAtom)(VMFrame &, JSAtom *);
typedef void (JS_FASTCALL *VoidStubName)(VMFrame &, PropertyName *);
typedef JSString * (JS_FASTCALL *JSStrStub)(VMFrame &);
typedef JSString * (JS_FASTCALL *JSStrStubUInt32)(VMFrame &, uint32_t);
typedef void (JS_FASTCALL *VoidStubJSObj)(VMFrame &, JSObject *);

Просмотреть файл

@ -87,12 +87,11 @@ void JS_FASTCALL
ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
{
JSObject &obj = f.fp()->scopeChain().global();
JSAtom *atom = f.script()->getAtom(GET_INDEX(f.pc()));
jsid id = ATOM_TO_JSID(atom);
PropertyName *name = f.script()->getName(GET_INDEX(f.pc()));
RecompilationMonitor monitor(f.cx);
const Shape *shape = obj.nativeLookup(f.cx, id);
const Shape *shape = obj.nativeLookup(f.cx, js_CheckForStringIndex(ATOM_TO_JSID(name)));
if (monitor.recompiled()) {
stubs::GetGlobalName(f);
@ -127,9 +126,7 @@ template <JSBool strict>
static void JS_FASTCALL
DisabledSetGlobal(VMFrame &f, ic::SetGlobalNameIC *ic)
{
JSScript *script = f.script();
JSAtom *atom = script->getAtom(GET_INDEX(f.pc()));
stubs::SetGlobalName<strict>(f, atom);
stubs::SetGlobalName<strict>(f, f.script()->getName(GET_INDEX(f.pc())));
}
template void JS_FASTCALL DisabledSetGlobal<true>(VMFrame &f, ic::SetGlobalNameIC *ic);
@ -139,9 +136,7 @@ template <JSBool strict>
static void JS_FASTCALL
DisabledSetGlobalNoCache(VMFrame &f, ic::SetGlobalNameIC *ic)
{
JSScript *script = f.script();
JSAtom *atom = script->getAtom(GET_INDEX(f.pc()));
stubs::SetGlobalNameNoCache<strict>(f, atom);
stubs::SetGlobalNameNoCache<strict>(f, f.script()->getName(GET_INDEX(f.pc())));
}
template void JS_FASTCALL DisabledSetGlobalNoCache<true>(VMFrame &f, ic::SetGlobalNameIC *ic);
@ -210,11 +205,11 @@ ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
{
JSObject &obj = f.fp()->scopeChain().global();
JSScript *script = f.script();
JSAtom *atom = script->getAtom(GET_INDEX(f.pc()));
PropertyName *name = script->getName(GET_INDEX(f.pc()));
RecompilationMonitor monitor(f.cx);
const Shape *shape = obj.nativeLookup(f.cx, ATOM_TO_JSID(atom));
const Shape *shape = obj.nativeLookup(f.cx, ATOM_TO_JSID(name));
if (!monitor.recompiled()) {
LookupStatus status = UpdateSetGlobalName(f, ic, &obj, shape);
@ -223,9 +218,9 @@ ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
}
if (ic->usePropertyCache)
STRICT_VARIANT(stubs::SetGlobalName)(f, atom);
STRICT_VARIANT(stubs::SetGlobalName)(f, name);
else
STRICT_VARIANT(stubs::SetGlobalNameNoCache)(f, atom);
STRICT_VARIANT(stubs::SetGlobalNameNoCache)(f, name);
}
class EqualityICLinker : public LinkerHelper

Просмотреть файл

@ -200,14 +200,14 @@ GeneratePrototypeGuards(JSContext *cx, Vector<JSC::MacroAssembler::Jump,8> &mism
class SetPropCompiler : public PICStubCompiler
{
JSObject *obj;
JSAtom *atom;
PropertyName *name;
int lastStubSecondShapeGuard;
public:
SetPropCompiler(VMFrame &f, JSScript *script, JSObject *obj, ic::PICInfo &pic, JSAtom *atom,
SetPropCompiler(VMFrame &f, JSScript *script, JSObject *obj, ic::PICInfo &pic, PropertyName *name,
VoidStubPIC stub)
: PICStubCompiler("setprop", f, script, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
obj(obj), atom(atom), lastStubSecondShapeGuard(pic.secondShapeGuard)
obj(obj), name(name), lastStubSecondShapeGuard(pic.secondShapeGuard)
{ }
static void reset(Repatcher &repatcher, ic::PICInfo &pic)
@ -490,7 +490,7 @@ class SetPropCompiler : public PICStubCompiler
JS_ASSERT(pic.typeMonitored);
RecompilationMonitor monitor(cx);
jsid id = ATOM_TO_JSID(atom);
jsid id = ATOM_TO_JSID(name);
if (!obj->getType(cx)->unknownProperties()) {
types::AutoEnterTypeInference enter(cx);
@ -523,14 +523,12 @@ class SetPropCompiler : public PICStubCompiler
if (clasp->ops.setProperty)
return disable("ops set property hook");
jsid id = ATOM_TO_JSID(atom);
JSObject *holder;
JSProperty *prop = NULL;
/* lookupProperty can trigger recompilations. */
RecompilationMonitor monitor(cx);
if (!obj->lookupGeneric(cx, id, &holder, &prop))
if (!obj->lookupProperty(cx, name, &holder, &prop))
return error();
if (monitor.recompiled())
return Lookup_Uncacheable;
@ -566,10 +564,6 @@ class SetPropCompiler : public PICStubCompiler
if (clasp->ops.defineProperty)
return disable("ops define property hook");
uint32_t index;
if (js_IdIsIndex(id, &index))
return disable("index");
/*
* When adding a property we need to check shapes along the entire
* prototype chain to watch for an added setter.
@ -603,9 +597,8 @@ class SetPropCompiler : public PICStubCompiler
* populate the slot to satisfy the method invariant (in case we
* hit an early return below).
*/
id = js_CheckForStringIndex(id);
const Shape *shape =
obj->putProperty(cx, id, getter, clasp->setProperty,
obj->putProperty(cx, name, getter, clasp->setProperty,
SHAPE_INVALID_SLOT, JSPROP_ENUMERATE, flags, 0);
if (!shape)
return error();
@ -729,11 +722,11 @@ IsCacheableProtoChain(JSObject *obj, JSObject *holder)
}
template <typename IC>
struct GetPropertyHelper {
struct GetPropHelper {
// These fields are set in the constructor and describe a property lookup.
JSContext *cx;
JSObject *obj;
JSAtom *atom;
PropertyName *name;
IC &ic;
VMFrame &f;
@ -747,15 +740,15 @@ struct GetPropertyHelper {
// Lookup_Cacheable, otherwise it is NULL.
const Shape *shape;
GetPropertyHelper(JSContext *cx, JSObject *obj, JSAtom *atom, IC &ic, VMFrame &f)
: cx(cx), obj(obj), atom(atom), ic(ic), f(f), holder(NULL), prop(NULL), shape(NULL)
GetPropHelper(JSContext *cx, JSObject *obj, PropertyName *name, IC &ic, VMFrame &f)
: cx(cx), obj(obj), name(name), ic(ic), f(f), holder(NULL), prop(NULL), shape(NULL)
{ }
public:
LookupStatus bind() {
RecompilationMonitor monitor(cx);
bool global = (js_CodeSpec[*f.pc()].format & JOF_GNAME);
if (!js_FindProperty(cx, ATOM_TO_JSID(atom), global, &obj, &holder, &prop))
if (!FindProperty(cx, name, global, &obj, &holder, &prop))
return ic.error(cx);
if (monitor.recompiled())
return Lookup_Uncacheable;
@ -775,7 +768,7 @@ struct GetPropertyHelper {
return ic.disable(cx, "non-native");
RecompilationMonitor monitor(cx);
if (!aobj->lookupGeneric(cx, ATOM_TO_JSID(atom), &holder, &prop))
if (!aobj->lookupProperty(cx, name, &holder, &prop))
return ic.error(cx);
if (monitor.recompiled())
return Lookup_Uncacheable;
@ -830,16 +823,16 @@ struct GetPropertyHelper {
class GetPropCompiler : public PICStubCompiler
{
JSObject *obj;
JSAtom *atom;
PropertyName *name;
int lastStubSecondShapeGuard;
public:
GetPropCompiler(VMFrame &f, JSScript *script, JSObject *obj, ic::PICInfo &pic, JSAtom *atom,
VoidStubPIC stub)
GetPropCompiler(VMFrame &f, JSScript *script, JSObject *obj, ic::PICInfo &pic,
PropertyName *name, VoidStubPIC stub)
: PICStubCompiler(pic.kind == ic::PICInfo::CALL ? "callprop" : "getprop", f, script, pic,
JS_FUNC_TO_DATA_PTR(void *, stub)),
obj(obj),
atom(atom),
name(name),
lastStubSecondShapeGuard(pic.secondShapeGuard)
{ }
@ -1003,7 +996,7 @@ class GetPropCompiler : public PICStubCompiler
if (!f.fp()->script()->hasGlobal())
return disable("String.prototype without compile-and-go global");
GetPropertyHelper<GetPropCompiler> getprop(cx, obj, atom, *this, f);
GetPropHelper<GetPropCompiler> getprop(cx, obj, name, *this, f);
LookupStatus status = getprop.lookupAndTest();
if (status != Lookup_Cacheable)
return status;
@ -1379,7 +1372,7 @@ class GetPropCompiler : public PICStubCompiler
{
JS_ASSERT(pic.hit);
GetPropertyHelper<GetPropCompiler> getprop(cx, obj, atom, *this, f);
GetPropHelper<GetPropCompiler> getprop(cx, obj, name, *this, f);
LookupStatus status = getprop.lookupAndTest();
if (status != Lookup_Cacheable)
return status;
@ -1402,8 +1395,8 @@ class ScopeNameCompiler : public PICStubCompiler
typedef Vector<Jump, 8> JumpList;
JSObject *scopeChain;
JSAtom *atom;
GetPropertyHelper<ScopeNameCompiler> getprop;
PropertyName *name;
GetPropHelper<ScopeNameCompiler> getprop;
ScopeNameCompiler *thisFromCtor() { return this; }
void patchPreviousToHere(CodeLocationLabel cs)
@ -1457,10 +1450,10 @@ class ScopeNameCompiler : public PICStubCompiler
public:
ScopeNameCompiler(VMFrame &f, JSScript *script, JSObject *scopeChain, ic::PICInfo &pic,
JSAtom *atom, VoidStubPIC stub)
PropertyName *name, VoidStubPIC stub)
: PICStubCompiler("name", f, script, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
scopeChain(scopeChain), atom(atom),
getprop(f.cx, NULL, atom, *thisFromCtor(), f)
scopeChain(scopeChain), name(name),
getprop(f.cx, NULL, name, *thisFromCtor(), f)
{ }
static void reset(Repatcher &repatcher, ic::PICInfo &pic)
@ -1746,14 +1739,14 @@ class ScopeNameCompiler : public PICStubCompiler
return true;
}
}
ReportAtomNotDefined(cx, atom);
ReportAtomNotDefined(cx, name);
return false;
}
// If the property was found, but we decided not to cache it, then
// take a slow path and do a full property fetch.
if (!getprop.shape) {
if (!obj->getGeneric(cx, ATOM_TO_JSID(atom), vp))
if (!obj->getProperty(cx, name, vp))
return false;
if (thisvp)
return ComputeImplicitThis(cx, obj, *vp, thisvp);
@ -1774,13 +1767,13 @@ class ScopeNameCompiler : public PICStubCompiler
class BindNameCompiler : public PICStubCompiler
{
JSObject *scopeChain;
JSAtom *atom;
PropertyName *name;
public:
BindNameCompiler(VMFrame &f, JSScript *script, JSObject *scopeChain, ic::PICInfo &pic,
JSAtom *atom, VoidStubPIC stub)
PropertyName *name, VoidStubPIC stub)
: PICStubCompiler("bind", f, script, pic, JS_FUNC_TO_DATA_PTR(void *, stub)),
scopeChain(scopeChain), atom(atom)
scopeChain(scopeChain), name(name)
{ }
static void reset(Repatcher &repatcher, ic::PICInfo &pic)
@ -1881,7 +1874,7 @@ class BindNameCompiler : public PICStubCompiler
{
RecompilationMonitor monitor(cx);
JSObject *obj = js_FindIdentifierBase(cx, scopeChain, ATOM_TO_JSID(atom));
JSObject *obj = FindIdentifierBase(cx, scopeChain, name);
if (!obj || monitor.recompiled())
return obj;
@ -1908,7 +1901,7 @@ DisabledGetPropIC(VMFrame &f, ic::PICInfo *pic)
static void JS_FASTCALL
DisabledGetPropICNoCache(VMFrame &f, ic::PICInfo *pic)
{
stubs::GetPropNoCache(f, pic->atom);
stubs::GetPropNoCache(f, pic->name);
}
void JS_FASTCALL
@ -1916,8 +1909,8 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
JSAtom *atom = pic->atom;
if (atom == f.cx->runtime->atomState.lengthAtom) {
PropertyName *name = pic->name;
if (name == f.cx->runtime->atomState.lengthAtom) {
if (f.regs.sp[-1].isString()) {
GetPropCompiler cc(f, script, NULL, *pic, NULL, DisabledGetPropIC);
LookupStatus status = cc.generateStringLengthStub();
@ -1955,7 +1948,7 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
return;
}
}
atom = f.cx->runtime->atomState.lengthAtom;
name = f.cx->runtime->atomState.lengthAtom;
}
/*
@ -1973,13 +1966,13 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic)
VoidStubPIC stub = pic->usePropCache
? DisabledGetPropIC
: DisabledGetPropICNoCache;
GetPropCompiler cc(f, script, obj, *pic, atom, stub);
GetPropCompiler cc(f, script, obj, *pic, name, stub);
if (!cc.update())
THROW();
}
Value v;
if (!obj->getGeneric(f.cx, ATOM_TO_JSID(atom), &v))
if (!obj->getProperty(f.cx, name, &v))
THROW();
f.regs.sp[-1] = v;
@ -2000,14 +1993,14 @@ template <JSBool strict>
static void JS_FASTCALL
DisabledSetPropIC(VMFrame &f, ic::PICInfo *pic)
{
stubs::SetName<strict>(f, pic->atom);
stubs::SetName<strict>(f, pic->name);
}
template <JSBool strict>
static void JS_FASTCALL
DisabledSetPropICNoCache(VMFrame &f, ic::PICInfo *pic)
{
stubs::SetPropNoCache<strict>(f, pic->atom);
stubs::SetPropNoCache<strict>(f, pic->name);
}
void JS_FASTCALL
@ -2021,8 +2014,8 @@ ic::SetProp(VMFrame &f, ic::PICInfo *pic)
: STRICT_VARIANT(DisabledSetPropICNoCache);
// Save this in case the compiler triggers a recompilation of this script.
JSAtom *atom = pic->atom;
VoidStubAtom nstub = pic->usePropCache
PropertyName *name = pic->name;
VoidStubName nstub = pic->usePropCache
? STRICT_VARIANT(stubs::SetName)
: STRICT_VARIANT(stubs::SetPropNoCache);
@ -2035,19 +2028,19 @@ ic::SetProp(VMFrame &f, ic::PICInfo *pic)
// Note, we can't use SetName for PROPINC PICs because the property
// cache can't handle a GET and SET from the same scripted PC.
if (!monitor.recompiled() && pic->shouldUpdate(f.cx)) {
SetPropCompiler cc(f, script, obj, *pic, atom, stub);
SetPropCompiler cc(f, script, obj, *pic, name, stub);
LookupStatus status = cc.update();
if (status == Lookup_Error)
THROW();
}
nstub(f, atom);
nstub(f, name);
}
static void JS_FASTCALL
DisabledCallPropIC(VMFrame &f, ic::PICInfo *pic)
{
stubs::CallProp(f, pic->atom);
stubs::CallProp(f, pic->name);
}
void JS_FASTCALL
@ -2063,7 +2056,7 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
lval = regs.sp[-1];
// Do this first in case js_GetClassPrototype triggers a recompilation.
jsid id = ATOM_TO_JSID(pic->atom);
PropertyName *name = pic->name;
Value objv;
if (lval.isObject()) {
@ -2092,9 +2085,9 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), aobj, obj2, entry, atom);
if (!atom) {
PropertyName *name_;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), aobj, obj2, entry, name_);
if (!name_) {
NATIVE_GET(cx, &objv.toObject(), obj2, entry->prop, JSGET_NO_METHOD_BARRIER, &rval,
THROW());
/*
@ -2106,27 +2099,26 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
regs.sp[-2] = rval;
regs.sp[-1] = lval;
} else {
/*
* Cache miss: use the immediate atom that was loaded for us under
* PropertyCache::test.
*/
/* Cache miss: use the name loaded for us under PropertyCache::test. */
regs.sp++;
regs.sp[-1].setNull();
if (lval.isObject()) {
if (!js_GetMethod(cx, &objv.toObject(), id,
JS_LIKELY(!objv.toObject().getOps()->getProperty)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_NO_METHOD_BARRIER,
&rval)) {
if (!GetMethod(cx, &objv.toObject(), name,
JS_LIKELY(!objv.toObject().getOps()->getProperty)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_NO_METHOD_BARRIER,
&rval))
{
THROW();
}
regs.sp[-1] = objv;
regs.sp[-2] = rval;
} else {
JS_ASSERT(!objv.toObject().getOps()->getProperty);
if (!js_GetPropertyHelper(cx, &objv.toObject(), id,
JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER,
&rval)) {
if (!GetPropertyHelper(cx, &objv.toObject(), name,
JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER,
&rval))
{
THROW();
}
regs.sp[-1] = lval;
@ -2136,7 +2128,7 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
regs.sp[-2].setString(JSID_TO_STRING(id));
regs.sp[-2].setString(name);
if (!OnUnknownMethod(cx, regs.sp - 2))
THROW();
}
@ -2145,7 +2137,7 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
if (monitor.recompiled())
return;
GetPropCompiler cc(f, script, &objv.toObject(), *pic, pic->atom, DisabledCallPropIC);
GetPropCompiler cc(f, script, &objv.toObject(), *pic, pic->name, DisabledCallPropIC);
if (lval.isObject()) {
if (pic->shouldUpdate(cx)) {
LookupStatus status = cc.update();
@ -2181,7 +2173,7 @@ ic::XName(VMFrame &f, ic::PICInfo *pic)
/* GETXPROP is guaranteed to have an object. */
JSObject *obj = &f.regs.sp[-1].toObject();
ScopeNameCompiler cc(f, script, obj, *pic, pic->atom, DisabledXNameIC);
ScopeNameCompiler cc(f, script, obj, *pic, pic->name, DisabledXNameIC);
LookupStatus status = cc.updateForXName();
if (status == Lookup_Error)
@ -2198,7 +2190,7 @@ ic::Name(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
ScopeNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->atom, DisabledNameIC);
ScopeNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->name, DisabledNameIC);
LookupStatus status = cc.updateForName();
if (status == Lookup_Error)
@ -2221,7 +2213,7 @@ ic::CallName(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
ScopeNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->atom, DisabledCallNameIC);
ScopeNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->name, DisabledCallNameIC);
LookupStatus status = cc.updateForName();
if (status == Lookup_Error)
@ -2244,7 +2236,7 @@ DisabledBindNameIC(VMFrame &f, ic::PICInfo *pic)
static void JS_FASTCALL
DisabledBindNameICNoCache(VMFrame &f, ic::PICInfo *pic)
{
stubs::BindNameNoCache(f, pic->atom);
stubs::BindNameNoCache(f, pic->name);
}
void JS_FASTCALL
@ -2255,7 +2247,7 @@ ic::BindName(VMFrame &f, ic::PICInfo *pic)
VoidStubPIC stub = pic->usePropCache
? DisabledBindNameIC
: DisabledBindNameICNoCache;
BindNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->atom, stub);
BindNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->name, stub);
JSObject *obj = cc.update();
if (!obj)
@ -2399,12 +2391,13 @@ GetElementIC::purge(Repatcher &repatcher)
}
LookupStatus
GetElementIC::attachGetProp(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp)
GetElementIC::attachGetProp(VMFrame &f, JSObject *obj, const Value &v, PropertyName *name,
Value *vp)
{
JS_ASSERT(v.isString());
JSContext *cx = f.cx;
GetPropertyHelper<GetElementIC> getprop(cx, obj, JSID_TO_ATOM(id), *this, f);
GetPropHelper<GetElementIC> getprop(cx, obj, name, *this, f);
LookupStatus status = getprop.lookupAndTest();
if (status != Lookup_Cacheable)
return status;
@ -2503,7 +2496,7 @@ GetElementIC::attachGetProp(VMFrame &f, JSObject *obj, const Value &v, jsid id,
#if DEBUG
char *chars = DeflateString(cx, v.toString()->getChars(cx), v.toString()->length());
JaegerSpew(JSpew_PICs, "generated %s stub at %p for atom %p (\"%s\") shape %p (%s: %d)\n",
js_CodeName[op], cs.executableAddress(), (void*)JSID_TO_ATOM(id), chars,
js_CodeName[op], cs.executableAddress(), (void*)name, chars,
(void*)holder->lastProperty(), cx->fp()->script()->filename, CurrentLine(cx));
cx->free_(chars);
#endif
@ -2825,7 +2818,7 @@ GetElementIC::update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *
* use when looking up non-integer identifiers.
*/
if (v.isString() && js_CheckForStringIndex(id) == id)
return attachGetProp(f, obj, v, id, vp);
return attachGetProp(f, obj, v, JSID_TO_ATOM(id)->asPropertyName(), vp);
if (obj->isArguments())
return attachArguments(f, obj, v, id, vp);

Просмотреть файл

@ -299,7 +299,8 @@ struct GetElementIC : public BasePolyIC {
}
void purge(Repatcher &repatcher);
LookupStatus update(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
LookupStatus attachGetProp(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
LookupStatus attachGetProp(VMFrame &f, JSObject *obj, const Value &v, PropertyName *name,
Value *vp);
LookupStatus attachArguments(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
LookupStatus attachTypedArray(VMFrame &f, JSObject *obj, const Value &v, jsid id, Value *vp);
LookupStatus disable(JSContext *cx, const char *reason);
@ -534,7 +535,7 @@ struct PICInfo : public BasePolyIC {
jsbytecode *pc;
// Index into the script's atom table.
JSAtom *atom;
PropertyName *name;
// Reset the data members to the state of a fresh PIC before any patching
// or stub generation was done.

Просмотреть файл

@ -91,14 +91,13 @@ stubs::BindName(VMFrame &f)
/* Fast-path should have caught this. See comment in interpreter. */
JS_ASSERT(!f.fp()->scopeChain().isGlobal());
JSAtom *atom;
PropertyName *name;
JSObject *obj2;
JSContext *cx = f.cx;
JSObject *obj = &f.fp()->scopeChain();
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), obj, obj2, entry, atom);
if (atom) {
jsid id = ATOM_TO_JSID(atom);
obj = js_FindIdentifierBase(cx, &f.fp()->scopeChain(), id);
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), obj, obj2, entry, name);
if (name) {
obj = FindIdentifierBase(cx, &f.fp()->scopeChain(), name);
if (!obj)
THROW();
}
@ -107,9 +106,9 @@ stubs::BindName(VMFrame &f)
}
void JS_FASTCALL
stubs::BindNameNoCache(VMFrame &f, JSAtom *atom)
stubs::BindNameNoCache(VMFrame &f, PropertyName *name)
{
JSObject *obj = js_FindIdentifierBase(f.cx, &f.fp()->scopeChain(), ATOM_TO_JSID(atom));
JSObject *obj = FindIdentifierBase(f.cx, &f.fp()->scopeChain(), name);
if (!obj)
THROW();
f.regs.sp[0].setObject(*obj);
@ -123,7 +122,7 @@ stubs::BindGlobalName(VMFrame &f)
template<JSBool strict>
void JS_FASTCALL
stubs::SetName(VMFrame &f, JSAtom *origAtom)
stubs::SetName(VMFrame &f, PropertyName *origName)
{
JSContext *cx = f.cx;
@ -157,8 +156,8 @@ stubs::SetName(VMFrame &f, JSAtom *origAtom)
*/
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
if (cache->testForSet(cx, f.pc(), obj, &entry, &obj2, &atom)) {
PropertyName *name;
if (cache->testForSet(cx, f.pc(), obj, &entry, &obj2, &name)) {
/*
* Property cache hit, only partially confirmed by testForSet. We
* know that the entry applies to regs.pc and that obj's shape
@ -191,12 +190,11 @@ stubs::SetName(VMFrame &f, JSAtom *origAtom)
}
PCMETER(cache->setpcmisses++);
atom = origAtom;
name = origName;
} else {
JS_ASSERT(atom);
JS_ASSERT(name);
}
jsid id = ATOM_TO_JSID(atom);
if (entry && JS_LIKELY(!obj->getOps()->setProperty)) {
uintN defineHow;
JSOp op = JSOp(*f.pc());
@ -206,10 +204,10 @@ stubs::SetName(VMFrame &f, JSAtom *origAtom)
defineHow = DNP_CACHE_RESULT | DNP_UNQUALIFIED;
else
defineHow = DNP_CACHE_RESULT;
if (!js_SetPropertyHelper(cx, obj, id, defineHow, &rval, strict))
if (!SetPropertyHelper(cx, obj, name, defineHow, &rval, strict))
THROW();
} else {
if (!obj->setGeneric(cx, id, &rval, strict))
if (!obj->setProperty(cx, name, &rval, strict))
THROW();
}
} while (0);
@ -217,53 +215,53 @@ stubs::SetName(VMFrame &f, JSAtom *origAtom)
f.regs.sp[-2] = f.regs.sp[-1];
}
template void JS_FASTCALL stubs::SetName<true>(VMFrame &f, JSAtom *origAtom);
template void JS_FASTCALL stubs::SetName<false>(VMFrame &f, JSAtom *origAtom);
template void JS_FASTCALL stubs::SetName<true>(VMFrame &f, PropertyName *origName);
template void JS_FASTCALL stubs::SetName<false>(VMFrame &f, PropertyName *origName);
template<JSBool strict>
void JS_FASTCALL
stubs::SetPropNoCache(VMFrame &f, JSAtom *atom)
stubs::SetPropNoCache(VMFrame &f, PropertyName *name)
{
JSObject *obj = ValueToObject(f.cx, &f.regs.sp[-2]);
if (!obj)
THROW();
Value rval = f.regs.sp[-1];
if (!obj->setGeneric(f.cx, ATOM_TO_JSID(atom), &f.regs.sp[-1], strict))
if (!obj->setProperty(f.cx, name, &f.regs.sp[-1], strict))
THROW();
f.regs.sp[-2] = rval;
}
template void JS_FASTCALL stubs::SetPropNoCache<true>(VMFrame &f, JSAtom *origAtom);
template void JS_FASTCALL stubs::SetPropNoCache<false>(VMFrame &f, JSAtom *origAtom);
template void JS_FASTCALL stubs::SetPropNoCache<true>(VMFrame &f, PropertyName *name);
template void JS_FASTCALL stubs::SetPropNoCache<false>(VMFrame &f, PropertyName *name);
template<JSBool strict>
void JS_FASTCALL
stubs::SetGlobalNameNoCache(VMFrame &f, JSAtom *atom)
stubs::SetGlobalNameNoCache(VMFrame &f, PropertyName *name)
{
JSContext *cx = f.cx;
Value rval = f.regs.sp[-1];
Value &lref = f.regs.sp[-2];
JSObject *obj = ValueToObject(cx, &lref);
if (!obj || !obj->setProperty(cx, atom->asPropertyName(), &rval, strict))
if (!obj || !obj->setProperty(cx, name, &rval, strict))
THROW();
f.regs.sp[-2] = f.regs.sp[-1];
}
template void JS_FASTCALL stubs::SetGlobalNameNoCache<true>(VMFrame &f, JSAtom *atom);
template void JS_FASTCALL stubs::SetGlobalNameNoCache<false>(VMFrame &f, JSAtom *atom);
template void JS_FASTCALL stubs::SetGlobalNameNoCache<true>(VMFrame &f, PropertyName *name);
template void JS_FASTCALL stubs::SetGlobalNameNoCache<false>(VMFrame &f, PropertyName *name);
template<JSBool strict>
void JS_FASTCALL
stubs::SetGlobalName(VMFrame &f, JSAtom *atom)
stubs::SetGlobalName(VMFrame &f, PropertyName *name)
{
SetName<strict>(f, atom);
SetName<strict>(f, name);
}
template void JS_FASTCALL stubs::SetGlobalName<true>(VMFrame &f, JSAtom *atom);
template void JS_FASTCALL stubs::SetGlobalName<false>(VMFrame &f, JSAtom *atom);
template void JS_FASTCALL stubs::SetGlobalName<true>(VMFrame &f, PropertyName *name);
template void JS_FASTCALL stubs::SetGlobalName<false>(VMFrame &f, PropertyName *name);
static inline void
PushImplicitThis(VMFrame &f, JSObject *obj, Value &rval)
@ -282,20 +280,17 @@ NameOp(VMFrame &f, JSObject *obj, bool callname)
Value rval;
jsid id;
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), obj, obj2, entry, atom);
if (!atom) {
PropertyName *name;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), obj, obj2, entry, name);
if (!name) {
NATIVE_GET(cx, obj, obj2, entry->prop, JSGET_METHOD_BARRIER, &rval, return NULL);
JS_ASSERT(obj->isGlobal() || IsCacheableNonGlobalScope(obj));
} else {
id = ATOM_TO_JSID(atom);
JSProperty *prop;
bool global = (js_CodeSpec[*f.pc()].format & JOF_GNAME);
if (!js_FindPropertyHelper(cx, id, true, global, &obj, &obj2, &prop))
if (!FindPropertyHelper(cx, name, true, global, &obj, &obj2, &prop))
return NULL;
if (!prop) {
/* Kludge to allow (typeof foo == "undefined") tests. */
@ -305,13 +300,13 @@ NameOp(VMFrame &f, JSObject *obj, bool callname)
f.regs.sp[-1].setUndefined();
return obj;
}
ReportAtomNotDefined(cx, atom);
ReportAtomNotDefined(cx, name);
return NULL;
}
/* Take the slow path if prop was not found in a native object. */
if (!obj->isNative() || !obj2->isNative()) {
if (!obj->getGeneric(cx, id, &rval))
if (!obj->getProperty(cx, name, &rval))
return NULL;
} else {
Shape *shape = (Shape *)prop;
@ -326,7 +321,7 @@ NameOp(VMFrame &f, JSObject *obj, bool callname)
* to capture the type effect on the intermediate value.
*/
if (rval.isUndefined() && (js_CodeSpec[*f.pc()].format & (JOF_INC|JOF_DEC)))
AddTypePropertyId(cx, obj, id, Type::UndefinedType());
AddTypePropertyId(cx, obj, ATOM_TO_JSID(name), Type::UndefinedType());
}
*f.regs.sp++ = rval;
@ -711,7 +706,6 @@ stubs::DefFun(VMFrame &f, JSFunction *fun)
/* ES5 10.5 (NB: with subsequent errata). */
PropertyName *name = fun->atom->asPropertyName();
jsid id = ATOM_TO_JSID(name);
JSProperty *prop = NULL;
JSObject *pobj;
if (!parent->lookupProperty(cx, name, &pobj, &prop))
@ -745,9 +739,9 @@ stubs::DefFun(VMFrame &f, JSFunction *fun)
if (shape->isAccessorDescriptor() || !shape->writable() || !shape->enumerable()) {
JSAutoByteString bytes;
if (const char *name = js_ValueToPrintable(cx, IdToValue(id), &bytes)) {
if (js_AtomToPrintableString(cx, name, &bytes)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CANT_REDEFINE_PROP, name);
JSMSG_CANT_REDEFINE_PROP, bytes.ptr());
}
THROW();
}
@ -1479,22 +1473,20 @@ InlineGetProp(VMFrame &f)
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), aobj, obj2, entry, atom);
if (!atom) {
PropertyName *name;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), aobj, obj2, entry, name);
if (!name) {
NATIVE_GET(cx, obj, obj2, entry->prop, JSGET_METHOD_BARRIER, &rval, return false);
break;
}
jsid id = ATOM_TO_JSID(atom);
if (JS_LIKELY(!aobj->getOps()->getProperty)
? !js_GetPropertyHelper(cx, obj, id,
JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER,
&rval)
: !obj->getGeneric(cx, id, &rval)) {
? !GetPropertyHelper(cx, obj, name, JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER, &rval)
: !obj->getProperty(cx, name, &rval))
{
return false;
}
} while(0);
} while (false);
regs.sp[-1] = rval;
return true;
@ -1508,7 +1500,7 @@ stubs::GetProp(VMFrame &f)
}
void JS_FASTCALL
stubs::GetPropNoCache(VMFrame &f, JSAtom *atom)
stubs::GetPropNoCache(VMFrame &f, PropertyName *name)
{
JSContext *cx = f.cx;
@ -1517,14 +1509,14 @@ stubs::GetPropNoCache(VMFrame &f, JSAtom *atom)
if (!obj)
THROW();
if (!obj->getGeneric(cx, ATOM_TO_JSID(atom), vp))
if (!obj->getProperty(cx, name, vp))
THROW();
/* Don't check for undefined, this is only used for 'prototype'. See ic::GetProp. */
}
void JS_FASTCALL
stubs::CallProp(VMFrame &f, JSAtom *origAtom)
stubs::CallProp(VMFrame &f, PropertyName *origName)
{
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
@ -1559,39 +1551,35 @@ stubs::CallProp(VMFrame &f, JSAtom *origAtom)
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), aobj, obj2, entry, atom);
if (!atom) {
PropertyName *name;
JS_PROPERTY_CACHE(cx).test(cx, f.pc(), aobj, obj2, entry, name);
if (!name) {
NATIVE_GET(cx, &objv.toObject(), obj2, entry->prop, JSGET_NO_METHOD_BARRIER, &rval,
THROW());
regs.sp++;
regs.sp[-2] = rval;
regs.sp[-1] = lval;
} else {
/*
* Cache miss: use the immediate atom that was loaded for us under
* PropertyCache::test.
*/
jsid id;
id = ATOM_TO_JSID(origAtom);
/* Cache miss: use the name loaded for us under PropertyCache::test. */
regs.sp++;
regs.sp[-1].setNull();
if (lval.isObject()) {
if (!js_GetMethod(cx, &objv.toObject(), id,
JS_LIKELY(!aobj->getOps()->getProperty)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_NO_METHOD_BARRIER,
&rval)) {
if (!GetMethod(cx, &objv.toObject(), name,
JS_LIKELY(!aobj->getOps()->getProperty)
? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
: JSGET_NO_METHOD_BARRIER,
&rval))
{
THROW();
}
regs.sp[-1] = objv;
regs.sp[-2] = rval;
} else {
JS_ASSERT(!objv.toObject().getOps()->getProperty);
if (!js_GetPropertyHelper(cx, &objv.toObject(), id,
JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER,
&rval)) {
if (!GetPropertyHelper(cx, &objv.toObject(), name,
JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER,
&rval))
{
THROW();
}
regs.sp[-1] = lval;
@ -1600,7 +1588,7 @@ stubs::CallProp(VMFrame &f, JSAtom *origAtom)
}
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isPrimitive()) && regs.sp[-1].isObject()) {
regs.sp[-2].setString(origAtom);
regs.sp[-2].setString(origName);
if (!OnUnknownMethod(cx, regs.sp - 2))
THROW();
}
@ -1616,7 +1604,7 @@ stubs::Iter(VMFrame &f, uint32_t flags)
}
static void
InitPropOrMethod(VMFrame &f, JSAtom *atom, JSOp op)
InitPropOrMethod(VMFrame &f, PropertyName *name, JSOp op)
{
JSContext *cx = f.cx;
FrameRegs &regs = f.regs;
@ -1643,8 +1631,8 @@ InitPropOrMethod(VMFrame &f, JSAtom *atom, JSOp op)
*/
PropertyCacheEntry *entry;
JSObject *obj2;
JSAtom *atom2;
if (JS_PROPERTY_CACHE(cx).testForSet(cx, f.pc(), obj, &entry, &obj2, &atom2) &&
PropertyName *name2;
if (JS_PROPERTY_CACHE(cx).testForSet(cx, f.pc(), obj, &entry, &obj2, &name2) &&
entry->prop->hasDefaultSetter() &&
entry->isOwnPropertyHit())
{
@ -1654,31 +1642,29 @@ InitPropOrMethod(VMFrame &f, JSAtom *atom, JSOp op)
} else {
PCMETER(JS_PROPERTY_CACHE(cx).inipcmisses++);
/* Get the immediate property name into id. */
jsid id = ATOM_TO_JSID(atom);
uintN defineHow = (op == JSOP_INITMETHOD)
? DNP_CACHE_RESULT | DNP_SET_METHOD
: DNP_CACHE_RESULT;
if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
? !js_SetPropertyHelper(cx, obj, id, defineHow, &rval, false)
: !DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, defineHow)) {
if (JS_UNLIKELY(name == cx->runtime->atomState.protoAtom)
? !SetPropertyHelper(cx, obj, name, defineHow, &rval, false)
: !DefineNativeProperty(cx, obj, name, rval, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, defineHow))
{
THROW();
}
}
}
void JS_FASTCALL
stubs::InitProp(VMFrame &f, JSAtom *atom)
stubs::InitProp(VMFrame &f, PropertyName *name)
{
InitPropOrMethod(f, atom, JSOP_INITPROP);
InitPropOrMethod(f, name, JSOP_INITPROP);
}
void JS_FASTCALL
stubs::InitMethod(VMFrame &f, JSAtom *atom)
stubs::InitMethod(VMFrame &f, PropertyName *name)
{
InitPropOrMethod(f, atom, JSOP_INITMETHOD);
InitPropOrMethod(f, name, JSOP_INITMETHOD);
}
void JS_FASTCALL
@ -1721,8 +1707,7 @@ stubs::TypeOf(VMFrame &f)
{
const Value &ref = f.regs.sp[-1];
JSType type = JS_TypeOfValue(f.cx, ref);
JSAtom *atom = f.cx->runtime->atomState.typeAtoms[type];
return atom;
return f.cx->runtime->atomState.typeAtoms[type];
}
void JS_FASTCALL
@ -2018,12 +2003,11 @@ stubs::Pos(VMFrame &f)
}
void JS_FASTCALL
stubs::DelName(VMFrame &f, JSAtom *atom)
stubs::DelName(VMFrame &f, PropertyName *name)
{
jsid id = ATOM_TO_JSID(atom);
JSObject *obj, *obj2;
JSProperty *prop;
if (!js_FindProperty(f.cx, id, false, &obj, &obj2, &prop))
if (!FindProperty(f.cx, name, false, &obj, &obj2, &prop))
THROW();
/* Strict mode code should never contain JSOP_DELNAME opcodes. */
@ -2033,14 +2017,14 @@ stubs::DelName(VMFrame &f, JSAtom *atom)
f.regs.sp++;
f.regs.sp[-1] = BooleanValue(true);
if (prop) {
if (!obj->deleteProperty(f.cx, atom->asPropertyName(), &f.regs.sp[-1], false))
if (!obj->deleteProperty(f.cx, name, &f.regs.sp[-1], false))
THROW();
}
}
template<JSBool strict>
void JS_FASTCALL
stubs::DelProp(VMFrame &f, JSAtom *atom)
stubs::DelProp(VMFrame &f, PropertyName *name)
{
JSContext *cx = f.cx;
@ -2049,14 +2033,14 @@ stubs::DelProp(VMFrame &f, JSAtom *atom)
THROW();
Value rval;
if (!obj->deleteGeneric(cx, ATOM_TO_JSID(atom), &rval, strict))
if (!obj->deleteProperty(cx, name, &rval, strict))
THROW();
f.regs.sp[-1] = rval;
}
template void JS_FASTCALL stubs::DelProp<true>(VMFrame &f, JSAtom *atom);
template void JS_FASTCALL stubs::DelProp<false>(VMFrame &f, JSAtom *atom);
template void JS_FASTCALL stubs::DelProp<true>(VMFrame &f, PropertyName *name);
template void JS_FASTCALL stubs::DelProp<false>(VMFrame &f, PropertyName *name);
template<JSBool strict>
void JS_FASTCALL
@ -2077,7 +2061,7 @@ stubs::DelElem(VMFrame &f)
}
void JS_FASTCALL
stubs::DefVarOrConst(VMFrame &f, JSAtom *atom_)
stubs::DefVarOrConst(VMFrame &f, PropertyName *name)
{
JSContext *cx = f.cx;
StackFrame *fp = f.fp();
@ -2089,8 +2073,6 @@ stubs::DefVarOrConst(VMFrame &f, JSAtom *atom_)
attrs |= JSPROP_PERMANENT;
/* Lookup id in order to check for redeclaration problems. */
PropertyName *name = atom_->asPropertyName();
jsid id = ATOM_TO_JSID(name);
bool shouldDefine;
if (JSOp(*f.pc()) == JSOP_DEFVAR) {
/*
@ -2105,7 +2087,7 @@ stubs::DefVarOrConst(VMFrame &f, JSAtom *atom_)
} else {
JS_ASSERT(JSOp(*f.pc()) == JSOP_DEFCONST);
attrs |= JSPROP_READONLY;
if (!CheckRedeclaration(cx, obj, id, attrs))
if (!CheckRedeclaration(cx, obj, name, attrs))
THROW();
/*
@ -2117,23 +2099,24 @@ stubs::DefVarOrConst(VMFrame &f, JSAtom *atom_)
/* Bind a variable only if it's not yet defined. */
if (shouldDefine &&
!DefineNativeProperty(cx, obj, id, UndefinedValue(), JS_PropertyStub, JS_StrictPropertyStub,
attrs, 0, 0)) {
!DefineNativeProperty(cx, obj, name, UndefinedValue(),
JS_PropertyStub, JS_StrictPropertyStub, attrs, 0, 0))
{
THROW();
}
}
void JS_FASTCALL
stubs::SetConst(VMFrame &f, JSAtom *atom)
stubs::SetConst(VMFrame &f, PropertyName *name)
{
JSContext *cx = f.cx;
JSObject *obj = &f.fp()->varObj();
const Value &ref = f.regs.sp[-1];
if (!obj->defineProperty(cx, atom->asPropertyName(), ref,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY)) {
if (!obj->defineProperty(cx, name, ref, JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY))
{
THROW();
}
}

Просмотреть файл

@ -61,8 +61,8 @@ void JS_FASTCALL DebuggerStatement(VMFrame &f, jsbytecode *pc);
void JS_FASTCALL Interrupt(VMFrame &f, jsbytecode *pc);
void JS_FASTCALL RecompileForInline(VMFrame &f);
void JS_FASTCALL InitElem(VMFrame &f, uint32_t last);
void JS_FASTCALL InitProp(VMFrame &f, JSAtom *atom);
void JS_FASTCALL InitMethod(VMFrame &f, JSAtom *atom);
void JS_FASTCALL InitProp(VMFrame &f, PropertyName *name);
void JS_FASTCALL InitMethod(VMFrame &f, PropertyName *name);
void JS_FASTCALL HitStackQuota(VMFrame &f);
void * JS_FASTCALL FixupArity(VMFrame &f, uint32_t argc);
@ -116,15 +116,15 @@ void * JS_FASTCALL LookupSwitch(VMFrame &f, jsbytecode *pc);
void * JS_FASTCALL TableSwitch(VMFrame &f, jsbytecode *origPc);
void JS_FASTCALL BindName(VMFrame &f);
void JS_FASTCALL BindNameNoCache(VMFrame &f, JSAtom *atom);
void JS_FASTCALL BindNameNoCache(VMFrame &f, PropertyName *name);
JSObject * JS_FASTCALL BindGlobalName(VMFrame &f);
template<JSBool strict> void JS_FASTCALL SetName(VMFrame &f, JSAtom *atom);
template<JSBool strict> void JS_FASTCALL SetPropNoCache(VMFrame &f, JSAtom *atom);
template<JSBool strict> void JS_FASTCALL SetGlobalName(VMFrame &f, JSAtom *atom);
template<JSBool strict> void JS_FASTCALL SetGlobalNameNoCache(VMFrame &f, JSAtom *atom);
template<JSBool strict> void JS_FASTCALL SetName(VMFrame &f, PropertyName *name);
template<JSBool strict> void JS_FASTCALL SetPropNoCache(VMFrame &f, PropertyName *name);
template<JSBool strict> void JS_FASTCALL SetGlobalName(VMFrame &f, PropertyName *name);
template<JSBool strict> void JS_FASTCALL SetGlobalNameNoCache(VMFrame &f, PropertyName *name);
void JS_FASTCALL Name(VMFrame &f);
void JS_FASTCALL GetProp(VMFrame &f);
void JS_FASTCALL GetPropNoCache(VMFrame &f, JSAtom *atom);
void JS_FASTCALL GetPropNoCache(VMFrame &f, PropertyName *name);
void JS_FASTCALL GetElem(VMFrame &f);
void JS_FASTCALL CallElem(VMFrame &f);
template<JSBool strict> void JS_FASTCALL SetElem(VMFrame &f);
@ -134,14 +134,14 @@ void JS_FASTCALL PushImplicitThisForGlobal(VMFrame &f);
void JS_FASTCALL GetUpvar(VMFrame &f, uint32_t index);
void JS_FASTCALL GetGlobalName(VMFrame &f);
void JS_FASTCALL CallProp(VMFrame &f, JSAtom *atom);
template <JSBool strict> void JS_FASTCALL DelProp(VMFrame &f, JSAtom *atom);
void JS_FASTCALL CallProp(VMFrame &f, PropertyName *name);
template <JSBool strict> void JS_FASTCALL DelProp(VMFrame &f, PropertyName *name);
template <JSBool strict> void JS_FASTCALL DelElem(VMFrame &f);
void JS_FASTCALL DelName(VMFrame &f, JSAtom *atom);
void JS_FASTCALL DelName(VMFrame &f, PropertyName *name);
JSBool JS_FASTCALL In(VMFrame &f);
void JS_FASTCALL DefVarOrConst(VMFrame &f, JSAtom *atom);
void JS_FASTCALL SetConst(VMFrame &f, JSAtom *atom);
void JS_FASTCALL DefVarOrConst(VMFrame &f, PropertyName *name);
void JS_FASTCALL SetConst(VMFrame &f, PropertyName *name);
template<JSBool strict> void JS_FASTCALL DefFun(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL DefLocalFun(VMFrame &f, JSFunction *fun);
JSObject * JS_FASTCALL DefLocalFun_FC(VMFrame &f, JSFunction *fun);