[bug 424376] backing out - too much compatibility problems.

This commit is contained in:
igor%mir2.org 2008-03-28 22:27:37 +00:00
Родитель a819dca863
Коммит b7c7e118a6
19 изменённых файлов: 389 добавлений и 391 удалений

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

@ -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],

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

@ -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 *

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

@ -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, &regs.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, &notePool,
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;
}