Merge tm to mc

This commit is contained in:
Robert Sayre 2009-02-19 11:48:08 -05:00
commit 695b4646c3
22 changed files with 235 additions and 155 deletions

View File

@ -376,7 +376,7 @@ class AutoFreeJSStack {
public:
AutoFreeJSStack(JSContext *ctx, void *aPtr) : mContext(ctx), mStack(aPtr) {
}
~AutoFreeJSStack() {
JS_REQUIRES_STACK ~AutoFreeJSStack() {
if (mContext && mStack)
js_FreeStack(mContext, mStack);
}
@ -2523,6 +2523,8 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs,
{
nsresult rv = NS_OK;
js_LeaveTrace(mContext);
// If the array implements nsIJSArgArray, just grab the values directly.
nsCOMPtr<nsIJSArgArray> fastArray = do_QueryInterface(aArgs);
if (fastArray != nsnull) {

View File

@ -199,10 +199,11 @@ protected:
nsresult FindXPCNativeWrapperClass(nsIXPConnectJSObjectHolder *aHolder);
// Helper to convert xpcom datatypes to jsvals.
nsresult ConvertSupportsTojsvals(nsISupports *aArgs,
void *aScope,
PRUint32 *aArgc, void **aArgv,
void **aMarkp);
JS_FORCES_STACK nsresult ConvertSupportsTojsvals(nsISupports *aArgs,
void *aScope,
PRUint32 *aArgc,
void **aArgv,
void **aMarkp);
nsresult AddSupportsPrimitiveTojsvals(nsISupports *aArg, jsval *aArgv);

View File

@ -79,4 +79,8 @@
#undef JS_INTPTR_TYPE
#undef JS_BYTES_PER_WORD
/* Some mozilla code uses JS-friend APIs that depend on JS_TRACER being
correct. */
#undef JS_TRACER
#endif /* js_config_h___ */

View File

@ -4587,7 +4587,7 @@ js_generic_fast_native_method_dispatcher(JSContext *cx, uintN argc, jsval *vp)
native =
#ifdef JS_TRACER
(fs->flags & JSFUN_TRACEABLE)
? ((JSTraceableNative *) fs->call)->native
? JS_FUNC_TO_DATA_PTR(JSTraceableNative *, fs->call)->native
:
#endif
(JSFastNative) fs->call;

View File

@ -1489,15 +1489,6 @@ js_InvokeOperationCallback(JSContext *cx)
return !cb || cb(cx);
}
#ifndef JS_TRACER
/* This is defined in jstracer.cpp in JS_TRACER builds. */
extern JS_FORCES_STACK JSStackFrame *
js_GetTopStackFrame(JSContext *cx)
{
return cx->fp;
}
#endif
JSStackFrame *
js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
{

View File

@ -1401,17 +1401,53 @@ extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
extern JSBool
js_InvokeOperationCallback(JSContext *cx);
extern JSStackFrame *
js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp);
#ifdef JS_TRACER
/*
* Reconstruct the JS stack and clear cx->onTrace. We must be currently
* executing a _FAIL builtin from trace on cx. The machine code for the trace
* remains on the C stack when js_DeepBail returns.
*
* Implemented in jstracer.cpp.
*/
JS_FORCES_STACK JS_FRIEND_API(void)
js_DeepBail(JSContext *cx);
#endif
static JS_FORCES_STACK JS_INLINE void
js_LeaveTrace(JSContext *cx)
{
#ifdef JS_TRACER
if (JS_ON_TRACE(cx))
js_DeepBail(cx);
#endif
}
static JS_INLINE JSBool
js_CanLeaveTrace(JSContext *cx)
{
JS_ASSERT(JS_ON_TRACE(cx));
#ifdef JS_TRACER
return cx->bailExit != NULL;
#else
return JS_FALSE;
#endif
}
/*
* Get the current cx->fp, first lazily instantiating stack frames if needed.
* (Do not access cx->fp directly except in JS_REQUIRES_STACK code.)
*
* Defined in jstracer.cpp if JS_TRACER is defined.
*/
extern JS_FORCES_STACK JSStackFrame *
js_GetTopStackFrame(JSContext *cx);
extern JSStackFrame *
js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp);
static JS_FORCES_STACK JS_INLINE JSStackFrame *
js_GetTopStackFrame(JSContext *cx)
{
js_LeaveTrace(cx);
return cx->fp;
}
JS_END_EXTERN_C

View File

@ -435,7 +435,7 @@ js_TraceWatchPoints(JSTracer *trc, JSObject *obj)
if (wp->object == obj) {
TRACE_SCOPE_PROPERTY(trc, wp->sprop);
if ((wp->sprop->attrs & JSPROP_SETTER) && wp->setter) {
JS_CALL_OBJECT_TRACER(trc, (JSObject *)wp->setter,
JS_CALL_OBJECT_TRACER(trc, js_CastAsObject(wp->setter),
"wp->setter");
}
JS_SET_TRACING_NAME(trc, "wp->closure");
@ -651,7 +651,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
ok = !wp->setter ||
((sprop->attrs & JSPROP_SETTER)
? js_InternalCall(cx, obj,
OBJECT_TO_JSVAL((JSObject *)wp->setter),
js_CastAsObjectJSVal(wp->setter),
1, vp, vp)
: wp->setter(cx, obj, userid, vp));
if (injectFrame) {
@ -709,11 +709,11 @@ js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
atom = NULL;
}
wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0,
OBJ_GET_PARENT(cx, (JSObject *)setter),
OBJ_GET_PARENT(cx, js_CastAsObject(setter)),
atom);
if (!wrapper)
return NULL;
return (JSPropertyOp) FUN_OBJECT(wrapper);
return js_CastAsPropertyOp(FUN_OBJECT(wrapper));
}
JS_PUBLIC_API(JSBool)
@ -1108,7 +1108,7 @@ JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
* XXX ill-defined: null return here means error was reported, unlike a
* null returned above or in the #else
*/
return js_GetCallObject(cx, fp, NULL);
return js_GetCallObject(cx, fp);
}
JS_PUBLIC_API(JSObject *)

View File

@ -590,9 +590,9 @@ JSClass js_ArgumentsClass = {
#define CALL_CLASS_FIXED_RESERVED_SLOTS 2
JSObject *
js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
js_GetCallObject(JSContext *cx, JSStackFrame *fp)
{
JSObject *callobj, *funobj;
JSObject *callobj;
/* Create a call object for fp only if it lacks one. */
JS_ASSERT(fp->fun);
@ -600,15 +600,18 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
if (callobj)
return callobj;
/* The default call parent is its function's parent (static link). */
if (!parent) {
funobj = fp->callee;
if (funobj)
parent = OBJ_GET_PARENT(cx, funobj);
}
#ifdef DEBUG
/* A call object should be a frame's outermost scope chain element. */
JSClass *classp = OBJ_GET_CLASS(cx, fp->scopeChain);
if (classp == &js_WithClass || classp == &js_BlockClass || classp == &js_CallClass)
JS_ASSERT(OBJ_GET_PRIVATE(cx, fp->scopeChain) != fp);
#endif
/* Create the call object and link it to its stack frame. */
callobj = js_NewObject(cx, &js_CallClass, NULL, parent, 0);
/*
* Create the call object, using the frame's enclosing scope as
* its parent, and link the call to its stack frame.
*/
callobj = js_NewObject(cx, &js_CallClass, NULL, fp->scopeChain, 0);
if (!callobj)
return NULL;
@ -617,8 +620,10 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
OBJECT_TO_JSVAL(FUN_OBJECT(fp->fun)));
fp->callobj = callobj;
/* Make callobj be the scope chain and the variables object. */
JS_ASSERT(fp->scopeChain == parent);
/*
* Push callobj on the top of the scope chain, and make it the
* variables object.
*/
fp->scopeChain = callobj;
fp->varobj = callobj;
return callobj;
@ -2110,7 +2115,8 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
fun->u.n.spare = 0;
if (flags & JSFUN_TRACEABLE) {
#ifdef JS_TRACER
JSTraceableNative *trcinfo = (JSTraceableNative *) native;
JSTraceableNative *trcinfo =
JS_FUNC_TO_DATA_PTR(JSTraceableNative *, native);
fun->u.n.native = (JSNative) trcinfo->native;
FUN_TRCINFO(fun) = trcinfo;
#else

View File

@ -124,7 +124,7 @@ struct JSFunction {
#ifdef JS_TRACER
/* MSVC demands the intermediate (void *) cast here. */
# define JS_TN(name,fastcall,nargs,flags,trcinfo) \
{name, (JSNative)(void *)(trcinfo), nargs, \
{name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs, \
(flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRACEABLE, 0}
#else
# define JS_TN(name,fastcall,nargs,flags,trcinfo) \
@ -204,7 +204,7 @@ extern void
js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
extern JSObject *
js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent);
js_GetCallObject(JSContext *cx, JSStackFrame *fp);
extern JS_FRIEND_API(JSBool)
js_PutCallObject(JSContext *cx, JSStackFrame *fp);

View File

@ -189,7 +189,7 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape,
* Optimize the cached vword based on our parameters and the current pc's
* opcode format flags.
*/
op = (JSOp) *pc;
op = js_GetOpcode(cx, cx->fp->script, pc);
cs = &js_CodeSpec[op];
do {
@ -318,7 +318,7 @@ js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc,
JS_ASSERT(uintN((cx->fp->imacpc ? cx->fp->imacpc : pc) - cx->fp->script->code)
< cx->fp->script->length);
op = (JSOp) *pc;
op = js_GetOpcode(cx, cx->fp->script, pc);
cs = &js_CodeSpec[op];
if (op == JSOP_LENGTH) {
atom = cx->runtime->atomState.lengthAtom;
@ -687,7 +687,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
if (fp->fun && !fp->callobj) {
JS_ASSERT(OBJ_GET_CLASS(cx, fp->scopeChain) != &js_BlockClass ||
OBJ_GET_PRIVATE(cx, fp->scopeChain) != fp);
if (!js_GetCallObject(cx, fp, fp->scopeChain))
if (!js_GetCallObject(cx, fp))
return NULL;
}
@ -1326,7 +1326,7 @@ have_fun:
frame.scopeChain = parent;
if (JSFUN_HEAVYWEIGHT_TEST(fun->flags)) {
/* Scope with a call object parented by the callee's parent. */
if (!js_GetCallObject(cx, &frame, parent)) {
if (!js_GetCallObject(cx, &frame)) {
ok = JS_FALSE;
goto out;
}
@ -3079,7 +3079,8 @@ js_Interpret(JSContext *cx)
inlineCallCount--;
if (JS_LIKELY(ok)) {
TRACE_0(LeaveFrame);
JS_ASSERT(js_CodeSpec[*regs.pc].length == JSOP_CALL_LENGTH);
JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, script, regs.pc)].length
== JSOP_CALL_LENGTH);
len = JSOP_CALL_LENGTH;
DO_NEXT_OP(len);
}
@ -3404,7 +3405,7 @@ js_Interpret(JSContext *cx)
GET_ATOM_FROM_BYTECODE(script, regs.pc, pcoff, atom_); \
else \
atom_ = rt->atomState.lengthAtom; \
if (JOF_OPMODE(*regs.pc) == JOF_NAME) { \
if (JOF_OPMODE(op) == JOF_NAME) { \
ok = js_FindProperty(cx, ATOM_TO_JSID(atom_), &obj_, &pobj_, \
&prop_); \
} else { \
@ -4932,7 +4933,7 @@ js_Interpret(JSContext *cx)
/* Scope with a call object parented by callee's parent. */
if (JSFUN_HEAVYWEIGHT_TEST(fun->flags) &&
!js_GetCallObject(cx, &newifp->frame, parent)) {
!js_GetCallObject(cx, &newifp->frame)) {
goto bad_inline_call;
}
@ -5075,7 +5076,7 @@ js_Interpret(JSContext *cx)
if (!ok)
goto error;
if (!cx->rval2set) {
op2 = (JSOp) regs.pc[JSOP_SETCALL_LENGTH];
op2 = js_GetOpcode(cx, script, regs.pc + JSOP_SETCALL_LENGTH);
if (op2 != JSOP_DELELEM) {
JS_ASSERT(!(js_CodeSpec[op2].format & JOF_DEL));
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
@ -5137,7 +5138,7 @@ js_Interpret(JSContext *cx)
if (!prop) {
/* Kludge to allow (typeof foo == "undefined") tests. */
endpc = script->code + script->length;
op2 = (JSOp) regs.pc[JSOP_NAME_LENGTH];
op2 = js_GetOpcode(cx, script, regs.pc + JSOP_NAME_LENGTH);
if (op2 == JSOP_TYPEOF) {
PUSH_OPND(JSVAL_VOID);
len = JSOP_NAME_LENGTH;
@ -5786,9 +5787,9 @@ js_Interpret(JSContext *cx)
attrs |= flags | JSPROP_SHARED;
rval = JSVAL_VOID;
if (flags == JSPROP_GETTER)
getter = JS_EXTENSION (JSPropertyOp) obj;
getter = js_CastAsPropertyOp(obj);
else
setter = JS_EXTENSION (JSPropertyOp) obj;
setter = js_CastAsPropertyOp(obj);
}
/*
@ -6292,7 +6293,7 @@ js_Interpret(JSContext *cx)
JS_ASSERT(OBJ_IS_ARRAY(cx, obj));
JS_ASSERT(JSID_IS_INT(id));
JS_ASSERT((jsuint) JSID_TO_INT(id) < ARRAY_INIT_LIMIT);
if ((JSOp) regs.pc[JSOP_INITELEM_LENGTH] == JSOP_ENDINIT &&
if (js_GetOpcode(cx, script, regs.pc + JSOP_INITELEM_LENGTH) == JSOP_ENDINIT &&
!js_SetLengthProperty(cx, obj, (jsuint) (JSID_TO_INT(id) + 1))) {
goto error;
}
@ -7041,7 +7042,7 @@ js_Interpret(JSContext *cx)
switch (tn->kind) {
case JSTRY_CATCH:
JS_ASSERT(*regs.pc == JSOP_ENTERBLOCK);
JS_ASSERT(js_GetOpcode(cx, fp->script, regs.pc) == JSOP_ENTERBLOCK);
#if JS_HAS_GENERATORS
/* Catch cannot intercept the closing of a generator. */
@ -7076,7 +7077,7 @@ js_Interpret(JSContext *cx)
* adjustment and regs.sp[1] after, to save and restore the
* pending exception.
*/
JS_ASSERT(*regs.pc == JSOP_ENDITER);
JS_ASSERT(js_GetOpcode(cx, fp->script, regs.pc) == JSOP_ENDITER);
regs.sp[-1] = cx->exception;
cx->throwing = JS_FALSE;
ok = js_CloseIterator(cx, regs.sp[-2]);

View File

@ -71,7 +71,7 @@
#include "jsstaticcheck.h"
#include "jsstr.h"
#include "jstracer.h"
#include "jsdbgapi.h" /* whether or not JS_HAS_OBJ_WATCHPOINT */
#include "jsdbgapi.h"
#if JS_HAS_GENERATORS
#include "jsiter.h"
@ -404,9 +404,10 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
if (ok) {
if (OBJ_IS_NATIVE(obj2) &&
(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
JSScopeProperty *sprop = (JSScopeProperty *) prop;
val = JSVAL_NULL;
if (attrs & JSPROP_GETTER)
val = (jsval) ((JSScopeProperty*)prop)->getter;
val = js_CastAsObjectJSVal(sprop->getter);
if (attrs & JSPROP_SETTER) {
if (val != JSVAL_NULL) {
/* Mark the getter, then set val to setter. */
@ -414,7 +415,7 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
NULL)
!= NULL);
}
val = (jsval) ((JSScopeProperty*)prop)->setter;
val = js_CastAsObjectJSVal(sprop->setter);
}
} else {
ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
@ -769,8 +770,9 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp)
}
if (OBJ_IS_NATIVE(obj2) &&
(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
JSScopeProperty *sprop = (JSScopeProperty *) prop;
if (attrs & JSPROP_GETTER) {
val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter;
val[valcnt] = js_CastAsObjectJSVal(sprop->getter);
gsopold[valcnt] =
ATOM_TO_STRING(cx->runtime->atomState.getterAtom);
gsop[valcnt] =
@ -779,7 +781,7 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp)
valcnt++;
}
if (attrs & JSPROP_SETTER) {
val[valcnt] = (jsval) ((JSScopeProperty *)prop)->setter;
val[valcnt] = js_CastAsObjectJSVal(sprop->setter);
gsopold[valcnt] =
ATOM_TO_STRING(cx->runtime->atomState.setterAtom);
gsop[valcnt] =
@ -1192,9 +1194,10 @@ js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
return principals->codebase;
}
if (caller->regs && *caller->regs->pc == JSOP_EVAL) {
JS_ASSERT(caller->regs->pc[JSOP_EVAL_LENGTH] == JSOP_LINENO);
*linenop = GET_UINT16(caller->regs->pc + JSOP_EVAL_LENGTH);
jsbytecode *pc = caller->regs->pc;
if (caller->regs && js_GetOpcode(cx, caller->script, pc) == JSOP_EVAL) {
JS_ASSERT(js_GetOpcode(cx, caller->script, pc + JSOP_EVAL_LENGTH) == JSOP_LINENO);
*linenop = GET_UINT16(pc + JSOP_EVAL_LENGTH);
} else {
*linenop = js_FramePCToLineNumber(cx, caller);
}
@ -1278,7 +1281,7 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
* object, then we need to provide one for the compiler to stick any
* declared (var) variables into.
*/
if (caller && !caller->varobj && !js_GetCallObject(cx, caller, NULL))
if (caller && !caller->varobj && !js_GetCallObject(cx, caller))
return JS_FALSE;
/* Accept an optional trailing argument that overrides the scope object. */
@ -1819,7 +1822,7 @@ js_obj_defineGetter(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
*vp = JSVAL_VOID;
return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID,
(JSPropertyOp) JSVAL_TO_OBJECT(fval),
js_CastAsPropertyOp(JSVAL_TO_OBJECT(fval)),
JS_PropertyStub,
JSPROP_ENUMERATE | JSPROP_GETTER | JSPROP_SHARED,
NULL);
@ -1855,7 +1858,7 @@ js_obj_defineSetter(JSContext *cx, uintN argc, jsval *vp)
*vp = JSVAL_VOID;
return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID,
JS_PropertyStub,
(JSPropertyOp) JSVAL_TO_OBJECT(fval),
js_CastAsPropertyOp(JSVAL_TO_OBJECT(fval)),
JSPROP_ENUMERATE | JSPROP_SETTER | JSPROP_SHARED,
NULL);
}
@ -1878,7 +1881,7 @@ obj_lookupGetter(JSContext *cx, uintN argc, jsval *vp)
if (OBJ_IS_NATIVE(pobj)) {
sprop = (JSScopeProperty *) prop;
if (sprop->attrs & JSPROP_GETTER)
*vp = OBJECT_TO_JSVAL((JSObject *) sprop->getter);
*vp = js_CastAsObjectJSVal(sprop->getter);
}
OBJ_DROP_PROPERTY(cx, pobj, prop);
}
@ -1903,7 +1906,7 @@ obj_lookupSetter(JSContext *cx, uintN argc, jsval *vp)
if (OBJ_IS_NATIVE(pobj)) {
sprop = (JSScopeProperty *) prop;
if (sprop->attrs & JSPROP_SETTER)
*vp = OBJECT_TO_JSVAL((JSObject *) sprop->setter);
*vp = js_CastAsObjectJSVal(sprop->setter);
}
OBJ_DROP_PROPERTY(cx, pobj, prop);
}
@ -2016,18 +2019,15 @@ static JS_REQUIRES_STACK JSBool
Detecting(JSContext *cx, jsbytecode *pc)
{
JSScript *script;
jsbytecode *endpc;
JSOp op;
JSAtom *atom;
if (!cx->fp)
return JS_FALSE;
script = cx->fp->script;
for (endpc = script->code + script->length;
pc < endpc;
pc += js_CodeSpec[op].length) {
for (;; pc += js_CodeSpec[op].length) {
/* General case: a branch or equality op follows the access. */
op = (JSOp) *pc;
op = js_GetOpcode(cx, script, pc);
if (js_CodeSpec[op].format & JOF_DETECTING)
return JS_TRUE;
@ -2037,9 +2037,9 @@ Detecting(JSContext *cx, jsbytecode *pc)
* Special case #1: handle (document.all == null). Don't sweat
* about JS1.2's revision of the equality operators here.
*/
if (++pc < endpc)
return *pc == JSOP_EQ || *pc == JSOP_NE;
return JS_FALSE;
pc++;
op = js_GetOpcode(cx, script, pc);
return op == JSOP_EQ || op == JSOP_NE;
case JSOP_NAME:
/*
@ -2048,9 +2048,9 @@ Detecting(JSContext *cx, jsbytecode *pc)
* Edition 3, so is read/write for backward compatibility.
*/
GET_ATOM_FROM_BYTECODE(script, pc, 0, atom);
if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID] &&
(pc += js_CodeSpec[op].length) < endpc) {
op = (JSOp) *pc;
if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID]) {
pc += js_CodeSpec[op].length;
op = js_GetOpcode(cx, script, pc);
return op == JSOP_EQ || op == JSOP_NE ||
op == JSOP_STRICTEQ || op == JSOP_STRICTNE;
}
@ -2066,7 +2066,6 @@ Detecting(JSContext *cx, jsbytecode *pc)
break;
}
}
return JS_FALSE;
}
/*
@ -2088,7 +2087,7 @@ InferFlags(JSContext *cx, uintN defaultFlags)
if (!fp || !fp->regs)
return defaultFlags;
pc = fp->regs->pc;
cs = &js_CodeSpec[*pc];
cs = &js_CodeSpec[js_GetOpcode(cx, fp->script, pc)];
format = cs->format;
if (JOF_MODE(format) != JOF_NAME)
flags |= JSRESOLVE_QUALIFIED;
@ -3945,8 +3944,11 @@ js_GetCurrentBytecodePC(JSContext* cx)
pc = fp->regs->pc;
// FIXME: Set pc to imacpc when recording JSOP_CALL inside the
// JSOP_GETELEM imacro (bug 476559).
if (*pc == JSOP_CALL && fp->imacpc && *fp->imacpc == JSOP_GETELEM)
if (*pc == JSOP_CALL &&
fp->imacpc &&
js_GetOpcode(cx, fp->script, fp->imacpc) == JSOP_GETELEM) {
pc = fp->imacpc;
}
} else {
pc = NULL;
}
@ -3994,6 +3996,10 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
uintN flags;
op = (JSOp) *pc;
if (op == JSOP_TRAP) {
JS_ASSERT_NOT_ON_TRACE(cx);
op = JS_GetTrapOpcode(cx, cx->fp->script, pc);
}
if (op == JSOP_GETXPROP) {
flags = JSREPORT_ERROR;
} else {
@ -4009,10 +4015,15 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
if (id == ATOM_TO_JSID(cx->runtime->atomState.iteratorAtom))
return JS_TRUE;
/* Kludge to allow (typeof foo == "undefined") tests. */
pc += js_CodeSpec[op].length;
if (Detecting(cx, pc))
/* Do not warn about tests like (obj[prop] == undefined). */
if (cx->resolveFlags == JSRESOLVE_INFER) {
js_LeaveTrace(cx);
pc += js_CodeSpec[op].length;
if (Detecting(cx, pc))
return JS_TRUE;
} else if (cx->resolveFlags & JSRESOLVE_DETECTING) {
return JS_TRUE;
}
flags = JSREPORT_WARNING | JSREPORT_STRICT;
}
@ -5653,7 +5664,7 @@ dumpValue(jsval val)
fprintf(stderr, "<%s%s at %p>",
cls->name,
cls == &js_ObjectClass ? "" : " object",
obj);
(void *) obj);
} else if (JSVAL_IS_INT(val)) {
fprintf(stderr, "%d", JSVAL_TO_INT(val));
} else if (JSVAL_IS_STRING(val)) {
@ -5749,7 +5760,7 @@ js_DumpObject(JSObject *obj)
if (sharesScope) {
if (proto) {
fprintf(stderr, "no own properties - see proto (%s at %p)\n",
STOBJ_GET_CLASS(proto)->name, proto);
STOBJ_GET_CLASS(proto)->name, (void *) proto);
} else {
fprintf(stderr, "no own properties - null proto\n");
}

View File

@ -137,9 +137,7 @@ js_GetIndexFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc,
JSOp op;
uintN span, base;
op = (JSOp)*pc;
if (op == JSOP_TRAP)
op = JS_GetTrapOpcode(cx, script, pc);
op = js_GetOpcode(cx, script, pc);
JS_ASSERT(js_CodeSpec[op].length >= 1 + pcoff + UINT16_LEN);
/*
@ -5210,9 +5208,7 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
LOCAL_ASSERT(script->main <= target && target < script->code + script->length);
pcdepth = 0;
for (pc = script->main; pc < target; pc += oplen) {
op = (JSOp) *pc;
if (op == JSOP_TRAP)
op = JS_GetTrapOpcode(cx, script, pc);
op = js_GetOpcode(cx, script, pc);
cs = &js_CodeSpec[op];
oplen = cs->length;
if (oplen < 0)
@ -5232,7 +5228,7 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
jmpoff = js_GetSrcNoteOffset(sn, 0);
if (pc + jmpoff < target) {
pc += jmpoff;
op = (JSOp) *pc;
op = js_GetOpcode(cx, script, pc);
JS_ASSERT(op == JSOP_GOTO || op == JSOP_GOTOX);
cs = &js_CodeSpec[op];
oplen = cs->length;

View File

@ -55,6 +55,7 @@
*/
#include "jspubtd.h"
#include "jsutil.h"
/* Internal identifier (jsid) macros. */
@ -260,4 +261,19 @@ struct JSTempValueRooter {
extern JSBool js_CStringsAreUTF8;
#endif
/*
* Helper macros to convert between function and data pointers assuming that
* they have the same size.
*/
JS_STATIC_ASSERT(sizeof(void *) == sizeof(void (*)()));
#ifdef __GNUC__
# define JS_FUNC_TO_DATA_PTR(type, fun) (__extension__ (type) (fun))
# define JS_DATA_TO_FUNC_PTR(type, ptr) (__extension__ (type) (ptr))
#else
/* Use an extra (void *) cast for MSVC. */
# define JS_FUNC_TO_DATA_PTR(type, fun) ((type) (void *) (fun))
# define JS_DATA_TO_FUNC_PTR(type, ptr) ((type) (void *) (ptr))
#endif
#endif /* jsprvtd_h___ */

View File

@ -3903,7 +3903,7 @@ MatchRegExp(REGlobalData *gData, REMatchState *x)
caller ? caller->script->filename : "<unknown>",
caller ? js_FramePCToLineNumber(gData->cx, caller) : 0,
caller ? FramePCOffset(caller) : 0,
(void *) native);
JS_FUNC_TO_DATA_PTR(void *, native));
})
#endif

