зеркало из https://github.com/mozilla/gecko-dev.git
Bug 475761 - TM: js_Any_GetProp and friends can reenter. r=brendan. Note that this patch alone does not fix the bug. The rest of the fix comes in bug 462027.
This commit is contained in:
Родитель
bef69f676f
Коммит
196e202090
|
@ -77,10 +77,6 @@ BUILTIN1(extern, UINT32, js_DoubleToUint32, DOUBLE,
|
|||
|
||||
BUILTIN2(extern, DOUBLE, js_StringToNumber, CONTEXT, STRING, 1, 1)
|
||||
BUILTIN2(extern, INT32, js_StringToInt32, CONTEXT, STRING, 1, 1)
|
||||
BUILTIN3(extern, JSVAL, js_Any_getprop, CONTEXT, OBJECT, STRING, 0, 0)
|
||||
BUILTIN4(extern, BOOL, js_Any_setprop, CONTEXT, OBJECT, STRING, JSVAL, 0, 0)
|
||||
BUILTIN3(extern, JSVAL, js_Any_getelem, CONTEXT, OBJECT, INT32, 0, 0)
|
||||
BUILTIN4(extern, BOOL, js_Any_setelem, CONTEXT, OBJECT, INT32, JSVAL, 0, 0)
|
||||
BUILTIN2(FRIEND, BOOL, js_CloseIterator, CONTEXT, JSVAL, 0, 0)
|
||||
BUILTIN2(extern, SIDEEXIT, js_CallTree, INTERPSTATE, FRAGMENT, 0, 0)
|
||||
BUILTIN2(extern, OBJECT, js_FastNewObject, CONTEXT, OBJECT, 0, 0)
|
||||
|
|
|
@ -594,6 +594,64 @@ static struct {
|
|||
/*11*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode getprop[10];
|
||||
jsbytecode getelem[10];
|
||||
} getelem_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_CALLBUILTIN, ((JSBUILTIN_GetProperty) & 0xff00) >> 8, ((JSBUILTIN_GetProperty) & 0xff),
|
||||
/* 4*/ JSOP_PICK, 2,
|
||||
/* 6*/ JSOP_CALL, 0, 1,
|
||||
/* 9*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_SWAP,
|
||||
/* 1*/ JSOP_CALLBUILTIN, ((JSBUILTIN_GetElement) & 0xff00) >> 8, ((JSBUILTIN_GetElement) & 0xff),
|
||||
/* 4*/ JSOP_PICK, 2,
|
||||
/* 6*/ JSOP_CALL, 0, 1,
|
||||
/* 9*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode setprop[15];
|
||||
jsbytecode setelem[15];
|
||||
} setelem_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
/* 1*/ JSOP_PICK, 3,
|
||||
/* 3*/ JSOP_CALLBUILTIN, ((JSBUILTIN_SetProperty) & 0xff00) >> 8, ((JSBUILTIN_SetProperty) & 0xff),
|
||||
/* 6*/ JSOP_PICK, 4,
|
||||
/* 8*/ JSOP_PICK, 4,
|
||||
/*10*/ JSOP_CALL, 0, 2,
|
||||
/*13*/ JSOP_POP,
|
||||
/*14*/ JSOP_STOP,
|
||||
},
|
||||
{
|
||||
/* 0*/ JSOP_DUP,
|
||||
/* 1*/ JSOP_PICK, 3,
|
||||
/* 3*/ JSOP_CALLBUILTIN, ((JSBUILTIN_SetElement) & 0xff00) >> 8, ((JSBUILTIN_SetElement) & 0xff),
|
||||
/* 6*/ JSOP_PICK, 4,
|
||||
/* 8*/ JSOP_PICK, 4,
|
||||
/*10*/ JSOP_CALL, 0, 2,
|
||||
/*13*/ JSOP_POP,
|
||||
/*14*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
static struct {
|
||||
jsbytecode initelem[15];
|
||||
} initelem_imacros = {
|
||||
{
|
||||
/* 0*/ JSOP_PICK, 2,
|
||||
/* 2*/ JSOP_DUP,
|
||||
/* 3*/ JSOP_CALLBUILTIN, ((JSBUILTIN_SetElement) & 0xff00) >> 8, ((JSBUILTIN_SetElement) & 0xff),
|
||||
/* 6*/ JSOP_PICK, 4,
|
||||
/* 8*/ JSOP_PICK, 4,
|
||||
/*10*/ JSOP_CALL, 0, 2,
|
||||
/*13*/ JSOP_POP,
|
||||
/*14*/ JSOP_STOP,
|
||||
},
|
||||
};
|
||||
uint8 js_opcode2extra[JSOP_LIMIT] = {
|
||||
0, /* JSOP_NOP */
|
||||
0, /* JSOP_PUSH */
|
||||
|
@ -650,8 +708,8 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
|||
0, /* JSOP_ELEMDEC */
|
||||
0, /* JSOP_GETPROP */
|
||||
0, /* JSOP_SETPROP */
|
||||
0, /* JSOP_GETELEM */
|
||||
0, /* JSOP_SETELEM */
|
||||
2, /* JSOP_GETELEM */
|
||||
2, /* JSOP_SETELEM */
|
||||
0, /* JSOP_CALLNAME */
|
||||
0, /* JSOP_CALL */
|
||||
0, /* JSOP_NAME */
|
||||
|
@ -687,7 +745,7 @@ uint8 js_opcode2extra[JSOP_LIMIT] = {
|
|||
0, /* JSOP_NEWINIT */
|
||||
0, /* JSOP_ENDINIT */
|
||||
0, /* JSOP_INITPROP */
|
||||
0, /* JSOP_INITELEM */
|
||||
2, /* JSOP_INITELEM */
|
||||
0, /* JSOP_DEFSHARP */
|
||||
0, /* JSOP_USESHARP */
|
||||
0, /* JSOP_INCARG */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# -*- indent-tabs-mode: nil; -*-
|
||||
# vim: set sw=4 ts=8 et tw=78 ft=asm:
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -635,3 +636,64 @@
|
|||
.end
|
||||
|
||||
.end
|
||||
|
||||
.igroup getelem JSOP_GETELEM
|
||||
|
||||
.imacro getprop # obj name
|
||||
swap # name obj
|
||||
callbuiltin (JSBUILTIN_GetProperty) # name fun obj
|
||||
pick 2 # fun obj name
|
||||
call 1 # propval
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro getelem # obj i
|
||||
swap # i obj
|
||||
callbuiltin (JSBUILTIN_GetElement) # i fun obj
|
||||
pick 2 # fun obj i
|
||||
call 1 # propval
|
||||
stop
|
||||
.end
|
||||
|
||||
.end
|
||||
|
||||
.igroup setelem JSOP_SETELEM
|
||||
|
||||
.imacro setprop # obj name val
|
||||
dup # obj name val val
|
||||
pick 3 # name val val obj
|
||||
callbuiltin (JSBUILTIN_SetProperty) # name val val fun obj
|
||||
pick 4 # val val fun obj name
|
||||
pick 4 # val fun obj name val
|
||||
call 2 # val junk
|
||||
pop # val
|
||||
stop
|
||||
.end
|
||||
|
||||
.imacro setelem # obj i val
|
||||
dup # obj i val val
|
||||
pick 3 # i val val obj
|
||||
callbuiltin (JSBUILTIN_SetElement) # i val val fun obj
|
||||
pick 4 # val val fun obj i
|
||||
pick 4 # val fun obj i val
|
||||
call 2 # val junk
|
||||
pop # val
|
||||
stop
|
||||
.end
|
||||
|
||||
.end
|
||||
|
||||
.igroup initelem JSOP_INITELEM
|
||||
|
||||
.imacro initelem # obj i val
|
||||
pick 2 # i val obj
|
||||
dup # i val obj obj
|
||||
callbuiltin (JSBUILTIN_SetElement) # i val obj fun obj
|
||||
pick 4 # val obj fun obj i
|
||||
pick 4 # obj fun obj i val
|
||||
call 2 # obj junk
|
||||
pop # obj
|
||||
stop
|
||||
.end
|
||||
|
||||
.end
|
||||
|
|
|
@ -187,62 +187,6 @@ js_StringToInt32(JSContext* cx, JSString* str)
|
|||
return js_DoubleToECMAInt32(d);
|
||||
}
|
||||
|
||||
static inline JSBool
|
||||
js_Int32ToId(JSContext* cx, int32 index, jsid* id)
|
||||
{
|
||||
if (index <= JSVAL_INT_MAX) {
|
||||
*id = INT_TO_JSID(index);
|
||||
return JS_TRUE;
|
||||
}
|
||||
JSString* str = js_NumberToString(cx, index);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return js_ValueToStringId(cx, STRING_TO_JSVAL(str), id);
|
||||
}
|
||||
|
||||
jsval FASTCALL
|
||||
js_Any_getprop(JSContext* cx, JSObject* obj, JSString* idstr)
|
||||
{
|
||||
jsval v;
|
||||
jsid id;
|
||||
|
||||
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
return v;
|
||||
}
|
||||
|
||||
JSBool FASTCALL
|
||||
js_Any_setprop(JSContext* cx, JSObject* obj, JSString* idstr, jsval v)
|
||||
{
|
||||
jsid id;
|
||||
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id))
|
||||
return JS_FALSE;
|
||||
return OBJ_SET_PROPERTY(cx, obj, id, &v);
|
||||
}
|
||||
|
||||
jsval FASTCALL
|
||||
js_Any_getelem(JSContext* cx, JSObject* obj, int32 index)
|
||||
{
|
||||
jsval v;
|
||||
jsid id;
|
||||
if (!js_Int32ToId(cx, index, &id))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
return v;
|
||||
}
|
||||
|
||||
JSBool FASTCALL
|
||||
js_Any_setelem(JSContext* cx, JSObject* obj, int32 index, jsval v)
|
||||
{
|
||||
jsid id;
|
||||
if (!js_Int32ToId(cx, index, &id))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
return OBJ_SET_PROPERTY(cx, obj, id, &v);
|
||||
}
|
||||
|
||||
SideExit* FASTCALL
|
||||
js_CallTree(InterpState* state, Fragment* f)
|
||||
{
|
||||
|
|
|
@ -322,6 +322,19 @@ js_StringToNumber(JSContext* cx, JSString* str);
|
|||
jsdouble FASTCALL
|
||||
js_BooleanOrUndefinedToNumber(JSContext* cx, int32 unboxed);
|
||||
|
||||
static JS_INLINE JSBool
|
||||
js_Int32ToId(JSContext* cx, int32 index, jsid* id)
|
||||
{
|
||||
if (index <= JSVAL_INT_MAX) {
|
||||
*id = INT_TO_JSID(index);
|
||||
return JS_TRUE;
|
||||
}
|
||||
JSString* str = js_NumberToString(cx, index);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return js_ValueToStringId(cx, STRING_TO_JSVAL(str), id);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define JS_DEFINE_CALLINFO_1(linkage, rt, op, at0, cse, fold)
|
||||
|
|
|
@ -257,6 +257,10 @@ typedef enum JSRuntimeState {
|
|||
typedef enum JSBuiltinFunctionId {
|
||||
JSBUILTIN_ObjectToIterator,
|
||||
JSBUILTIN_CallIteratorNext,
|
||||
JSBUILTIN_GetProperty,
|
||||
JSBUILTIN_GetElement,
|
||||
JSBUILTIN_SetProperty,
|
||||
JSBUILTIN_SetElement,
|
||||
JSBUILTIN_LIMIT
|
||||
} JSBuiltinFunctionId;
|
||||
|
||||
|
|
|
@ -489,8 +489,7 @@ OPDEF(JSOP_LEAVEBLOCK, 200,"leaveblock", NULL, 3, -1, 0, 0, JOF_UINT16
|
|||
/*
|
||||
* Pick an element from the stack.
|
||||
*/
|
||||
OPDEF(JSOP_PICK, 201,"pick", NULL, 2, 1, 0, 0, JOF_UINT8)
|
||||
|
||||
OPDEF(JSOP_PICK, 201,"pick", NULL, 2, 0, 0, 0, JOF_UINT8)
|
||||
|
||||
/* Throws a TypeError if the value at the top of the stack is not primitive. */
|
||||
OPDEF(JSOP_PRIMTOP, 202, "primtop", NULL, 1, 1, 1, 0, JOF_BYTE)
|
||||
|
|
|
@ -4228,6 +4228,7 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op)
|
|||
!cx->fp->imacpc, stdout);) \
|
||||
flag = tr->record_##x(); \
|
||||
if (x == JSOP_ITER || x == JSOP_NEXTITER || x == JSOP_APPLY || \
|
||||
x == JSOP_GETELEM || x == JSOP_SETELEM || x== JSOP_INITELEM || \
|
||||
JSOP_IS_BINARY(x) || JSOP_IS_UNARY(x) || \
|
||||
JSOP_IS_EQUALITY(x)) { \
|
||||
goto imacro; \
|
||||
|
@ -6809,6 +6810,69 @@ TraceRecorder::record_SetPropMiss(JSPropCacheEntry* entry)
|
|||
return record_SetPropHit(entry, sprop);
|
||||
}
|
||||
|
||||
/* Functions used by JSOP_GETELEM. */
|
||||
|
||||
static JSBool
|
||||
GetProperty(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
jsval *argv;
|
||||
jsid id;
|
||||
|
||||
JS_ASSERT(argc == 1);
|
||||
argv = JS_ARGV(cx, vp);
|
||||
JS_ASSERT(JSVAL_IS_STRING(argv[0]));
|
||||
if (!js_ValueToStringId(cx, argv[0], &id))
|
||||
return JS_FALSE;
|
||||
argv[0] = ID_TO_VALUE(id);
|
||||
return OBJ_GET_PROPERTY(cx, JS_THIS_OBJECT(cx, vp), id, &JS_RVAL(cx, vp));
|
||||
}
|
||||
|
||||
static jsval FASTCALL
|
||||
GetProperty_tn(JSContext *cx, JSObject *obj, JSString *name)
|
||||
{
|
||||
jsid id;
|
||||
jsval v;
|
||||
|
||||
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(name), &id) ||
|
||||
!OBJ_GET_PROPERTY(cx, obj, id, &v)) {
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
GetElement(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
jsval *argv;
|
||||
jsid id;
|
||||
|
||||
JS_ASSERT(argc == 1);
|
||||
argv = JS_ARGV(cx, vp);
|
||||
JS_ASSERT(JSVAL_IS_NUMBER(argv[0]));
|
||||
if (!JS_ValueToId(cx, argv[0], &id))
|
||||
return JS_FALSE;
|
||||
argv[0] = ID_TO_VALUE(id);
|
||||
return OBJ_GET_PROPERTY(cx, JS_THIS_OBJECT(cx, vp), id, &JS_RVAL(cx, vp));
|
||||
}
|
||||
|
||||
static jsval FASTCALL
|
||||
GetElement_tn(JSContext* cx, JSObject* obj, int32 index)
|
||||
{
|
||||
jsval v;
|
||||
jsid id;
|
||||
|
||||
if (!js_Int32ToId(cx, index, &id))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
|
||||
return JSVAL_ERROR_COOKIE;
|
||||
return v;
|
||||
}
|
||||
|
||||
JS_DEFINE_TRCINFO_1(GetProperty,
|
||||
(3, (static, JSVAL_FAIL, GetProperty_tn, CONTEXT, THIS, STRING, 0, 0)))
|
||||
JS_DEFINE_TRCINFO_1(GetElement,
|
||||
(3, (extern, JSVAL_FAIL, GetElement_tn, CONTEXT, THIS, INT32, 0, 0)))
|
||||
|
||||
JS_REQUIRES_STACK bool
|
||||
TraceRecorder::record_JSOP_GETELEM()
|
||||
{
|
||||
|
@ -6853,12 +6917,7 @@ TraceRecorder::record_JSOP_GETELEM()
|
|||
if (!guardElemOp(obj, obj_ins, id, offsetof(JSObjectOps, getProperty), &v))
|
||||
return false;
|
||||
}
|
||||
LIns* args[] = { idx_ins, obj_ins, cx_ins };
|
||||
v_ins = lir->insCall(&js_Any_getprop_ci, args);
|
||||
guard(false, lir->ins2(LIR_eq, v_ins, INS_CONST(JSVAL_ERROR_COOKIE)), MISMATCH_EXIT);
|
||||
unbox_jsval(v, v_ins);
|
||||
set(&lval, v_ins);
|
||||
return true;
|
||||
return call_imacro(getelem_imacros.getprop);
|
||||
}
|
||||
|
||||
/* At this point we expect a whole number or we bail. */
|
||||
|
@ -6870,17 +6929,11 @@ TraceRecorder::record_JSOP_GETELEM()
|
|||
/* Accessing an object using integer index but not a dense array. */
|
||||
if (!OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||
idx_ins = makeNumberInt32(idx_ins);
|
||||
LIns* args[] = { idx_ins, obj_ins, cx_ins };
|
||||
if (!js_IndexToId(cx, JSVAL_TO_INT(idx), &id))
|
||||
return false;
|
||||
idx = ID_TO_VALUE(id);
|
||||
if (!guardElemOp(obj, obj_ins, id, offsetof(JSObjectOps, getProperty), &v))
|
||||
return false;
|
||||
LIns* v_ins = lir->insCall(&js_Any_getelem_ci, args);
|
||||
guard(false, lir->ins2(LIR_eq, v_ins, INS_CONST(JSVAL_ERROR_COOKIE)), MISMATCH_EXIT);
|
||||
unbox_jsval(v, v_ins);
|
||||
set(&lval, v_ins);
|
||||
return true;
|
||||
return call_imacro(getelem_imacros.getelem);
|
||||
}
|
||||
|
||||
jsval* vp;
|
||||
|
@ -6891,6 +6944,71 @@ TraceRecorder::record_JSOP_GETELEM()
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Functions used by JSOP_SETELEM */
|
||||
|
||||
static JSBool
|
||||
SetProperty(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
jsval *argv;
|
||||
jsid id;
|
||||
|
||||
JS_ASSERT(argc == 2);
|
||||
argv = JS_ARGV(cx, vp);
|
||||
JS_ASSERT(JSVAL_IS_STRING(argv[0]));
|
||||
if (!js_ValueToStringId(cx, argv[0], &id))
|
||||
return JS_FALSE;
|
||||
argv[0] = ID_TO_VALUE(id);
|
||||
if (!OBJ_SET_PROPERTY(cx, JS_THIS_OBJECT(cx, vp), id, &argv[1]))
|
||||
return JS_FALSE;
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static int32 FASTCALL
|
||||
SetProperty_tn(JSContext* cx, JSObject* obj, JSString* idstr, jsval v)
|
||||
{
|
||||
jsid id;
|
||||
|
||||
if (!js_ValueToStringId(cx, STRING_TO_JSVAL(idstr), &id) ||
|
||||
!OBJ_SET_PROPERTY(cx, obj, id, &v)) {
|
||||
return JSVAL_TO_BOOLEAN(JSVAL_VOID);
|
||||
}
|
||||
return JSVAL_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
SetElement(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
jsval *argv;
|
||||
jsid id;
|
||||
|
||||
JS_ASSERT(argc == 2);
|
||||
argv = JS_ARGV(cx, vp);
|
||||
JS_ASSERT(JSVAL_IS_NUMBER(argv[0]));
|
||||
if (!JS_ValueToId(cx, argv[0], &id))
|
||||
return JS_FALSE;
|
||||
argv[0] = ID_TO_VALUE(id);
|
||||
if (!OBJ_SET_PROPERTY(cx, JS_THIS_OBJECT(cx, vp), id, &argv[1]))
|
||||
return JS_FALSE;
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static int32 FASTCALL
|
||||
SetElement_tn(JSContext* cx, JSObject* obj, int32 index, jsval v)
|
||||
{
|
||||
jsid id;
|
||||
|
||||
if (!js_Int32ToId(cx, index, &id) || !OBJ_SET_PROPERTY(cx, obj, id, &v))
|
||||
return JSVAL_TO_BOOLEAN(JSVAL_VOID);
|
||||
return JSVAL_TRUE;
|
||||
}
|
||||
|
||||
JS_DEFINE_TRCINFO_1(SetProperty,
|
||||
(4, (extern, BOOL_FAIL, SetProperty_tn, CONTEXT, THIS, STRING, JSVAL, 0, 0)))
|
||||
JS_DEFINE_TRCINFO_1(SetElement,
|
||||
(4, (extern, BOOL_FAIL, SetElement_tn, CONTEXT, THIS, INT32, JSVAL, 0, 0)))
|
||||
|
||||
JS_REQUIRES_STACK bool
|
||||
TraceRecorder::record_JSOP_SETELEM()
|
||||
{
|
||||
|
@ -6918,35 +7036,36 @@ TraceRecorder::record_JSOP_SETELEM()
|
|||
idx = ID_TO_VALUE(id);
|
||||
if (!guardElemOp(obj, obj_ins, id, offsetof(JSObjectOps, setProperty), NULL))
|
||||
return false;
|
||||
LIns* args[] = { boxed_v_ins, idx_ins, obj_ins, cx_ins };
|
||||
LIns* ok_ins = lir->insCall(&js_Any_setprop_ci, args);
|
||||
guard(false, lir->ins_eq0(ok_ins), MISMATCH_EXIT);
|
||||
} else if (JSVAL_IS_INT(idx)) {
|
||||
return call_imacro(setelem_imacros.setprop);
|
||||
}
|
||||
if (JSVAL_IS_INT(idx)) {
|
||||
if (JSVAL_TO_INT(idx) < 0)
|
||||
ABORT_TRACE("negative JSOP_SETELEM index");
|
||||
idx_ins = makeNumberInt32(idx_ins);
|
||||
LIns* args[] = { boxed_v_ins, idx_ins, obj_ins, cx_ins };
|
||||
LIns* res_ins;
|
||||
if (guardDenseArray(obj, obj_ins, BRANCH_EXIT)) {
|
||||
res_ins = lir->insCall(&js_Array_dense_setelem_ci, args);
|
||||
} else {
|
||||
|
||||
if (!guardDenseArray(obj, obj_ins, BRANCH_EXIT)) {
|
||||
if (!js_IndexToId(cx, JSVAL_TO_INT(idx), &id))
|
||||
return false;
|
||||
idx = ID_TO_VALUE(id);
|
||||
if (!guardElemOp(obj, obj_ins, id, offsetof(JSObjectOps, setProperty), NULL))
|
||||
return false;
|
||||
res_ins = lir->insCall(&js_Any_setelem_ci, args);
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
return call_imacro((*pc == JSOP_INITELEM)
|
||||
? initelem_imacros.initelem
|
||||
: setelem_imacros.setelem);
|
||||
}
|
||||
|
||||
LIns* args[] = { boxed_v_ins, idx_ins, obj_ins, cx_ins };
|
||||
LIns* res_ins = lir->insCall(&js_Array_dense_setelem_ci, args);
|
||||
guard(false, lir->ins_eq0(res_ins), MISMATCH_EXIT);
|
||||
} else {
|
||||
ABORT_TRACE("non-string, non-int JSOP_SETELEM index");
|
||||
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
if (*pc == JSOP_SETELEM && pc[JSOP_SETELEM_LENGTH] != JSOP_POP)
|
||||
set(&lval, v_ins);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
if (*pc == JSOP_SETELEM && pc[JSOP_SETELEM_LENGTH] != JSOP_POP)
|
||||
set(&lval, v_ins);
|
||||
|
||||
return true;
|
||||
ABORT_TRACE("non-string, non-int JSOP_SETELEM index");
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK bool
|
||||
|
@ -8811,7 +8930,11 @@ static const struct BuiltinFunctionInfo {
|
|||
int nargs;
|
||||
} builtinFunctionInfo[JSBUILTIN_LIMIT] = {
|
||||
{ObjectToIterator_trcinfo, 1},
|
||||
{CallIteratorNext_trcinfo, 0}
|
||||
{CallIteratorNext_trcinfo, 0},
|
||||
{GetProperty_trcinfo, 1},
|
||||
{GetElement_trcinfo, 1},
|
||||
{SetProperty_trcinfo, 2},
|
||||
{SetElement_trcinfo, 2}
|
||||
};
|
||||
|
||||
JSObject *
|
||||
|
@ -9027,6 +9150,9 @@ InitIMacroCode()
|
|||
|
||||
imacro_code[JSOP_ITER] = (jsbytecode*)&iter_imacros - 1;
|
||||
imacro_code[JSOP_NEXTITER] = (jsbytecode*)&nextiter_imacros - 1;
|
||||
imacro_code[JSOP_GETELEM] = (jsbytecode*)&getelem_imacros - 1;
|
||||
imacro_code[JSOP_SETELEM] = (jsbytecode*)&setelem_imacros - 1;
|
||||
imacro_code[JSOP_INITELEM] = (jsbytecode*)&initelem_imacros - 1;
|
||||
imacro_code[JSOP_APPLY] = (jsbytecode*)&apply_imacros - 1;
|
||||
|
||||
imacro_code[JSOP_NEG] = (jsbytecode*)&unary_imacros - 1;
|
||||
|
|
|
@ -4107,6 +4107,47 @@ function testInterpreterReentry3() {
|
|||
testInterpreterReentry3.expected = 1;
|
||||
test(testInterpreterReentry3);
|
||||
|
||||
function testInterpreterReentry4() {
|
||||
var obj = {a:1, b:1, c:1, d:1, get e() 1000 };
|
||||
for (var p in obj)
|
||||
obj[p];
|
||||
}
|
||||
test(testInterpreterReentry4);
|
||||
|
||||
function testInterpreterReentry5() {
|
||||
var arr = [0, 1, 2, 3, 4];
|
||||
arr.__defineGetter__("4", function() 1000);
|
||||
for (var i = 0; i < 5; i++)
|
||||
arr[i];
|
||||
for (var p in arr)
|
||||
arr[p];
|
||||
}
|
||||
test(testInterpreterReentry5);
|
||||
|
||||
/* // These tests should pass but currently crash, pending bug 462027.
|
||||
function testInterpreterReentry6() {
|
||||
var obj = {a:1, b:1, c:1, d:1, set e(x) { this._e = x; }};
|
||||
for (var p in obj)
|
||||
obj[p] = "grue";
|
||||
return obj._e;
|
||||
}
|
||||
testInterpreterReentry6.expected = "grue";
|
||||
test(testInterpreterReentry6);
|
||||
|
||||
function testInterpreterReentry7() {
|
||||
var arr = [0, 1, 2, 3, 4];
|
||||
arr.__defineSetter__("4", function(x) { this._4 = x; });
|
||||
for (var i = 0; i < 5; i++)
|
||||
arr[i] = "grue";
|
||||
var tmp = arr._4;
|
||||
for (var p in arr)
|
||||
arr[p] = "bleen";
|
||||
return tmp + " " + arr._4;
|
||||
}
|
||||
testInterpreterReentry7.expected = "grue bleen";
|
||||
test(testInterpreterReentry7);
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* _____ _ _ _____ ______ _____ _______ *
|
||||
|
|
Загрузка…
Ссылка в новой задаче