diff --git a/js/src/jsobj.c b/js/src/jsobj.c index e20ea166cd55..76360ebba8bc 100644 --- a/js/src/jsobj.c +++ b/js/src/jsobj.c @@ -3096,9 +3096,9 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp) if (xdr->mode == JSXDR_ENCODE) { clasp = OBJ_GET_CLASS(cx, *objp); className = clasp->name; - classId = JS_FindClassIdByName(xdr, className); + classId = JS_XDRFindClassIdByName(xdr, className); classDef = !classId; - if (classDef && !JS_RegisterClass(xdr, clasp, &classId)) + if (classDef && !JS_XDRRegisterClass(xdr, clasp, &classId)) return JS_FALSE; } else { classDef = 0; @@ -3123,11 +3123,11 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp) if (!ok) goto out; clasp = OBJ_GET_CLASS(cx, proto); - ok = JS_RegisterClass(xdr, clasp, &classId); + ok = JS_XDRRegisterClass(xdr, clasp, &classId); if (!ok) goto out; } else { - clasp = JS_FindClassById(xdr, classId); + clasp = JS_XDRFindClassById(xdr, classId); if (!clasp) { char numBuf[12]; JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)classId); @@ -3312,4 +3312,3 @@ void printAtom(JSAtom *atom) { } #endif - diff --git a/js/src/jsscript.c b/js/src/jsscript.c index efe4990088e8..4d489fee1106 100644 --- a/js/src/jsscript.c +++ b/js/src/jsscript.c @@ -60,7 +60,7 @@ #if JS_HAS_TOSOURCE static JSBool script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval) + jsval *rval) { JSScript *script; size_t i, j, k, n; @@ -70,40 +70,40 @@ script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, JSString *str; if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) - return JS_FALSE; + return JS_FALSE; script = (JSScript *) JS_GetPrivate(cx, obj); /* Let n count the source string length, j the "front porch" length. */ j = JS_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name); n = j + 2; if (!script) { - /* Let k count the constructor argument string length. */ - k = 0; + /* Let k count the constructor argument string length. */ + k = 0; s = NULL; /* quell GCC overwarning */ } else { - indent = 0; - if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) - return JS_FALSE; - str = JS_DecompileScript(cx, script, "Script.prototype.toSource", - (uintN)indent); - if (!str) - return JS_FALSE; - str = js_QuoteString(cx, str, '\''); - if (!str) - return JS_FALSE; - s = str->chars; - k = str->length; - n += k; + indent = 0; + if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) + return JS_FALSE; + str = JS_DecompileScript(cx, script, "Script.prototype.toSource", + (uintN)indent); + if (!str) + return JS_FALSE; + str = js_QuoteString(cx, str, '\''); + if (!str) + return JS_FALSE; + s = str->chars; + k = str->length; + n += k; } /* Allocate the source string and copy into it. */ t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); if (!t) - return JS_FALSE; + return JS_FALSE; for (i = 0; i < j; i++) - t[i] = buf[i]; + t[i] = buf[i]; for (j = 0; j < k; i++, j++) - t[i] = s[j]; + t[i] = s[j]; t[i++] = ')'; t[i++] = ')'; t[i] = 0; @@ -111,8 +111,8 @@ script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, /* Create and return a JS string for t. */ str = JS_NewUCString(cx, t, n); if (!str) { - JS_free(cx, t); - return JS_FALSE; + JS_free(cx, t); + return JS_FALSE; } *rval = STRING_TO_JSVAL(str); return JS_TRUE; @@ -121,34 +121,34 @@ script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, static JSBool script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval) + jsval *rval) { JSScript *script; uint32 indent; JSString *str; if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) - return JS_FALSE; + return JS_FALSE; script = (JSScript *) JS_GetPrivate(cx, obj); if (!script) { - *rval = STRING_TO_JSVAL(cx->runtime->emptyString); - return JS_TRUE; + *rval = STRING_TO_JSVAL(cx->runtime->emptyString); + return JS_TRUE; } indent = 0; if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) - return JS_FALSE; + return JS_FALSE; str = JS_DecompileScript(cx, script, "Script.prototype.toString", - (uintN)indent); + (uintN)indent); if (!str) - return JS_FALSE; + return JS_FALSE; *rval = STRING_TO_JSVAL(str); return JS_TRUE; } static JSBool script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval) + jsval *rval) { JSScript *oldscript, *script; JSString *str; @@ -160,12 +160,12 @@ script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, /* If no args, leave private undefined and return early. */ if (argc == 0) - goto out; + goto out; /* Otherwise, the first arg is the script source to compile. */ str = js_ValueToString(cx, argv[0]); if (!str) - return JS_FALSE; + return JS_FALSE; /* Compile using the caller's scope chain, which js_Invoke passes to fp. */ fp = cx->fp; @@ -174,38 +174,38 @@ script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, scopeobj = NULL; if (argc >= 2) { - if (!js_ValueToObject(cx, argv[1], &scopeobj)) - return JS_FALSE; - argv[1] = OBJECT_TO_JSVAL(scopeobj); + if (!js_ValueToObject(cx, argv[1], &scopeobj)) + return JS_FALSE; + argv[1] = OBJECT_TO_JSVAL(scopeobj); } if (!scopeobj) - scopeobj = caller->scopeChain; + scopeobj = caller->scopeChain; if (caller->script) { - file = caller->script->filename; - line = js_PCToLineNumber(caller->script, caller->pc); - principals = caller->script->principals; + file = caller->script->filename; + line = js_PCToLineNumber(caller->script, caller->pc); + principals = caller->script->principals; } else { - file = NULL; - line = 0; - principals = NULL; + file = NULL; + line = 0; + principals = NULL; } /* Compile the new script using the caller's scope chain, a la eval(). */ script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals, - str->chars, str->length, - file, line); + str->chars, str->length, + file, line); if (!script) - return JS_FALSE; + return JS_FALSE; /* Swap script for obj's old script, if any. */ oldscript = (JSScript *) JS_GetPrivate(cx, obj); if (!JS_SetPrivate(cx, obj, script)) { - js_DestroyScript(cx, script); - return JS_FALSE; + js_DestroyScript(cx, script); + return JS_FALSE; } if (oldscript) - js_DestroyScript(cx, oldscript); + js_DestroyScript(cx, oldscript); script->object = obj; out: @@ -222,16 +222,16 @@ script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) JSObject *scopeobj; if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) - return JS_FALSE; + return JS_FALSE; script = (JSScript *) JS_GetPrivate(cx, obj); if (!script) - return JS_TRUE; + return JS_TRUE; scopeobj = NULL; if (argc) { - if (!js_ValueToObject(cx, argv[0], &scopeobj)) - return JS_FALSE; - argv[0] = OBJECT_TO_JSVAL(scopeobj); + if (!js_ValueToObject(cx, argv[0], &scopeobj)) + return JS_FALSE; + argv[0] = OBJECT_TO_JSVAL(scopeobj); } /* Emulate eval() by using caller's this, scope chain, and sharp array. */ @@ -247,25 +247,25 @@ script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) #if JS_HAS_XDR static JSBool -XDRAtom1(JSXDRState *xdr, JSAtomListElement *ale) +XDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale) { jsval value; jsatomid index; if (xdr->mode == JSXDR_ENCODE) - value = ATOM_KEY(ALE_ATOM(ale)); + value = ATOM_KEY(ALE_ATOM(ale)); index = ALE_INDEX(ale); if (!JS_XDRUint32(xdr, &index)) - return JS_FALSE; + return JS_FALSE; ALE_SET_INDEX(ale, index); if (!JS_XDRValue(xdr, &value)) - return JS_FALSE; + return JS_FALSE; if (xdr->mode == JSXDR_DECODE) { - if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0))) - return JS_FALSE; + if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0))) + return JS_FALSE; } return JS_TRUE; } @@ -278,47 +278,47 @@ XDRAtomMap(JSXDRState *xdr, JSAtomMap *map) JSBool ok; if (xdr->mode == JSXDR_ENCODE) - length = map->length; + length = map->length; if (!JS_XDRUint32(xdr, &length)) - return JS_FALSE; + return JS_FALSE; if (xdr->mode == JSXDR_DECODE) { - JSContext *cx; - void *mark; - JSAtomList al; - JSAtomListElement *ale; + JSContext *cx; + void *mark; + JSAtomList al; + JSAtomListElement *ale; - cx = xdr->cx; - mark = JS_ARENA_MARK(&cx->tempPool); - ATOM_LIST_INIT(&al); - for (i = 0; i < length; i++) { - JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool); - if (!ale || - !XDRAtom1(xdr, ale)) { - if (!ale) - JS_ReportOutOfMemory(cx); - JS_ARENA_RELEASE(&cx->tempPool, mark); - return JS_FALSE; - } - ALE_SET_NEXT(ale, al.list); - al.count++; - al.list = ale; - } + cx = xdr->cx; + mark = JS_ARENA_MARK(&cx->tempPool); + ATOM_LIST_INIT(&al); + for (i = 0; i < length; i++) { + JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool); + if (!ale || + !XDRAtomListElement(xdr, ale)) { + if (!ale) + JS_ReportOutOfMemory(cx); + JS_ARENA_RELEASE(&cx->tempPool, mark); + return JS_FALSE; + } + ALE_SET_NEXT(ale, al.list); + al.count++; + al.list = ale; + } ok = js_InitAtomMap(cx, map, &al); JS_ARENA_RELEASE(&cx->tempPool, mark); return ok; } if (xdr->mode == JSXDR_ENCODE) { - JSAtomListElement ale; + JSAtomListElement ale; - for (i = 0; i < map->length; i++) { - ALE_SET_ATOM(&ale, map->vector[i]); - ALE_SET_INDEX(&ale, i); - if (!XDRAtom1(xdr, &ale)) - return JS_FALSE; - } + for (i = 0; i < map->length; i++) { + ALE_SET_ATOM(&ale, map->vector[i]); + ALE_SET_INDEX(&ale, i); + if (!XDRAtomListElement(xdr, &ale)) + return JS_FALSE; + } } return JS_TRUE; } @@ -348,7 +348,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic) *hasMagic = JS_TRUE; if (xdr->mode == JSXDR_ENCODE) { - jssrcnote *end = script->notes; + jssrcnote *sn = script->notes; length = script->length; prologLength = script->main - script->code; version = (int32) script->version; @@ -363,9 +363,10 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic) } /* Count the src notes. */ - while (!SN_IS_TERMINATOR(end)) - end = SN_NEXT(end); - notelen = end - script->notes; + while (!SN_IS_TERMINATOR(sn)) + sn = SN_NEXT(sn); + notelen = sn - script->notes; + notelen++; /* room for the terminator */ } if (!JS_XDRUint32(xdr, &length)) @@ -441,7 +442,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic) static JSBool script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval) + jsval *rval) { JSXDRState *xdr; JSScript *script; @@ -451,37 +452,37 @@ script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, JSString *str; if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) - return JS_FALSE; + return JS_FALSE; script = (JSScript *) JS_GetPrivate(cx, obj); if (!script) - return JS_TRUE; + return JS_TRUE; /* create new XDR */ xdr = JS_XDRNewMem(cx, JSXDR_ENCODE); if (!xdr) - return JS_FALSE; + return JS_FALSE; /* write */ ok = js_XDRScript(xdr, &script, &hasMagic); if (!ok) - goto out; + goto out; if (!hasMagic) { - *rval = JSVAL_VOID; - goto out; + *rval = JSVAL_VOID; + goto out; } buf = JS_XDRMemGetData(xdr, &len); if (!buf) { - ok = JS_FALSE; - goto out; + ok = JS_FALSE; + goto out; } JS_ASSERT((jsword)buf % sizeof(jschar) == 0); len /= sizeof(jschar); str = JS_NewUCStringCopyN(cx, (jschar *)buf, len); if (!str) { - ok = JS_FALSE; - goto out; + ok = JS_FALSE; + goto out; } #if IS_BIG_ENDIAN @@ -492,7 +493,7 @@ script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, /* Swap bytes in Unichars to keep frozen strings machine-independent. */ chars = JS_GetStringChars(str); for (i = 0; i < len; i++) - chars[i] = JSXDR_SWAB16(chars[i]); + chars[i] = JSXDR_SWAB16(chars[i]); } #endif *rval = STRING_TO_JSVAL(str); @@ -504,7 +505,7 @@ out: static JSBool script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval) + jsval *rval) { JSXDRState *xdr; JSString *str; @@ -514,18 +515,18 @@ script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, JSBool ok, hasMagic; if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) - return JS_FALSE; + return JS_FALSE; if (argc == 0) - return JS_TRUE; + return JS_TRUE; str = js_ValueToString(cx, argv[0]); if (!str) - return JS_FALSE; + return JS_FALSE; /* create new XDR */ xdr = JS_XDRNewMem(cx, JSXDR_DECODE); if (!xdr) - return JS_FALSE; + return JS_FALSE; buf = JS_GetStringChars(str); len = JS_GetStringLength(str); @@ -542,7 +543,7 @@ script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, return JS_FALSE; } for (i = 0; i < len; i++) - to[i] = JSXDR_SWAB16(from[i]); + to[i] = JSXDR_SWAB16(from[i]); buf = (char *)to; } #endif @@ -552,21 +553,21 @@ script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, /* XXXbe should magic mismatch be error, or false return value? */ ok = js_XDRScript(xdr, &script, &hasMagic); if (!ok) - goto out; + goto out; if (!hasMagic) { - *rval = JSVAL_FALSE; - goto out; + *rval = JSVAL_FALSE; + goto out; } /* Swap script for obj's old script, if any. */ oldscript = (JSScript *) JS_GetPrivate(cx, obj); ok = JS_SetPrivate(cx, obj, script); if (!ok) { - JS_free(cx, script); - goto out; + JS_free(cx, script); + goto out; } if (oldscript) - js_DestroyScript(cx, oldscript); + js_DestroyScript(cx, oldscript); script->object = obj; @@ -596,8 +597,8 @@ static JSFunctionSpec script_methods[] = { {"compile", script_compile, 2,0,0}, {"exec", script_exec, 1,0,0}, #if JS_HAS_XDR - {"freeze", script_freeze, 0,0,0}, - {js_thaw_str, script_thaw, 1,0,0}, + {"freeze", script_freeze, 0,0,0}, + {js_thaw_str, script_thaw, 1,0,0}, #endif /* JS_HAS_XDR */ {0,0,0,0,0} }; @@ -611,7 +612,7 @@ script_finalize(JSContext *cx, JSObject *obj) script = (JSScript *) JS_GetPrivate(cx, obj); if (script) - js_DestroyScript(cx, script); + js_DestroyScript(cx, script); } static JSBool @@ -651,9 +652,9 @@ Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { /* If not constructing, replace obj with a new Script object. */ if (!cx->fp->constructing) { - obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); - if (!obj) - return JS_FALSE; + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + if (!obj) + return JS_FALSE; } return script_compile(cx, obj, argc, argv, rval); } @@ -662,13 +663,13 @@ Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) static JSBool script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, - jsval *rval) + jsval *rval) { obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); if (!obj) - return JS_FALSE; + return JS_FALSE; if (!script_thaw(cx, obj, argc, argv, rval)) - return JS_FALSE; + return JS_FALSE; *rval = OBJECT_TO_JSVAL(obj); return JS_TRUE; } @@ -688,7 +689,7 @@ JSObject * js_InitScriptClass(JSContext *cx, JSObject *obj) { return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1, - NULL, script_methods, NULL, script_static_methods); + NULL, script_methods, NULL, script_static_methods); } #endif /* JS_HAS_SCRIPT_OBJECT */ @@ -701,7 +702,7 @@ js_NewScript(JSContext *cx, uint32 length) script = (JSScript *) JS_malloc(cx, sizeof(JSScript) + length * sizeof(jsbytecode)); if (!script) - return NULL; + return NULL; memset(script, 0, sizeof(JSScript)); script->code = script->main = (jsbytecode *)(script + 1); script->length = length; @@ -711,32 +712,32 @@ js_NewScript(JSContext *cx, uint32 length) JSScript * js_NewScriptFromParams(JSContext *cx, jsbytecode *code, uint32 length, - jsbytecode *prolog, uint32 prologLength, - const char *filename, uintN lineno, uintN depth, - jssrcnote *notes, JSTryNote *trynotes, - JSPrincipals *principals) + jsbytecode *prolog, uint32 prologLength, + const char *filename, uintN lineno, uintN depth, + jssrcnote *notes, JSTryNote *trynotes, + JSPrincipals *principals) { JSScript *script; script = js_NewScript(cx, prologLength + length); if (!script) - return NULL; + return NULL; script->main += prologLength; memcpy(script->code, prolog, prologLength * sizeof(jsbytecode)); memcpy(script->main, code, length * sizeof(jsbytecode)); if (filename) { - script->filename = JS_strdup(cx, filename); - if (!script->filename) { - js_DestroyScript(cx, script); - return NULL; - } + script->filename = JS_strdup(cx, filename); + if (!script->filename) { + js_DestroyScript(cx, script); + return NULL; + } } script->lineno = lineno; script->depth = depth; script->notes = notes; script->trynotes = trynotes; if (principals) - JSPRINCIPALS_HOLD(cx, principals); + JSPRINCIPALS_HOLD(cx, principals); script->principals = principals; return script; } @@ -751,26 +752,26 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun) JSNewScriptHook hook; if (!js_FinishTakingTryNotes(cx, cg, &trynotes)) - return NULL; + return NULL; notes = js_FinishTakingSrcNotes(cx, cg); script = js_NewScriptFromParams(cx, CG_BASE(cg), CG_OFFSET(cg), CG_PROLOG_BASE(cg), CG_PROLOG_OFFSET(cg), - cg->filename, cg->firstLine, - cg->maxStackDepth, notes, trynotes, - cg->principals); + cg->filename, cg->firstLine, + cg->maxStackDepth, notes, trynotes, + cg->principals); if (!script) - return NULL; + return NULL; if (!notes || !js_InitAtomMap(cx, &script->atomMap, &cg->atomList)) { - js_DestroyScript(cx, script); - return NULL; + js_DestroyScript(cx, script); + return NULL; } /* Tell the debugger about this compiled script. */ rt = cx->runtime; hook = rt->newScriptHook; if (hook) { - (*hook)(cx, cg->filename, cg->firstLine, script, fun, - rt->newScriptHookData); + (*hook)(cx, cg->filename, cg->firstLine, script, fun, + rt->newScriptHookData); } return script; } @@ -784,7 +785,7 @@ js_DestroyScript(JSContext *cx, JSScript *script) rt = cx->runtime; hook = rt->destroyScriptHook; if (hook) - (*hook)(cx, script, rt->destroyScriptHookData); + (*hook)(cx, script, rt->destroyScriptHookData); JS_ClearScriptTraps(cx, script); js_FreeAtomMap(cx, &script->atomMap); @@ -792,7 +793,7 @@ js_DestroyScript(JSContext *cx, JSScript *script) JS_free(cx, script->notes); JS_free(cx, script->trynotes); if (script->principals) - JSPRINCIPALS_DROP(cx, script->principals); + JSPRINCIPALS_DROP(cx, script->principals); JS_free(cx, script); } @@ -818,14 +819,14 @@ js_GetSrcNote(JSScript *script, jsbytecode *pc) sn = script->notes; if (!sn) - return NULL; + return NULL; target = PTRDIFF(pc, script->main, jsbytecode); if ((uintN)target >= script->length) - return NULL; + return NULL; for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { - offset += SN_DELTA(sn); - if (offset == target && SN_IS_GETTABLE(sn)) - return sn; + offset += SN_DELTA(sn); + if (offset == target && SN_IS_GETTABLE(sn)) + return sn; } return NULL; } @@ -840,21 +841,21 @@ js_PCToLineNumber(JSScript *script, jsbytecode *pc) sn = script->notes; if (!sn) - return 0; + return 0; target = PTRDIFF(pc, script->main, jsbytecode); lineno = script->lineno; for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { - offset += SN_DELTA(sn); - type = (JSSrcNoteType) SN_TYPE(sn); - if (type == SRC_SETLINE) { - if (offset <= target) - lineno = (uintN) js_GetSrcNoteOffset(sn, 0); - } else if (type == SRC_NEWLINE) { - if (offset <= target) - lineno++; - } - if (offset > target) - break; + offset += SN_DELTA(sn); + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + if (offset <= target) + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + if (offset <= target) + lineno++; + } + if (offset > target) + break; } return lineno; } @@ -869,18 +870,18 @@ js_LineNumberToPC(JSScript *script, uintN target) sn = script->notes; if (!sn) - return NULL; + return NULL; lineno = script->lineno; for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { - if (lineno >= target) - break; - offset += SN_DELTA(sn); - type = (JSSrcNoteType) SN_TYPE(sn); - if (type == SRC_SETLINE) { - lineno = (uintN) js_GetSrcNoteOffset(sn, 0); - } else if (type == SRC_NEWLINE) { - lineno++; - } + if (lineno >= target) + break; + offset += SN_DELTA(sn); + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + lineno++; + } } return script->main + offset; } @@ -894,15 +895,15 @@ js_GetScriptLineExtent(JSScript *script) sn = script->notes; if (!sn) - return 0; + return 0; lineno = script->lineno; for (; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { - type = (JSSrcNoteType) SN_TYPE(sn); - if (type == SRC_SETLINE) { - lineno = (uintN) js_GetSrcNoteOffset(sn, 0); - } else if (type == SRC_NEWLINE) { - lineno++; - } + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + lineno++; + } } return 1 + lineno - script->lineno; } diff --git a/js/src/jsxdrapi.c b/js/src/jsxdrapi.c index 08690d17831f..f8c27ebced60 100644 --- a/js/src/jsxdrapi.c +++ b/js/src/jsxdrapi.c @@ -36,10 +36,11 @@ #include #include "jstypes.h" #include "jsutil.h" /* Added by JSIFY */ +#include "jsdhash.h" #include "jsprf.h" #include "jsapi.h" #include "jscntxt.h" -#include "jsobj.h" /* js_XDRObject */ +#include "jsobj.h" /* js_XDRObject */ #include "jsstr.h" #include "jsxdrapi.h" @@ -64,36 +65,29 @@ typedef struct JSXDRMemState { #define MEM_LEFT(xdr, bytes) \ JS_BEGIN_MACRO \ - if ((xdr)->mode == JSXDR_DECODE && \ - MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ - JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \ - JSMSG_END_OF_DATA); \ - return 0; \ - } \ + if ((xdr)->mode == JSXDR_DECODE && \ + MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ + JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \ + JSMSG_END_OF_DATA); \ + return 0; \ + } \ JS_END_MACRO -/* XXXbe why does NEED even allow or cope with non-ENCODE mode? */ #define MEM_NEED(xdr, bytes) \ JS_BEGIN_MACRO \ - if ((xdr)->mode == JSXDR_ENCODE) { \ - uint32 _new_limit = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\ - if (MEM_LIMIT(xdr) && \ - MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ - void *_data = JS_realloc((xdr)->cx, \ - (xdr)->data, \ - _new_limit); \ - if (!_data) \ - return 0; \ - (xdr)->data = _data; \ - MEM_LIMIT(xdr) = _new_limit; \ - } \ - } else { \ - if (MEM_LIMIT(xdr) < MEM_COUNT(xdr) + bytes) { \ - JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \ - JSMSG_END_OF_DATA); \ - return 0; \ - } \ - } \ + if ((xdr)->mode == JSXDR_ENCODE) { \ + uint32 new_limit_ = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\ + if (MEM_LIMIT(xdr) && \ + MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ + void *data_ = JS_realloc((xdr)->cx, (xdr)->data, new_limit_); \ + if (!data_) \ + return 0; \ + (xdr)->data = data_; \ + MEM_LIMIT(xdr) = new_limit_; \ + } \ + } else { \ + MEM_LEFT(xdr, bytes); \ + } \ JS_END_MACRO #define MEM_DATA(xdr) ((void *)((char *)(xdr)->data + MEM_COUNT(xdr))) @@ -140,9 +134,9 @@ mem_raw(JSXDRState *xdr, uint32 len) { void *data; if (xdr->mode == JSXDR_ENCODE) { - MEM_NEED(xdr, len); + MEM_NEED(xdr, len); } else if (xdr->mode == JSXDR_DECODE) { - MEM_LEFT(xdr, len); + MEM_LEFT(xdr, len); } data = MEM_DATA(xdr); MEM_INCR(xdr, len); @@ -154,50 +148,50 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence) { switch (whence) { case JSXDR_SEEK_CUR: - if ((int32)MEM_COUNT(xdr) + offset < 0) { - JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, - JSMSG_SEEK_BEYOND_START); - return JS_FALSE; - } - if (offset > 0) - MEM_NEED(xdr, offset); - MEM_COUNT(xdr) += offset; - return JS_TRUE; + if ((int32)MEM_COUNT(xdr) + offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_START); + return JS_FALSE; + } + if (offset > 0) + MEM_NEED(xdr, offset); + MEM_COUNT(xdr) += offset; + return JS_TRUE; case JSXDR_SEEK_SET: - if (offset < 0) { - JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, - JSMSG_SEEK_BEYOND_START); - return JS_FALSE; - } - if (xdr->mode == JSXDR_ENCODE) { - if ((uint32)offset > MEM_COUNT(xdr)) - MEM_NEED(xdr, offset - MEM_COUNT(xdr)); - MEM_COUNT(xdr) = offset; - } else { - if ((uint32)offset > MEM_LIMIT(xdr)) { - JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, - JSMSG_SEEK_BEYOND_END); - return JS_FALSE; - } - MEM_COUNT(xdr) = offset; - } - return JS_TRUE; + if (offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_START); + return JS_FALSE; + } + if (xdr->mode == JSXDR_ENCODE) { + if ((uint32)offset > MEM_COUNT(xdr)) + MEM_NEED(xdr, offset - MEM_COUNT(xdr)); + MEM_COUNT(xdr) = offset; + } else { + if ((uint32)offset > MEM_LIMIT(xdr)) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_END); + return JS_FALSE; + } + MEM_COUNT(xdr) = offset; + } + return JS_TRUE; case JSXDR_SEEK_END: - if (offset >= 0 || - xdr->mode == JSXDR_ENCODE || - (int32)MEM_LIMIT(xdr) + offset < 0) { - JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, - JSMSG_END_SEEK); - return JS_FALSE; - } - MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset; - return JS_TRUE; + if (offset >= 0 || + xdr->mode == JSXDR_ENCODE || + (int32)MEM_LIMIT(xdr) + offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_END_SEEK); + return JS_FALSE; + } + MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset; + return JS_TRUE; default: { - char numBuf[12]; - JS_snprintf(numBuf, sizeof numBuf, "%d", whence); - JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, - JSMSG_WHITHER_WHENCE, numBuf); - return JS_FALSE; + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%d", whence); + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_WHITHER_WHENCE, numBuf); + return JS_FALSE; } } } @@ -211,8 +205,7 @@ mem_tell(JSXDRState *xdr) static void mem_finalize(JSXDRState *xdr) { - JSContext *cx = xdr->cx; - JS_free(cx, xdr->data); + JS_free(xdr->cx, xdr->data); } static JSXDROps xdrmem_ops = { @@ -221,12 +214,13 @@ static JSXDROps xdrmem_ops = { }; JS_PUBLIC_API(void) -JS_XDRNewBase(JSContext *cx, JSXDRState *xdr, JSXDRMode mode) +JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx) { - xdr->cx = cx; xdr->mode = mode; + xdr->cx = cx; xdr->registry = NULL; - xdr->nclasses = 0; + xdr->numclasses = xdr->maxclasses = 0; + xdr->reghash = NULL; } JS_PUBLIC_API(JSXDRState *) @@ -234,16 +228,16 @@ JS_XDRNewMem(JSContext *cx, JSXDRMode mode) { JSXDRState *xdr = (JSXDRState *) JS_malloc(cx, sizeof(JSXDRMemState)); if (!xdr) - return NULL; - JS_XDRNewBase(cx, xdr, mode); + return NULL; + JS_XDRInitBase(xdr, mode, cx); if (mode == JSXDR_ENCODE) { - if (!(xdr->data = JS_malloc(cx, MEM_BLOCK))) { - JS_free(cx, xdr); - return NULL; - } + if (!(xdr->data = JS_malloc(cx, MEM_BLOCK))) { + JS_free(cx, xdr); + return NULL; + } } else { - /* XXXbe ok, so better not deref xdr->data if not ENCODE */ - xdr->data = NULL; + /* XXXbe ok, so better not deref xdr->data if not ENCODE */ + xdr->data = NULL; } xdr->ops = &xdrmem_ops; MEM_PRIV(xdr)->count = 0; @@ -255,7 +249,7 @@ JS_PUBLIC_API(void *) JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp) { if (xdr->ops != &xdrmem_ops) - return NULL; + return NULL; *lp = MEM_PRIV(xdr)->count; return xdr->data; } @@ -264,19 +258,32 @@ JS_PUBLIC_API(void) JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len) { if (xdr->ops != &xdrmem_ops) - return; + return; MEM_PRIV(xdr)->limit = len; xdr->data = data; MEM_PRIV(xdr)->count = 0; } +JS_PUBLIC_API(void) +JS_XDRDestroy(JSXDRState *xdr) +{ + JSContext *cx = xdr->cx; + xdr->ops->finalize(xdr); + if (xdr->registry) { + JS_free(cx, xdr->registry); + if (xdr->reghash) + JS_DHashTableDestroy(xdr->reghash); + } + JS_free(cx, xdr); +} + JS_PUBLIC_API(JSBool) JS_XDRUint8(JSXDRState *xdr, uint8 *b) { uint32 l = *b; if (!JS_XDRUint32(xdr, &l)) - return JS_FALSE; - *b = (uint8) l & 0xff; + return JS_FALSE; + *b = (uint8) l; return JS_TRUE; } @@ -285,21 +292,21 @@ JS_XDRUint16(JSXDRState *xdr, uint16 *s) { uint32 l = *s; if (!JS_XDRUint32(xdr, &l)) - return JS_FALSE; - *s = (uint16) l & 0xffff; + return JS_FALSE; + *s = (uint16) l; return JS_TRUE; } JS_PUBLIC_API(JSBool) JS_XDRUint32(JSXDRState *xdr, uint32 *lp) { - JSBool ok = JS_FALSE; + JSBool ok = JS_TRUE; if (xdr->mode == JSXDR_ENCODE) { - uint32 xl = JSXDR_SWAB32(*lp); - ok = xdr->ops->set32(xdr, &xl); + uint32 xl = JSXDR_SWAB32(*lp); + ok = xdr->ops->set32(xdr, &xl); } else if (xdr->mode == JSXDR_DECODE) { - ok = xdr->ops->get32(xdr, lp); - *lp = JSXDR_SWAB32(*lp); + ok = xdr->ops->get32(xdr, lp); + *lp = JSXDR_SWAB32(*lp); } return ok; } @@ -307,19 +314,28 @@ JS_XDRUint32(JSXDRState *xdr, uint32 *lp) JS_PUBLIC_API(JSBool) JS_XDRBytes(JSXDRState *xdr, char **bytesp, uint32 len) { + uint32 padlen; + char *padbp; + static char padbuf[JSXDR_ALIGN-1]; + if (xdr->mode == JSXDR_ENCODE) { - if (!xdr->ops->setbytes(xdr, bytesp, len)) - return JS_FALSE; + if (!xdr->ops->setbytes(xdr, bytesp, len)) + return JS_FALSE; } else { - if (!xdr->ops->getbytes(xdr, bytesp, len)) - return JS_FALSE; + if (!xdr->ops->getbytes(xdr, bytesp, len)) + return JS_FALSE; } len = xdr->ops->tell(xdr); if (len % JSXDR_ALIGN) { - if (!xdr->ops->seek(xdr, JSXDR_ALIGN - (len % JSXDR_ALIGN), - JSXDR_SEEK_CUR)) { - return JS_FALSE; - } + padlen = JSXDR_ALIGN - (len % JSXDR_ALIGN); + if (xdr->mode == JSXDR_ENCODE) { + padbp = padbuf; + if (!xdr->ops->setbytes(xdr, &padbp, padlen)) + return JS_FALSE; + } else { + if (!xdr->ops->seek(xdr, padlen, JSXDR_SEEK_CUR)) + return JS_FALSE; + } } return JS_TRUE; } @@ -335,22 +351,22 @@ JS_XDRCString(JSXDRState *xdr, char **sp) uint32 len; if (xdr->mode == JSXDR_ENCODE) - len = strlen(*sp); + len = strlen(*sp); JS_XDRUint32(xdr, &len); if (xdr->mode == JSXDR_DECODE) { - if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1))) - return JS_FALSE; + if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1))) + return JS_FALSE; } if (!JS_XDRBytes(xdr, sp, len)) { - if (xdr->mode == JSXDR_DECODE) - JS_free(xdr->cx, *sp); - return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + JS_free(xdr->cx, *sp); + return JS_FALSE; } if (xdr->mode == JSXDR_DECODE) { - (*sp)[len] = '\0'; + (*sp)[len] = '\0'; } else if (xdr->mode == JSXDR_FREE) { - JS_free(xdr->cx, *sp); - *sp = NULL; + JS_free(xdr->cx, *sp); + *sp = NULL; } return JS_TRUE; } @@ -360,10 +376,10 @@ JS_XDRCStringOrNull(JSXDRState *xdr, char **sp) { uint32 null = (*sp == NULL); if (!JS_XDRUint32(xdr, &null)) - return JS_FALSE; + return JS_FALSE; if (null) { - *sp = NULL; - return JS_TRUE; + *sp = NULL; + return JS_TRUE; } return JS_XDRCString(xdr, sp); } @@ -374,42 +390,47 @@ JS_XDRCStringOrNull(JSXDRState *xdr, char **sp) JS_PUBLIC_API(JSBool) JS_XDRString(JSXDRState *xdr, JSString **strp) { - uint32 i, len, nbytes; + uint32 i, len, padlen, nbytes; jschar *chars = NULL, *raw; if (xdr->mode == JSXDR_ENCODE) - len = (*strp)->length; + len = (*strp)->length; if (!JS_XDRUint32(xdr, &len)) - return JS_FALSE; + return JS_FALSE; nbytes = len * sizeof(jschar); - if (xdr->mode == JSXDR_ENCODE) { - chars = (*strp)->chars; - } else if (xdr->mode == JSXDR_DECODE) { - if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar)))) - return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) { + if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar)))) + return JS_FALSE; + } else { + chars = (*strp)->chars; } - if (nbytes % JSXDR_ALIGN) - nbytes += JSXDR_ALIGN - (nbytes % JSXDR_ALIGN); + padlen = nbytes % JSXDR_ALIGN; + if (padlen) { + padlen = JSXDR_ALIGN - padlen; + nbytes += padlen; + } if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes))) - goto bad; + goto bad; if (xdr->mode == JSXDR_ENCODE) { - for (i = 0; i < len; i++) - raw[i] = JSXDR_SWAB16(chars[i]); + for (i = 0; i < len; i++) + raw[i] = JSXDR_SWAB16(chars[i]); + if (padlen) + memset((char *)raw + nbytes - padlen, 0, padlen); } else if (xdr->mode == JSXDR_DECODE) { - for (i = 0; i < len; i++) - chars[i] = JSXDR_SWAB16(raw[i]); + for (i = 0; i < len; i++) + chars[i] = JSXDR_SWAB16(raw[i]); chars[len] = 0; - if (!(*strp = JS_NewUCString(xdr->cx, chars, len))) - goto bad; + if (!(*strp = JS_NewUCString(xdr->cx, chars, len))) + goto bad; } return JS_TRUE; bad: if (xdr->mode == JSXDR_DECODE) - JS_free(xdr->cx, chars); + JS_free(xdr->cx, chars); return JS_FALSE; } @@ -418,10 +439,10 @@ JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp) { uint32 null = (*strp == NULL); if (!JS_XDRUint32(xdr, &null)) - return JS_FALSE; + return JS_FALSE; if (null) { - *strp = NULL; - return JS_TRUE; + *strp = NULL; + return JS_TRUE; } return JS_XDRString(xdr, strp); } @@ -431,150 +452,213 @@ JS_XDRDouble(JSXDRState *xdr, jsdouble **dp) { jsdouble d; if (xdr->mode == JSXDR_ENCODE) - d = **dp; + d = **dp; #if IS_BIG_ENDIAN if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) || - !JS_XDRUint32(xdr, (uint32 *)&d)) -#else /* !IS_BIG_ENDIAN */ + !JS_XDRUint32(xdr, (uint32 *)&d)) +#else if (!JS_XDRUint32(xdr, (uint32 *)&d) || - !JS_XDRUint32(xdr, (uint32 *)&d + 1)) -#endif /* IS_BIG_ENDIAN */ - return JS_FALSE; + !JS_XDRUint32(xdr, (uint32 *)&d + 1)) +#endif + return JS_FALSE; if (xdr->mode == JSXDR_DECODE) { - *dp = JS_NewDouble(xdr->cx, d); - if (!*dp) - return JS_FALSE; + *dp = JS_NewDouble(xdr->cx, d); + if (!*dp) + return JS_FALSE; } return JS_TRUE; } +/* These are magic: see jsapi.h, near the top, for the real jsval tags. */ +#define JSVAL_XDRNULL 0x8 +#define JSVAL_XDRVOID 0xA + JS_PUBLIC_API(JSBool) JS_XDRValue(JSXDRState *xdr, jsval *vp) { - uint32 type = JSVAL_TAG(*vp); + uint32 type; + + if (xdr->mode == JSXDR_ENCODE) { + if (JSVAL_IS_NULL(*vp)) + type = JSVAL_XDRNULL; + else if (JSVAL_IS_VOID(*vp)) + type = JSVAL_XDRVOID; + else + type = JSVAL_TAG(*vp); + } if (!JS_XDRUint32(xdr, &type)) - return JS_FALSE; + return JS_FALSE; switch (type) { + case JSVAL_XDRNULL: + *vp = JSVAL_NULL; + break; + case JSVAL_XDRVOID: + *vp = JSVAL_VOID; + break; case JSVAL_STRING: { - JSString *str = JSVAL_TO_STRING(*vp); - if (!JS_XDRString(xdr, &str)) - return JS_FALSE; - if (xdr->mode == JSXDR_DECODE) - *vp = STRING_TO_JSVAL(str); - break; + JSString *str = JSVAL_TO_STRING(*vp); + if (!JS_XDRString(xdr, &str)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = STRING_TO_JSVAL(str); + break; } case JSVAL_DOUBLE: { - jsdouble *dp; - if (xdr->mode == JSXDR_ENCODE) - dp = JSVAL_TO_DOUBLE(*vp); - if (!JS_XDRDouble(xdr, &dp)) - return JS_FALSE; - if (xdr->mode == JSXDR_DECODE) - *vp = DOUBLE_TO_JSVAL(dp); - break; + jsdouble *dp; + if (xdr->mode == JSXDR_ENCODE) + dp = JSVAL_TO_DOUBLE(*vp); + if (!JS_XDRDouble(xdr, &dp)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = DOUBLE_TO_JSVAL(dp); + break; } case JSVAL_OBJECT: { - JSObject *obj; - if (xdr->mode == JSXDR_ENCODE) - obj = JSVAL_TO_OBJECT(*vp); - if (!js_XDRObject(xdr, &obj)) - return JS_FALSE; - if (xdr->mode == JSXDR_DECODE) - *vp = OBJECT_TO_JSVAL(obj); - break; + JSObject *obj; + if (xdr->mode == JSXDR_ENCODE) + obj = JSVAL_TO_OBJECT(*vp); + if (!js_XDRObject(xdr, &obj)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = OBJECT_TO_JSVAL(obj); + break; } case JSVAL_BOOLEAN: { - uint32 b; - if (xdr->mode == JSXDR_ENCODE) - b = (uint32)JSVAL_TO_BOOLEAN(*vp); - if (!JS_XDRUint32(xdr, &b)) - return JS_FALSE; - if (xdr->mode == JSXDR_DECODE) - *vp = BOOLEAN_TO_JSVAL((JSBool)b); - break; + uint32 b; + if (xdr->mode == JSXDR_ENCODE) + b = (uint32)JSVAL_TO_BOOLEAN(*vp); + if (!JS_XDRUint32(xdr, &b)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = BOOLEAN_TO_JSVAL((JSBool)b); + break; } - case JSVAL_VOID: - if (!JS_XDRUint32(xdr, (uint32 *)vp)) - return JS_FALSE; - break; default: { - char numBuf[12]; - if (type & JSVAL_INT) { - uint32 i; - if (xdr->mode == JSXDR_ENCODE) - i = JSVAL_TO_INT(*vp); - if (!JS_XDRUint32(xdr, &i)) - return JS_FALSE; - if (xdr->mode == JSXDR_DECODE) - *vp = INT_TO_JSVAL(i); - break; - } - JS_snprintf(numBuf, sizeof numBuf, "%#lx", type); - JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, - JSMSG_BAD_JVAL_TYPE, type); - return JS_FALSE; + char numBuf[12]; + if (type & JSVAL_INT) { + uint32 i; + if (xdr->mode == JSXDR_ENCODE) + i = (uint32) JSVAL_TO_INT(*vp); + if (!JS_XDRUint32(xdr, &i)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = INT_TO_JSVAL((int32) i); + break; + } + JS_snprintf(numBuf, sizeof numBuf, "%#lx", type); + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_BAD_JVAL_TYPE, type); + return JS_FALSE; } } return JS_TRUE; } - -JS_PUBLIC_API(void) -JS_XDRDestroy(JSXDRState *xdr) +JS_PUBLIC_API(JSBool) +JS_XDRScript(JSXDRState *xdr, JSScript **scriptp) { - JSContext *cx = xdr->cx; - xdr->ops->finalize(xdr); - if (xdr->registry) - JS_free(cx, xdr->registry); - JS_free(cx, xdr); + JSBool hasMagic; + + return js_XDRScript(xdr, scriptp, &hasMagic); } -#define REGISTRY_CHUNK 4 +#define CLASS_REGISTRY_MIN 8 +#define CLASS_INDEX_TO_ID(i) ((i)+1) +#define CLASS_ID_TO_INDEX(id) ((id)-1) + +typedef struct JSRegHashEntry { + JSDHashEntryHdr hdr; + const char *name; + uint32 index; +} JSRegHashEntry; JS_PUBLIC_API(JSBool) -JS_RegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp) +JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp) { - uintN nclasses; + uintN numclasses, maxclasses; JSClass **registry; - nclasses = xdr->nclasses; - if (nclasses == 0) { - registry = (JSClass **) - JS_malloc(xdr->cx, REGISTRY_CHUNK * sizeof(JSClass *)); - } else if (nclasses % REGISTRY_CHUNK == 0) { - registry = (JSClass **) - JS_realloc(xdr->cx, - xdr->registry, - (nclasses + REGISTRY_CHUNK) * sizeof(JSClass *)); + numclasses = xdr->numclasses; + maxclasses = xdr->maxclasses; + if (numclasses == maxclasses) { + maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1; + registry = (JSClass **) + JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *)); + if (!registry) + return JS_FALSE; + xdr->registry = registry; + xdr->maxclasses = maxclasses; } else { + JS_ASSERT(numclasses && numclasses < maxclasses); registry = xdr->registry; } - if (!registry) - return JS_FALSE; - registry[nclasses++] = clasp; - xdr->registry = registry; - xdr->nclasses = nclasses; - *idp = nclasses; + + registry[numclasses] = clasp; + if (xdr->reghash) { + JSRegHashEntry *entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD); + if (!entry) { + JS_ReportOutOfMemory(xdr->cx); + return JS_FALSE; + } + entry->name = clasp->name; + entry->index = numclasses; + } + *idp = CLASS_INDEX_TO_ID(numclasses); + xdr->numclasses = ++numclasses; return JS_TRUE; } JS_PUBLIC_API(uint32) -JS_FindClassIdByName(JSXDRState *xdr, const char *name) +JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name) { - uintN i; + uintN i, numclasses; - for (i = 0; i < xdr->nclasses; i++) { - if (!strcmp(name, xdr->registry[i]->name)) - return i+1; + numclasses = xdr->numclasses; + if (numclasses >= 10) { + JSRegHashEntry *entry; + + /* Bootstrap reghash from registry on first overpopulated Find. */ + if (!xdr->reghash) { + xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL, + sizeof(JSRegHashEntry), + numclasses); + if (xdr->reghash) { + for (i = 0; i < numclasses; i++) { + JSClass *clasp = xdr->registry[i]; + entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, clasp->name, + JS_DHASH_ADD); + entry->name = clasp->name; + entry->index = i; + } + } + } + + /* If we managed to create reghash, use it for O(1) Find. */ + if (xdr->reghash) { + entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP); + if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) + return CLASS_INDEX_TO_ID(entry->index); + } + } + + /* Only a few classes, or we couldn't malloc reghash: use linear search. */ + for (i = 0; i < numclasses; i++) { + if (!strcmp(name, xdr->registry[i]->name)) + return CLASS_INDEX_TO_ID(i); } return 0; } JS_PUBLIC_API(JSClass *) -JS_FindClassById(JSXDRState *xdr, uint32 id) +JS_XDRFindClassById(JSXDRState *xdr, uint32 id) { - if (id > xdr->nclasses) - return NULL; - return xdr->registry[id-1]; + uintN i = CLASS_ID_TO_INDEX(id); + + if (i >= xdr->numclasses) + return NULL; + return xdr->registry[i]; } diff --git a/js/src/jsxdrapi.h b/js/src/jsxdrapi.h index 34eddd1b41cd..22a1f9a45954 100644 --- a/js/src/jsxdrapi.h +++ b/js/src/jsxdrapi.h @@ -66,11 +66,11 @@ JS_BEGIN_EXTERN_C #define JSXDR_SWAB32(x) x #define JSXDR_SWAB16(x) x #elif defined IS_BIG_ENDIAN -#define JSXDR_SWAB32(x) (((x) >> 24) | \ - (((x) >> 8) & 0xff00) | \ - (((x) << 8) & 0xff0000) | \ - ((x) << 24)) -#define JSXDR_SWAB16(x) (((x) >> 8) | ((x) << 8)) +#define JSXDR_SWAB32(x) (((uint32)(x) >> 24) | \ + (((uint32)(x) >> 8) & 0xff00) | \ + (((uint32)(x) << 8) & 0xff0000) | \ + ((uint32)(x) << 24)) +#define JSXDR_SWAB16(x) (((uint16)(x) >> 8) | ((uint16)(x) << 8)) #else #error "unknown byte order" #endif @@ -105,12 +105,14 @@ struct JSXDRState { JSXDROps *ops; JSContext *cx; JSClass **registry; - uintN nclasses; + uintN numclasses; + uintN maxclasses; + void *reghash; void *data; }; extern JS_PUBLIC_API(void) -JS_XDRNewBase(JSContext *cx, JSXDRState *xdr, JSXDRMode mode); +JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx); extern JS_PUBLIC_API(JSXDRState *) JS_XDRNewMem(JSContext *cx, JSXDRMode mode); @@ -155,16 +157,20 @@ extern JS_PUBLIC_API(JSBool) JS_XDRValue(JSXDRState *xdr, jsval *vp); extern JS_PUBLIC_API(JSBool) -JS_RegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp); +JS_XDRScript(JSXDRState *xdr, JSScript **scriptp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp); extern JS_PUBLIC_API(uint32) -JS_FindClassIdByName(JSXDRState *xdr, const char *name); +JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name); extern JS_PUBLIC_API(JSClass *) -JS_FindClassById(JSXDRState *xdr, uint32 id); - -/* Magic values */ +JS_XDRFindClassById(JSXDRState *xdr, uint32 id); +/* + * Magic numbers. + */ #define JSXDR_MAGIC_SCRIPT_1 0xdead0001 #define JSXDR_MAGIC_SCRIPT_2 0xdead0002 #define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_2