bug 507573 - put activation clenup. r=brendan

This commit is contained in:
Igor Bukanov 2009-08-04 12:55:58 +02:00
Родитель cd713e6a13
Коммит 09801bf00f
5 изменённых файлов: 146 добавлений и 203 удалений

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

@ -672,11 +672,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
: wp->setter(cx, obj, userid, vp)); : wp->setter(cx, obj, userid, vp));
if (injectFrame) { if (injectFrame) {
/* Evil code can cause us to have an arguments object. */ /* Evil code can cause us to have an arguments object. */
if (frame.callobj) ok = frame.putActivationObjects(cx);
ok &= js_PutCallObject(cx, &frame);
if (frame.argsobj)
ok &= js_PutArgsObject(cx, &frame);
cx->fp = frame.down; cx->fp = frame.down;
if (argv != smallv) if (argv != smallv)
cx->free(argv); cx->free(argv);

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

@ -241,8 +241,6 @@ js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp)
JSObject * JSObject *
js_GetArgsObject(JSContext *cx, JSStackFrame *fp) js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
{ {
JSObject *argsobj, *global, *parent;
/* /*
* We must be in a function activation; the function must be lightweight * We must be in a function activation; the function must be lightweight
* or else fp must have a variable object. * or else fp must have a variable object.
@ -254,17 +252,10 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
fp = fp->down; fp = fp->down;
/* Create an arguments object for fp only if it lacks one. */ /* Create an arguments object for fp only if it lacks one. */
argsobj = JSVAL_TO_OBJECT(fp->argsobj); JSObject *argsobj = JSVAL_TO_OBJECT(fp->argsobj);
if (argsobj) if (argsobj)
return argsobj; return argsobj;
/* Link the new object to fp so it can get actual argument values. */
argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL);
if (!argsobj || !JS_SetPrivate(cx, argsobj, fp)) {
cx->weakRoots.newborn[GCX_OBJECT] = NULL;
return NULL;
}
/* /*
* Give arguments an intrinsic scope chain link to fp's global object. * Give arguments an intrinsic scope chain link to fp's global object.
* Since the arguments object lacks a prototype because js_ArgumentsClass * Since the arguments object lacks a prototype because js_ArgumentsClass
@ -276,10 +267,15 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
* js_GetClassPrototype not being able to find a global object containing * js_GetClassPrototype not being able to find a global object containing
* the standard prototype by starting from arguments and following parent. * the standard prototype by starting from arguments and following parent.
*/ */
global = fp->scopeChain; JSObject *parent, *global = fp->scopeChain;
while ((parent = OBJ_GET_PARENT(cx, global)) != NULL) while ((parent = OBJ_GET_PARENT(cx, global)) != NULL)
global = parent; global = parent;
STOBJ_SET_PARENT(argsobj, global); argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, global, 0);
if (!argsobj)
return NULL;
/* Link the new object to fp so it can get actual argument values. */
JS_SetPrivate(cx, argsobj, fp);
fp->argsobj = OBJECT_TO_JSVAL(argsobj); fp->argsobj = OBJECT_TO_JSVAL(argsobj);
return argsobj; return argsobj;
} }
@ -287,7 +283,7 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
static JSBool static JSBool
args_enumerate(JSContext *cx, JSObject *obj); args_enumerate(JSContext *cx, JSObject *obj);
JS_FRIEND_API(JSBool) JSBool
js_PutArgsObject(JSContext *cx, JSStackFrame *fp) js_PutArgsObject(JSContext *cx, JSStackFrame *fp)
{ {
JSObject *argsobj; JSObject *argsobj;
@ -339,32 +335,23 @@ js_PutArgsObject(JSContext *cx, JSStackFrame *fp)
} }
static JSBool static JSBool
args_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) args_delProperty(JSContext *cx, JSObject *obj, jsval idval, jsval *vp)
{ {
jsint slot; JSStackFrame *fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
JSStackFrame *fp;
if (!JSVAL_IS_INT(id))
return JS_TRUE;
fp = (JSStackFrame *)
JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
if (!fp) if (!fp)
return JS_TRUE; return JS_TRUE;
JS_ASSERT(fp->argsobj); JS_ASSERT(fp->argsobj);
slot = JSVAL_TO_INT(id); if (JSVAL_IS_INT(idval)) {
switch (slot) { uintN arg = uintN(JSVAL_TO_INT(idval));
case ARGS_CALLEE: if (arg < fp->argc && !MarkArgDeleted(cx, fp, arg))
case ARGS_LENGTH: return false;
SET_OVERRIDE_BIT(fp, slot); } else if (idval == ATOM_KEY(cx->runtime->atomState.lengthAtom)) {
break; SET_OVERRIDE_BIT(fp, ARGS_LENGTH);
} else if (idval == ATOM_KEY(cx->runtime->atomState.calleeAtom)) {
default: SET_OVERRIDE_BIT(fp, ARGS_CALLEE);
if ((uintN)slot < fp->argc && !MarkArgDeleted(cx, fp, slot))
return JS_FALSE;
break;
} }
return JS_TRUE; return true;
} }
static JS_REQUIRES_STACK JSObject * static JS_REQUIRES_STACK JSObject *
@ -536,23 +523,27 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSObject *funobj, JSFunctio
} }
static JSBool static JSBool
args_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) ArgGetter(JSContext *cx, JSObject *obj, jsval idval, jsval *vp)
{ {
jsint slot; JSStackFrame *fp = (JSStackFrame *)
JSStackFrame *fp; JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
if (!JSVAL_IS_INT(id))
return JS_TRUE;
fp = (JSStackFrame *)
JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
if (!fp) if (!fp)
return JS_TRUE; return true;
JS_ASSERT(fp->argsobj);
slot = JSVAL_TO_INT(id); if (JSVAL_IS_INT(idval)) {
switch (slot) { /*
case ARGS_CALLEE: * arg can exceed the number of arguments if a script changed the
if (!TEST_OVERRIDE_BIT(fp, slot)) { * prototype to point to another Arguments object with a bigger argc.
*/
uintN arg = uintN(JSVAL_TO_INT(idval));
if (arg < fp->argc && !ArgWasDeleted(cx, fp, arg))
*vp = fp->argv[arg];
} else if (idval == ATOM_KEY(cx->runtime->atomState.lengthAtom)) {
if (!TEST_OVERRIDE_BIT(fp, ARGS_LENGTH))
*vp = INT_TO_JSVAL((jsint)fp->argc);
} else {
JS_ASSERT(idval == ATOM_KEY(cx->runtime->atomState.calleeAtom));
if (!TEST_OVERRIDE_BIT(fp, ARGS_CALLEE)) {
/* /*
* If this function or one in it needs upvars that reach above it * If this function or one in it needs upvars that reach above it
* in the scope chain, it must not be a null closure (it could be a * in the scope chain, it must not be a null closure (it could be a
@ -564,182 +555,139 @@ args_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
if (fp->fun->needsWrapper()) { if (fp->fun->needsWrapper()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_OPTIMIZED_CLOSURE_LEAK); JSMSG_OPTIMIZED_CLOSURE_LEAK);
return JS_FALSE; return false;
} }
*vp = OBJECT_TO_JSVAL(fp->callee); *vp = OBJECT_TO_JSVAL(fp->callee);
} }
break;
case ARGS_LENGTH:
if (!TEST_OVERRIDE_BIT(fp, slot))
*vp = INT_TO_JSVAL((jsint)fp->argc);
break;
default:
if ((uintN)slot < fp->argc && !ArgWasDeleted(cx, fp, slot))
*vp = fp->argv[slot];
break;
} }
return JS_TRUE; return true;
} }
static JSBool static JSBool
args_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) ArgSetter(JSContext *cx, JSObject *obj, jsval idval, jsval *vp)
{ {
JSStackFrame *fp; JSStackFrame *fp = (JSStackFrame *)
jsint slot; JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
if (!JSVAL_IS_INT(id))
return JS_TRUE;
fp = (JSStackFrame *)
JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
if (!fp) if (!fp)
return JS_TRUE; return true;
JS_ASSERT(fp->argsobj);
slot = JSVAL_TO_INT(id); if (JSVAL_IS_INT(idval)) {
switch (slot) { uintN arg = uintN(JSVAL_TO_INT(idval));
case ARGS_CALLEE:
case ARGS_LENGTH:
SET_OVERRIDE_BIT(fp, slot);
break;
default:
if (FUN_INTERPRETED(fp->fun) && if (FUN_INTERPRETED(fp->fun) &&
(uintN)slot < fp->argc && arg < fp->argc &&
!ArgWasDeleted(cx, fp, slot)) { !ArgWasDeleted(cx, fp, arg)) {
fp->argv[slot] = *vp; fp->argv[arg] = *vp;
} }
break; } else {
JS_ASSERT(idval == ATOM_KEY(cx->runtime->atomState.lengthAtom) ||
idval == ATOM_KEY(cx->runtime->atomState.calleeAtom));
SET_OVERRIDE_BIT(fp,
(idval == ATOM_KEY(cx->runtime->atomState.lengthAtom))
? ARGS_LENGTH
: ARGS_CALLEE);
} }
return JS_TRUE; return true;
} }
static JSBool static JSBool
args_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, args_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
JSObject **objp) JSObject **objp)
{ {
JSStackFrame *fp; JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_ArgumentsClass);
uintN slot;
JSString *str;
JSAtom *atom;
intN tinyid;
jsval value;
*objp = NULL; *objp = NULL;
fp = (JSStackFrame *)
JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL); JSStackFrame *fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
if (!fp) if (!fp)
return JS_TRUE; return true;
JS_ASSERT(fp->argsobj); JS_ASSERT(fp->argsobj);
if (JSVAL_IS_INT(id)) { jsid id;
slot = JSVAL_TO_INT(id); jsval v;
if (slot < fp->argc && !ArgWasDeleted(cx, fp, slot)) { if (JSVAL_IS_INT(idval)) {
/* XXX ECMA specs DontEnum, contrary to other array-like objects */ uintN arg = uintN(JSVAL_TO_INT(idval));
if (!js_DefineProperty(cx, obj, INT_JSVAL_TO_JSID(id), if (arg >= fp->argc || ArgWasDeleted(cx, fp, arg))
fp->argv[slot], return true;
args_getProperty, args_setProperty, id = INT_JSVAL_TO_JSID(idval);
0, NULL)) { v = fp->argv[arg];
return JS_FALSE; } else {
} if (!JSVAL_IS_STRING(idval))
*objp = obj; return true;
} JSString *str = JSVAL_TO_STRING(idval);
} else if (JSVAL_IS_STRING(id)) { JSAtom *atom = cx->runtime->atomState.lengthAtom;
str = JSVAL_TO_STRING(id);
atom = cx->runtime->atomState.lengthAtom;
if (str == ATOM_TO_STRING(atom)) { if (str == ATOM_TO_STRING(atom)) {
tinyid = ARGS_LENGTH; if (TEST_OVERRIDE_BIT(fp, ARGS_LENGTH))
value = INT_TO_JSVAL(fp->argc); return true;
v = INT_TO_JSVAL(fp->argc);
} else { } else {
atom = cx->runtime->atomState.calleeAtom; atom = cx->runtime->atomState.calleeAtom;
if (str == ATOM_TO_STRING(atom)) { if (str == ATOM_TO_STRING(atom)) {
tinyid = ARGS_CALLEE; if (TEST_OVERRIDE_BIT(fp, ARGS_CALLEE))
value = OBJECT_TO_JSVAL(fp->callee); return true;
v = INT_TO_JSVAL(fp->callee);
} else { } else {
atom = NULL; return true;
/* Quell GCC overwarnings. */
tinyid = 0;
value = JSVAL_NULL;
} }
} }
id = ATOM_TO_JSID(atom);
if (atom && !TEST_OVERRIDE_BIT(fp, tinyid)) {
if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
args_getProperty, args_setProperty, 0,
SPROP_HAS_SHORTID, tinyid, NULL)) {
return JS_FALSE;
}
*objp = obj;
}
} }
return JS_TRUE; /* XXX ECMA specs DontEnum, contrary to other array-like objects */
if (!js_DefineProperty(cx, obj, id, v, ArgGetter, ArgSetter, 0, NULL))
return false;
*objp = obj;
return true;
} }
static JSBool static JSBool
args_enumerate(JSContext *cx, JSObject *obj) args_enumerate(JSContext *cx, JSObject *obj)
{ {
JSStackFrame *fp; JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_ArgumentsClass);
JSObject *pobj;
JSProperty *prop;
uintN slot, argc;
fp = (JSStackFrame *) JSStackFrame *fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
if (!fp) if (!fp)
return JS_TRUE; return JS_TRUE;
JS_ASSERT(fp->argsobj); JS_ASSERT(fp->argsobj);
/* /*
* Trigger reflection with value snapshot in args_resolve using a series * Trigger reflection in with value snapshot in args_resolve using a series
* of js_LookupProperty calls. We handle length, callee, and the indexed * of js_LookupProperty calls. We handle length, callee, and the indexed
* argument properties. We know that args_resolve covers all these cases * argument properties. We know that args_resolve covers all these cases
* and creates direct properties of obj, but that it may fail to resolve * and creates direct properties of obj, but that it may fail to resolve
* length or callee if overridden. * length or callee if overridden.
*/ */
if (!js_LookupProperty(cx, obj, int argc = int(fp->argc);
ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), for (int i = -2; i != argc; i++) {
&pobj, &prop)) { jsid id = (i == -2)
return JS_FALSE; ? ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)
} : (i == -1)
if (prop) ? ATOM_TO_JSID(cx->runtime->atomState.calleeAtom)
OBJ_DROP_PROPERTY(cx, pobj, prop); : INT_JSVAL_TO_JSID(INT_TO_JSVAL(i));
if (!js_LookupProperty(cx, obj, JSObject *pobj;
ATOM_TO_JSID(cx->runtime->atomState.calleeAtom), JSProperty *prop;
&pobj, &prop)) { if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
return JS_FALSE; return false;
}
if (prop)
OBJ_DROP_PROPERTY(cx, pobj, prop);
argc = fp->argc;
for (slot = 0; slot < argc; slot++) {
if (!js_LookupProperty(cx, obj, INT_TO_JSID((jsint)slot), &pobj, &prop))
return JS_FALSE;
if (prop) if (prop)
OBJ_DROP_PROPERTY(cx, pobj, prop); OBJ_DROP_PROPERTY(cx, pobj, prop);
} }
return JS_TRUE; return true;
} }
JSBool JS_FASTCALL JSBool JS_FASTCALL
js_PutArguments(JSContext *cx, JSObject *argsobj, uint32 length, JSObject *callee, jsval *args) js_PutArguments(JSContext *cx, JSObject *argsobj, uint32 length, JSObject *callee, jsval *args)
{ {
if (!js_DefineProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), if (!js_DefineProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
INT_TO_JSVAL(length), args_getProperty, args_setProperty, 0, NULL)) { INT_TO_JSVAL(length), ArgGetter, ArgSetter, 0, NULL)) {
return false; return false;
} }
if (!js_DefineProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.calleeAtom), if (!js_DefineProperty(cx, argsobj, ATOM_TO_JSID(cx->runtime->atomState.calleeAtom),
OBJECT_TO_JSVAL(callee), args_getProperty, args_setProperty, 0, NULL)) { OBJECT_TO_JSVAL(callee), ArgGetter, ArgSetter, 0, NULL)) {
return false; return false;
} }
for (uintN i = 0; i < length; ++i) { for (uintN i = 0; i < length; ++i) {
if (!js_DefineProperty(cx, argsobj, INT_TO_JSID(i), args[i], if (!js_DefineProperty(cx, argsobj, INT_TO_JSID(i), args[i],
args_getProperty, args_setProperty, 0, NULL)) { ArgGetter, ArgSetter, 0, NULL)) {
return false; return false;
} }
} }
@ -784,7 +732,7 @@ JSClass js_ArgumentsClass = {
JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1) |
JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object), JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
JS_PropertyStub, args_delProperty, JS_PropertyStub, args_delProperty,
args_getProperty, args_setProperty, JS_PropertyStub, JS_PropertyStub,
args_enumerate, (JSResolveOp) args_resolve, args_enumerate, (JSResolveOp) args_resolve,
JS_ConvertStub, NULL, JS_ConvertStub, NULL,
NULL, NULL, NULL, NULL,
@ -931,13 +879,25 @@ GetCallObjectFunction(JSObject *obj)
return GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(v)); return GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(v));
} }
JS_FRIEND_API(JSBool) JSBool
js_PutCallObject(JSContext *cx, JSStackFrame *fp) js_PutCallObject(JSContext *cx, JSStackFrame *fp)
{ {
JSObject *callobj; JSObject *callobj = fp->callobj;
JSBool ok; JS_ASSERT(callobj);
JSFunction *fun;
uintN n; /*
* Get the arguments object to snapshot fp's actual argument values.
*/
JSBool ok = JS_TRUE;
if (fp->argsobj) {
if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS))
STOBJ_SET_SLOT(callobj, JSSLOT_CALL_ARGUMENTS, fp->argsobj);
ok &= js_PutArgsObject(cx, fp);
}
JSFunction *fun = fp->fun;
JS_ASSERT(fun == GetCallObjectFunction(callobj));
uintN n = fun->countArgsAndVars();
/* /*
* Since for a call object all fixed slots happen to be taken, we can copy * Since for a call object all fixed slots happen to be taken, we can copy
@ -945,26 +905,6 @@ js_PutCallObject(JSContext *cx, JSStackFrame *fp)
*/ */
JS_STATIC_ASSERT(JS_INITIAL_NSLOTS - JSSLOT_PRIVATE == JS_STATIC_ASSERT(JS_INITIAL_NSLOTS - JSSLOT_PRIVATE ==
1 + CALL_CLASS_FIXED_RESERVED_SLOTS); 1 + CALL_CLASS_FIXED_RESERVED_SLOTS);
callobj = fp->callobj;
if (!callobj)
return JS_TRUE;
/*
* Get the arguments object to snapshot fp's actual argument values.
*/
ok = JS_TRUE;
if (fp->argsobj) {
if (!TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
STOBJ_SET_SLOT(callobj, JSSLOT_CALL_ARGUMENTS,
fp->argsobj);
}
ok &= js_PutArgsObject(cx, fp);
}
fun = fp->fun;
JS_ASSERT(fun == GetCallObjectFunction(callobj));
n = fun->countArgsAndVars();
if (n != 0) { if (n != 0) {
n += JS_INITIAL_NSLOTS; n += JS_INITIAL_NSLOTS;
JS_LOCK_OBJ(cx, callobj); JS_LOCK_OBJ(cx, callobj);

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

@ -273,7 +273,7 @@ js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
extern JSObject * extern JSObject *
js_GetCallObject(JSContext *cx, JSStackFrame *fp); js_GetCallObject(JSContext *cx, JSStackFrame *fp);
extern JS_FRIEND_API(JSBool) extern JSBool
js_PutCallObject(JSContext *cx, JSStackFrame *fp); js_PutCallObject(JSContext *cx, JSStackFrame *fp);
extern JSBool extern JSBool
@ -316,7 +316,7 @@ js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, jsval *vp);
extern JSObject * extern JSObject *
js_GetArgsObject(JSContext *cx, JSStackFrame *fp); js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
extern JS_FRIEND_API(JSBool) extern JSBool
js_PutArgsObject(JSContext *cx, JSStackFrame *fp); js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
extern JSBool extern JSBool

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

@ -1394,13 +1394,7 @@ out:
hook(cx, &frame, JS_FALSE, &ok, hookData); hook(cx, &frame, JS_FALSE, &ok, hookData);
} }
/* If frame has a call object, sync values and clear back-pointer. */ ok &= frame.putActivationObjects(cx);
if (frame.callobj)
ok &= js_PutCallObject(cx, &frame);
/* If frame has an arguments object, sync values and clear back-pointer. */
if (frame.argsobj)
ok &= js_PutArgsObject(cx, &frame);
*vp = frame.rval; *vp = frame.rval;
@ -3282,11 +3276,7 @@ js_Interpret(JSContext *cx)
* calls eval unexpectedly (in a way that is hidden from the * calls eval unexpectedly (in a way that is hidden from the
* compiler). See bug 325540. * compiler). See bug 325540.
*/ */
if (fp->callobj) ok &= fp->putActivationObjects(cx);
ok &= js_PutCallObject(cx, fp);
if (fp->argsobj)
ok &= js_PutArgsObject(cx, fp);
#ifdef INCLUDE_MOZILLA_DTRACE #ifdef INCLUDE_MOZILLA_DTRACE
/* DTrace function return, inlines */ /* DTrace function return, inlines */

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

@ -131,6 +131,23 @@ struct JSStackFrame {
script->staticLevel */ script->staticLevel */
inline void assertValidStackDepth(uintN depth); inline void assertValidStackDepth(uintN depth);
JSBool putActivationObjects(JSContext *cx) {
/*
* The order of calls here is important as js_PutCallObject needs to
* access argsobj.
*/
JSBool ok;
if (callobj) {
ok = js_PutCallObject(cx, this);
JS_ASSERT(!argsobj);
} else if (argsobj) {
ok = js_PutArgsObject(cx, this);
} else {
ok = JS_TRUE;
}
return ok;
}
}; };
#ifdef __cplusplus #ifdef __cplusplus