View File

@ -1559,16 +1559,12 @@ js_TraceScopeProperty(JSTracer *trc, JSScopeProperty *sprop)
#if JS_HAS_GETTER_SETTER
if (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
if (sprop->attrs & JSPROP_GETTER) {
JS_ASSERT(JSVAL_IS_OBJECT((jsval) sprop->getter));
JS_SET_TRACING_DETAILS(trc, PrintPropertyGetterOrSetter, sprop, 0);
JS_CallTracer(trc, JSVAL_TO_OBJECT((jsval) sprop->getter),
JSTRACE_OBJECT);
JS_CallTracer(trc, js_CastAsObject(sprop->getter), JSTRACE_OBJECT);
}
if (sprop->attrs & JSPROP_SETTER) {
JS_ASSERT(JSVAL_IS_OBJECT((jsval) sprop->setter));
JS_SET_TRACING_DETAILS(trc, PrintPropertyGetterOrSetter, sprop, 1);
JS_CallTracer(trc, JSVAL_TO_OBJECT((jsval) sprop->setter),
JSTRACE_OBJECT);
JS_CallTracer(trc, js_CastAsObject(sprop->setter), JSTRACE_OBJECT);
}
}
#endif /* JS_HAS_GETTER_SETTER */

View File

@ -271,6 +271,27 @@ JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap));
#define SCOPE_LAST_PROP(scope) ((scope)->lastProp)
#define SCOPE_REMOVE_LAST_PROP(scope) ((scope)->lastProp = \
(scope)->lastProp->parent)
/*
* Helpers for reinterpreting JSPropertyOp as JSObject* for scripted getters
* and setters.
*/
static inline JSObject *
js_CastAsObject(JSPropertyOp op)
{
return JS_FUNC_TO_DATA_PTR(JSObject *, op);
}
static inline jsval
js_CastAsObjectJSVal(JSPropertyOp op)
{
return OBJECT_TO_JSVAL(JS_FUNC_TO_DATA_PTR(JSObject *, op));
}
static inline JSPropertyOp
js_CastAsPropertyOp(JSObject *object)
{
return JS_DATA_TO_FUNC_PTR(JSPropertyOp, object);
}
struct JSScopeProperty {
jsid id; /* int-tagged jsval/untagged JSAtom* */
@ -334,8 +355,8 @@ SPROP_GET(JSContext* cx, JSScopeProperty* sprop, JSObject* obj, JSObject* obj2,
JS_ASSERT(!SPROP_HAS_STUB_GETTER(sprop));
if (sprop->attrs & JSPROP_GETTER) {
return js_InternalGetOrSet(cx, obj, sprop->id,
OBJECT_TO_JSVAL((JSObject *) sprop->getter), JSACC_READ,
jsval fval = js_CastAsObjectJSVal(sprop->getter);
return js_InternalGetOrSet(cx, obj, sprop->id, fval, JSACC_READ,
0, 0, vp);
}
@ -349,9 +370,9 @@ SPROP_SET(JSContext* cx, JSScopeProperty* sprop, JSObject* obj, JSObject* obj2,
!(sprop->attrs & JSPROP_GETTER)));
if (sprop->attrs & JSPROP_SETTER) {
return js_InternalGetOrSet(cx, obj, (sprop)->id,
OBJECT_TO_JSVAL((JSObject *) sprop->setter),
JSACC_WRITE, 1, vp, vp);
jsval fval = js_CastAsObjectJSVal(sprop->setter);
return js_InternalGetOrSet(cx, obj, (sprop)->id, fval, JSACC_WRITE,
1, vp, vp);
}
if (sprop->attrs & JSPROP_GETTER) {

View File

@ -310,7 +310,7 @@ static JSBool
script_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval)
{
JSObject *scopeobj, *parent;
JSObject *scopeobj;
JSStackFrame *caller;
JSPrincipals *principals;
JSScript *script;
@ -343,9 +343,8 @@ script_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
/* Called from a lightweight function. */
JS_ASSERT(caller->fun && !JSFUN_HEAVYWEIGHT_TEST(caller->fun->flags));
/* Scope chain links from Call object to callee's parent. */
parent = OBJ_GET_PARENT(cx, caller->callee);
if (!js_GetCallObject(cx, caller, parent))
/* Scope chain links from Call object to caller's scope chain. */
if (!js_GetCallObject(cx, caller))
return JS_FALSE;
}
@ -362,7 +361,7 @@ script_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
} else {
/*
* Called from native code, so we don't know what scope object to
* use. We could use parent (see above), but Script.prototype.exec
* use. We could use the caller's scope chain (see above), but Script.prototype.exec
* might be a shared/sealed "superglobal" method. A more general
* approach would use cx->globalObject, which will be the same as
* exec.__parent__ in the non-superglobal case. In the superglobal
@ -1755,6 +1754,7 @@ js_FramePCToLineNumber(JSContext *cx, JSStackFrame *fp)
uintN
js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
{
JSOp op;
JSFunction *fun;
uintN lineno;
ptrdiff_t offset, target;
@ -1769,8 +1769,9 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
* Special case: function definition needs no line number note because
* the function's script contains its starting line number.
*/
if (js_CodeSpec[*pc].format & JOF_INDEXBASE)
pc += js_CodeSpec[*pc].length;
op = js_GetOpcode(cx, script, pc);
if (js_CodeSpec[op].format & JOF_INDEXBASE)
pc += js_CodeSpec[op].length;
if (*pc == JSOP_DEFFUN) {
GET_FUNCTION_FROM_BYTECODE(script, pc, 0, fun);
return fun->u.i.script->lineno;

View File

@ -45,6 +45,7 @@
*/
#include "jsatom.h"
#include "jsprvtd.h"
#include "jsdbgapi.h"
JS_BEGIN_EXTERN_C
@ -315,6 +316,15 @@ js_LineNumberToPC(JSScript *script, uintN lineno);
extern JS_FRIEND_API(uintN)
js_GetScriptLineExtent(JSScript *script);
static JS_INLINE JSOp
js_GetOpcode(JSContext *cx, JSScript *script, jsbytecode *pc)
{
JSOp op = (JSOp) *pc;
if (op == JSOP_TRAP)
op = JS_GetTrapOpcode(cx, script, pc);
return op;
}
/*
* If magic is non-null, js_XDRScript succeeds on magic number mismatch but
* returns false in *magic; it reflects a match via a true *magic out param.

View File

@ -210,8 +210,9 @@ js_InitJITStatsClass(JSContext *cx, JSObject *glob)
#define AUDIT(x) ((void)0)
#endif /* JS_JIT_SPEW */
#define INS_CONST(c) addName(lir->insImm(c), #c)
#define INS_CONSTPTR(p) addName(lir->insImmPtr((void*) (p)), #p)
#define INS_CONST(c) addName(lir->insImm(c), #c)
#define INS_CONSTPTR(p) addName(lir->insImmPtr((void*) (p)), #p)
#define INS_CONSTFUNPTR(p) addName(lir->insImmPtr(JS_FUNC_TO_DATA_PTR(void*, p)), #p)
using namespace avmplus;
using namespace nanojit;
@ -850,7 +851,7 @@ public:
{
}
JS_REQUIRES_STACK LInsp ins2(LOpcode v, LInsp s0, LInsp s1)
LInsp ins2(LOpcode v, LInsp s0, LInsp s1)
{
if (s0 == s1 && v == LIR_feq) {
if (isPromote(s0)) {
@ -3204,7 +3205,7 @@ js_SynthesizeFrame(JSContext* cx, const FrameInfo& fi)
#ifdef DEBUG
JSObject *obj =
#endif
js_GetCallObject(cx, &newifp->frame, newifp->frame.scopeChain);
js_GetCallObject(cx, &newifp->frame);
JS_ASSERT(obj);
JS_TRACE_MONITOR(cx).useReservedObjects = JS_FALSE;
}
@ -4637,22 +4638,21 @@ js_FlushJITCache(JSContext* cx)
oracle.clearHitCounts();
}
JS_FORCES_STACK JSStackFrame *
js_GetTopStackFrame(JSContext *cx)
JS_FORCES_STACK JS_FRIEND_API(void)
js_DeepBail(JSContext *cx)
{
if (JS_ON_TRACE(cx)) {
/* It's a bug if a non-FAIL_STATUS builtin gets here. */
JS_ASSERT(cx->bailExit);
JS_ASSERT(JS_ON_TRACE(cx));
JS_TRACE_MONITOR(cx).onTrace = false;
JS_TRACE_MONITOR(cx).prohibitRecording = true;
LeaveTree(*cx->interpState, cx->bailExit);
/* It's a bug if a non-FAIL_STATUS builtin gets here. */
JS_ASSERT(cx->bailExit);
JS_TRACE_MONITOR(cx).onTrace = false;
JS_TRACE_MONITOR(cx).prohibitRecording = true;
LeaveTree(*cx->interpState, cx->bailExit);
#ifdef DEBUG
cx->bailExit = NULL;
cx->bailExit = NULL;
#endif
cx->builtinStatus |= JSBUILTIN_BAILED;
}
return cx->fp;
cx->builtinStatus |= JSBUILTIN_BAILED;
}
JS_REQUIRES_STACK jsval&
@ -5547,7 +5547,7 @@ TraceRecorder::map_is_native(JSObjectMap* map, LIns* map_ins, LIns*& ops_ins, si
#define OP(ops) (*(JSObjectOp*) ((char*)(ops) + op_offset))
if (OP(map->ops) == OP(&js_ObjectOps)) {
guard(true, addName(lir->ins2(LIR_eq, n, INS_CONSTPTR(OP(&js_ObjectOps))),
guard(true, addName(lir->ins2(LIR_eq, n, INS_CONSTFUNPTR(OP(&js_ObjectOps))),
"guard(native-map)"),
MISMATCH_EXIT);
return true;
@ -7060,7 +7060,8 @@ GetProperty(JSContext *cx, uintN argc, jsval *vp)
jsval *argv;
jsid id;
JS_ASSERT(!JS_ON_TRACE(cx) && cx->fp->imacpc && argc == 1);
JS_ASSERT_NOT_ON_TRACE(cx);
JS_ASSERT(cx->fp->imacpc && argc == 1);
argv = JS_ARGV(cx, vp);
JS_ASSERT(JSVAL_IS_STRING(argv[0]));
if (!js_ValueToStringId(cx, argv[0], &id))
@ -7091,7 +7092,8 @@ GetElement(JSContext *cx, uintN argc, jsval *vp)
jsval *argv;
jsid id;
JS_ASSERT(!JS_ON_TRACE(cx) && cx->fp->imacpc && argc == 1);
JS_ASSERT_NOT_ON_TRACE(cx);
JS_ASSERT(cx->fp->imacpc && argc == 1);
argv = JS_ARGV(cx, vp);
JS_ASSERT(JSVAL_IS_NUMBER(argv[0]));
if (!JS_ValueToId(cx, argv[0], &id))
@ -9250,10 +9252,12 @@ js_GetBuiltinFunction(JSContext *cx, uintN index)
if (!funobj) {
/* Use NULL parent and atom. Builtin functions never escape to scripts. */
JS_ASSERT(index < JS_ARRAY_LENGTH(builtinFunctionInfo));
const BuiltinFunctionInfo *bfi = &builtinFunctionInfo[index];
JSFunction *fun = js_NewFunction(cx,
NULL,
(JSNative) builtinFunctionInfo[index].tn,
builtinFunctionInfo[index].nargs,
JS_DATA_TO_FUNC_PTR(JSNative, bfi->tn),
bfi->nargs,
JSFUN_FAST_NATIVE | JSFUN_TRACEABLE,
NULL,
NULL);

View File

@ -629,22 +629,4 @@ js_GetBuiltinFunction(JSContext *cx, uintN index);
#endif /* !JS_TRACER */
static JS_INLINE JS_FORCES_STACK void
js_LeaveTrace(JSContext *cx)
{
if (JS_ON_TRACE(cx))
js_GetTopStackFrame(cx);
}
static JS_INLINE bool
js_CanLeaveTrace(JSContext *cx)
{
JS_ASSERT(JS_ON_TRACE(cx));
#ifdef JS_TRACER
return cx->bailExit;
#else
return false;
#endif
}
#endif /* jstracer_h___ */

View File

@ -1399,7 +1399,7 @@ PCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
#ifdef DEBUG
static void
UpdateSwitchTableBounds(JSScript *script, uintN offset,
UpdateSwitchTableBounds(JSContext *cx, JSScript *script, uintN offset,
uintN *start, uintN *end)
{
jsbytecode *pc;
@ -1408,7 +1408,7 @@ UpdateSwitchTableBounds(JSScript *script, uintN offset,
jsint low, high, n;
pc = script->code + offset;
op = (JSOp) *pc;
op = js_GetOpcode(cx, script, pc);
switch (op) {
case JSOP_TABLESWITCHX:
jmplen = JUMPX_OFFSET_LEN;
@ -1471,7 +1471,7 @@ SrcNotes(JSContext *cx, JSScript *script)
if (switchTableStart <= offset && offset < switchTableEnd) {
name = "case";
} else {
JS_ASSERT(script->code[offset] == JSOP_NOP);
JS_ASSERT(js_GetOpcode(cx, script, script->code + offset) == JSOP_NOP);
}
}
fprintf(gOutFile, "%3u: %5u [%4u] %-8s",
@ -1529,7 +1529,7 @@ SrcNotes(JSContext *cx, JSScript *script)
caseOff = (uintN) js_GetSrcNoteOffset(sn, 1);
if (caseOff)
fprintf(gOutFile, " first case offset %u", caseOff);
UpdateSwitchTableBounds(script, offset,
UpdateSwitchTableBounds(cx, script, offset,
&switchTableStart, &switchTableEnd);
break;
case SRC_CATCH:

View File

@ -1261,6 +1261,8 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
// prepare to do the function call. This adds a fair amount of complexity,
// but is a good optimization compared to calling JS_AddRoot for each item.
js_LeaveTrace(cx);
// setup stack
// if this isn't a function call then we don't need to push extra stuff