зеркало из https://github.com/mozilla/gecko-dev.git
Merge tracemonkey to mozilla-central.
This commit is contained in:
Коммит
d0c7618343
|
@ -1607,7 +1607,7 @@ js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
|
|||
|
||||
#if defined DEBUG && defined XP_UNIX
|
||||
/* For gdb usage. */
|
||||
void js_traceon(JSContext *cx) { cx->tracefp = stderr; cx->tracePrevOp = JSOP_LIMIT; }
|
||||
void js_traceon(JSContext *cx) { cx->tracefp = stderr; cx->tracePrevPc = NULL; }
|
||||
void js_traceoff(JSContext *cx) { cx->tracefp = NULL; }
|
||||
#endif
|
||||
|
||||
|
|
|
@ -932,7 +932,7 @@ struct JSContext {
|
|||
char *lastMessage;
|
||||
#ifdef DEBUG
|
||||
void *tracefp;
|
||||
JSOp tracePrevOp;
|
||||
jsbytecode *tracePrevPc;
|
||||
#endif
|
||||
|
||||
/* Per-context optional error reporter. */
|
||||
|
|
|
@ -6274,32 +6274,40 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
case TOK_ARRAYCOMP:
|
||||
#endif
|
||||
/*
|
||||
* Emit code for [a, b, c] of the form:
|
||||
* Emit code for [a, b, c] that is equivalent to constructing a new
|
||||
* array and in source order evaluating each element value and adding
|
||||
* it to the array, without invoking latent setters. We use the
|
||||
* JSOP_NEWINIT and JSOP_INITELEM bytecodes to ignore setters and to
|
||||
* avoid dup'ing and popping the array as each element is added, as
|
||||
* JSOP_SETELEM/JSOP_SETPROP would do.
|
||||
*
|
||||
* t = new Array; t[0] = a; t[1] = b; t[2] = c; t;
|
||||
*
|
||||
* but use a stack slot for t and avoid dup'ing and popping it using
|
||||
* the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
|
||||
*
|
||||
* If no sharp variable is defined and the initialiser is not for an
|
||||
* array comprehension, use JSOP_NEWARRAY.
|
||||
* If no sharp variable is defined, the initializer is not for an array
|
||||
* comprehension, the initializer is not overlarge, and the initializer
|
||||
* is not in global code (whose stack growth cannot be precisely modeled
|
||||
* due to the need to reserve space for global variables and regular
|
||||
* expressions), use JSOP_NEWARRAY to minimize opcodes and to create the
|
||||
* array using a fast, all-at-once process rather than a slow, element-
|
||||
* by-element process.
|
||||
*/
|
||||
#if JS_HAS_SHARP_VARS
|
||||
sharpnum = -1;
|
||||
do_emit_array:
|
||||
#endif
|
||||
|
||||
#if JS_HAS_GENERATORS || JS_HAS_SHARP_VARS
|
||||
op = JSOP_NEWARRAY;
|
||||
# if JS_HAS_GENERATORS
|
||||
op = (JS_LIKELY(pn->pn_count < JS_BIT(16)) && (cg->flags & TCF_IN_FUNCTION))
|
||||
? JSOP_NEWARRAY
|
||||
: JSOP_NEWINIT;
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
if (pn->pn_type == TOK_ARRAYCOMP)
|
||||
op = JSOP_NEWINIT;
|
||||
# endif
|
||||
# if JS_HAS_SHARP_VARS
|
||||
#endif
|
||||
#if JS_HAS_SHARP_VARS
|
||||
JS_ASSERT_IF(sharpnum >= 0, cg->flags & TCF_HAS_SHARPS);
|
||||
if (cg->flags & TCF_HAS_SHARPS)
|
||||
op = JSOP_NEWINIT;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
if (op == JSOP_NEWINIT) {
|
||||
if (js_Emit2(cx, cg, op, (jsbytecode) JSProto_Array) < 0)
|
||||
return JS_FALSE;
|
||||
|
@ -6308,7 +6316,6 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid) sharpnum);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
if (pn->pn_type == TOK_ARRAYCOMP) {
|
||||
|
@ -6335,10 +6342,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
|
||||
pn2 = pn->pn_head;
|
||||
for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
|
||||
#if JS_HAS_SHARP_VARS
|
||||
if (op == JSOP_NEWINIT && !EmitNumberOp(cx, atomIndex, cg))
|
||||
return JS_FALSE;
|
||||
#endif
|
||||
if (pn2->pn_type == TOK_COMMA) {
|
||||
if (js_Emit1(cx, cg, JSOP_HOLE) < 0)
|
||||
return JS_FALSE;
|
||||
|
@ -6346,10 +6351,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
if (!js_EmitTree(cx, cg, pn2))
|
||||
return JS_FALSE;
|
||||
}
|
||||
#if JS_HAS_SHARP_VARS
|
||||
if (op == JSOP_NEWINIT && js_Emit1(cx, cg, JSOP_INITELEM) < 0)
|
||||
return JS_FALSE;
|
||||
#endif
|
||||
}
|
||||
JS_ASSERT(atomIndex == pn->pn_count);
|
||||
|
||||
|
@ -6359,20 +6362,18 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#if JS_HAS_SHARP_VARS
|
||||
if (op == JSOP_NEWINIT) {
|
||||
/* Emit an op for sharp array cleanup and decompilation. */
|
||||
/*
|
||||
* Emit an op to finish the array and, secondarily, to aid in sharp
|
||||
* array cleanup (if JS_HAS_SHARP_VARS) and decompilation.
|
||||
*/
|
||||
if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0)
|
||||
return JS_FALSE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
off = js_EmitN(cx, cg, JSOP_NEWARRAY, 3);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
pc = CG_CODE(cg, off);
|
||||
SET_UINT24(pc, atomIndex);
|
||||
UpdateDepth(cx, cg, off);
|
||||
|
||||
JS_ASSERT(atomIndex < JS_BIT(16));
|
||||
EMIT_UINT16_IMM_OP(JSOP_NEWARRAY, atomIndex);
|
||||
break;
|
||||
|
||||
case TOK_RC:
|
||||
|
@ -6388,12 +6389,12 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
}
|
||||
#endif
|
||||
/*
|
||||
* Emit code for {p:a, '%q':b, 2:c} of the form:
|
||||
*
|
||||
* t = new Object; t.p = a; t['%q'] = b; t[2] = c; t;
|
||||
*
|
||||
* but use a stack slot for t and avoid dup'ing and popping it via
|
||||
* the JSOP_NEWINIT and JSOP_INITELEM/JSOP_INITPROP bytecodes.
|
||||
* Emit code for {p:a, '%q':b, 2:c} that is equivalent to constructing
|
||||
* a new object and in source order evaluating each property value and
|
||||
* adding the property to the object, without invoking latent setters.
|
||||
* We use the JSOP_NEWINIT and JSOP_INITELEM/JSOP_INITPROP bytecodes to
|
||||
* ignore setters and to avoid dup'ing and popping the object as each
|
||||
* property is added, as JSOP_SETELEM/JSOP_SETPROP would do.
|
||||
*/
|
||||
if (js_Emit2(cx, cg, JSOP_NEWINIT, (jsbytecode) JSProto_Object) < 0)
|
||||
return JS_FALSE;
|
||||
|
|
|
@ -261,7 +261,7 @@ struct JSTreeContext { /* tree context for semantic checks */
|
|||
#define TCF_HAS_SHARPS 0x8000 /* source contains sharp defs or uses */
|
||||
|
||||
/*
|
||||
* Flags to propagate from FunctionBody.
|
||||
* Sticky deoptimization flags to propagate from FunctionBody.
|
||||
*/
|
||||
#define TCF_FUN_FLAGS (TCF_FUN_SETS_OUTER_NAME | \
|
||||
TCF_FUN_USES_ARGUMENTS | \
|
||||
|
|
|
@ -2104,9 +2104,10 @@ js_TraceOpcode(JSContext *cx)
|
|||
* Operations in prologues don't produce interesting values, and
|
||||
* js_DecompileValueGenerator isn't set up to handle them anyway.
|
||||
*/
|
||||
if (cx->tracePrevOp != JSOP_LIMIT && regs->pc >= fp->script->main) {
|
||||
ndefs = js_GetStackDefs(cx, &js_CodeSpec[cx->tracePrevOp],
|
||||
cx->tracePrevOp, fp->script, regs->pc);
|
||||
if (cx->tracePrevPc && regs->pc >= fp->script->main) {
|
||||
JSOp tracePrevOp = JSOp(*cx->tracePrevPc);
|
||||
ndefs = js_GetStackDefs(cx, &js_CodeSpec[tracePrevOp], tracePrevOp,
|
||||
fp->script, cx->tracePrevPc);
|
||||
|
||||
/*
|
||||
* If there aren't that many elements on the stack, then
|
||||
|
@ -2159,7 +2160,7 @@ js_TraceOpcode(JSContext *cx)
|
|||
}
|
||||
fprintf(tracefp, " @ %u\n", (uintN) (regs->sp - StackBase(fp)));
|
||||
}
|
||||
cx->tracePrevOp = op;
|
||||
cx->tracePrevPc = regs->pc;
|
||||
|
||||
/* It's nice to have complete traces when debugging a crash. */
|
||||
fflush(tracefp);
|
||||
|
@ -3638,7 +3639,25 @@ js_Interpret(JSContext *cx)
|
|||
do {
|
||||
JSPropCacheEntry *entry;
|
||||
|
||||
/*
|
||||
* We can skip the property lookup for the global object. If
|
||||
* the property does not exist anywhere on the scope chain,
|
||||
* JSOP_SETNAME adds the property to the global.
|
||||
*
|
||||
* As a consequence of this optimization for the global object
|
||||
* we run its JSRESOLVE_ASSIGNING-tolerant resolve hooks only
|
||||
* in JSOP_SETNAME, after the interpreter evaluates the right-
|
||||
* hand-side of the assignment, and not here.
|
||||
*
|
||||
* This should be transparent to the hooks because the script,
|
||||
* instead of name = rhs, could have used global.name = rhs
|
||||
* given a global object reference, which also calls the hooks
|
||||
* only after evaluating the rhs. We desire such resolve hook
|
||||
* equivalence between the two forms.
|
||||
*/
|
||||
obj = fp->scopeChain;
|
||||
if (!OBJ_GET_PARENT(cx, obj))
|
||||
break;
|
||||
if (JS_LIKELY(OBJ_IS_NATIVE(obj))) {
|
||||
PROPERTY_CACHE_TEST(cx, regs.pc, obj, obj2, entry, atom);
|
||||
if (!atom) {
|
||||
|
@ -3651,7 +3670,7 @@ js_Interpret(JSContext *cx)
|
|||
LOAD_ATOM(0);
|
||||
}
|
||||
id = ATOM_TO_JSID(atom);
|
||||
obj = js_FindIdentifierBase(cx, id, entry);
|
||||
obj = js_FindIdentifierBase(cx, fp->scopeChain, id, entry);
|
||||
if (!obj)
|
||||
goto error;
|
||||
} while (0);
|
||||
|
@ -4757,8 +4776,10 @@ js_Interpret(JSContext *cx)
|
|||
LOAD_ATOM(0);
|
||||
id = ATOM_TO_JSID(atom);
|
||||
if (entry) {
|
||||
if (!js_SetPropertyHelper(cx, obj, id, &rval, &entry))
|
||||
if (!js_SetPropertyHelper(cx, obj, id, op == JSOP_SETNAME,
|
||||
&rval, &entry)) {
|
||||
goto error;
|
||||
}
|
||||
#ifdef JS_TRACER
|
||||
if (entry)
|
||||
TRACE_1(SetPropMiss, entry);
|
||||
|
@ -6252,8 +6273,8 @@ js_Interpret(JSContext *cx)
|
|||
END_CASE(JSOP_HOLE)
|
||||
|
||||
BEGIN_CASE(JSOP_NEWARRAY)
|
||||
len = GET_UINT24(regs.pc);
|
||||
JS_ASSERT(len <= regs.sp - StackBase(fp));
|
||||
len = GET_UINT16(regs.pc);
|
||||
cx->fp->assertValidStackDepth(len);
|
||||
obj = js_NewArrayObject(cx, len, regs.sp - len, JS_TRUE);
|
||||
if (!obj)
|
||||
goto error;
|
||||
|
@ -6412,7 +6433,7 @@ js_Interpret(JSContext *cx)
|
|||
goto error;
|
||||
}
|
||||
if (JS_UNLIKELY(atom == cx->runtime->atomState.protoAtom)
|
||||
? !js_SetPropertyHelper(cx, obj, id, &rval, &entry)
|
||||
? !js_SetPropertyHelper(cx, obj, id, false, &rval, &entry)
|
||||
: !js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL,
|
||||
&entry)) {
|
||||
|
@ -7288,6 +7309,10 @@ js_Interpret(JSContext *cx)
|
|||
ok &= js_UnwindScope(cx, fp, 0, ok || cx->throwing);
|
||||
JS_ASSERT(regs.sp == StackBase(fp));
|
||||
|
||||
#ifdef DEBUG
|
||||
cx->tracePrevPc = NULL;
|
||||
#endif
|
||||
|
||||
if (inlineCallCount)
|
||||
goto inline_return;
|
||||
|
||||
|
|
|
@ -132,6 +132,14 @@ struct JSStackFrame {
|
|||
#ifdef DEBUG
|
||||
jsrefcount pcDisabledSave; /* for balanced property cache control */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus /* Aargh, LiveConnect, bug 442399. */
|
||||
void assertValidStackDepth(uintN depth) {
|
||||
extern jsval *StackBase(JSStackFrame *fp);
|
||||
JS_ASSERT(0 <= regs->sp - StackBase(this));
|
||||
JS_ASSERT(depth <= uintptr_t(regs->sp - StackBase(this)));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
116
js/src/jsobj.cpp
116
js/src/jsobj.cpp
|
@ -4070,45 +4070,68 @@ js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
|
|||
}
|
||||
|
||||
JS_REQUIRES_STACK JSObject *
|
||||
js_FindIdentifierBase(JSContext *cx, jsid id, JSPropCacheEntry *entry)
|
||||
js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id,
|
||||
JSPropCacheEntry *entry)
|
||||
{
|
||||
JSObject *obj, *pobj;
|
||||
JSProperty *prop;
|
||||
/*
|
||||
* This function should not be called for a global object or from the
|
||||
* trace and should have a valid cache entry for native scopeChain.
|
||||
*/
|
||||
JSObject *parent = OBJ_GET_PARENT(cx, scopeChain);
|
||||
JS_ASSERT(parent);
|
||||
JS_ASSERT(!JS_ON_TRACE(cx));
|
||||
JS_ASSERT_IF(OBJ_IS_NATIVE(scopeChain), entry);
|
||||
|
||||
/*
|
||||
* Look for id's property along the "with" statement chain and the
|
||||
* statically-linked scope chain.
|
||||
* Optimize and cache only for classes that do not have resolve hooks and
|
||||
* where the prototype is used only to implement a shared scope, bug 462734
|
||||
* and bug 487039.
|
||||
*/
|
||||
if (js_FindPropertyHelper(cx, id, &obj, &pobj, &prop, &entry) < 0)
|
||||
return NULL;
|
||||
if (prop) {
|
||||
OBJ_DROP_PROPERTY(cx, pobj, prop);
|
||||
return obj;
|
||||
}
|
||||
JSObject *obj = scopeChain;
|
||||
for (int scopeIndex = 0; ; scopeIndex++) {
|
||||
JSClass *clasp = OBJ_GET_CLASS(cx, obj);
|
||||
if (clasp != &js_CallClass && clasp != &js_BlockClass)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Use the top-level scope from the scope chain, which won't end in the
|
||||
* same scope as cx->globalObject for cross-context function calls.
|
||||
*/
|
||||
JS_ASSERT(obj);
|
||||
|
||||
/*
|
||||
* Property not found. Give a strict warning if binding an undeclared
|
||||
* top-level variable.
|
||||
*/
|
||||
if (JS_HAS_STRICT_OPTION(cx)) {
|
||||
JSString *str = JSVAL_TO_STRING(ID_TO_VALUE(id));
|
||||
const char *bytes = js_GetStringBytes(cx, str);
|
||||
|
||||
if (!bytes ||
|
||||
!JS_ReportErrorFlagsAndNumber(cx,
|
||||
JSREPORT_WARNING | JSREPORT_STRICT,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_UNDECLARED_VAR, bytes)) {
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
int protoIndex = js_LookupPropertyWithFlags(cx, obj, id, 0,
|
||||
&pobj, &prop);
|
||||
if (protoIndex < 0)
|
||||
return NULL;
|
||||
if (prop) {
|
||||
JS_ASSERT(OBJ_IS_NATIVE(pobj));
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, pobj) == clasp);
|
||||
js_FillPropertyCache(cx, scopeChain, OBJ_SHAPE(scopeChain),
|
||||
scopeIndex, protoIndex, pobj,
|
||||
(JSScopeProperty *) prop, &entry);
|
||||
JS_UNLOCK_OBJ(cx, pobj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
obj = parent;
|
||||
parent = OBJ_GET_PARENT(cx, parent);
|
||||
if (!parent) {
|
||||
/*
|
||||
* Here obj is the global one and we can skip any checks for it,
|
||||
* see comments in the JSOP_BINDNAME case of js_Interpret.
|
||||
*/
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
JSObject *pobj;
|
||||
JSProperty *prop;
|
||||
if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
|
||||
return NULL;
|
||||
if (prop) {
|
||||
OBJ_DROP_PROPERTY(cx, pobj, prop);
|
||||
break;
|
||||
}
|
||||
obj = parent;
|
||||
parent = OBJ_GET_PARENT(cx, parent);
|
||||
} while (parent);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -4337,8 +4360,8 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
||||
JSPropCacheEntry **entryp)
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSBool unqualified, jsval *vp, JSPropCacheEntry **entryp)
|
||||
{
|
||||
uint32 shape;
|
||||
int protoIndex;
|
||||
|
@ -4368,10 +4391,28 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
&pobj, &prop);
|
||||
if (protoIndex < 0)
|
||||
return JS_FALSE;
|
||||
if (prop) {
|
||||
if (!OBJ_IS_NATIVE(pobj)) {
|
||||
OBJ_DROP_PROPERTY(cx, pobj, prop);
|
||||
prop = NULL;
|
||||
}
|
||||
} else {
|
||||
/* We should never add properties to lexical blocks. */
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) != &js_BlockClass);
|
||||
|
||||
if (prop && !OBJ_IS_NATIVE(pobj)) {
|
||||
OBJ_DROP_PROPERTY(cx, pobj, prop);
|
||||
prop = NULL;
|
||||
if (unqualified && !OBJ_GET_PARENT(cx, obj) &&
|
||||
JS_HAS_STRICT_OPTION(cx)) {
|
||||
JSString *str = JSVAL_TO_STRING(ID_TO_VALUE(id));
|
||||
const char *bytes = js_GetStringBytes(cx, str);
|
||||
if (!bytes ||
|
||||
!JS_ReportErrorFlagsAndNumber(cx,
|
||||
JSREPORT_WARNING |
|
||||
JSREPORT_STRICT,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_UNDECLARED_VAR, bytes)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
sprop = (JSScopeProperty *) prop;
|
||||
|
||||
|
@ -4487,9 +4528,6 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
}
|
||||
|
||||
if (!sprop) {
|
||||
/* We should never add properties to lexical blocks. */
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) != &js_BlockClass);
|
||||
|
||||
/*
|
||||
* Purge the property cache of now-shadowed id in obj's scope chain.
|
||||
* Do this early, before locking obj to avoid nesting locks.
|
||||
|
@ -4549,7 +4587,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
JSBool
|
||||
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
return js_SetPropertyHelper(cx, obj, id, vp, NULL);
|
||||
return js_SetPropertyHelper(cx, obj, id, false, vp, NULL);
|
||||
}
|
||||
|
||||
JSBool
|
||||
|
|
|
@ -681,7 +681,8 @@ js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
|
|||
JSProperty **propp);
|
||||
|
||||
extern JS_REQUIRES_STACK JSObject *
|
||||
js_FindIdentifierBase(JSContext *cx, jsid id, JSPropCacheEntry *entry);
|
||||
js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id,
|
||||
JSPropCacheEntry *entry);
|
||||
|
||||
extern JSObject *
|
||||
js_FindVariableScope(JSContext *cx, JSFunction **funp);
|
||||
|
@ -711,8 +712,8 @@ js_GetMethod(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
|||
JSPropCacheEntry **entryp);
|
||||
|
||||
extern JSBool
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
||||
JSPropCacheEntry **entryp);
|
||||
js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSBool unqualified, jsval *vp, JSPropCacheEntry **entryp);
|
||||
|
||||
extern JSBool
|
||||
js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
|
||||
|
|
|
@ -214,7 +214,7 @@ js_GetVariableStackUses(JSOp op, jsbytecode *pc)
|
|||
case JSOP_LEAVEBLOCKEXPR:
|
||||
return GET_UINT16(pc) + 1;
|
||||
case JSOP_NEWARRAY:
|
||||
return GET_UINT24(pc);
|
||||
return GET_UINT16(pc);
|
||||
default:
|
||||
/* stack: fun, this, [argc arguments] */
|
||||
JS_ASSERT(op == JSOP_NEW || op == JSOP_CALL ||
|
||||
|
@ -4357,7 +4357,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
break;
|
||||
|
||||
case JSOP_NEWARRAY:
|
||||
argc = GET_UINT24(pc);
|
||||
argc = GET_UINT16(pc);
|
||||
LOCAL_ASSERT(ss->top >= (uintN) argc);
|
||||
if (argc == 0) {
|
||||
todo = SprintCString(&ss->sprinter, "[]");
|
||||
|
|
|
@ -554,9 +554,9 @@ OPDEF(JSOP_LENGTH, 221, "length", NULL, 1, 1, 1, 18, JOF_BYTE|J
|
|||
* stack, consuming those values and replacing them with the newly-constructed
|
||||
* array. The topmost value is the last value in the new array, and the
|
||||
* bottommost value is the first value in the array; the array length is a
|
||||
* 24-bit immediate operand to the instruction.
|
||||
* 16-bit immediate operand to the instruction.
|
||||
*/
|
||||
OPDEF(JSOP_NEWARRAY, 222, "newarray", NULL, 4, -1, 1, 19, JOF_UINT24)
|
||||
OPDEF(JSOP_NEWARRAY, 222, "newarray", NULL, 3, -1, 1, 19, JOF_UINT16)
|
||||
|
||||
/*
|
||||
* Push a JSVAL_HOLE value onto the stack, representing an omitted property in
|
||||
|
|
|
@ -6405,9 +6405,15 @@ GeneratorExpr(JSParseNode *pn, JSParseNode *kid, JSTreeContext *tc)
|
|||
if (!funbox)
|
||||
return NULL;
|
||||
|
||||
gentc.flags |= TCF_FUN_IS_GENERATOR | TCF_GENEXP_LAMBDA;
|
||||
if (tc->flags & TCF_HAS_SHARPS)
|
||||
gentc.flags |= TCF_HAS_SHARPS;
|
||||
/*
|
||||
* We assume conservatively that any deoptimization flag in tc->flags
|
||||
* besides TCF_FUN_PARAM_ARGUMENTS can come from the kid. So we
|
||||
* propagate these flags into genfn. For code simplicity we also do
|
||||
* not detect if the flags were only set in the kid and could be
|
||||
* removed from tc->flags.
|
||||
*/
|
||||
gentc.flags |= TCF_FUN_IS_GENERATOR | TCF_GENEXP_LAMBDA |
|
||||
(tc->flags & (TCF_FUN_FLAGS & ~TCF_FUN_PARAM_ARGUMENTS));
|
||||
funbox->tcflags |= gentc.flags;
|
||||
genfn->pn_funbox = funbox;
|
||||
genfn->pn_blockid = gentc.bodyid;
|
||||
|
|
|
@ -7180,7 +7180,9 @@ TraceRecorder::functionCall(bool constructing, uintN argc)
|
|||
JS_REQUIRES_STACK bool
|
||||
TraceRecorder::record_JSOP_NEW()
|
||||
{
|
||||
return functionCall(true, GET_ARGC(cx->fp->regs->pc));
|
||||
uintN argc = GET_ARGC(cx->fp->regs->pc);
|
||||
cx->fp->assertValidStackDepth(argc + 2);
|
||||
return functionCall(true, argc);
|
||||
}
|
||||
|
||||
JS_REQUIRES_STACK bool
|
||||
|
@ -7893,7 +7895,9 @@ TraceRecorder::interpretedFunctionCall(jsval& fval, JSFunction* fun, uintN argc,
|
|||
JS_REQUIRES_STACK bool
|
||||
TraceRecorder::record_JSOP_CALL()
|
||||
{
|
||||
return functionCall(false, GET_ARGC(cx->fp->regs->pc));
|
||||
uintN argc = GET_ARGC(cx->fp->regs->pc);
|
||||
cx->fp->assertValidStackDepth(argc + 2);
|
||||
return functionCall(false, argc);
|
||||
}
|
||||
|
||||
static jsbytecode* apply_imacro_table[] = {
|
||||
|
@ -7926,8 +7930,9 @@ TraceRecorder::record_JSOP_APPLY()
|
|||
JSStackFrame* fp = cx->fp;
|
||||
jsbytecode *pc = fp->regs->pc;
|
||||
uintN argc = GET_ARGC(pc);
|
||||
cx->fp->assertValidStackDepth(argc + 2);
|
||||
|
||||
jsval* vp = fp->regs->sp - (argc + 2);
|
||||
JS_ASSERT(vp >= StackBase(fp));
|
||||
jsuint length = 0;
|
||||
JSObject* aobj = NULL;
|
||||
LIns* aobj_ins = NULL;
|
||||
|
@ -9919,7 +9924,9 @@ TraceRecorder::record_JSOP_NEWARRAY()
|
|||
if (!getClassPrototype(JSProto_Array, proto_ins))
|
||||
return false;
|
||||
|
||||
uint32 len = GET_UINT24(cx->fp->regs->pc);
|
||||
uint32 len = GET_UINT16(cx->fp->regs->pc);
|
||||
cx->fp->assertValidStackDepth(len);
|
||||
|
||||
LIns* args[] = { lir->insImm(len), proto_ins, cx_ins };
|
||||
LIns* v_ins = lir->insCall(&js_NewUninitializedArray_ci, args);
|
||||
guard(false, lir->ins_eq0(v_ins), OOM_EXIT);
|
||||
|
|
|
@ -204,7 +204,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
|
|||
* before deserialization of bytecode. If the saved version does not match
|
||||
* the current version, abort deserialization and invalidate the file.
|
||||
*/
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 45)
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 46)
|
||||
|
||||
/*
|
||||
* Library-private functions.
|
||||
|
|
|
@ -1882,7 +1882,7 @@ Tracing(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if (cx->tracefp && cx->tracefp != stderr)
|
||||
fclose((FILE *)cx->tracefp);
|
||||
cx->tracefp = file;
|
||||
cx->tracePrevOp = JSOP_LIMIT;
|
||||
cx->tracePrevPc = NULL;
|
||||
return JS_TRUE;
|
||||
|
||||
bad_argument:
|
||||
|
|
Загрузка…
Ссылка в новой задаче