зеркало из https://github.com/mozilla/pjs.git
[bug 424376] backing out - too much compatibility problems.
This commit is contained in:
Родитель
a819dca863
Коммит
b7c7e118a6
|
@ -1641,7 +1641,7 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
|
|||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
JSFunction *fun = OBJ_TO_FUNCTION((JSObject *)aFunObj);
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(aCx, (JSObject *)aFunObj);
|
||||
JSScript *script = JS_GetFunctionScript(aCx, fun);
|
||||
|
||||
NS_ASSERTION(!script, "Null principal for non-native function!");
|
||||
|
@ -2156,7 +2156,7 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
|
|||
nsresult *rv)
|
||||
{
|
||||
NS_PRECONDITION(rv, "Null out param");
|
||||
JSFunction *fun = OBJ_TO_FUNCTION(obj);
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
JSScript *script = JS_GetFunctionScript(cx, fun);
|
||||
|
||||
*rv = NS_OK;
|
||||
|
@ -2180,17 +2180,29 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
|
|||
// Script object came from, and we want the principal of
|
||||
// the eval function object or new Script object.
|
||||
|
||||
return GetScriptPrincipal(cx, frameScript, rv);
|
||||
script = frameScript;
|
||||
}
|
||||
else if (JS_GetFunctionObject(fun) != obj)
|
||||
{
|
||||
// Here, obj is a cloned function object. In this case, the
|
||||
// clone's prototype may have been precompiled from brutally
|
||||
// shared chrome, or else it is a lambda or nested function.
|
||||
// The general case here is a function compiled against a
|
||||
// different scope than the one it is parented by at runtime,
|
||||
// hence the creation of a clone to carry the correct scope
|
||||
// chain linkage.
|
||||
//
|
||||
// Since principals follow scope, we must get the object
|
||||
// principal from the clone's scope chain. There are no
|
||||
// reliable principals compiled into the function itself.
|
||||
|
||||
nsIPrincipal *result = doGetObjectPrincipal(obj);
|
||||
if (!result)
|
||||
*rv = NS_ERROR_FAILURE;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Since principals follow scope, we must get the object
|
||||
// principal from the function's scope chain. There are no
|
||||
// reliable principals compiled into the function itself.
|
||||
|
||||
nsIPrincipal *result = doGetObjectPrincipal(obj);
|
||||
if (!result)
|
||||
*rv = NS_ERROR_FAILURE;
|
||||
return result;
|
||||
return GetScriptPrincipal(cx, script, rv);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -2213,7 +2225,7 @@ nsScriptSecurityManager::GetFramePrincipal(JSContext *cx,
|
|||
#ifdef DEBUG
|
||||
if (NS_SUCCEEDED(*rv) && !result)
|
||||
{
|
||||
JSFunction *fun = OBJ_TO_FUNCTION(obj);
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
JSScript *script = JS_GetFunctionScript(cx, fun);
|
||||
|
||||
NS_ASSERTION(!script, "Null principal for non-native function!");
|
||||
|
|
|
@ -1391,6 +1391,7 @@ Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
SHOW_FLAG(THISP_NUMBER);
|
||||
SHOW_FLAG(THISP_BOOLEAN);
|
||||
SHOW_FLAG(EXPR_CLOSURE);
|
||||
SHOW_FLAG(SCRIPTED);
|
||||
|
||||
#undef SHOW_FLAG
|
||||
putchar('\n');
|
||||
|
|
|
@ -2076,12 +2076,10 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
|
|||
|
||||
case JSTRACE_SCRIPTED_FUNCTION:
|
||||
{
|
||||
JSScriptedFunction *sfun = (JSScriptedFunction *)thing;
|
||||
JSScriptedFunction *fun = (JSScriptedFunction *)thing;
|
||||
|
||||
if (sfun->atom) {
|
||||
js_PutEscapedString(buf, bufsize, ATOM_TO_STRING(sfun->atom),
|
||||
0);
|
||||
}
|
||||
if (fun->atom && ATOM_IS_STRING(fun->atom))
|
||||
js_PutEscapedString(buf, bufsize, ATOM_TO_STRING(fun->atom), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2743,7 +2741,7 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
* we know to create an object of this class when we call the
|
||||
* constructor.
|
||||
*/
|
||||
NATIVE_FUN_SET_CLASS(fun, clasp);
|
||||
fun->clasp = clasp;
|
||||
|
||||
/*
|
||||
* Optionally construct the prototype object, before the class has
|
||||
|
@ -2751,7 +2749,7 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
* different object, as is done for operator new -- and as at least
|
||||
* XML support requires.
|
||||
*/
|
||||
ctor = &fun->base.object;
|
||||
ctor = &fun->object;
|
||||
if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
|
||||
cval = OBJECT_TO_JSVAL(ctor);
|
||||
if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval))
|
||||
|
@ -4199,7 +4197,7 @@ JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags,
|
|||
JSObject *parent, const char *name)
|
||||
{
|
||||
JSAtom *atom;
|
||||
JSNativeFunction *nfun;
|
||||
JSNativeFunction *fun;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
|
@ -4210,8 +4208,8 @@ JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags,
|
|||
if (!atom)
|
||||
return NULL;
|
||||
}
|
||||
nfun = js_NewNativeFunction(cx, native, nargs, flags, parent, atom);
|
||||
return nfun ? &nfun->base : NULL;
|
||||
fun = js_NewNativeFunction(cx, native, nargs, flags, parent, atom);
|
||||
return fun ? NATIVE_TO_FUN(fun) : NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
|
@ -4384,7 +4382,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
|
|||
uintN flags;
|
||||
JSObject *ctor;
|
||||
JSFunction *fun;
|
||||
JSNativeFunction *nfun;
|
||||
JSNativeFunction *native;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
ctor = NULL;
|
||||
|
@ -4411,15 +4409,15 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
|
|||
fs->nargs + 1, flags);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
nfun = FUN_TO_NATIVE(fun);
|
||||
nfun->extra = (uint16)fs->extra;
|
||||
nfun->minargs = (uint16)(fs->extra >> 16);
|
||||
native = FUN_TO_NATIVE(fun);
|
||||
native->extra = (uint16)fs->extra;
|
||||
native->minargs = (uint16)(fs->extra >> 16);
|
||||
|
||||
/*
|
||||
* As jsapi.h notes, fs must point to storage that lives as long
|
||||
* as fun->object lives.
|
||||
*/
|
||||
if (!JS_SetReservedSlot(cx, &nfun->base.object, 0,
|
||||
if (!JS_SetReservedSlot(cx, &native->object, 0,
|
||||
PRIVATE_TO_JSVAL(fs)))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -4429,9 +4427,9 @@ JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
|
|||
fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
nfun = FUN_TO_NATIVE(fun);
|
||||
nfun->extra = (uint16)fs->extra;
|
||||
nfun->minargs = (uint16)(fs->extra >> 16);
|
||||
native = FUN_TO_NATIVE(fun);
|
||||
native->extra = (uint16)fs->extra;
|
||||
native->minargs = (uint16)(fs->extra >> 16);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -4441,14 +4439,14 @@ JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
|
|||
uintN nargs, uintN attrs)
|
||||
{
|
||||
JSAtom *atom;
|
||||
JSNativeFunction *nfun;
|
||||
JSNativeFunction *fun;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
if (!atom)
|
||||
return NULL;
|
||||
nfun = js_DefineFunction(cx, obj, atom, call, nargs, attrs);
|
||||
return nfun ? &nfun->base : NULL;
|
||||
fun = js_DefineFunction(cx, obj, atom, call, nargs, attrs);
|
||||
return fun ? NATIVE_TO_FUN(fun) : NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
|
@ -4457,13 +4455,13 @@ JS_DefineUCFunction(JSContext *cx, JSObject *obj,
|
|||
uintN nargs, uintN attrs)
|
||||
{
|
||||
JSAtom *atom;
|
||||
JSNativeFunction *nfun;
|
||||
JSNativeFunction *fun;
|
||||
|
||||
atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
|
||||
if (!atom)
|
||||
return NULL;
|
||||
nfun = js_DefineFunction(cx, obj, atom, call, nargs, attrs);
|
||||
return nfun ? &nfun->base : NULL;
|
||||
fun = js_DefineFunction(cx, obj, atom, call, nargs, attrs);
|
||||
return fun ? NATIVE_TO_FUN(fun) : NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript *)
|
||||
|
@ -4729,8 +4727,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno)
|
||||
{
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *sfun;
|
||||
JSScriptedFunction *fun;
|
||||
JSTempValueRooter tvr;
|
||||
JSAtom *funAtom, *argAtom;
|
||||
uintN i;
|
||||
|
@ -4741,45 +4738,44 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
} else {
|
||||
funAtom = js_Atomize(cx, name, strlen(name), 0);
|
||||
if (!funAtom) {
|
||||
funobj = NULL;
|
||||
fun = NULL;
|
||||
goto out2;
|
||||
}
|
||||
}
|
||||
funobj = js_NewScriptedFunction(cx, NULL, 0, obj, funAtom);
|
||||
if (!funobj)
|
||||
fun = js_NewScriptedFunction(cx, NULL, 0, obj, funAtom);
|
||||
if (!fun)
|
||||
goto out2;
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
|
||||
/* From this point the control must flow through the label out. */
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, &funobj->object, &tvr);
|
||||
JS_PUSH_TEMP_ROOT_FUNCTION(cx, fun, &tvr);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
|
||||
if (!argAtom) {
|
||||
funobj = NULL;
|
||||
fun = NULL;
|
||||
goto out;
|
||||
}
|
||||
if (!js_AddLocal(cx, sfun, argAtom, JSLOCAL_ARG)) {
|
||||
funobj = NULL;
|
||||
if (!js_AddLocal(cx, fun, argAtom, JSLOCAL_ARG)) {
|
||||
fun = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!js_CompileFunctionBody(cx, funobj, principals, chars, length,
|
||||
if (!js_CompileFunctionBody(cx, fun, principals, chars, length,
|
||||
filename, lineno)) {
|
||||
funobj = NULL;
|
||||
fun = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (obj &&
|
||||
funAtom &&
|
||||
!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(funAtom),
|
||||
OBJECT_TO_JSVAL(&funobj->object),
|
||||
OBJECT_TO_JSVAL(fun->object),
|
||||
NULL, NULL, JSPROP_ENUMERATE, NULL)) {
|
||||
funobj = NULL;
|
||||
fun = NULL;
|
||||
}
|
||||
|
||||
#ifdef JS_SCOPE_DEPTH_METER
|
||||
if (funobj && obj) {
|
||||
if (fun && obj) {
|
||||
JSObject *pobj = obj;
|
||||
uintN depth = 1;
|
||||
|
||||
|
@ -4790,13 +4786,12 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
#endif
|
||||
|
||||
out:
|
||||
cx->weakRoots.newborn[JSTRACE_OBJECT] = &funobj->object;
|
||||
cx->weakRoots.newborn[JSTRACE_SCRIPTED_FUNCTION] = sfun;
|
||||
cx->weakRoots.newborn[JSTRACE_SCRIPTED_FUNCTION] = fun;
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
|
||||
out2:
|
||||
LAST_FRAME_CHECKS(cx, funobj);
|
||||
return funobj;
|
||||
LAST_FRAME_CHECKS(cx, fun);
|
||||
return fun ? SCRIPTED_TO_FUN(fun) : NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
|
|
|
@ -574,7 +574,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
closure = (JSObject *) wp->closure;
|
||||
clasp = OBJ_GET_CLASS(cx, closure);
|
||||
if (clasp == &js_FunctionClass) {
|
||||
fun = OBJ_TO_FUNCTION(closure);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, closure);
|
||||
script = FUN_IS_SCRIPTED(fun)
|
||||
? FUN_TO_SCRIPTED(fun)->script
|
||||
: NULL;
|
||||
|
@ -673,7 +673,8 @@ js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
jsval userid;
|
||||
|
||||
funobj = JSVAL_TO_OBJECT(argv[-2]);
|
||||
wrapper = OBJ_TO_FUNCTION(funobj);
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass);
|
||||
wrapper = GET_FUNCTION_PRIVATE(cx, funobj);
|
||||
userid = ATOM_KEY(FUN_ATOM(wrapper));
|
||||
*rval = argv[0];
|
||||
return js_watch_set(cx, obj, userid, rval);
|
||||
|
@ -702,7 +703,7 @@ js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
|
|||
atom);
|
||||
if (!wrapper)
|
||||
return NULL;
|
||||
return (JSPropertyOp) &wrapper->base.object;
|
||||
return (JSPropertyOp) &wrapper->object;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -1013,9 +1014,11 @@ JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
|
|||
if (fp->fun) {
|
||||
JSRuntime *rt = cx->runtime;
|
||||
|
||||
if (rt->findObjectPrincipals)
|
||||
return rt->findObjectPrincipals(cx, fp->callee);
|
||||
/* FALL THROUGH */
|
||||
if (rt->findObjectPrincipals) {
|
||||
if (FUN_OBJECT(fp->fun) != fp->callee)
|
||||
return rt->findObjectPrincipals(cx, fp->callee);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
}
|
||||
if (fp->script)
|
||||
return fp->script->principals;
|
||||
|
@ -1577,24 +1580,26 @@ GetAtomTotalSize(JSContext *cx, JSAtom *atom)
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(size_t)
|
||||
JS_GetFunctionTotalSize(JSContext *cx, JSFunction *funobj)
|
||||
JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
|
||||
{
|
||||
size_t nbytes;
|
||||
|
||||
nbytes = JS_GetObjectTotalSize(cx, &funobj->object);
|
||||
if (FUN_IS_SCRIPTED(funobj)) {
|
||||
if (FUN_IS_SCRIPTED(fun)) {
|
||||
JSScriptedFunction *sfun;
|
||||
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
nbytes += sizeof *sfun;
|
||||
sfun = FUN_TO_SCRIPTED(fun);
|
||||
nbytes = sizeof *sfun;
|
||||
nbytes += JS_GetScriptTotalSize(cx, sfun->script);
|
||||
if (sfun->object)
|
||||
nbytes += JS_GetObjectTotalSize(cx, sfun->object);
|
||||
if (sfun->atom)
|
||||
nbytes += GetAtomTotalSize(cx, sfun->atom);
|
||||
} else {
|
||||
JSNativeFunction *nfun;
|
||||
|
||||
nfun = FUN_TO_NATIVE(funobj);
|
||||
nbytes += sizeof(JSNativeFunction) - sizeof(JSObject);
|
||||
nfun = FUN_TO_NATIVE(fun);
|
||||
nbytes = sizeof(JSNativeFunction) - sizeof(JSObject);
|
||||
nbytes += JS_GetObjectTotalSize(cx, &nfun->object);
|
||||
if (nfun->atom)
|
||||
nbytes += GetAtomTotalSize(cx, nfun->atom);
|
||||
}
|
||||
|
@ -1660,6 +1665,7 @@ JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
|
|||
pbytes = JS_HOWMANY(pbytes, principals->refcount);
|
||||
nbytes += pbytes;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,13 +54,13 @@ static char dempty[] = "<null>";
|
|||
char *
|
||||
jsdtrace_funcclass_name(JSFunction *fun)
|
||||
{
|
||||
JSClass *clasp;
|
||||
JSNativeFunction *nfun;
|
||||
|
||||
if (FUN_IS_SCRIPTED(fun))
|
||||
return dempty;
|
||||
|
||||
clasp = NATIVE_FUN_GET_CLASS(FUN_TO_NATIVE(fun));
|
||||
return clasp ? (char *) clasp->name : dempty;
|
||||
nfun = FUN_TO_NATIVE(fun);
|
||||
return nfun->clasp ? (char *) nfun->clasp->name : dempty;
|
||||
}
|
||||
|
||||
char *
|
||||
|
|
|
@ -1614,8 +1614,8 @@ LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
|
|||
* nor can prop be deleted.
|
||||
*/
|
||||
if (cg->treeContext.flags & TCF_IN_FUNCTION) {
|
||||
if (js_LookupLocal(cx, FUN_TO_SCRIPTED(cg->treeContext.funobj),
|
||||
atom, NULL) != JSLOCAL_NONE) {
|
||||
if (js_LookupLocal(cx, cg->treeContext.fun, atom, NULL) !=
|
||||
JSLOCAL_NONE) {
|
||||
break;
|
||||
}
|
||||
} else if (cg->treeContext.flags & TCF_COMPILE_N_GO) {
|
||||
|
@ -1962,8 +1962,7 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
|||
* to stack slot. Look for an argument or variable in the function and
|
||||
* rewrite pn_op and update pn accordingly.
|
||||
*/
|
||||
localKind = js_LookupLocal(cx, FUN_TO_SCRIPTED(tc->funobj), atom,
|
||||
&index);
|
||||
localKind = js_LookupLocal(cx, tc->fun, atom, &index);
|
||||
if (localKind != JSLOCAL_NONE) {
|
||||
op = PN_OP(pn);
|
||||
if (localKind == JSLOCAL_ARG) {
|
||||
|
@ -2054,7 +2053,7 @@ CheckSideEffects(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
|||
* name in that scope object. See comments at case JSOP_NAMEDFUNOBJ:
|
||||
* in jsinterp.c.
|
||||
*/
|
||||
fun = FUN_TO_SCRIPTED(OBJ_TO_FUNCTION(pn->pn_funpob->object));
|
||||
fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object));
|
||||
if (fun->atom)
|
||||
*answer = JS_TRUE;
|
||||
break;
|
||||
|
@ -3925,7 +3924,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
switch (pn->pn_type) {
|
||||
case TOK_FUNCTION:
|
||||
{
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *fun;
|
||||
void *cg2mark;
|
||||
JSCodeGenerator *cg2;
|
||||
uintN slot;
|
||||
|
@ -3938,8 +3937,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
}
|
||||
#endif
|
||||
|
||||
funobj = OBJ_TO_FUNCTION(pn->pn_funpob->object);
|
||||
if (FUN_TO_SCRIPTED(funobj)->script) {
|
||||
fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, pn->pn_funpob->object));
|
||||
if (fun->script) {
|
||||
/*
|
||||
* This second pass is needed to emit JSOP_NOP with a source note
|
||||
* for the already-emitted function. See comments in the TOK_LC
|
||||
|
@ -3965,7 +3964,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
pn->pn_pos.begin.lineno);
|
||||
cg2->treeContext.flags = (uint16) (pn->pn_flags | TCF_IN_FUNCTION);
|
||||
cg2->treeContext.maxScopeDepth = pn->pn_sclen;
|
||||
cg2->treeContext.funobj = funobj;
|
||||
cg2->treeContext.fun = fun;
|
||||
cg2->parent = cg;
|
||||
if (!js_EmitFunctionScript(cx, cg2, pn->pn_body)) {
|
||||
pn = NULL;
|
||||
|
@ -4026,8 +4025,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
#ifdef DEBUG
|
||||
JSLocalKind localKind =
|
||||
#endif
|
||||
js_LookupLocal(cx, FUN_TO_SCRIPTED(cg->treeContext.funobj),
|
||||
FUN_TO_SCRIPTED(funobj)->atom, &slot);
|
||||
js_LookupLocal(cx, cg->treeContext.fun, fun->atom, &slot);
|
||||
JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
|
||||
JS_ASSERT(pn->pn_index == (uint32) -1);
|
||||
pn->pn_index = index;
|
||||
|
|
|
@ -175,7 +175,7 @@ struct JSTreeContext { /* tree context for semantic checks */
|
|||
XXX combine with blockChain? */
|
||||
JSAtomList decls; /* function, const, and var declarations */
|
||||
JSParseContext *parseContext;
|
||||
JSFunction *funobj; /* function to store argument and variable
|
||||
JSScriptedFunction *fun; /* function to store argument and variable
|
||||
names when flags & TCF_IN_FUNCTION */
|
||||
};
|
||||
|
||||
|
@ -216,7 +216,7 @@ struct JSTreeContext { /* tree context for semantic checks */
|
|||
ATOM_LIST_INIT(&(tc)->decls), \
|
||||
(tc)->blockNode = NULL, \
|
||||
(tc)->parseContext = (pc), \
|
||||
(tc)->funobj = NULL)
|
||||
(tc)->fun = NULL)
|
||||
|
||||
#define TREE_CONTEXT_FINISH(tc) \
|
||||
((void)0)
|
||||
|
|
|
@ -1070,10 +1070,10 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
break;
|
||||
|
||||
/* Make this constructor make objects of class Exception. */
|
||||
NATIVE_FUN_SET_CLASS(fun, &js_ErrorClass);
|
||||
fun->clasp = &js_ErrorClass;
|
||||
|
||||
/* Extract the constructor object. */
|
||||
funobj = &fun->base.object;
|
||||
funobj = &fun->object;
|
||||
|
||||
/* Make the prototype and constructor links. */
|
||||
if (!js_SetClassPrototype(cx, funobj, protos[i],
|
||||
|
|
306
js/src/jsfun.c
306
js/src/jsfun.c
|
@ -763,7 +763,7 @@ call_enumerate(JSContext *cx, JSObject *obj)
|
|||
fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
|
||||
if (!fp)
|
||||
return JS_TRUE;
|
||||
JS_ASSERT(OBJ_TO_FUNCTION(fp->callee) == fp->fun);
|
||||
JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fp->fun);
|
||||
|
||||
/*
|
||||
* Reflect actual args from fp->argv for formal parameters, and local vars
|
||||
|
@ -832,7 +832,7 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
|
|||
if (!fp)
|
||||
return JS_TRUE;
|
||||
JS_ASSERT(fp->fun && FUN_IS_SCRIPTED(fp->fun));
|
||||
JS_ASSERT(OBJ_TO_FUNCTION(fp->callee) == fp->fun);
|
||||
JS_ASSERT(GET_FUNCTION_PRIVATE(cx, fp->callee) == fp->fun);
|
||||
|
||||
if (!JSVAL_IS_STRING(idval))
|
||||
return JS_TRUE;
|
||||
|
@ -1074,7 +1074,8 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
|||
if (!JSVAL_IS_STRING(id))
|
||||
return JS_TRUE;
|
||||
|
||||
fun = OBJ_TO_FUNCTION(obj);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
JS_ASSERT(FUN_OBJECT(fun));
|
||||
|
||||
/*
|
||||
* No need to reflect fun.prototype in 'fun.prototype = ... '.
|
||||
|
@ -1170,8 +1171,7 @@ static JSBool
|
|||
fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
||||
{
|
||||
JSContext *cx;
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *sfun;
|
||||
JSScriptedFunction *fun;
|
||||
uint32 nullAtom; /* flag to indicate if fun->atom is NULL */
|
||||
uintN nargs, nvars, n;
|
||||
uint32 localsword; /* word to xdr argument and variable counts */
|
||||
|
@ -1181,38 +1181,39 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
|
||||
cx = xdr->cx;
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
funobj = OBJ_TO_FUNCTION(*objp);
|
||||
if (!FUN_IS_SCRIPTED(funobj)) {
|
||||
JSFunction *f;
|
||||
|
||||
f = GET_FUNCTION_PRIVATE(cx, *objp);
|
||||
if (!FUN_IS_SCRIPTED(f)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NOT_SCRIPTED_FUNCTION,
|
||||
JS_GetFunctionName(funobj));
|
||||
JS_GetFunctionName(f));
|
||||
return JS_FALSE;
|
||||
}
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
nullAtom = !sfun->atom;
|
||||
nargs = sfun->nargs;
|
||||
nvars = sfun->nvars;
|
||||
fun = FUN_TO_SCRIPTED(f);
|
||||
nullAtom = !fun->atom;
|
||||
nargs = fun->nargs;
|
||||
nvars = fun->nvars;
|
||||
localsword = (nargs << 16) | nvars;
|
||||
flagsword = sfun->flags;
|
||||
flagsword = fun->flags;
|
||||
} else {
|
||||
funobj = js_NewScriptedFunction(cx, NULL, 0, NULL, NULL);
|
||||
if (!funobj)
|
||||
fun = js_NewScriptedFunction(cx, NULL, 0, NULL, NULL);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
STOBJ_SET_PARENT(&funobj->object, NULL);
|
||||
STOBJ_SET_PROTO(&funobj->object, NULL);
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
STOBJ_SET_PARENT(fun->object, NULL);
|
||||
STOBJ_SET_PROTO(fun->object, NULL);
|
||||
#ifdef __GNUC__
|
||||
nvars = nargs = 0; /* quell GCC uninitialized warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* From here on, control flow must flow through label out. */
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, &funobj->object, &tvr);
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, fun->object, &tvr);
|
||||
ok = JS_TRUE;
|
||||
|
||||
if (!JS_XDRUint32(xdr, &nullAtom))
|
||||
goto bad;
|
||||
if (!nullAtom && !js_XDRStringAtom(xdr, &sfun->atom))
|
||||
if (!nullAtom && !js_XDRStringAtom(xdr, &fun->atom))
|
||||
goto bad;
|
||||
if (!JS_XDRUint32(xdr, &localsword) ||
|
||||
!JS_XDRUint32(xdr, &flagsword)) {
|
||||
|
@ -1222,11 +1223,12 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
if (xdr->mode == JSXDR_DECODE) {
|
||||
nargs = localsword >> 16;
|
||||
nvars = localsword & JS_BITMASK(16);
|
||||
sfun->flags = (uint16) flagsword;
|
||||
JS_ASSERT(flagsword | JSFUN_SCRIPTED);
|
||||
fun->flags = (uint16) flagsword;
|
||||
}
|
||||
|
||||
/* do arguments and local vars */
|
||||
if ((n = nargs + nvars) != 0) {
|
||||
if (fun->object && (n = nargs + nvars) != 0) {
|
||||
void *mark;
|
||||
uintN i;
|
||||
uintN bitmapLength;
|
||||
|
@ -1256,14 +1258,14 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
goto release_mark;
|
||||
}
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
names = js_GetLocalNameArray(xdr->cx, sfun, &xdr->cx->tempPool);
|
||||
names = js_GetLocalNameArray(xdr->cx, fun, &xdr->cx->tempPool);
|
||||
if (!names) {
|
||||
ok = JS_FALSE;
|
||||
goto release_mark;
|
||||
}
|
||||
memset(bitmap, 0, bitmapLength * sizeof *bitmap);
|
||||
for (i = 0; i != n; ++i) {
|
||||
if (i < sfun->nargs
|
||||
if (i < fun->nargs
|
||||
? JS_LOCAL_NAME_TO_ATOM(names[i]) != NULL
|
||||
: JS_LOCAL_NAME_IS_CONST(names[i])) {
|
||||
bitmap[i >> JS_BITS_PER_UINT32_LOG2] |=
|
||||
|
@ -1286,7 +1288,7 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
!(bitmap[i >> JS_BITS_PER_UINT32_LOG2] &
|
||||
JS_BIT(i & (JS_BITS_PER_UINT32 - 1)))) {
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
ok = js_AddLocal(xdr->cx, sfun, NULL, JSLOCAL_ARG);
|
||||
ok = js_AddLocal(xdr->cx, fun, NULL, JSLOCAL_ARG);
|
||||
if (!ok)
|
||||
goto release_mark;
|
||||
} else {
|
||||
|
@ -1306,7 +1308,7 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
JS_BIT(i & (JS_BITS_PER_UINT32 - 1))
|
||||
? JSLOCAL_CONST
|
||||
: JSLOCAL_VAR;
|
||||
ok = js_AddLocal(xdr->cx, sfun, name, localKind);
|
||||
ok = js_AddLocal(xdr->cx, fun, name, localKind);
|
||||
if (!ok)
|
||||
goto release_mark;
|
||||
}
|
||||
|
@ -1319,18 +1321,18 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
goto out;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE)
|
||||
js_FreezeLocalNames(cx, sfun);
|
||||
js_FreezeLocalNames(cx, fun);
|
||||
}
|
||||
|
||||
if (!js_XDRScript(xdr, &sfun->script, NULL))
|
||||
if (!js_XDRScript(xdr, &fun->script, NULL))
|
||||
goto bad;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
*objp = &funobj->object;
|
||||
*objp = fun->object;
|
||||
#ifdef CHECK_SCRIPT_OWNER
|
||||
sfun->script->owner = NULL;
|
||||
fun->script->owner = NULL;
|
||||
#endif
|
||||
js_CallNewScriptHook(cx, sfun->script, funobj);
|
||||
js_CallNewScriptHook(cx, fun->script, fun);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -1382,39 +1384,43 @@ static void
|
|||
fun_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
JSFunction *fun;
|
||||
JSScriptedFunction *sfun;
|
||||
JSNativeFunction *nfun;
|
||||
JSNativeFunction *native;
|
||||
|
||||
/* A newborn function object may have a not yet initialized private slot. */
|
||||
fun = (JSFunction *) JS_GetPrivate(trc->context, obj);
|
||||
if (!fun)
|
||||
return;
|
||||
|
||||
fun = OBJ_TO_FUNCTION(obj);
|
||||
if (FUN_IS_SCRIPTED(fun)) {
|
||||
/* For a just newborn function object sfun is null. */
|
||||
sfun = FUN_TO_SCRIPTED(fun);
|
||||
if (sfun)
|
||||
JS_CALL_TRACER(trc, sfun, JSTRACE_SCRIPTED_FUNCTION, "sfun");
|
||||
} else {
|
||||
nfun = FUN_TO_NATIVE(fun);
|
||||
if (nfun->atom)
|
||||
JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(nfun->atom), "atom");
|
||||
JS_CALL_TRACER(trc, FUN_TO_SCRIPTED(fun),
|
||||
JSTRACE_SCRIPTED_FUNCTION, "private");
|
||||
return;
|
||||
}
|
||||
|
||||
native = (JSNativeFunction *) obj;
|
||||
JS_ASSERT(FUN_TO_NATIVE(fun) == native);
|
||||
if (native->atom)
|
||||
JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(native->atom), "atom");
|
||||
}
|
||||
|
||||
static uint32
|
||||
fun_reserveSlots(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *sfun;
|
||||
|
||||
funobj = OBJ_TO_FUNCTION(obj);
|
||||
if (!FUN_IS_SCRIPTED(funobj))
|
||||
return 0;
|
||||
JSFunction *fun;
|
||||
JSScript *script;
|
||||
|
||||
/*
|
||||
* sfun is null when js_InitFunctionClass is called before the private
|
||||
* slots of the function object is set.
|
||||
* We use JS_GetPrivate and not GET_FUNCTION_PRIVATE because during
|
||||
* js_InitFunctionClass invocation the function is called before the
|
||||
* private slot of the function object is set.
|
||||
*/
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
return (sfun && sfun->script && sfun->script->regexpsOffset != 0)
|
||||
? JS_SCRIPT_REGEXPS(sfun->script)->length
|
||||
fun = (JSFunction *) JS_GetPrivate(cx, obj);
|
||||
if (!fun || !FUN_IS_SCRIPTED(fun))
|
||||
return 0;
|
||||
|
||||
script = FUN_TO_SCRIPTED(fun)->script;
|
||||
return (script && script->regexpsOffset != 0)
|
||||
? JS_SCRIPT_REGEXPS(script)->length
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
@ -1479,7 +1485,7 @@ fun_toStringHelper(JSContext *cx, uint32 indent, uintN argc, jsval *vp)
|
|||
}
|
||||
|
||||
JS_ASSERT(JS_ObjectIsFunction(cx, obj));
|
||||
fun = OBJ_TO_FUNCTION(obj);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
if (!fun)
|
||||
return JS_TRUE;
|
||||
str = JS_DecompileFunction(cx, fun, (uintN)indent);
|
||||
|
@ -1717,9 +1723,8 @@ static JSBool
|
|||
Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSStackFrame *fp, *caller;
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *fun;
|
||||
JSObject *parent;
|
||||
JSScriptedFunction *sfun;
|
||||
uintN i, n, lineno;
|
||||
JSAtom *atom;
|
||||
const char *filename;
|
||||
|
@ -1733,15 +1738,20 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
JSTokenType tt;
|
||||
|
||||
fp = cx->fp;
|
||||
if (fp->flags & JSFRAME_CONSTRUCTING) {
|
||||
/* Quit if the constructor object is already initialized. */
|
||||
funobj = OBJ_TO_FUNCTION(obj);
|
||||
if (FUN_TO_SCRIPTED(funobj))
|
||||
return JS_TRUE;
|
||||
} else {
|
||||
funobj = NULL;
|
||||
if (!(fp->flags & JSFRAME_CONSTRUCTING)) {
|
||||
obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* The constructor is called before the private slot is initialized so we
|
||||
* must use JS_GetPrivate, not GET_FUNCTION_PRIVATE here.
|
||||
*/
|
||||
if (JS_GetPrivate(cx, obj))
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* NB: (new Function) is not lexically closed by its caller, it's just an
|
||||
* anonymous function in the top-level scope that its constructor inhabits.
|
||||
|
@ -1754,14 +1764,11 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
*/
|
||||
parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2]));
|
||||
|
||||
funobj = js_NewScriptedFunction(cx, funobj, JSFUN_LAMBDA, parent,
|
||||
cx->runtime->atomState.anonymousAtom);
|
||||
fun = js_NewScriptedFunction(cx, obj, JSFUN_LAMBDA, parent,
|
||||
cx->runtime->atomState.anonymousAtom);
|
||||
|
||||
if (!funobj)
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
if (!(fp->flags & JSFRAME_CONSTRUCTING))
|
||||
*rval = OBJECT_TO_JSVAL(funobj);
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
|
||||
/*
|
||||
* Function is static and not called directly by other functions in this
|
||||
|
@ -1770,7 +1777,9 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
* are built for Function.prototype.call or .apply activations that invoke
|
||||
* Function indirectly from a script.
|
||||
*/
|
||||
JS_ASSERT(fp->fun && FUN_TO_NATIVE(fp->fun)->native == Function);
|
||||
JS_ASSERT(fp->fun &&
|
||||
!FUN_IS_SCRIPTED(fp->fun) &&
|
||||
FUN_TO_NATIVE(fp->fun)->native == Function);
|
||||
caller = JS_GetScriptedCaller(cx, fp);
|
||||
if (caller) {
|
||||
principals = JS_EvalFramePrincipals(cx, fp, caller);
|
||||
|
@ -1884,7 +1893,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
atom = CURRENT_TOKEN(&ts).t_atom;
|
||||
|
||||
/* Check for a duplicate parameter name. */
|
||||
if (js_LookupLocal(cx, sfun, atom, NULL) != JSLOCAL_NONE) {
|
||||
if (js_LookupLocal(cx, fun, atom, NULL) != JSLOCAL_NONE) {
|
||||
const char *name;
|
||||
|
||||
name = js_AtomToPrintableString(cx, atom);
|
||||
|
@ -1897,7 +1906,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if (!ok)
|
||||
goto after_args;
|
||||
}
|
||||
if (!js_AddLocal(cx, sfun, atom, JSLOCAL_ARG))
|
||||
if (!js_AddLocal(cx, fun, atom, JSLOCAL_ARG))
|
||||
goto after_args;
|
||||
|
||||
/*
|
||||
|
@ -1938,7 +1947,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
str = cx->runtime->emptyString;
|
||||
}
|
||||
|
||||
return js_CompileFunctionBody(cx, funobj, principals,
|
||||
return js_CompileFunctionBody(cx, fun, principals,
|
||||
JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
|
||||
filename, lineno);
|
||||
}
|
||||
|
@ -1948,8 +1957,7 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
JSObject *proto;
|
||||
JSAtom *atom;
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *sfun;
|
||||
JSScriptedFunction *fun;
|
||||
|
||||
proto = JS_InitClass(cx, obj, NULL, &js_FunctionClass, Function, 1,
|
||||
function_props, function_methods, NULL, NULL);
|
||||
|
@ -1959,16 +1967,15 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj)
|
|||
0);
|
||||
if (!atom)
|
||||
goto bad;
|
||||
funobj = js_NewScriptedFunction(cx, OBJ_TO_FUNCTION(proto), 0, obj, NULL);
|
||||
if (!funobj)
|
||||
fun = js_NewScriptedFunction(cx, proto, 0, obj, NULL);
|
||||
if (!fun)
|
||||
goto bad;
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
sfun->script = js_NewScript(cx, 1, 0, 0, 0, 0, 0);
|
||||
if (!sfun->script)
|
||||
fun->script = js_NewScript(cx, 1, 0, 0, 0, 0, 0);
|
||||
if (!fun->script)
|
||||
goto bad;
|
||||
sfun->script->code[0] = JSOP_STOP;
|
||||
fun->script->code[0] = JSOP_STOP;
|
||||
#ifdef CHECK_SCRIPT_OWNER
|
||||
sfun->script->owner = NULL;
|
||||
fun->script->owner = NULL;
|
||||
#endif
|
||||
return proto;
|
||||
|
||||
|
@ -1995,24 +2002,8 @@ js_InitCallClass(JSContext *cx, JSObject *obj)
|
|||
return proto;
|
||||
}
|
||||
|
||||
static void
|
||||
InitFunctionPrivateSlot(JSFunction *funobj)
|
||||
{
|
||||
STOBJ_SET_SLOT(&funobj->object, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(funobj));
|
||||
}
|
||||
|
||||
static void
|
||||
InitAsScriptedFunctionObject(JSFunction *funobj,
|
||||
JSScriptedFunction *sfun)
|
||||
{
|
||||
JS_ASSERT(funobj->sfunOrClass == 0);
|
||||
JS_ASSERT(((jsuword) sfun & (jsuword) 1) == 0);
|
||||
InitFunctionPrivateSlot(funobj);
|
||||
funobj->sfunOrClass = (jsuword) sfun;
|
||||
}
|
||||
|
||||
JSFunction *
|
||||
js_NewScriptedFunction(JSContext *cx, JSFunction *funobj, uintN flags,
|
||||
JSScriptedFunction *
|
||||
js_NewScriptedFunction(JSContext *cx, JSObject *funobj, uintN flags,
|
||||
JSObject *parent, JSAtom *atom)
|
||||
{
|
||||
JSScriptedFunction *sfun;
|
||||
|
@ -2020,18 +2011,17 @@ js_NewScriptedFunction(JSContext *cx, JSFunction *funobj, uintN flags,
|
|||
|
||||
JS_ASSERT((flags & ~JSFUN_LAMBDA) == 0);
|
||||
|
||||
/* If funobj is null, allocate an object for it. */
|
||||
if (funobj) {
|
||||
OBJ_SET_PARENT(cx, &funobj->object, parent);
|
||||
OBJ_SET_PARENT(cx, funobj, parent);
|
||||
} else {
|
||||
funobj = (JSFunction *)
|
||||
js_NewObject(cx, &js_FunctionClass, NULL, parent,
|
||||
sizeof(JSFunction) - sizeof(JSObject));
|
||||
funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent, 0);
|
||||
if (!funobj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Protect fun from any potential GC callback. */
|
||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, &funobj->object, &tvr);
|
||||
JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(funobj), &tvr);
|
||||
|
||||
/*
|
||||
* Allocate fun after allocating funobj so allocations in js_NewObject
|
||||
|
@ -2039,13 +2029,12 @@ js_NewScriptedFunction(JSContext *cx, JSFunction *funobj, uintN flags,
|
|||
*/
|
||||
sfun = (JSScriptedFunction *)
|
||||
js_NewGCThing(cx, GCX_FUNCTION, sizeof(JSScriptedFunction));
|
||||
if (!sfun) {
|
||||
funobj = NULL;
|
||||
if (!sfun)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Initialize all function members. */
|
||||
sfun->flags = flags;
|
||||
sfun->object = NULL;
|
||||
sfun->flags = (flags & JSFUN_FLAGS_MASK) | JSFUN_SCRIPTED;
|
||||
sfun->nargs = 0;
|
||||
sfun->nvars = 0;
|
||||
sfun->spare = 0;
|
||||
|
@ -2055,11 +2044,13 @@ js_NewScriptedFunction(JSContext *cx, JSFunction *funobj, uintN flags,
|
|||
#endif
|
||||
sfun->atom = atom;
|
||||
|
||||
InitAsScriptedFunctionObject(funobj, sfun);
|
||||
/* Link fun to funobj and vice versa. */
|
||||
sfun->object = funobj;
|
||||
JS_SetPrivate(cx, funobj, SCRIPTED_TO_FUN(sfun));
|
||||
|
||||
out:
|
||||
JS_POP_TEMP_ROOT(cx, &tvr);
|
||||
return funobj;
|
||||
return sfun;
|
||||
}
|
||||
|
||||
JSNativeFunction *
|
||||
|
@ -2068,37 +2059,40 @@ js_NewNativeFunction(JSContext *cx, JSNative native, uintN nargs,
|
|||
{
|
||||
JSNativeFunction *nfun;
|
||||
|
||||
JS_ASSERT(!(flags & JSFUN_LAMBDA));
|
||||
nfun = (JSNativeFunction *)
|
||||
js_NewObject(cx, &js_FunctionClass, NULL, parent,
|
||||
sizeof(JSNativeFunction) - sizeof(JSObject));
|
||||
JS_ASSERT(!(flags & (JSFUN_LAMBDA | JSFUN_SCRIPTED)));
|
||||
nfun = (JSNativeFunction *) js_NewObject(cx, &js_FunctionClass, NULL,
|
||||
parent,
|
||||
sizeof(JSNativeFunction) -
|
||||
sizeof(JSObject));
|
||||
if (!nfun)
|
||||
return NULL;
|
||||
|
||||
/* Initialize all function members. */
|
||||
nfun->flags = flags & JSFUN_FLAGS_MASK;
|
||||
nfun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_SCRIPTED);
|
||||
nfun->nargs = nargs;
|
||||
nfun->native = native;
|
||||
JS_ASSERT(nfun->extra == 0);
|
||||
JS_ASSERT(nfun->minargs == 0);
|
||||
nfun->extra = 0;
|
||||
nfun->minargs = 0;
|
||||
nfun->clasp = NULL;
|
||||
nfun->atom = atom;
|
||||
InitFunctionPrivateSlot(&nfun->base);
|
||||
NATIVE_FUN_SET_CLASS(nfun, NULL);
|
||||
JS_SetPrivate(cx, &nfun->object, NATIVE_TO_FUN(nfun));
|
||||
|
||||
return nfun;
|
||||
}
|
||||
|
||||
static void
|
||||
TraceLocalNames(JSTracer *trc, JSScriptedFunction *sfun);
|
||||
TraceLocalNames(JSTracer *trc, JSScriptedFunction *fun);
|
||||
|
||||
void
|
||||
js_TraceScriptedFunction(JSTracer *trc, JSScriptedFunction *sfun)
|
||||
js_TraceFunction(JSTracer *trc, JSScriptedFunction *fun)
|
||||
{
|
||||
if (sfun->script)
|
||||
js_TraceScript(trc, sfun->script);
|
||||
TraceLocalNames(trc, sfun);
|
||||
if (sfun->atom)
|
||||
JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(sfun->atom), "atom");
|
||||
if (fun->object)
|
||||
JS_CALL_OBJECT_TRACER(trc, fun->object, "object");
|
||||
if (fun->atom)
|
||||
JS_CALL_STRING_TRACER(trc, ATOM_TO_STRING(fun->atom), "atom");
|
||||
if (fun->script)
|
||||
js_TraceScript(trc, fun->script);
|
||||
TraceLocalNames(trc, fun);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2120,35 +2114,32 @@ JSObject *
|
|||
js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
|
||||
{
|
||||
JSFunction *fun;
|
||||
JSFunction *newfunobj;
|
||||
JSObject *newfunobj;
|
||||
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass);
|
||||
fun = OBJ_TO_FUNCTION(funobj);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, funobj);
|
||||
if (FUN_IS_SCRIPTED(fun)) {
|
||||
JSScriptedFunction *sfun;
|
||||
|
||||
sfun = FUN_TO_SCRIPTED(fun);
|
||||
newfunobj = (JSFunction *)
|
||||
js_NewObject(cx, &js_FunctionClass, NULL, parent,
|
||||
sizeof(JSFunction) - sizeof(JSObject));
|
||||
JS_ASSERT(sfun->object);
|
||||
newfunobj = js_NewObject(cx, &js_FunctionClass, NULL, parent, 0);
|
||||
if (!newfunobj)
|
||||
return NULL;
|
||||
InitAsScriptedFunctionObject(newfunobj, sfun);
|
||||
JS_SetPrivate(cx, newfunobj, SCRIPTED_TO_FUN(sfun));
|
||||
} else {
|
||||
JSNativeFunction *cloned;
|
||||
|
||||
cloned = (JSNativeFunction *)
|
||||
js_NewObject(cx, &js_FunctionClass, NULL, parent,
|
||||
sizeof(JSNativeFunction) - sizeof(JSObject));
|
||||
if (!cloned)
|
||||
JS_ASSERT((JSNativeFunction *) funobj == FUN_TO_NATIVE(fun));
|
||||
newfunobj = js_NewObject(cx, &js_FunctionClass, NULL, parent,
|
||||
sizeof(JSNativeFunction) - sizeof(JSObject));
|
||||
if (!newfunobj)
|
||||
return NULL;
|
||||
InitFunctionPrivateSlot(&cloned->base);
|
||||
memcpy((uint8 *) cloned + sizeof(JSObject),
|
||||
memcpy((uint8 *) newfunobj + sizeof(JSObject),
|
||||
(uint8 *) funobj + sizeof(JSObject),
|
||||
sizeof(JSNativeFunction) - sizeof(JSObject));
|
||||
newfunobj = &cloned->base;
|
||||
JS_SetPrivate(cx, newfunobj,
|
||||
NATIVE_TO_FUN((JSNativeFunction *) newfunobj));
|
||||
}
|
||||
return &newfunobj->object;
|
||||
return newfunobj;
|
||||
}
|
||||
|
||||
JSNativeFunction *
|
||||
|
@ -2163,7 +2154,7 @@ js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
|
|||
return NULL;
|
||||
gsop = (attrs & JSFUN_STUB_GSOPS) ? JS_PropertyStub : NULL;
|
||||
if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
|
||||
OBJECT_TO_JSVAL(&fun->base.object),
|
||||
OBJECT_TO_JSVAL(&fun->object),
|
||||
gsop, gsop,
|
||||
attrs & ~JSFUN_FLAGS_MASK, NULL)) {
|
||||
return NULL;
|
||||
|
@ -2185,7 +2176,7 @@ js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags)
|
|||
obj = NULL;
|
||||
if (JSVAL_IS_OBJECT(v)) {
|
||||
obj = JSVAL_TO_OBJECT(v);
|
||||
if (obj && !HAS_FUNCTION_CLASS(obj)) {
|
||||
if (obj && OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) {
|
||||
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &v))
|
||||
return NULL;
|
||||
obj = VALUE_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL;
|
||||
|
@ -2195,16 +2186,17 @@ js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags)
|
|||
js_ReportIsNotFunction(cx, vp, flags);
|
||||
return NULL;
|
||||
}
|
||||
return OBJ_TO_FUNCTION(obj);
|
||||
return GET_FUNCTION_PRIVATE(cx, obj);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
|
||||
{
|
||||
JSFunction *fun;
|
||||
JSObject *funobj;
|
||||
JSAtom *atom;
|
||||
JSStackFrame *caller;
|
||||
JSPrincipals *principals;
|
||||
JSAtom *atom;
|
||||
|
||||
if (VALUE_IS_FUNCTION(cx, *vp))
|
||||
return JSVAL_TO_OBJECT(*vp);
|
||||
|
@ -2212,7 +2204,20 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
|
|||
fun = js_ValueToFunction(cx, vp, flags);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
*vp = OBJECT_TO_JSVAL(&fun->object);
|
||||
if (FUN_IS_SCRIPTED(fun)) {
|
||||
JSScriptedFunction *sfun;
|
||||
|
||||
sfun = FUN_TO_SCRIPTED(fun);
|
||||
funobj = sfun->object;
|
||||
atom = sfun->atom;
|
||||
} else {
|
||||
JSNativeFunction *nfun;
|
||||
|
||||
nfun = FUN_TO_NATIVE(fun);
|
||||
funobj = &nfun->object;
|
||||
atom = nfun->atom;
|
||||
}
|
||||
*vp = OBJECT_TO_JSVAL(funobj);
|
||||
|
||||
caller = JS_GetScriptedCaller(cx, cx->fp);
|
||||
if (caller) {
|
||||
|
@ -2222,14 +2227,13 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
|
|||
principals = NULL;
|
||||
}
|
||||
|
||||
atom = FUN_ATOM(fun);
|
||||
if (!js_CheckPrincipalsAccess(cx, &fun->object, principals,
|
||||
if (!js_CheckPrincipalsAccess(cx, funobj, principals,
|
||||
atom
|
||||
? atom
|
||||
: cx->runtime->atomState.anonymousAtom)) {
|
||||
return NULL;
|
||||
}
|
||||
return &fun->object;
|
||||
return funobj;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
|
121
js/src/jsfun.h
121
js/src/jsfun.h
|
@ -50,29 +50,6 @@ JS_BEGIN_EXTERN_C
|
|||
|
||||
typedef struct JSLocalNameMap JSLocalNameMap;
|
||||
|
||||
/*
|
||||
* When the sfunOrClass field of the JSFunction instance has the lowest bit
|
||||
* set, the function object is JSNativeFunction and the field stores
|
||||
* constructor's class for the native function. When the bit is unset, the
|
||||
* field stores a pointer to JSScriptedFunction.
|
||||
*/
|
||||
struct JSFunction {
|
||||
JSObject object;
|
||||
jsuword sfunOrClass; /* scripted function or constructor class */
|
||||
};
|
||||
|
||||
struct JSNativeFunction {
|
||||
JSFunction base;
|
||||
uint16 flags; /* bound method and other flags, see jsapi.h */
|
||||
uint16 nargs; /* maximum number of specified arguments,
|
||||
reflected as f.length/f.arity */
|
||||
uint16 extra; /* number of arg slots for local GC roots */
|
||||
uint16 minargs; /* minimum number of specified arguments, used
|
||||
only when calling fast native */
|
||||
JSNative native; /* native method pointer */
|
||||
JSAtom *atom; /* name for diagnostics and decompiling */
|
||||
};
|
||||
|
||||
/*
|
||||
* Depending on the number of arguments and variables in the function their
|
||||
* names and attributes are stored either as a single atom or as an array of
|
||||
|
@ -86,55 +63,74 @@ typedef union JSLocalNames {
|
|||
JSLocalNameMap *map;
|
||||
} JSLocalNames;
|
||||
|
||||
struct JSNativeFunction {
|
||||
JSObject object;
|
||||
uint16 flags; /* bound method and other flags, see jsapi.h */
|
||||
uint16 nargs; /* maximum number of specified arguments,
|
||||
reflected as f.length/f.arity */
|
||||
uint16 extra; /* number of arg slots for local GC roots */
|
||||
uint16 minargs; /* minimum number of specified arguments, used
|
||||
only when calling fast native */
|
||||
JSNative native; /* native method pointer or null */
|
||||
JSClass *clasp; /* if non-null, constructor for this class */
|
||||
JSAtom *atom; /* name for diagnostics and decompiling */
|
||||
};
|
||||
|
||||
struct JSScriptedFunction {
|
||||
JSObject *object; /* back-pointer to GC'ed object header */
|
||||
uint16 flags; /* bound method and other flags, see jsapi.h */
|
||||
uint16 nargs; /* number of arguments */
|
||||
uint16 nvars; /* number of local variables */
|
||||
uint16 spare; /* reserved for future use */
|
||||
JSScript *script; /* interpreted bytecode descriptor or null */
|
||||
JSLocalNames names; /* argument and variable names */
|
||||
JSAtom *atom; /* function name */
|
||||
JSAtom *atom; /* name for diagnostics and decompiling */
|
||||
};
|
||||
|
||||
#define JSFUN_EXPR_CLOSURE 0x4000 /* expression closure: function(x)x*x */
|
||||
#define JSFUN_SCRIPTED 0x8000 /* use FUN_TO_SCRIPTED if set,
|
||||
FUN_TO_NATIVE if unset */
|
||||
|
||||
#define FUN_OBJECT(funobj) (&(funobj)->object)
|
||||
|
||||
#define OBJ_TO_FUNCTION(obj) \
|
||||
(JS_ASSERT(HAS_FUNCTION_CLASS(obj)), (JSFunction *) (obj))
|
||||
/*
|
||||
* JSFunction * points into the flags field of either JSNativeFunction
|
||||
* or JSScriptedFunction.
|
||||
*/
|
||||
#define FUN_FLAGS(fun) (*(uint16 *) (fun))
|
||||
|
||||
#define FUN_IS_SCRIPTED(funobj) \
|
||||
(((funobj)->sfunOrClass & (jsuword) 1) == 0)
|
||||
#define FUN_IS_SCRIPTED(fun) (FUN_FLAGS(fun) & JSFUN_SCRIPTED)
|
||||
|
||||
#define FUN_TO_SCRIPTED(funobj) \
|
||||
(JS_ASSERT(FUN_IS_SCRIPTED(funobj)), \
|
||||
(JSScriptedFunction *) (funobj)->sfunOrClass)
|
||||
#define FUN_TO_SCRIPTED(fun) \
|
||||
(JS_ASSERT(FUN_IS_SCRIPTED(fun)), \
|
||||
(JSScriptedFunction *)((uint8 *)fun - offsetof(JSScriptedFunction, flags)))
|
||||
|
||||
#define FUN_TO_NATIVE(funobj) \
|
||||
(JS_ASSERT(!FUN_IS_SCRIPTED(funobj)), (JSNativeFunction *) (funobj))
|
||||
#define FUN_TO_NATIVE(fun) \
|
||||
(JS_ASSERT(!FUN_IS_SCRIPTED(fun)), \
|
||||
(JSNativeFunction *)((uint8 *)fun - offsetof(JSNativeFunction, flags)))
|
||||
|
||||
#define FUN_FLAGS(funobj) (FUN_IS_SCRIPTED(funobj) \
|
||||
? FUN_TO_SCRIPTED(funobj)->flags \
|
||||
: FUN_TO_NATIVE(funobj)->flags)
|
||||
#define NATIVE_TO_FUN(nfun) \
|
||||
(JS_ASSERT(((nfun)->flags & JSFUN_SCRIPTED) == 0), \
|
||||
(JSFunction *) (void *) &(nfun)->flags)
|
||||
|
||||
#define FUN_NARGS(funobj) (FUN_IS_SCRIPTED(funobj) \
|
||||
? FUN_TO_SCRIPTED(funobj)->nargs \
|
||||
: FUN_TO_NATIVE(funobj)->nargs)
|
||||
#define SCRIPTED_TO_FUN(sfun) \
|
||||
(JS_ASSERT((sfun)->flags & JSFUN_SCRIPTED), \
|
||||
(JSFunction *) (void *) &(sfun)->flags)
|
||||
|
||||
#define FUN_ATOM(funobj) (FUN_IS_SCRIPTED(funobj) \
|
||||
? FUN_TO_SCRIPTED(funobj)->atom \
|
||||
: FUN_TO_NATIVE(funobj)->atom)
|
||||
#define FUN_NARGS(fun) (FUN_IS_SCRIPTED(fun) \
|
||||
? FUN_TO_SCRIPTED(fun)->nargs \
|
||||
: FUN_TO_NATIVE(fun)->nargs)
|
||||
|
||||
#define FUN_OBJECT(fun) (FUN_IS_SCRIPTED(fun) \
|
||||
? FUN_TO_SCRIPTED(fun)->object \
|
||||
: &FUN_TO_NATIVE(fun)->object)
|
||||
|
||||
#define FUN_ATOM(fun) (FUN_IS_SCRIPTED(fun) \
|
||||
? FUN_TO_SCRIPTED(fun)->atom \
|
||||
: FUN_TO_NATIVE(fun)->atom)
|
||||
|
||||
#define NATIVE_FUN_MINARGS(nfun) \
|
||||
(((nfun)->flags & JSFUN_FAST_NATIVE) ? (nfun)->minargs : (nfun)->nargs)
|
||||
|
||||
#define NATIVE_FUN_GET_CLASS(nfun) \
|
||||
((JSClass *)((nfun)->base.sfunOrClass & ~(jsuword) 1))
|
||||
|
||||
#define NATIVE_FUN_SET_CLASS(nfun, clasp) \
|
||||
(JS_ASSERT(((jsuword) (clasp) & (jsuword) 1) == 0), \
|
||||
(nfun)->base.sfunOrClass = (jsuword) (clasp) | (jsuword) 1)
|
||||
|
||||
extern JSClass js_ArgumentsClass;
|
||||
extern JS_FRIEND_DATA(JSClass) js_CallClass;
|
||||
|
||||
|
@ -149,6 +145,14 @@ extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
|
|||
#define VALUE_IS_FUNCTION(cx, v) \
|
||||
(!JSVAL_IS_PRIMITIVE(v) && HAS_FUNCTION_CLASS(JSVAL_TO_OBJECT(v)))
|
||||
|
||||
/*
|
||||
* Macro to access the private slot of the function object after the slot is
|
||||
* initialized.
|
||||
*/
|
||||
#define GET_FUNCTION_PRIVATE(cx, funobj) \
|
||||
(JS_ASSERT(HAS_FUNCTION_CLASS(funobj)), \
|
||||
(JSFunction *) OBJ_GET_PRIVATE(cx, funobj))
|
||||
|
||||
extern JSObject *
|
||||
js_InitFunctionClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
|
@ -166,15 +170,15 @@ extern JSNativeFunction *
|
|||
js_NewNativeFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags,
|
||||
JSObject *parent, JSAtom *atom);
|
||||
|
||||
extern JSFunction *
|
||||
js_NewScriptedFunction(JSContext *cx, JSFunction *funobj, uintN flags,
|
||||
extern JSScriptedFunction *
|
||||
js_NewScriptedFunction(JSContext *cx, JSObject *funobj, uintN flags,
|
||||
JSObject *parent, JSAtom *atom);
|
||||
|
||||
extern void
|
||||
js_TraceScriptedFunction(JSTracer *trc, JSScriptedFunction *sfun);
|
||||
js_TraceFunction(JSTracer *trc, JSScriptedFunction *fun);
|
||||
|
||||
extern void
|
||||
js_FinalizeFunction(JSContext *cx, JSScriptedFunction *sfun);
|
||||
js_FinalizeFunction(JSContext *cx, JSScriptedFunction *fun);
|
||||
|
||||
extern JSObject *
|
||||
js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent);
|
||||
|
@ -241,7 +245,7 @@ typedef enum JSLocalKind {
|
|||
#define JS_GET_LOCAL_NAME_COUNT(fun) ((fun)->nargs + (fun)->nvars)
|
||||
|
||||
extern JSBool
|
||||
js_AddLocal(JSContext *cx, JSScriptedFunction *sfun, JSAtom *atom,
|
||||
js_AddLocal(JSContext *cx, JSScriptedFunction *fun, JSAtom *atom,
|
||||
JSLocalKind kind);
|
||||
|
||||
/*
|
||||
|
@ -251,7 +255,7 @@ js_AddLocal(JSContext *cx, JSScriptedFunction *sfun, JSAtom *atom,
|
|||
* variable.
|
||||
*/
|
||||
extern JSLocalKind
|
||||
js_LookupLocal(JSContext *cx, JSScriptedFunction *sfun, JSAtom *atom,
|
||||
js_LookupLocal(JSContext *cx, JSScriptedFunction *fun, JSAtom *atom,
|
||||
uintN *indexp);
|
||||
|
||||
/*
|
||||
|
@ -269,8 +273,7 @@ js_LookupLocal(JSContext *cx, JSScriptedFunction *sfun, JSAtom *atom,
|
|||
* corresponds to the const declaration.
|
||||
*/
|
||||
extern jsuword *
|
||||
js_GetLocalNameArray(JSContext *cx, JSScriptedFunction *sfun,
|
||||
JSArenaPool *pool);
|
||||
js_GetLocalNameArray(JSContext *cx, JSScriptedFunction *fun, JSArenaPool *pool);
|
||||
|
||||
#define JS_LOCAL_NAME_TO_ATOM(nameWord) \
|
||||
((JSAtom *) ((nameWord) & ~(jsuword) 1))
|
||||
|
@ -279,7 +282,7 @@ js_GetLocalNameArray(JSContext *cx, JSScriptedFunction *sfun,
|
|||
((((nameWord) & (jsuword) 1)) != 0)
|
||||
|
||||
extern void
|
||||
js_FreezeLocalNames(JSContext *cx, JSScriptedFunction *sfun);
|
||||
js_FreezeLocalNames(JSContext *cx, JSScriptedFunction *fun);
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
|
|
|
@ -2251,7 +2251,7 @@ JS_TraceChildren(JSTracer *trc, void *thing, uint32 kind)
|
|||
break;
|
||||
|
||||
case JSTRACE_SCRIPTED_FUNCTION:
|
||||
js_TraceScriptedFunction(trc, (JSScriptedFunction *) thing);
|
||||
js_TraceFunction(trc, (JSScriptedFunction *) thing);
|
||||
break;
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
|
|
|
@ -1087,7 +1087,7 @@ js_Invoke(JSContext *cx, uintN argc, jsval *vp, uintN flags)
|
|||
} else {
|
||||
have_fun:
|
||||
/* Get private data and set derived locals from it. */
|
||||
fun = OBJ_TO_FUNCTION(funobj);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, funobj);
|
||||
if (FUN_IS_SCRIPTED(fun)) {
|
||||
JSScriptedFunction *sfun;
|
||||
|
||||
|
@ -1408,7 +1408,7 @@ js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
|
|||
JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE);
|
||||
if (cx->runtime->checkObjectAccess &&
|
||||
VALUE_IS_FUNCTION(cx, fval) &&
|
||||
FUN_IS_SCRIPTED(OBJ_TO_FUNCTION(JSVAL_TO_OBJECT(fval))) &&
|
||||
FUN_IS_SCRIPTED(GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(fval))) &&
|
||||
!cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode,
|
||||
&fval)) {
|
||||
return JS_FALSE;
|
||||
|
@ -1841,17 +1841,16 @@ js_InvokeConstructor(JSContext *cx, jsval *vp, uintN argc)
|
|||
parent = OBJ_GET_PARENT(cx, obj2);
|
||||
|
||||
if (OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass) {
|
||||
fun2 = OBJ_TO_FUNCTION(obj2);
|
||||
fun2 = GET_FUNCTION_PRIVATE(cx, obj2);
|
||||
if (!FUN_IS_SCRIPTED(fun2)) {
|
||||
JSClass *constructorClass;
|
||||
JSNativeFunction *nfun;
|
||||
|
||||
constructorClass = NATIVE_FUN_GET_CLASS(FUN_TO_NATIVE(fun2));
|
||||
if (constructorClass)
|
||||
clasp = constructorClass;
|
||||
nfun = FUN_TO_NATIVE(fun2);
|
||||
if (nfun->clasp)
|
||||
clasp = nfun->clasp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj = js_NewObject(cx, clasp, proto, parent, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
|
@ -4295,7 +4294,7 @@ interrupt:
|
|||
/* FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=412571 */
|
||||
if (!VALUE_IS_FUNCTION(cx, rval) ||
|
||||
(obj = JSVAL_TO_OBJECT(rval),
|
||||
fun = OBJ_TO_FUNCTION(obj),
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj),
|
||||
!PRIMITIVE_THIS_TEST(fun, lval))) {
|
||||
if (!js_PrimitiveToObject(cx, ®s.sp[-1]))
|
||||
goto error;
|
||||
|
@ -4622,7 +4621,7 @@ interrupt:
|
|||
JSNativeFunction *nfun;
|
||||
|
||||
obj = JSVAL_TO_OBJECT(lval);
|
||||
fun = OBJ_TO_FUNCTION(obj);
|
||||
fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
if (FUN_IS_SCRIPTED(fun)) {
|
||||
uintN nframeslots, nvars, missing;
|
||||
JSArena *a;
|
||||
|
@ -5622,7 +5621,7 @@ interrupt:
|
|||
* and setters do not need a slot, their value is stored elsewhere
|
||||
* in the property itself, not in obj slots.
|
||||
*/
|
||||
sfun = FUN_TO_SCRIPTED(OBJ_TO_FUNCTION(obj));
|
||||
sfun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj));
|
||||
flags = JSFUN_GSFLAG2ATTR(sfun->flags);
|
||||
if (flags) {
|
||||
attrs |= flags | JSPROP_SHARED;
|
||||
|
@ -5762,7 +5761,7 @@ interrupt:
|
|||
* name is [sfun->atom, the identifier parsed by the compiler],
|
||||
* value is Result(3), and attributes are { DontDelete, ReadOnly }.
|
||||
*/
|
||||
sfun = FUN_TO_SCRIPTED(OBJ_TO_FUNCTION(obj));
|
||||
sfun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj));
|
||||
attrs = JSFUN_GSFLAG2ATTR(sfun->flags);
|
||||
if (attrs) {
|
||||
attrs |= JSPROP_SHARED;
|
||||
|
|
|
@ -2466,9 +2466,6 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
? clasp->getObjectOps(cx, clasp)
|
||||
: &js_ObjectOps;
|
||||
|
||||
if (clasp == &js_FunctionClass && extraBytes == 0)
|
||||
extraBytes = sizeof(JSFunction) - sizeof(JSObject);
|
||||
|
||||
/*
|
||||
* Allocate a zeroed object from the GC heap. Do this *after* any other
|
||||
* GC-thing allocations under js_GetClassPrototype or clasp->getObjectOps,
|
||||
|
@ -2502,9 +2499,6 @@ js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
for (i = JSSLOT_PRIVATE; i != JS_INITIAL_NSLOTS; ++i)
|
||||
obj->fslots[i] = JSVAL_VOID;
|
||||
|
||||
if (extraBytes != 0)
|
||||
memset((uint8 *) obj + sizeof(JSObject), 0, extraBytes);
|
||||
|
||||
/*
|
||||
* Root obj to prevent it from being collected out from under this call to
|
||||
* js_NewObject. There's a possibilty of GC under the objectHook call-out
|
||||
|
|
|
@ -2029,7 +2029,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
jp->indent, jp->pretty);
|
||||
if (!jp2)
|
||||
return NULL;
|
||||
fun = FUN_TO_SCRIPTED(OBJ_TO_FUNCTION(obj));
|
||||
fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj));
|
||||
ok = js_DecompileFunction(jp2, fun);
|
||||
if (ok && jp2->sprinter.base)
|
||||
js_puts(jp, jp2->sprinter.base);
|
||||
|
@ -3772,7 +3772,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
SprintStack ss2;
|
||||
|
||||
LOAD_FUNCTION(0);
|
||||
fun = FUN_TO_SCRIPTED(OBJ_TO_FUNCTION(obj));
|
||||
fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj));
|
||||
inner = fun->script;
|
||||
|
||||
/*
|
||||
|
@ -3888,10 +3888,10 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||
* parenthesization without confusing getter/setter code
|
||||
* that checks for JSOP_ANONFUNOBJ and JSOP_NAMEDFUNOBJ.
|
||||
*/
|
||||
fun = FUN_TO_SCRIPTED(OBJ_TO_FUNCTION(obj));
|
||||
fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj));
|
||||
if (!(fun->flags & JSFUN_EXPR_CLOSURE))
|
||||
indent |= JS_IN_GROUP_CONTEXT;
|
||||
str = JS_DecompileFunction(cx, OBJ_TO_FUNCTION(obj),
|
||||
str = JS_DecompileFunction(cx, SCRIPTED_TO_FUN(fun),
|
||||
indent);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
|
|
@ -805,8 +805,8 @@ ReportBadReturn(JSContext *cx, JSTreeContext *tc, uintN flags, uintN errnum,
|
|||
const char *name;
|
||||
|
||||
JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
|
||||
if (FUN_TO_SCRIPTED(tc->funobj)->atom) {
|
||||
name = js_AtomToPrintableString(cx, FUN_TO_SCRIPTED(tc->funobj)->atom);
|
||||
if (tc->fun->atom) {
|
||||
name = js_AtomToPrintableString(cx, tc->fun->atom);
|
||||
} else {
|
||||
errnum = anonerrnum;
|
||||
name = NULL;
|
||||
|
@ -891,7 +891,7 @@ FunctionBody(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
* handler attribute in an HTML <INPUT> tag.
|
||||
*/
|
||||
JSBool
|
||||
js_CompileFunctionBody(JSContext *cx, JSFunction *funobj,
|
||||
js_CompileFunctionBody(JSContext *cx, JSScriptedFunction *fun,
|
||||
JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno)
|
||||
|
@ -914,7 +914,7 @@ js_CompileFunctionBody(JSContext *cx, JSFunction *funobj,
|
|||
js_InitCodeGenerator(cx, &funcg, &pc, &codePool, ¬ePool,
|
||||
pc.tokenStream.lineno);
|
||||
funcg.treeContext.flags |= TCF_IN_FUNCTION;
|
||||
funcg.treeContext.funobj = funobj;
|
||||
funcg.treeContext.fun = fun;
|
||||
|
||||
/*
|
||||
* Farble the body so that it looks like a block statement to js_EmitTree,
|
||||
|
@ -977,15 +977,13 @@ struct BindData {
|
|||
static JSBool
|
||||
BindArg(JSContext *cx, JSAtom *atom, JSTreeContext *tc)
|
||||
{
|
||||
JSScriptedFunction *sfun;
|
||||
const char *name;
|
||||
|
||||
/*
|
||||
* Check for a duplicate parameter name, a "feature" required by ECMA-262.
|
||||
*/
|
||||
JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
|
||||
sfun = FUN_TO_SCRIPTED(tc->funobj);
|
||||
if (js_LookupLocal(cx, sfun, atom, NULL) != JSLOCAL_NONE) {
|
||||
if (js_LookupLocal(cx, tc->fun, atom, NULL) != JSLOCAL_NONE) {
|
||||
name = js_AtomToPrintableString(cx, atom);
|
||||
if (!name ||
|
||||
!js_ReportCompileErrorNumber(cx, TS(tc->parseContext), NULL,
|
||||
|
@ -996,7 +994,7 @@ BindArg(JSContext *cx, JSAtom *atom, JSTreeContext *tc)
|
|||
}
|
||||
}
|
||||
|
||||
return js_AddLocal(cx, sfun, atom, JSLOCAL_ARG);
|
||||
return js_AddLocal(cx, tc->fun, atom, JSLOCAL_ARG);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -1030,7 +1028,6 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
|
|||
JSTreeContext *tc)
|
||||
{
|
||||
JSAtomListElement *ale;
|
||||
JSScriptedFunction *sfun;
|
||||
const char *name;
|
||||
|
||||
JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
|
||||
|
@ -1042,8 +1039,7 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
|
|||
ALE_SET_JSOP(ale, data->op);
|
||||
}
|
||||
|
||||
sfun = FUN_TO_SCRIPTED(tc->funobj);
|
||||
if (js_LookupLocal(cx, sfun, atom, NULL) != JSLOCAL_NONE) {
|
||||
if (js_LookupLocal(cx, tc->fun, atom, NULL) != JSLOCAL_NONE) {
|
||||
name = js_AtomToPrintableString(cx, atom);
|
||||
if (!name ||
|
||||
!js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
|
||||
|
@ -1053,30 +1049,28 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
|
|||
return JS_FALSE;
|
||||
}
|
||||
} else {
|
||||
if (!BindLocalVariable(cx, sfun, atom, JSLOCAL_VAR))
|
||||
if (!BindLocalVariable(cx, tc->fun, atom, JSLOCAL_VAR))
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif /* JS_HAS_DESTRUCTURING */
|
||||
|
||||
static JSFunction *
|
||||
static JSScriptedFunction *
|
||||
NewCompilerFunction(JSContext *cx, JSTreeContext *tc, JSAtom *atom,
|
||||
uintN lambda)
|
||||
{
|
||||
JSObject *parent;
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *fun;
|
||||
|
||||
JS_ASSERT((lambda & ~JSFUN_LAMBDA) == 0);
|
||||
parent = (tc->flags & TCF_IN_FUNCTION)
|
||||
? &tc->funobj->object
|
||||
: cx->fp->varobj;
|
||||
funobj = js_NewScriptedFunction(cx, NULL, lambda, parent, atom);
|
||||
if (funobj && !(tc->flags & TCF_COMPILE_N_GO)) {
|
||||
STOBJ_SET_PARENT(&funobj->object, NULL);
|
||||
STOBJ_SET_PROTO(&funobj->object, NULL);
|
||||
parent = (tc->flags & TCF_IN_FUNCTION) ? tc->fun->object : cx->fp->varobj;
|
||||
fun = js_NewScriptedFunction(cx, NULL, lambda, parent, atom);
|
||||
if (fun && !(tc->flags & TCF_COMPILE_N_GO)) {
|
||||
STOBJ_SET_PARENT(fun->object, NULL);
|
||||
STOBJ_SET_PROTO(fun->object, NULL);
|
||||
}
|
||||
return funobj;
|
||||
return fun;
|
||||
}
|
||||
|
||||
static JSParseNode *
|
||||
|
@ -1089,8 +1083,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
JSAtom *funAtom;
|
||||
JSParsedObjectBox *funpob;
|
||||
JSAtomListElement *ale;
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *sfun;
|
||||
JSScriptedFunction *fun;
|
||||
JSTreeContext funtc;
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
JSParseNode *item, *list = NULL;
|
||||
|
@ -1177,37 +1170,35 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
* variable even if the parameter with the given name already
|
||||
* exists.
|
||||
*/
|
||||
sfun = FUN_TO_SCRIPTED(tc->funobj);
|
||||
localKind = js_LookupLocal(cx, sfun, funAtom, NULL);
|
||||
localKind = js_LookupLocal(cx, tc->fun, funAtom, NULL);
|
||||
if (localKind == JSLOCAL_NONE || localKind == JSLOCAL_ARG) {
|
||||
if (!js_AddLocal(cx, sfun, funAtom, JSLOCAL_VAR))
|
||||
if (!js_AddLocal(cx, tc->fun, funAtom, JSLOCAL_VAR))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
funobj = NewCompilerFunction(cx, tc, funAtom, lambda);
|
||||
if (!funobj)
|
||||
fun = NewCompilerFunction(cx, tc, funAtom, lambda);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
|
||||
#if JS_HAS_GETTER_SETTER
|
||||
if (op != JSOP_NOP)
|
||||
sfun->flags |= (op == JSOP_GETTER) ? JSPROP_GETTER : JSPROP_SETTER;
|
||||
fun->flags |= (op == JSOP_GETTER) ? JSPROP_GETTER : JSPROP_SETTER;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create wrapping box for fun->object early to protect against a
|
||||
* last-ditch GC.
|
||||
*/
|
||||
funpob = js_NewParsedObjectBox(cx, tc->parseContext, &funobj->object);
|
||||
funpob = js_NewParsedObjectBox(cx, tc->parseContext, fun->object);
|
||||
if (!funpob)
|
||||
return NULL;
|
||||
|
||||
/* Initialize early for possible flags mutation via DestructuringExpr. */
|
||||
TREE_CONTEXT_INIT(&funtc, tc->parseContext);
|
||||
funtc.flags |= TCF_IN_FUNCTION;
|
||||
funtc.funobj = funobj;
|
||||
funtc.fun = fun;
|
||||
|
||||
/* Now parse formal argument list and compute fun->nargs. */
|
||||
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL);
|
||||
|
@ -1240,8 +1231,8 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
* Adjust fun->nargs to count the single anonymous positional
|
||||
* parameter that is to be destructured.
|
||||
*/
|
||||
slot = sfun->nargs;
|
||||
if (!js_AddLocal(cx, sfun, NULL, JSLOCAL_ARG))
|
||||
slot = fun->nargs;
|
||||
if (!js_AddLocal(cx, fun, NULL, JSLOCAL_ARG))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
|
@ -1293,7 +1284,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
ts->flags &= ~TSF_OPERAND;
|
||||
if (tt != TOK_LC) {
|
||||
js_UngetToken(ts);
|
||||
sfun->flags |= JSFUN_EXPR_CLOSURE;
|
||||
fun->flags |= JSFUN_EXPR_CLOSURE;
|
||||
}
|
||||
#else
|
||||
MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY);
|
||||
|
@ -1359,7 +1350,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
* a call object per invocation).
|
||||
*/
|
||||
if (funtc.flags & TCF_FUN_HEAVYWEIGHT) {
|
||||
sfun->flags |= JSFUN_HEAVYWEIGHT;
|
||||
fun->flags |= JSFUN_HEAVYWEIGHT;
|
||||
tc->flags |= TCF_FUN_HEAVYWEIGHT;
|
||||
} else {
|
||||
/*
|
||||
|
@ -1674,7 +1665,6 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
|
|||
JSAtomListElement *ale;
|
||||
JSOp op, prevop;
|
||||
const char *name;
|
||||
JSScriptedFunction *sfun;
|
||||
JSLocalKind localKind;
|
||||
|
||||
stmt = js_LexicalLookup(tc, atom, NULL, 0);
|
||||
|
@ -1722,8 +1712,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
sfun = FUN_TO_SCRIPTED(tc->funobj);
|
||||
localKind = js_LookupLocal(cx, sfun, atom, NULL);
|
||||
localKind = js_LookupLocal(cx, tc->fun, atom, NULL);
|
||||
if (localKind == JSLOCAL_NONE) {
|
||||
/*
|
||||
* Property not found in current variable scope: we have not seen this
|
||||
|
@ -1735,7 +1724,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
|
|||
*/
|
||||
localKind = (data->op == JSOP_DEFCONST) ? JSLOCAL_CONST : JSLOCAL_VAR;
|
||||
if (!js_InWithStatement(tc) &&
|
||||
!BindLocalVariable(cx, sfun, atom, localKind)) {
|
||||
!BindLocalVariable(cx, tc->fun, atom, localKind)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
} else if (localKind == JSLOCAL_ARG) {
|
||||
|
@ -4264,7 +4253,7 @@ GeneratorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
uintN oldflags, JSParseNode *pn, JSParseNode *kid)
|
||||
{
|
||||
JSParseNode *body, *lambda;
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *fun;
|
||||
|
||||
/* Initialize pn, connecting it to kid. */
|
||||
JS_ASSERT(pn->pn_arity == PN_UNARY);
|
||||
|
@ -4287,8 +4276,8 @@ GeneratorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
* Make the generator function and flag it as interpreted ASAP (see the
|
||||
* comment in FunctionBody).
|
||||
*/
|
||||
funobj = NewCompilerFunction(cx, tc, NULL, JSFUN_LAMBDA);
|
||||
if (!funobj)
|
||||
fun = NewCompilerFunction(cx, tc, NULL, JSFUN_LAMBDA);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
|
@ -4304,7 +4293,7 @@ GeneratorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
lambda->pn_op = JSOP_ANONFUNOBJ;
|
||||
lambda->pn_pos.begin = body->pn_pos.begin;
|
||||
lambda->pn_funpob = js_NewParsedObjectBox(cx, tc->parseContext,
|
||||
&funobj->object);
|
||||
fun->object);
|
||||
if (!lambda->pn_funpob)
|
||||
return NULL;
|
||||
lambda->pn_body = body;
|
||||
|
|
|
@ -464,7 +464,7 @@ js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
|||
FILE *file, const char *filename, uintN lineno);
|
||||
|
||||
extern JSBool
|
||||
js_CompileFunctionBody(JSContext *cx, JSFunction *funobj,
|
||||
js_CompileFunctionBody(JSContext *cx, JSScriptedFunction *fun,
|
||||
JSPrincipals *principals,
|
||||
const jschar *chars, size_t length,
|
||||
const char *filename, uintN lineno);
|
||||
|
|
|
@ -1421,7 +1421,7 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
|
|||
uint32 mainLength, prologLength, nsrcnotes;
|
||||
JSScript *script;
|
||||
const char *filename;
|
||||
JSFunction *funobj;
|
||||
JSScriptedFunction *fun;
|
||||
|
||||
/* The counts of indexed things must be checked during code generation. */
|
||||
JS_ASSERT(cg->atomList.count <= INDEX_LIMIT);
|
||||
|
@ -1467,21 +1467,18 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
|
|||
FinishParsedObjects(&cg->regexpList, JS_SCRIPT_REGEXPS(script));
|
||||
|
||||
/* Initialize fun->script early for the debugger. */
|
||||
funobj = NULL;
|
||||
fun = NULL;
|
||||
if (cg->treeContext.flags & TCF_IN_FUNCTION) {
|
||||
JSScriptedFunction *sfun;
|
||||
|
||||
funobj = cg->treeContext.funobj;
|
||||
sfun = FUN_TO_SCRIPTED(funobj);
|
||||
JS_ASSERT(!sfun->script);
|
||||
js_FreezeLocalNames(cx, sfun);
|
||||
sfun->script = script;
|
||||
fun = cg->treeContext.fun;
|
||||
JS_ASSERT(!fun->script);
|
||||
js_FreezeLocalNames(cx, fun);
|
||||
fun->script = script;
|
||||
#ifdef CHECK_SCRIPT_OWNER
|
||||
script->owner = NULL;
|
||||
#endif
|
||||
if (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)
|
||||
sfun->flags |= JSFUN_HEAVYWEIGHT;
|
||||
if (sfun->flags & JSFUN_HEAVYWEIGHT)
|
||||
fun->flags |= JSFUN_HEAVYWEIGHT;
|
||||
if (fun->flags & JSFUN_HEAVYWEIGHT)
|
||||
++cg->treeContext.maxScopeDepth;
|
||||
}
|
||||
|
||||
|
@ -1491,7 +1488,7 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
|
|||
#endif
|
||||
|
||||
/* Tell the debugger about this compiled script. */
|
||||
js_CallNewScriptHook(cx, script, funobj);
|
||||
js_CallNewScriptHook(cx, script, fun);
|
||||
return script;
|
||||
|
||||
bad:
|
||||
|
@ -1500,14 +1497,15 @@ bad:
|
|||
}
|
||||
|
||||
void
|
||||
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
|
||||
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSScriptedFunction *fun)
|
||||
{
|
||||
JSNewScriptHook hook;
|
||||
|
||||
hook = cx->debugHooks->newScriptHook;
|
||||
if (hook) {
|
||||
JS_KEEP_ATOMS(cx->runtime);
|
||||
hook(cx, script->filename, script->lineno, script, fun,
|
||||
hook(cx, script->filename, script->lineno, script,
|
||||
fun ? SCRIPTED_TO_FUN(fun) : NULL,
|
||||
cx->debugHooks->newScriptHookData);
|
||||
JS_UNKEEP_ATOMS(cx->runtime);
|
||||
}
|
||||
|
@ -1693,7 +1691,7 @@ uintN
|
|||
js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
JSObject *obj;
|
||||
JSScriptedFunction *sfun;
|
||||
JSScriptedFunction *fun;
|
||||
uintN lineno;
|
||||
ptrdiff_t offset, target;
|
||||
jssrcnote *sn;
|
||||
|
@ -1711,8 +1709,8 @@ js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
|
|||
pc += js_CodeSpec[*pc].length;
|
||||
if (*pc == JSOP_DEFFUN) {
|
||||
GET_FUNCTION_FROM_BYTECODE(script, pc, 0, obj);
|
||||
sfun = FUN_TO_SCRIPTED(OBJ_TO_FUNCTION(obj));
|
||||
return sfun->script->lineno;
|
||||
fun = FUN_TO_SCRIPTED(GET_FUNCTION_PRIVATE(cx, obj));
|
||||
return fun->script->lineno;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -228,7 +228,7 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg);
|
|||
* of any owning function (the fun parameter) or script object (null fun).
|
||||
*/
|
||||
extern void
|
||||
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
|
||||
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSScriptedFunction *fun);
|
||||
|
||||
extern void
|
||||
js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
|
||||
|
|
|
@ -830,7 +830,7 @@ QName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
{
|
||||
jsval nameval, nsval;
|
||||
JSBool isQName, isNamespace;
|
||||
JSFunction *funobj;
|
||||
JSFunction *fun;
|
||||
JSXMLQName *qn;
|
||||
JSString *uri, *prefix, *name;
|
||||
JSObject *nsobj;
|
||||
|
@ -855,9 +855,8 @@ QName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
* Use the constructor's clasp so we can be shared by AttributeName
|
||||
* (see below after this function).
|
||||
*/
|
||||
funobj = JS_ValueToFunction(cx, argv[-2]);
|
||||
obj = js_NewObject(cx, NATIVE_FUN_GET_CLASS(FUN_TO_NATIVE(funobj)),
|
||||
NULL, NULL, 0);
|
||||
fun = JS_ValueToFunction(cx, argv[-2]);
|
||||
obj = js_NewObject(cx, FUN_TO_NATIVE(fun)->clasp, NULL, NULL, 0);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
|
@ -5596,7 +5595,7 @@ static JSXML *
|
|||
StartNonListXMLMethod(JSContext *cx, jsval *vp, JSObject **objp)
|
||||
{
|
||||
JSXML *xml;
|
||||
JSFunction *funobj;
|
||||
JSFunction *fun;
|
||||
char numBuf[12];
|
||||
|
||||
JS_ASSERT(VALUE_IS_FUNCTION(cx, *vp));
|
||||
|
@ -5617,11 +5616,11 @@ StartNonListXMLMethod(JSContext *cx, jsval *vp, JSObject **objp)
|
|||
}
|
||||
}
|
||||
|
||||
funobj = OBJ_TO_FUNCTION(JSVAL_TO_OBJECT(*vp));
|
||||
fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(*vp));
|
||||
JS_snprintf(numBuf, sizeof numBuf, "%u", xml->xml_kids.length);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NON_LIST_XML_METHOD,
|
||||
JS_GetFunctionName(funobj), numBuf);
|
||||
JS_GetFunctionName(fun), numBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -7714,7 +7713,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj)
|
|||
fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1, 0);
|
||||
if (!fun)
|
||||
return NULL;
|
||||
if (!js_SetClassPrototype(cx, &fun->object, proto,
|
||||
if (!js_SetClassPrototype(cx, &FUN_TO_NATIVE(fun)->object, proto,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT)) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче