From d12c3005eb049a0844e2383df58daba493f09ab3 Mon Sep 17 00:00:00 2001 From: "timeless@mozdev.org" Date: Sat, 13 Oct 2007 13:09:48 -0700 Subject: [PATCH] Bug 397239 ActionMonkey: Remove "extra" parameter to JS_FN patch by Jason Orendorff r=igor a=brendan --- js/src/js.c | 22 ++-- js/src/jsapi.h | 4 +- js/src/jsarray.c | 315 ++++++++++++++++++++++++++-------------------- js/src/jsbool.c | 6 +- js/src/jsdate.c | 96 +++++++------- js/src/jsexn.c | 58 +++++---- js/src/jsfun.c | 10 +- js/src/jsinterp.c | 8 +- js/src/jsiter.c | 14 +-- js/src/jsmath.c | 38 +++--- js/src/jsnum.c | 22 ++-- js/src/jsobj.c | 60 +++++---- js/src/jsregexp.c | 10 +- js/src/jsscript.c | 14 +-- js/src/jsstr.c | 90 ++++++------- js/src/jsxml.c | 90 ++++++------- 16 files changed, 463 insertions(+), 394 deletions(-) diff --git a/js/src/js.c b/js/src/js.c index 5ab41eaccb4..be3636fc32d 100644 --- a/js/src/js.c +++ b/js/src/js.c @@ -2428,27 +2428,27 @@ static JSFunctionSpec shell_functions[] = { JS_FS("version", Version, 0,0,0), JS_FS("options", Options, 0,0,0), JS_FS("load", Load, 1,0,0), - JS_FN("readline", ReadLine, 0,0,0,0), + JS_FN("readline", ReadLine, 0,0,0), JS_FS("print", Print, 0,0,0), JS_FS("help", Help, 0,0,0), JS_FS("quit", Quit, 0,0,0), - JS_FN("gc", GC, 0,0,0,0), - JS_FN("countHeap", CountHeap, 0,0,0,0), + JS_FN("gc", GC, 0,0,0), + JS_FN("countHeap", CountHeap, 0,0,0), #ifdef JS_GC_ZEAL - JS_FN("gczeal", GCZeal, 1,1,0,0), + JS_FN("gczeal", GCZeal, 1,1,0), #endif JS_FS("trap", Trap, 3,0,0), JS_FS("untrap", Untrap, 2,0,0), JS_FS("line2pc", LineToPC, 0,0,0), JS_FS("pc2line", PCToLine, 0,0,0), - JS_FN("stackQuota", StackQuota, 0,0,0,0), + JS_FN("stackQuota", StackQuota, 0,0,0), JS_FS("stringsAreUTF8", StringsAreUTF8, 0,0,0), JS_FS("testUTF8", TestUTF8, 1,0,0), JS_FS("throwError", ThrowError, 0,0,0), #ifdef DEBUG JS_FS("dis", Disassemble, 1,0,0), JS_FS("dissrc", DisassWithSrc, 1,0,0), - JS_FN("dumpHeap", DumpHeap, 0,0,0,0), + JS_FN("dumpHeap", DumpHeap, 0,0,0), JS_FS("notes", Notes, 1,0,0), JS_FS("tracing", Tracing, 0,0,0), JS_FS("stats", DumpStats, 1,0,0), @@ -2459,14 +2459,14 @@ static JSFunctionSpec shell_functions[] = { #ifdef TEST_CVTARGS JS_FS("cvtargs", ConvertArgs, 0,0,12), #endif - JS_FN("build", BuildDate, 0,0,0,0), + JS_FN("build", BuildDate, 0,0,0), JS_FS("clear", Clear, 0,0,0), - JS_FN("intern", Intern, 1,1,0,0), + JS_FN("intern", Intern, 1,1,0), JS_FS("clone", Clone, 1,0,0), JS_FS("seal", Seal, 1,0,1), - JS_FN("getpda", GetPDA, 1,1,0,0), - JS_FN("getslx", GetSLX, 1,1,0,0), - JS_FN("toint32", ToInt32, 1,1,0,0), + JS_FN("getpda", GetPDA, 1,1,0), + JS_FN("getslx", GetSLX, 1,1,0), + JS_FN("toint32", ToInt32, 1,1,0), JS_FS("evalcx", EvalInContext, 1,0,0), JS_FS_END }; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 06da165a851..2b5454396c2 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1447,9 +1447,9 @@ struct JSFunctionSpec { * in preference to JS_FS if the native in question does not need its own stack * frame when activated. */ -#define JS_FN(name,fastcall,minargs,nargs,flags,extra) \ +#define JS_FN(name,fastcall,minargs,nargs,flags) \ {name, (JSNative)(fastcall), nargs, (flags) | JSFUN_FAST_NATIVE, \ - (minargs) << 16 | (uint16)(extra)} + (minargs) << 16} extern JS_PUBLIC_API(JSObject *) JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, diff --git a/js/src/jsarray.c b/js/src/jsarray.c index d1fb5dfbede..e7a5b182e2a 100644 --- a/js/src/jsarray.c +++ b/js/src/jsarray.c @@ -811,33 +811,30 @@ static JSBool array_reverse(JSContext *cx, uintN argc, jsval *vp) { JSObject *obj; - jsval *argv, *tmproot, *tmproot2; + JSTempValueRooter tvr; jsuint len, half, i; - JSBool hole, hole2; + JSBool ok, hole, hole2; obj = JS_THIS_OBJECT(cx, vp); if (!js_GetLengthProperty(cx, obj, &len)) return JS_FALSE; - /* - * Use argv[argc] and argv[argc + 1] as local roots to hold temporarily - * array elements for GC-safe swap. - */ - argv = JS_ARGV(cx, vp); - tmproot = argv + argc; - tmproot2 = argv + argc + 1; + ok = JS_TRUE; + JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr); half = len / 2; for (i = 0; i < half; i++) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, obj, i, &hole, tmproot) || - !GetArrayElement(cx, obj, len - i - 1, &hole2, tmproot2) || - !SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, *tmproot) || - !SetOrDeleteArrayElement(cx, obj, i, hole2, *tmproot2)) { - return JS_FALSE; - } + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, obj, i, &hole, &tvr.u.value) && + GetArrayElement(cx, obj, len - i - 1, &hole2, vp) && + SetOrDeleteArrayElement(cx, obj, len - i - 1, hole, tvr.u.value) && + SetOrDeleteArrayElement(cx, obj, i, hole2, *vp); + if (!ok) + break; } + JS_POP_TEMP_ROOT(cx, &tvr); + *vp = OBJECT_TO_JSVAL(obj); - return JS_TRUE; + return ok; } typedef struct MSortArgs { @@ -1127,20 +1124,30 @@ array_sort(JSContext *cx, uintN argc, jsval *vp) } /* - * We need a temporary array of 2 * len jsvals to hold the array elements. - * Check that its size does not overflow size_t, which would allow for - * indexing beyond the end of the malloc'd vector. + * We need a temporary array of 2 * len + 1 jsvals to hold the array + * elements and a temporary root. Check that its size does not overflow + * size_t, which would allow for indexing beyond the end of the malloc'd + * vector. + * + * The overflow occurs when, mathematically, + * (2 * len + 1) * sizeof(jsval) > MAX_SIZE_T . + * But as a C expression this is always false, due to exactly the overflow + * condition we're trying to detect and avoid. So we rearrange: + * (2 * len + 1) * sizeof(jsval) > MAX_SIZE_T + * 2 * len + 1 > MAX_SIZE_T / sizeof(jsval) + * 2 * len > MAX_SIZE_T / sizeof(jsval) - 1 + * len > (MAX_SIZE_T / sizeof(jsval) - 1) / 2 */ - if (len > (size_t)-1 / (2 * sizeof(jsval))) { + if (len > ((size_t)-1 / sizeof(jsval) - 1) / 2) { JS_ReportOutOfMemory(cx); return JS_FALSE; } /* * Allocate 2 * len instead of len, to reserve space for the mergesort - * algorithm. + * algorithm; plus 1 for an additional temporary root. */ - vec = (jsval *) JS_malloc(cx, 2 * (size_t)len * sizeof(jsval)); + vec = (jsval *) JS_malloc(cx, (2 * (size_t)len + 1) * sizeof(jsval)); if (!vec) return JS_FALSE; @@ -1197,9 +1204,10 @@ array_sort(JSContext *cx, uintN argc, jsval *vp) * The first newlen elements of vec are copied from the array * object (above). * - * Of the remaining 2*len-newlen positions, newlen are used as GC - * rooted temp space for mergesort, and the last (2*len-2*newlen) - * positions are unused. + * Of the remaining 2*len-newlen positions, newlen are used as GC rooted + * temp space for mergesort and the last (2*len-2*newlen+1) positions are + * unused (except when all_strings is false, in which case one more + * element is used for ca.localroot below). * * Here we clear the tmp-values before GC-rooting the array. * We assume JSVAL_NULL==0 to optimize initialization using memset. @@ -1215,7 +1223,9 @@ array_sort(JSContext *cx, uintN argc, jsval *vp) } else { ca.context = cx; ca.fval = fval; - ca.localroot = argv + argc; /* local GC root for temporary string */ + /* local GC root for temporary string */ + ca.localroot = &vec[tvr.count++]; + *ca.localroot = JSVAL_NULL; ok = js_MergeSort(vec, (size_t) newlen, sizeof(jsval), sort_compare, &ca, mergesort_tmp); } @@ -1335,7 +1345,8 @@ array_shift(JSContext *cx, uintN argc, jsval *vp) { JSObject *obj; jsuint length, i; - JSBool hole; + JSBool hole, ok; + JSTempValueRooter tvr; obj = JS_THIS_OBJECT(cx, vp); if (!js_GetLengthProperty(cx, obj, &length)) @@ -1349,17 +1360,19 @@ array_shift(JSContext *cx, uintN argc, jsval *vp) if (!GetArrayElement(cx, obj, 0, &hole, vp)) return JS_FALSE; - /* - * Slide down the array above the first element, using our stack-local - * GC root at vp[2]. - */ + /* Slide down the array above the first element. */ + ok = JS_TRUE; + JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr); for (i = 0; i != length; i++) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, obj, i + 1, &hole, &vp[2]) || - !SetOrDeleteArrayElement(cx, obj, i, hole, vp[2])) { - return JS_FALSE; - } + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, obj, i + 1, &hole, &tvr.u.value) && + SetOrDeleteArrayElement(cx, obj, i, hole, tvr.u.value); + if (!ok) + break; } + JS_POP_TEMP_ROOT(cx, &tvr); + if (!ok) + return JS_FALSE; /* Delete the only or last element when it exist. */ if (!hole && !DeleteArrayElement(cx, obj, length)) @@ -1372,9 +1385,10 @@ static JSBool array_unshift(JSContext *cx, uintN argc, jsval *vp) { JSObject *obj; - jsval *argv, *localroot; + jsval *argv; jsuint length, last; - JSBool hole; + JSBool hole, ok; + JSTempValueRooter tvr; obj = JS_THIS_OBJECT(cx, vp); if (!js_GetLengthProperty(cx, obj, &length)) @@ -1384,16 +1398,20 @@ array_unshift(JSContext *cx, uintN argc, jsval *vp) argv = JS_ARGV(cx, vp); if (length > 0) { last = length; - localroot = argv + argc; + ok = JS_TRUE; + JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr); do { --last; - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, obj, last, &hole, localroot) || - !SetOrDeleteArrayElement(cx, obj, last + argc, hole, - *localroot)) { - return JS_FALSE; - } + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, obj, last, &hole, &tvr.u.value) && + SetOrDeleteArrayElement(cx, obj, last + argc, hole, + tvr.u.value); + if (!ok) + break; } while (last != 0); + JS_POP_TEMP_ROOT(cx, &tvr); + if (!ok) + return JS_FALSE; } /* Copy from argv to the bottom of the array. */ @@ -1412,21 +1430,18 @@ array_unshift(JSContext *cx, uintN argc, jsval *vp) static JSBool array_splice(JSContext *cx, uintN argc, jsval *vp) { - jsval *argv, *localroot; + jsval *argv; JSObject *obj; jsuint length, begin, end, count, delta, last; jsdouble d; - JSBool hole; + JSBool hole, ok; JSObject *obj2; + JSTempValueRooter tvr; - /* - * Nothing to do if no args. Otherwise point localroot at our single - * stack-local root and get length. - */ + /* Nothing to do if no args. Otherwise get length. */ if (argc == 0) return JS_TRUE; argv = JS_ARGV(cx, vp); - localroot = argv + argc; obj = JS_THIS_OBJECT(cx, vp); if (!js_GetLengthProperty(cx, obj, &length)) return JS_FALSE; @@ -1465,7 +1480,6 @@ array_splice(JSContext *cx, uintN argc, jsval *vp) argv++; } - /* * Create a new array value to return. Our ECMA v2 proposal specs * that splice always returns an array value, even when given no @@ -1477,21 +1491,28 @@ array_splice(JSContext *cx, uintN argc, jsval *vp) return JS_FALSE; *vp = OBJECT_TO_JSVAL(obj2); + /* After this, control must flow through label out: to exit. */ + JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr); + /* If there are elements to remove, put them into the return value. */ if (count > 0) { for (last = begin; last < end; last++) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, obj, last, &hole, localroot)) { - return JS_FALSE; - } + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, obj, last, &hole, &tvr.u.value); + if (!ok) + goto out; - /* Copy *localroot to new array unless it's a hole. */ - if (!hole && !SetArrayElement(cx, obj2, last - begin, *localroot)) - return JS_FALSE; + /* Copy tvr.u.value to new array unless it's a hole. */ + if (!hole) { + ok = SetArrayElement(cx, obj2, last - begin, tvr.u.value); + if (!ok) + goto out; + } } - if (!js_SetLengthProperty(cx, obj2, end - begin)) - return JS_FALSE; + ok = js_SetLengthProperty(cx, obj2, end - begin); + if (!ok) + goto out; } /* Find the direction (up or down) to copy and make way for argv. */ @@ -1500,33 +1521,38 @@ array_splice(JSContext *cx, uintN argc, jsval *vp) last = length; /* (uint) end could be 0, so can't use vanilla >= test */ while (last-- > end) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, obj, last, &hole, localroot) || - !SetOrDeleteArrayElement(cx, obj, last + delta, hole, - *localroot)) { - return JS_FALSE; - } + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, obj, last, &hole, &tvr.u.value) && + SetOrDeleteArrayElement(cx, obj, last + delta, hole, + tvr.u.value); + if (!ok) + goto out; } length += delta; } else if (argc < count) { delta = count - (jsuint)argc; for (last = end; last < length; last++) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, obj, last, &hole, localroot) || - !SetOrDeleteArrayElement(cx, obj, last - delta, hole, - *localroot)) { - return JS_FALSE; - } + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, obj, last, &hole, &tvr.u.value) && + SetOrDeleteArrayElement(cx, obj, last - delta, hole, + tvr.u.value); + if (!ok) + goto out; } length -= delta; } /* Copy from argv into the hole to complete the splice. */ - if (!InitArrayElements(cx, obj, begin, begin + argc, argv)) - return JS_FALSE; + ok = InitArrayElements(cx, obj, begin, begin + argc, argv); + if (!ok) + goto out; /* Update length in case we deleted elements from the end. */ - return js_SetLengthProperty(cx, obj, length); + ok = js_SetLengthProperty(cx, obj, length); + +out: + JS_POP_TEMP_ROOT(cx, &tvr); + return ok; } /* @@ -1535,18 +1561,15 @@ array_splice(JSContext *cx, uintN argc, jsval *vp) static JSBool array_concat(JSContext *cx, uintN argc, jsval *vp) { - jsval *argv, *localroot, v; + jsval *argv, v; JSObject *nobj, *aobj; jsuint length, alength, slot; uintN i; - JSBool hole; - - /* Hoist the explicit local root address computation. */ - argv = JS_ARGV(cx, vp); - localroot = argv + argc; + JSBool hole, ok; + JSTempValueRooter tvr; /* Treat our |this| object as the first argument; see ECMA 15.4.4.4. */ - --argv; + argv = JS_ARGV(cx, vp) - 1; JS_ASSERT(JS_THIS_OBJECT(cx, vp) == JSVAL_TO_OBJECT(argv[0])); /* Create a new Array object and root it using *vp. */ @@ -1555,36 +1578,44 @@ array_concat(JSContext *cx, uintN argc, jsval *vp) return JS_FALSE; *vp = OBJECT_TO_JSVAL(nobj); + /* After this, control must flow through label out: to exit. */ + JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr); + /* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */ length = 0; for (i = 0; i <= argc; i++) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP)) - return JS_FALSE; + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP); + if (!ok) + goto out; v = argv[i]; if (JSVAL_IS_OBJECT(v)) { aobj = JSVAL_TO_OBJECT(v); if (aobj && OBJ_GET_CLASS(cx, aobj) == &js_ArrayClass) { - if (!OBJ_GET_PROPERTY(cx, aobj, + ok = OBJ_GET_PROPERTY(cx, aobj, ATOM_TO_JSID(cx->runtime->atomState .lengthAtom), - localroot)) { - return JS_FALSE; - } - if (!ValueIsLength(cx, *localroot, &alength)) - return JS_FALSE; + &tvr.u.value); + if (!ok) + goto out; + ok = ValueIsLength(cx, tvr.u.value, &alength); + if (!ok) + goto out; for (slot = 0; slot < alength; slot++) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, aobj, slot, &hole, localroot)) { - return JS_FALSE; - } + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, aobj, slot, &hole, + &tvr.u.value); + if (!ok) + goto out; /* * Per ECMA 262, 15.4.4.4, step 9, ignore non-existent * properties. */ - if (!hole && - !SetArrayElement(cx, nobj, length + slot, *localroot)) { - return JS_FALSE; + if (!hole) { + ok = SetArrayElement(cx, nobj, length + slot, + tvr.u.value); + if (!ok) + goto out; } } length += alength; @@ -1592,26 +1623,30 @@ array_concat(JSContext *cx, uintN argc, jsval *vp) } } - if (!SetArrayElement(cx, nobj, length, v)) - return JS_FALSE; + ok = SetArrayElement(cx, nobj, length, v); + if (!ok) + goto out; length++; } - return js_SetLengthProperty(cx, nobj, length); + ok = js_SetLengthProperty(cx, nobj, length); + +out: + JS_POP_TEMP_ROOT(cx, &tvr); + return ok; } static JSBool array_slice(JSContext *cx, uintN argc, jsval *vp) { - jsval *argv, *localroot; + jsval *argv; JSObject *nobj, *obj; jsuint length, begin, end, slot; jsdouble d; - JSBool hole; + JSBool hole, ok; + JSTempValueRooter tvr; - /* Hoist the explicit local root address computation. */ argv = JS_ARGV(cx, vp); - localroot = argv + argc; /* Create a new Array object and root it using *vp. */ nobj = js_NewArrayObject(cx, 0, NULL); @@ -1656,15 +1691,25 @@ array_slice(JSContext *cx, uintN argc, jsval *vp) if (begin > end) begin = end; + /* After this, control must flow through label out: to exit. */ + JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr); + for (slot = begin; slot < end; slot++) { - if (!JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) || - !GetArrayElement(cx, obj, slot, &hole, localroot)) { - return JS_FALSE; + ok = JS_CHECK_OPERATION_LIMIT(cx, JSOW_JUMP) && + GetArrayElement(cx, obj, slot, &hole, &tvr.u.value); + if (!ok) + goto out; + if (!hole) { + ok = SetArrayElement(cx, nobj, slot - begin, tvr.u.value); + if (!ok) + goto out; } - if (!hole && !SetArrayElement(cx, nobj, slot - begin, *localroot)) - return JS_FALSE; } - return js_SetLengthProperty(cx, nobj, end - begin); + ok = js_SetLengthProperty(cx, nobj, end - begin); + +out: + JS_POP_TEMP_ROOT(cx, &tvr); + return ok; } #if JS_HAS_ARRAY_EXTRAS @@ -1995,35 +2040,35 @@ static JSPropertySpec array_props[] = { static JSFunctionSpec array_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, array_toSource, 0,0,0,0), + JS_FN(js_toSource_str, array_toSource, 0,0,0), #endif - JS_FN(js_toString_str, array_toString, 0,0,0,0), - JS_FN(js_toLocaleString_str,array_toLocaleString,0,0,0,0), + JS_FN(js_toString_str, array_toString, 0,0,0), + JS_FN(js_toLocaleString_str,array_toLocaleString,0,0,0), /* Perl-ish methods. */ - JS_FN("join", array_join, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("reverse", array_reverse, 0,0,JSFUN_GENERIC_NATIVE,2), - JS_FN("sort", array_sort, 0,1,JSFUN_GENERIC_NATIVE,1), - JS_FN("push", array_push, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("pop", array_pop, 0,0,JSFUN_GENERIC_NATIVE,0), - JS_FN("shift", array_shift, 0,0,JSFUN_GENERIC_NATIVE,1), - JS_FN("unshift", array_unshift, 0,1,JSFUN_GENERIC_NATIVE,1), - JS_FN("splice", array_splice, 0,2,JSFUN_GENERIC_NATIVE,1), + JS_FN("join", array_join, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("reverse", array_reverse, 0,0,JSFUN_GENERIC_NATIVE), + JS_FN("sort", array_sort, 0,1,JSFUN_GENERIC_NATIVE), + JS_FN("push", array_push, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("pop", array_pop, 0,0,JSFUN_GENERIC_NATIVE), + JS_FN("shift", array_shift, 0,0,JSFUN_GENERIC_NATIVE), + JS_FN("unshift", array_unshift, 0,1,JSFUN_GENERIC_NATIVE), + JS_FN("splice", array_splice, 0,2,JSFUN_GENERIC_NATIVE), /* Python-esque sequence methods. */ - JS_FN("concat", array_concat, 0,1,JSFUN_GENERIC_NATIVE,1), - JS_FN("slice", array_slice, 0,2,JSFUN_GENERIC_NATIVE,1), + JS_FN("concat", array_concat, 0,1,JSFUN_GENERIC_NATIVE), + JS_FN("slice", array_slice, 0,2,JSFUN_GENERIC_NATIVE), #if JS_HAS_ARRAY_EXTRAS - JS_FN("indexOf", array_indexOf, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("lastIndexOf", array_lastIndexOf, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("forEach", array_forEach, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("map", array_map, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("reduce", array_reduce, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("reduceRight", array_reduceRight, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("filter", array_filter, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("some", array_some, 1,1,JSFUN_GENERIC_NATIVE,0), - JS_FN("every", array_every, 1,1,JSFUN_GENERIC_NATIVE,0), + JS_FN("indexOf", array_indexOf, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("lastIndexOf", array_lastIndexOf, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("forEach", array_forEach, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("map", array_map, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("reduce", array_reduce, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("reduceRight", array_reduceRight, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("filter", array_filter, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("some", array_some, 1,1,JSFUN_GENERIC_NATIVE), + JS_FN("every", array_every, 1,1,JSFUN_GENERIC_NATIVE), #endif JS_FS_END diff --git a/js/src/jsbool.c b/js/src/jsbool.c index ae8520eeaa1..e196364bcc8 100644 --- a/js/src/jsbool.c +++ b/js/src/jsbool.c @@ -112,10 +112,10 @@ bool_valueOf(JSContext *cx, uintN argc, jsval *vp) static JSFunctionSpec boolean_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, bool_toSource, 0, 0, JSFUN_THISP_BOOLEAN,0), + JS_FN(js_toSource_str, bool_toSource, 0, 0, JSFUN_THISP_BOOLEAN), #endif - JS_FN(js_toString_str, bool_toString, 0, 0, JSFUN_THISP_BOOLEAN,0), - JS_FN(js_valueOf_str, bool_valueOf, 0, 0, JSFUN_THISP_BOOLEAN,0), + JS_FN(js_toString_str, bool_toString, 0, 0, JSFUN_THISP_BOOLEAN), + JS_FN(js_valueOf_str, bool_valueOf, 0, 0, JSFUN_THISP_BOOLEAN), JS_FS_END }; diff --git a/js/src/jsdate.c b/js/src/jsdate.c index 4a522901361..6828d304948 100644 --- a/js/src/jsdate.c +++ b/js/src/jsdate.c @@ -1980,60 +1980,60 @@ date_valueOf(JSContext *cx, uintN argc, jsval *vp) */ static JSFunctionSpec date_static_methods[] = { - JS_FN("UTC", date_UTC, 2,MAXARGS,0,0), - JS_FN("parse", date_parse, 1,1,0,0), - JS_FN("now", date_now, 0,0,0,0), + JS_FN("UTC", date_UTC, 2,MAXARGS,0), + JS_FN("parse", date_parse, 1,1,0), + JS_FN("now", date_now, 0,0,0), JS_FS_END }; static JSFunctionSpec date_methods[] = { - JS_FN("getTime", date_getTime, 0,0,0,0), - JS_FN("getTimezoneOffset", date_getTimezoneOffset, 0,0,0,0), - JS_FN("getYear", date_getYear, 0,0,0,0), - JS_FN("getFullYear", date_getFullYear, 0,0,0,0), - JS_FN("getUTCFullYear", date_getUTCFullYear, 0,0,0,0), - JS_FN("getMonth", date_getMonth, 0,0,0,0), - JS_FN("getUTCMonth", date_getUTCMonth, 0,0,0,0), - JS_FN("getDate", date_getDate, 0,0,0,0), - JS_FN("getUTCDate", date_getUTCDate, 0,0,0,0), - JS_FN("getDay", date_getDay, 0,0,0,0), - JS_FN("getUTCDay", date_getUTCDay, 0,0,0,0), - JS_FN("getHours", date_getHours, 0,0,0,0), - JS_FN("getUTCHours", date_getUTCHours, 0,0,0,0), - JS_FN("getMinutes", date_getMinutes, 0,0,0,0), - JS_FN("getUTCMinutes", date_getUTCMinutes, 0,0,0,0), - JS_FN("getSeconds", date_getUTCSeconds, 0,0,0,0), - JS_FN("getUTCSeconds", date_getUTCSeconds, 0,0,0,0), - JS_FN("getMilliseconds", date_getUTCMilliseconds, 0,0,0,0), - JS_FN("getUTCMilliseconds", date_getUTCMilliseconds, 0,0,0,0), - JS_FN("setTime", date_setTime, 1,1,0,0), - JS_FN("setYear", date_setYear, 1,1,0,0), - JS_FN("setFullYear", date_setFullYear, 1,3,0,0), - JS_FN("setUTCFullYear", date_setUTCFullYear, 1,3,0,0), - JS_FN("setMonth", date_setMonth, 1,2,0,0), - JS_FN("setUTCMonth", date_setUTCMonth, 1,2,0,0), - JS_FN("setDate", date_setDate, 1,1,0,0), - JS_FN("setUTCDate", date_setUTCDate, 1,1,0,0), - JS_FN("setHours", date_setHours, 1,4,0,0), - JS_FN("setUTCHours", date_setUTCHours, 1,4,0,0), - JS_FN("setMinutes", date_setMinutes, 1,3,0,0), - JS_FN("setUTCMinutes", date_setUTCMinutes, 1,3,0,0), - JS_FN("setSeconds", date_setSeconds, 1,2,0,0), - JS_FN("setUTCSeconds", date_setUTCSeconds, 1,2,0,0), - JS_FN("setMilliseconds", date_setMilliseconds, 1,1,0,0), - JS_FN("setUTCMilliseconds", date_setUTCMilliseconds, 1,1,0,0), - JS_FN("toUTCString", date_toGMTString, 0,0,0,0), - JS_FN(js_toLocaleString_str, date_toLocaleString, 0,0,0,0), - JS_FN("toLocaleDateString", date_toLocaleDateString, 0,0,0,0), - JS_FN("toLocaleTimeString", date_toLocaleTimeString, 0,0,0,0), - JS_FN("toLocaleFormat", date_toLocaleFormat, 0,0,0,0), - JS_FN("toDateString", date_toDateString, 0,0,0,0), - JS_FN("toTimeString", date_toTimeString, 0,0,0,0), + JS_FN("getTime", date_getTime, 0,0,0), + JS_FN("getTimezoneOffset", date_getTimezoneOffset, 0,0,0), + JS_FN("getYear", date_getYear, 0,0,0), + JS_FN("getFullYear", date_getFullYear, 0,0,0), + JS_FN("getUTCFullYear", date_getUTCFullYear, 0,0,0), + JS_FN("getMonth", date_getMonth, 0,0,0), + JS_FN("getUTCMonth", date_getUTCMonth, 0,0,0), + JS_FN("getDate", date_getDate, 0,0,0), + JS_FN("getUTCDate", date_getUTCDate, 0,0,0), + JS_FN("getDay", date_getDay, 0,0,0), + JS_FN("getUTCDay", date_getUTCDay, 0,0,0), + JS_FN("getHours", date_getHours, 0,0,0), + JS_FN("getUTCHours", date_getUTCHours, 0,0,0), + JS_FN("getMinutes", date_getMinutes, 0,0,0), + JS_FN("getUTCMinutes", date_getUTCMinutes, 0,0,0), + JS_FN("getSeconds", date_getUTCSeconds, 0,0,0), + JS_FN("getUTCSeconds", date_getUTCSeconds, 0,0,0), + JS_FN("getMilliseconds", date_getUTCMilliseconds, 0,0,0), + JS_FN("getUTCMilliseconds", date_getUTCMilliseconds, 0,0,0), + JS_FN("setTime", date_setTime, 1,1,0), + JS_FN("setYear", date_setYear, 1,1,0), + JS_FN("setFullYear", date_setFullYear, 1,3,0), + JS_FN("setUTCFullYear", date_setUTCFullYear, 1,3,0), + JS_FN("setMonth", date_setMonth, 1,2,0), + JS_FN("setUTCMonth", date_setUTCMonth, 1,2,0), + JS_FN("setDate", date_setDate, 1,1,0), + JS_FN("setUTCDate", date_setUTCDate, 1,1,0), + JS_FN("setHours", date_setHours, 1,4,0), + JS_FN("setUTCHours", date_setUTCHours, 1,4,0), + JS_FN("setMinutes", date_setMinutes, 1,3,0), + JS_FN("setUTCMinutes", date_setUTCMinutes, 1,3,0), + JS_FN("setSeconds", date_setSeconds, 1,2,0), + JS_FN("setUTCSeconds", date_setUTCSeconds, 1,2,0), + JS_FN("setMilliseconds", date_setMilliseconds, 1,1,0), + JS_FN("setUTCMilliseconds", date_setUTCMilliseconds, 1,1,0), + JS_FN("toUTCString", date_toGMTString, 0,0,0), + JS_FN(js_toLocaleString_str, date_toLocaleString, 0,0,0), + JS_FN("toLocaleDateString", date_toLocaleDateString, 0,0,0), + JS_FN("toLocaleTimeString", date_toLocaleTimeString, 0,0,0), + JS_FN("toLocaleFormat", date_toLocaleFormat, 0,0,0), + JS_FN("toDateString", date_toDateString, 0,0,0), + JS_FN("toTimeString", date_toTimeString, 0,0,0), #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, date_toSource, 0,0,0,0), + JS_FN(js_toSource_str, date_toSource, 0,0,0), #endif - JS_FN(js_toString_str, date_toString, 0,0,0,0), - JS_FN(js_valueOf_str, date_valueOf, 0,0,0,0), + JS_FN(js_toString_str, date_toString, 0,0,0), + JS_FN(js_valueOf_str, date_valueOf, 0,0,0), JS_FS_END }; diff --git a/js/src/jsexn.c b/js/src/jsexn.c index eae0f7e3a24..8765ce43e7a 100644 --- a/js/src/jsexn.c +++ b/js/src/jsexn.c @@ -870,15 +870,15 @@ exn_toString(JSContext *cx, uintN argc, jsval *vp) static JSBool exn_toSource(JSContext *cx, uintN argc, jsval *vp) { - jsval *localroots; JSObject *obj; JSString *name, *message, *filename, *lineno_as_str, *result; + jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL}; + JSTempValueRooter tvr; + JSBool ok; uint32 lineno; size_t lineno_length, name_length, message_length, filename_length, length; jschar *chars, *cp; - localroots = JS_ARGV(cx, vp) + argc; - obj = JS_THIS_OBJECT(cx, vp); if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), @@ -890,27 +890,32 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp) return JS_FALSE; *vp = STRING_TO_JSVAL(name); - if (!JS_GetProperty(cx, obj, js_message_str, &localroots[0]) || - !(message = js_ValueToSource(cx, localroots[0]))) { - return JS_FALSE; - } + /* After this, control must flow through label out: to exit. */ + JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr); + + ok = JS_GetProperty(cx, obj, js_message_str, &localroots[0]) && + (message = js_ValueToSource(cx, localroots[0])); + if (!ok) + goto out; localroots[0] = STRING_TO_JSVAL(message); - if (!JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) || - !(filename = js_ValueToSource(cx, localroots[1]))) { - return JS_FALSE; - } + ok = JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) && + (filename = js_ValueToSource(cx, localroots[1])); + if (!ok) + goto out; localroots[1] = STRING_TO_JSVAL(filename); - if (!JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]) || - !js_ValueToECMAUint32 (cx, localroots[2], &lineno)) { - return JS_FALSE; - } + ok = JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]) && + js_ValueToECMAUint32 (cx, localroots[2], &lineno); + if (!ok) + goto out; if (lineno != 0) { lineno_as_str = js_ValueToString(cx, localroots[2]); - if (!lineno_as_str) - return JS_FALSE; + if (!lineno_as_str) { + ok = JS_FALSE; + goto out; + } lineno_length = JSSTRING_LENGTH(lineno_as_str); } else { lineno_as_str = NULL; @@ -941,8 +946,10 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp) } cp = chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); - if (!chars) - return JS_FALSE; + if (!chars) { + ok = JS_FALSE; + goto out; + } *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' '; js_strncpy(cp, JSSTRING_CHARS(name), name_length); @@ -979,18 +986,23 @@ exn_toSource(JSContext *cx, uintN argc, jsval *vp) result = js_NewString(cx, chars, length); if (!result) { JS_free(cx, chars); - return JS_FALSE; + ok = JS_FALSE; + goto out; } *vp = STRING_TO_JSVAL(result); - return JS_TRUE; + ok = JS_TRUE; + +out: + JS_POP_TEMP_ROOT(cx, &tvr); + return ok; } #endif static JSFunctionSpec exception_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, exn_toSource, 0,0,0,3), + JS_FN(js_toSource_str, exn_toSource, 0,0,0), #endif - JS_FN(js_toString_str, exn_toString, 0,0,0,0), + JS_FN(js_toString_str, exn_toString, 0,0,0), JS_FS_END }; diff --git a/js/src/jsfun.c b/js/src/jsfun.c index 227f8395a02..bfe227c804b 100644 --- a/js/src/jsfun.c +++ b/js/src/jsfun.c @@ -1781,13 +1781,13 @@ out: static JSFunctionSpec function_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, fun_toSource, 0,0,0,0), + JS_FN(js_toSource_str, fun_toSource, 0,0,0), #endif - JS_FN(js_toString_str, fun_toString, 0,0,0,0), - JS_FN("apply", fun_apply, 0,2,0,0), - JS_FN(call_str, fun_call, 0,1,0,0), + JS_FN(js_toString_str, fun_toString, 0,0,0), + JS_FN("apply", fun_apply, 0,2,0), + JS_FN(call_str, fun_call, 0,1,0), #ifdef NARCISSUS - JS_FN("__applyConstructor__", fun_applyConstructor, 0,1,0,0), + JS_FN("__applyConstructor__", fun_applyConstructor, 0,1,0), #endif JS_FS_END }; diff --git a/js/src/jsinterp.c b/js/src/jsinterp.c index 5db32e9b84f..a85a57f38df 100644 --- a/js/src/jsinterp.c +++ b/js/src/jsinterp.c @@ -4054,15 +4054,15 @@ interrupt: } if (fun->flags & JSFUN_FAST_NATIVE) { - uintN nargs = JS_MAX(argc, fun->u.n.minargs); + JS_ASSERT(fun->u.n.extra == 0); + if (argc < fun->u.n.minargs) { + uintN nargs; - nargs += fun->u.n.extra; - if (argc < nargs) { /* * If we can't fit missing args and local roots in * this frame's operand stack, take the slow path. */ - nargs -= argc; + nargs = fun->u.n.minargs - argc; if (sp + nargs > fp->spbase + depth) goto do_invoke; do { diff --git a/js/src/jsiter.c b/js/src/jsiter.c index 7047126fb53..7b4a38bc4ba 100644 --- a/js/src/jsiter.c +++ b/js/src/jsiter.c @@ -311,8 +311,8 @@ iterator_self(JSContext *cx, uintN argc, jsval *vp) #define JSPROP_ROPERM (JSPROP_READONLY | JSPROP_PERMANENT) static JSFunctionSpec iterator_methods[] = { - JS_FN(js_iterator_str, iterator_self, 0,0,JSPROP_ROPERM,0), - JS_FN(js_next_str, iterator_next, 0,0,JSPROP_ROPERM,0), + JS_FN(js_iterator_str, iterator_self, 0,0,JSPROP_ROPERM), + JS_FN(js_next_str, iterator_next, 0,0,JSPROP_ROPERM), JS_FS_END }; @@ -1033,11 +1033,11 @@ generator_close(JSContext *cx, uintN argc, jsval *vp) } static JSFunctionSpec generator_methods[] = { - JS_FN(js_iterator_str, iterator_self, 0,0,JSPROP_ROPERM,0), - JS_FN(js_next_str, generator_next, 0,0,JSPROP_ROPERM,0), - JS_FN(js_send_str, generator_send, 1,1,JSPROP_ROPERM,0), - JS_FN(js_throw_str, generator_throw, 1,1,JSPROP_ROPERM,0), - JS_FN(js_close_str, generator_close, 0,0,JSPROP_ROPERM,0), + JS_FN(js_iterator_str, iterator_self, 0,0,JSPROP_ROPERM), + JS_FN(js_next_str, generator_next, 0,0,JSPROP_ROPERM), + JS_FN(js_send_str, generator_send, 1,1,JSPROP_ROPERM), + JS_FN(js_throw_str, generator_throw, 1,1,JSPROP_ROPERM), + JS_FN(js_close_str, generator_close, 0,0,JSPROP_ROPERM), JS_FS_END }; diff --git a/js/src/jsmath.c b/js/src/jsmath.c index f7836bc0091..c98b1706279 100644 --- a/js/src/jsmath.c +++ b/js/src/jsmath.c @@ -478,26 +478,26 @@ math_toSource(JSContext *cx, uintN argc, jsval *vp) static JSFunctionSpec math_static_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, math_toSource, 0, 0, 0, 0), + JS_FN(js_toSource_str, math_toSource, 0, 0, 0), #endif - JS_FN("abs", math_abs, 1, 1, 0, 0), - JS_FN("acos", math_acos, 1, 1, 0, 0), - JS_FN("asin", math_asin, 1, 1, 0, 0), - JS_FN("atan", math_atan, 1, 1, 0, 0), - JS_FN("atan2", math_atan2, 2, 2, 0, 0), - JS_FN("ceil", math_ceil, 1, 1, 0, 0), - JS_FN("cos", math_cos, 1, 1, 0, 0), - JS_FN("exp", math_exp, 1, 1, 0, 0), - JS_FN("floor", math_floor, 1, 1, 0, 0), - JS_FN("log", math_log, 1, 1, 0, 0), - JS_FN("max", math_max, 0, 2, 0, 0), - JS_FN("min", math_min, 0, 2, 0, 0), - JS_FN("pow", math_pow, 2, 2, 0, 0), - JS_FN("random", math_random, 0, 0, 0, 0), - JS_FN("round", math_round, 1, 1, 0, 0), - JS_FN("sin", math_sin, 1, 1, 0, 0), - JS_FN("sqrt", math_sqrt, 1, 1, 0, 0), - JS_FN("tan", math_tan, 1, 1, 0, 0), + JS_FN("abs", math_abs, 1, 1, 0), + JS_FN("acos", math_acos, 1, 1, 0), + JS_FN("asin", math_asin, 1, 1, 0), + JS_FN("atan", math_atan, 1, 1, 0), + JS_FN("atan2", math_atan2, 2, 2, 0), + JS_FN("ceil", math_ceil, 1, 1, 0), + JS_FN("cos", math_cos, 1, 1, 0), + JS_FN("exp", math_exp, 1, 1, 0), + JS_FN("floor", math_floor, 1, 1, 0), + JS_FN("log", math_log, 1, 1, 0), + JS_FN("max", math_max, 0, 2, 0), + JS_FN("min", math_min, 0, 2, 0), + JS_FN("pow", math_pow, 2, 2, 0), + JS_FN("random", math_random, 0, 0, 0), + JS_FN("round", math_round, 1, 1, 0), + JS_FN("sin", math_sin, 1, 1, 0), + JS_FN("sqrt", math_sqrt, 1, 1, 0), + JS_FN("tan", math_tan, 1, 1, 0), JS_FS_END }; diff --git a/js/src/jsnum.c b/js/src/jsnum.c index ccf4a38e929..81ebddf7db2 100644 --- a/js/src/jsnum.c +++ b/js/src/jsnum.c @@ -148,10 +148,10 @@ const char js_parseFloat_str[] = "parseFloat"; const char js_parseInt_str[] = "parseInt"; static JSFunctionSpec number_functions[] = { - JS_FN(js_isNaN_str, num_isNaN, 1,1,0,0), - JS_FN(js_isFinite_str, num_isFinite, 1,1,0,0), - JS_FN(js_parseFloat_str, num_parseFloat, 1,1,0,0), - JS_FN(js_parseInt_str, num_parseInt, 1,2,0,0), + JS_FN(js_isNaN_str, num_isNaN, 1,1,0), + JS_FN(js_isFinite_str, num_isFinite, 1,1,0), + JS_FN(js_parseFloat_str, num_parseFloat, 1,1,0), + JS_FN(js_parseInt_str, num_parseInt, 1,2,0), JS_FS_END }; @@ -474,14 +474,14 @@ num_toPrecision(JSContext *cx, uintN argc, jsval *vp) static JSFunctionSpec number_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, num_toSource, 0,0,JSFUN_THISP_NUMBER,0), + JS_FN(js_toSource_str, num_toSource, 0,0,JSFUN_THISP_NUMBER), #endif - JS_FN(js_toString_str, num_toString, 0,0,JSFUN_THISP_NUMBER,0), - JS_FN(js_toLocaleString_str, num_toLocaleString, 0,0,JSFUN_THISP_NUMBER,0), - JS_FN(js_valueOf_str, num_valueOf, 0,0,JSFUN_THISP_NUMBER,0), - JS_FN("toFixed", num_toFixed, 1,1,JSFUN_THISP_NUMBER,0), - JS_FN("toExponential", num_toExponential, 1,1,JSFUN_THISP_NUMBER,0), - JS_FN("toPrecision", num_toPrecision, 1,1,JSFUN_THISP_NUMBER,0), + JS_FN(js_toString_str, num_toString, 0,0,JSFUN_THISP_NUMBER), + JS_FN(js_toLocaleString_str, num_toLocaleString, 0,0,JSFUN_THISP_NUMBER), + JS_FN(js_valueOf_str, num_valueOf, 0,0,JSFUN_THISP_NUMBER), + JS_FN("toFixed", num_toFixed, 1,1,JSFUN_THISP_NUMBER), + JS_FN("toExponential", num_toExponential, 1,1,JSFUN_THISP_NUMBER), + JS_FN("toPrecision", num_toPrecision, 1,1,JSFUN_THISP_NUMBER), JS_FS_END }; diff --git a/js/src/jsobj.c b/js/src/jsobj.c index d95537cbdd3..508c429b8d6 100644 --- a/js/src/jsobj.c +++ b/js/src/jsobj.c @@ -700,8 +700,6 @@ js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map) JS_HashTableEnumerateEntries(map->table, gc_sharp_table_entry_marker, trc); } -#define OBJ_TOSTRING_EXTRA 4 /* for 4 local GC roots */ - #if JS_HAS_TOSOURCE static JSBool obj_toSource(JSContext *cx, uintN argc, jsval *vp) @@ -722,6 +720,8 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp) uintN attrs; #endif jsval *val; + jsval localroot[4] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL, JSVAL_NULL}; + JSTempValueRooter tvr; JSString *gsopold[2]; JSString *gsop[2]; JSString *idstr, *valstr, *str; @@ -732,12 +732,17 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp) return JS_FALSE; } + /* After this, control must flow through out: to exit. */ + JS_PUSH_TEMP_ROOT(cx, 4, localroot, &tvr); + /* If outermost, we need parentheses to be an expression, not a block. */ outermost = (cx->sharpObjectMap.depth == 0); obj = JSVAL_TO_OBJECT(vp[1]); he = js_EnterSharpObject(cx, obj, &ida, &chars); - if (!he) - return JS_FALSE; + if (!he) { + ok = JS_FALSE; + goto out; + } if (IS_SHARP(he)) { /* * We didn't enter -- obj is already "sharp", meaning we've visited it @@ -833,10 +838,10 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp) /* * We have four local roots for cooked and raw value GC safety. Hoist the - * "vp + 4" out of the loop using the val local, which refers to the raw - * (unconverted, "uncooked") values. + * "localroot + 2" out of the loop using the val local, which refers to + * the raw (unconverted, "uncooked") values. */ - val = vp + 4; + val = localroot + 2; for (i = 0, length = ida->length; i < length; i++) { JSBool idIsLexicalIdentifier, needOldStyleGetterSetter; @@ -946,7 +951,7 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp) ok = JS_FALSE; goto error; } - vp[2 + j] = STRING_TO_JSVAL(valstr); /* local root */ + localroot[j] = STRING_TO_JSVAL(valstr); /* local root */ JSSTRING_CHARS_AND_LENGTH(valstr, vchars, vlength); if (vchars[0] == '#') @@ -1121,21 +1126,26 @@ obj_toSource(JSContext *cx, uintN argc, jsval *vp) if (!ok) { if (chars) free(chars); - return ok; + goto out; } if (!chars) { JS_ReportOutOfMemory(cx); - return JS_FALSE; + ok = JS_FALSE; + goto out; } make_string: str = js_NewString(cx, chars, nchars); if (!str) { free(chars); - return JS_FALSE; + ok = JS_FALSE; + goto out; } *vp = STRING_TO_JSVAL(str); - return JS_TRUE; + ok = JS_TRUE; + out: + JS_POP_TEMP_ROOT(cx, &tvr); + return ok; overflow: JS_free(cx, vsharp); @@ -1817,23 +1827,23 @@ const char js_lookupSetter_str[] = "__lookupSetter__"; static JSFunctionSpec object_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, obj_toSource, 0,0,0,OBJ_TOSTRING_EXTRA), + JS_FN(js_toSource_str, obj_toSource, 0,0,0), #endif - JS_FN(js_toString_str, obj_toString, 0,0,0,0), - JS_FN(js_toLocaleString_str, obj_toLocaleString, 0,0,0,0), - JS_FN(js_valueOf_str, obj_valueOf, 0,0,0,0), + JS_FN(js_toString_str, obj_toString, 0,0,0), + JS_FN(js_toLocaleString_str, obj_toLocaleString, 0,0,0), + JS_FN(js_valueOf_str, obj_valueOf, 0,0,0), #if JS_HAS_OBJ_WATCHPOINT - JS_FN(js_watch_str, obj_watch, 2,2,0,0), - JS_FN(js_unwatch_str, obj_unwatch, 1,1,0,0), + JS_FN(js_watch_str, obj_watch, 2,2,0), + JS_FN(js_unwatch_str, obj_unwatch, 1,1,0), #endif - JS_FN(js_hasOwnProperty_str, obj_hasOwnProperty, 1,1,0,0), - JS_FN(js_isPrototypeOf_str, obj_isPrototypeOf, 1,1,0,0), - JS_FN(js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,1,0,0), + JS_FN(js_hasOwnProperty_str, obj_hasOwnProperty, 1,1,0), + JS_FN(js_isPrototypeOf_str, obj_isPrototypeOf, 1,1,0), + JS_FN(js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,1,0), #if JS_HAS_GETTER_SETTER - JS_FN(js_defineGetter_str, obj_defineGetter, 2,2,0,0), - JS_FN(js_defineSetter_str, obj_defineSetter, 2,2,0,0), - JS_FN(js_lookupGetter_str, obj_lookupGetter, 1,1,0,0), - JS_FN(js_lookupSetter_str, obj_lookupSetter, 1,1,0,0), + JS_FN(js_defineGetter_str, obj_defineGetter, 2,2,0), + JS_FN(js_defineSetter_str, obj_defineSetter, 2,2,0), + JS_FN(js_lookupGetter_str, obj_lookupGetter, 1,1,0), + JS_FN(js_lookupSetter_str, obj_lookupSetter, 1,1,0), #endif JS_FS_END }; diff --git a/js/src/jsregexp.c b/js/src/jsregexp.c index d20cdba0014..0205b6f7e1a 100644 --- a/js/src/jsregexp.c +++ b/js/src/jsregexp.c @@ -4181,12 +4181,12 @@ regexp_test(JSContext *cx, uintN argc, jsval *vp) static JSFunctionSpec regexp_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, regexp_toString, 0,0,0,0), + JS_FN(js_toSource_str, regexp_toString, 0,0,0), #endif - JS_FN(js_toString_str, regexp_toString, 0,0,0,0), - JS_FN("compile", regexp_compile, 0,2,0,0), - JS_FN("exec", regexp_exec, 0,1,0,0), - JS_FN("test", regexp_test, 0,1,0,0), + JS_FN(js_toString_str, regexp_toString, 0,0,0), + JS_FN("compile", regexp_compile, 0,2,0), + JS_FN("exec", regexp_exec, 0,1,0), + JS_FN("test", regexp_test, 0,1,0), JS_FS_END }; diff --git a/js/src/jsscript.c b/js/src/jsscript.c index 32a72f1a96c..d013ebf375f 100644 --- a/js/src/jsscript.c +++ b/js/src/jsscript.c @@ -804,14 +804,14 @@ static const char js_thaw_str[] = "thaw"; static JSFunctionSpec script_methods[] = { #if JS_HAS_TOSOURCE - JS_FN(js_toSource_str, script_toSource, 0,0,0,0), + JS_FN(js_toSource_str, script_toSource, 0,0,0), #endif - JS_FN(js_toString_str, script_toString, 0,0,0,0), - JS_FN("compile", script_compile, 0,2,0,0), - JS_FN("exec", script_exec, 0,1,0,0), + JS_FN(js_toString_str, script_toString, 0,0,0), + JS_FN("compile", script_compile, 0,2,0), + JS_FN("exec", script_exec, 0,1,0), #if JS_HAS_XDR_FREEZE_THAW - JS_FN("freeze", script_freeze, 0,0,0,0), - JS_FN(js_thaw_str, script_thaw, 0,1,0,0), + JS_FN("freeze", script_freeze, 0,0,0), + JS_FN(js_thaw_str, script_thaw, 0,1,0), #endif /* JS_HAS_XDR_FREEZE_THAW */ JS_FS_END }; @@ -904,7 +904,7 @@ script_static_thaw(JSContext *cx, uintN argc, jsval *vp) } static JSFunctionSpec script_static_methods[] = { - JS_FN(js_thaw_str, script_static_thaw, 1,1,0,0), + JS_FN(js_thaw_str, script_static_thaw, 1,1,0), JS_FS_END }; diff --git a/js/src/jsstr.c b/js/src/jsstr.c index 7f240725c85..3ab92fde343 100644 --- a/js/src/jsstr.c +++ b/js/src/jsstr.c @@ -482,15 +482,15 @@ const char js_decodeURIComponent_str[] = "decodeURIComponent"; const char js_encodeURIComponent_str[] = "encodeURIComponent"; static JSFunctionSpec string_functions[] = { - JS_FN(js_escape_str, str_escape, 1,1,0,0), - JS_FN(js_unescape_str, str_unescape, 1,1,0,0), + JS_FN(js_escape_str, str_escape, 1,1,0), + JS_FN(js_unescape_str, str_unescape, 1,1,0), #if JS_HAS_UNEVAL - JS_FN(js_uneval_str, str_uneval, 1,1,0,0), + JS_FN(js_uneval_str, str_uneval, 1,1,0), #endif - JS_FN(js_decodeURI_str, str_decodeURI, 1,1,0,0), - JS_FN(js_encodeURI_str, str_encodeURI, 1,1,0,0), - JS_FN(js_decodeURIComponent_str, str_decodeURI_Component, 1,1,0,0), - JS_FN(js_encodeURIComponent_str, str_encodeURI_Component, 1,1,0,0), + JS_FN(js_decodeURI_str, str_decodeURI, 1,1,0), + JS_FN(js_encodeURI_str, str_encodeURI, 1,1,0), + JS_FN(js_decodeURIComponent_str, str_decodeURI_Component, 1,1,0), + JS_FN(js_encodeURIComponent_str, str_encodeURI_Component, 1,1,0), JS_FS_END }; @@ -1285,16 +1285,18 @@ match_glob(JSContext *cx, jsint count, GlobData *data) static JSBool str_match(JSContext *cx, uintN argc, jsval *vp) { + JSTempValueRooter tvr; MatchData mdata; JSBool ok; + JS_PUSH_SINGLE_TEMP_ROOT(cx, JSVAL_NULL, &tvr); mdata.base.flags = MODE_MATCH; mdata.base.optarg = 1; - mdata.arrayval = &vp[4]; - *mdata.arrayval = JSVAL_NULL; + mdata.arrayval = &tvr.u.value; ok = match_or_replace(cx, match_glob, NULL, &mdata.base, argc, vp); if (ok && !JSVAL_IS_NULL(*mdata.arrayval)) *vp = *mdata.arrayval; + JS_POP_TEMP_ROOT(cx, &tvr); return ok; } @@ -2227,52 +2229,52 @@ str_sub(JSContext *cx, uintN argc, jsval *vp) static JSFunctionSpec string_methods[] = { #if JS_HAS_TOSOURCE - JS_FN("quote", str_quote, 0,0,GENERIC_PRIMITIVE,0), - JS_FN(js_toSource_str, str_toSource, 0,0,JSFUN_THISP_STRING,0), + JS_FN("quote", str_quote, 0,0,GENERIC_PRIMITIVE), + JS_FN(js_toSource_str, str_toSource, 0,0,JSFUN_THISP_STRING), #endif /* Java-like methods. */ - JS_FN(js_toString_str, str_toString, 0,0,JSFUN_THISP_STRING,0), - JS_FN(js_valueOf_str, str_toString, 0,0,JSFUN_THISP_STRING,0), - JS_FN("substring", str_substring, 0,2,GENERIC_PRIMITIVE,0), - JS_FN("toLowerCase", str_toLowerCase, 0,0,GENERIC_PRIMITIVE,0), - JS_FN("toUpperCase", str_toUpperCase, 0,0,GENERIC_PRIMITIVE,0), - JS_FN("charAt", str_charAt, 1,1,GENERIC_PRIMITIVE,0), - JS_FN("charCodeAt", str_charCodeAt, 1,1,GENERIC_PRIMITIVE,0), - JS_FN("indexOf", str_indexOf, 1,1,GENERIC_PRIMITIVE,0), - JS_FN("lastIndexOf", str_lastIndexOf, 1,1,GENERIC_PRIMITIVE,0), - JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,0,GENERIC_PRIMITIVE,0), - JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,0,GENERIC_PRIMITIVE,0), - JS_FN("localeCompare", str_localeCompare, 1,1,GENERIC_PRIMITIVE,0), + JS_FN(js_toString_str, str_toString, 0,0,JSFUN_THISP_STRING), + JS_FN(js_valueOf_str, str_toString, 0,0,JSFUN_THISP_STRING), + JS_FN("substring", str_substring, 0,2,GENERIC_PRIMITIVE), + JS_FN("toLowerCase", str_toLowerCase, 0,0,GENERIC_PRIMITIVE), + JS_FN("toUpperCase", str_toUpperCase, 0,0,GENERIC_PRIMITIVE), + JS_FN("charAt", str_charAt, 1,1,GENERIC_PRIMITIVE), + JS_FN("charCodeAt", str_charCodeAt, 1,1,GENERIC_PRIMITIVE), + JS_FN("indexOf", str_indexOf, 1,1,GENERIC_PRIMITIVE), + JS_FN("lastIndexOf", str_lastIndexOf, 1,1,GENERIC_PRIMITIVE), + JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,0,GENERIC_PRIMITIVE), + JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,0,GENERIC_PRIMITIVE), + JS_FN("localeCompare", str_localeCompare, 1,1,GENERIC_PRIMITIVE), /* Perl-ish methods (search is actually Python-esque). */ - JS_FN("match", str_match, 1,1,GENERIC_PRIMITIVE,2), - JS_FN("search", str_search, 1,1,GENERIC_PRIMITIVE,0), - JS_FN("replace", str_replace, 2,2,GENERIC_PRIMITIVE,0), - JS_FN("split", str_split, 0,2,GENERIC_PRIMITIVE,0), + JS_FN("match", str_match, 1,1,GENERIC_PRIMITIVE), + JS_FN("search", str_search, 1,1,GENERIC_PRIMITIVE), + JS_FN("replace", str_replace, 2,2,GENERIC_PRIMITIVE), + JS_FN("split", str_split, 0,2,GENERIC_PRIMITIVE), #if JS_HAS_PERL_SUBSTR - JS_FN("substr", str_substr, 0,2,GENERIC_PRIMITIVE,0), + JS_FN("substr", str_substr, 0,2,GENERIC_PRIMITIVE), #endif /* Python-esque sequence methods. */ - JS_FN("concat", str_concat, 0,1,GENERIC_PRIMITIVE,0), - JS_FN("slice", str_slice, 1,2,GENERIC_PRIMITIVE,0), + JS_FN("concat", str_concat, 0,1,GENERIC_PRIMITIVE), + JS_FN("slice", str_slice, 1,2,GENERIC_PRIMITIVE), /* HTML string methods. */ #if JS_HAS_STR_HTML_HELPERS - JS_FN("bold", str_bold, 0,0,PRIMITIVE,0), - JS_FN("italics", str_italics, 0,0,PRIMITIVE,0), - JS_FN("fixed", str_fixed, 0,0,PRIMITIVE,0), - JS_FN("fontsize", str_fontsize, 1,1,PRIMITIVE,0), - JS_FN("fontcolor", str_fontcolor, 1,1,PRIMITIVE,0), - JS_FN("link", str_link, 1,1,PRIMITIVE,0), - JS_FN("anchor", str_anchor, 1,1,PRIMITIVE,0), - JS_FN("strike", str_strike, 0,0,PRIMITIVE,0), - JS_FN("small", str_small, 0,0,PRIMITIVE,0), - JS_FN("big", str_big, 0,0,PRIMITIVE,0), - JS_FN("blink", str_blink, 0,0,PRIMITIVE,0), - JS_FN("sup", str_sup, 0,0,PRIMITIVE,0), - JS_FN("sub", str_sub, 0,0,PRIMITIVE,0), + JS_FN("bold", str_bold, 0,0,PRIMITIVE), + JS_FN("italics", str_italics, 0,0,PRIMITIVE), + JS_FN("fixed", str_fixed, 0,0,PRIMITIVE), + JS_FN("fontsize", str_fontsize, 1,1,PRIMITIVE), + JS_FN("fontcolor", str_fontcolor, 1,1,PRIMITIVE), + JS_FN("link", str_link, 1,1,PRIMITIVE), + JS_FN("anchor", str_anchor, 1,1,PRIMITIVE), + JS_FN("strike", str_strike, 0,0,PRIMITIVE), + JS_FN("small", str_small, 0,0,PRIMITIVE), + JS_FN("big", str_big, 0,0,PRIMITIVE), + JS_FN("blink", str_blink, 0,0,PRIMITIVE), + JS_FN("sup", str_sup, 0,0,PRIMITIVE), + JS_FN("sub", str_sub, 0,0,PRIMITIVE), #endif JS_FS_END @@ -2331,7 +2333,7 @@ str_fromCharCode(JSContext *cx, uintN argc, jsval *vp) } static JSFunctionSpec string_static_methods[] = { - JS_FN("fromCharCode", str_fromCharCode, 0,1,0,0), + JS_FN("fromCharCode", str_fromCharCode, 0,1,0), JS_FS_END }; diff --git a/js/src/jsxml.c b/js/src/jsxml.c index 9230b8e9046..9de9086e8ca 100644 --- a/js/src/jsxml.c +++ b/js/src/jsxml.c @@ -273,7 +273,7 @@ namespace_toString(JSContext *cx, uintN argc, jsval *vp) } static JSFunctionSpec namespace_methods[] = { - JS_FN(js_toString_str, namespace_toString, 0,0,0,0), + JS_FN(js_toString_str, namespace_toString, 0,0,0), JS_FS_END }; @@ -546,7 +546,7 @@ qname_toString(JSContext *cx, uintN argc, jsval *vp) } static JSFunctionSpec qname_methods[] = { - JS_FN(js_toString_str, qname_toString, 0,0,0,0), + JS_FN(js_toString_str, qname_toString, 0,0,0), JS_FS_END }; @@ -7176,46 +7176,46 @@ xml_valueOf(JSContext *cx, uintN argc, jsval *vp) } static JSFunctionSpec xml_methods[] = { - JS_FN("addNamespace", xml_addNamespace, 1,1,0,0), - JS_FN("appendChild", xml_appendChild, 1,1,0,0), - JS_FN(js_attribute_str, xml_attribute, 1,1,0,0), - JS_FN("attributes", xml_attributes, 0,0,0,0), - JS_FN("child", xml_child, 1,1,0,0), - JS_FN("childIndex", xml_childIndex, 0,0,0,0), - JS_FN("children", xml_children, 0,0,0,0), - JS_FN("comments", xml_comments, 0,0,0,0), - JS_FN("contains", xml_contains, 1,1,0,0), - JS_FN("copy", xml_copy, 0,0,0,0), - JS_FN("descendants", xml_descendants, 0,1,0,0), - JS_FN("elements", xml_elements, 0,1,0,0), - JS_FN("hasOwnProperty", xml_hasOwnProperty, 1,1,0,0), - JS_FN("hasComplexContent", xml_hasComplexContent, 1,1,0,0), - JS_FN("hasSimpleContent", xml_hasSimpleContent, 1,1,0,0), - JS_FN("inScopeNamespaces", xml_inScopeNamespaces, 0,0,0,0), - JS_FN("insertChildAfter", xml_insertChildAfter, 2,2,0,0), - JS_FN("insertChildBefore", xml_insertChildBefore, 2,2,0,0), - JS_FN(js_length_str, xml_length, 0,0,0,0), - JS_FN(js_localName_str, xml_localName, 0,0,0,0), - JS_FN(js_name_str, xml_name, 0,0,0,0), - JS_FN(js_namespace_str, xml_namespace, 0,1,0,0), - JS_FN("namespaceDeclarations", xml_namespaceDeclarations, 0,0,0,0), - JS_FN("nodeKind", xml_nodeKind, 0,0,0,0), - JS_FN("normalize", xml_normalize, 0,0,0,0), - JS_FN(js_xml_parent_str, xml_parent, 0,0,0,0), - JS_FN("processingInstructions",xml_processingInstructions,0,1,0,0), - JS_FN("prependChild", xml_prependChild, 1,1,0,0), - JS_FN("propertyIsEnumerable", xml_propertyIsEnumerable, 1,1,0,0), - JS_FN("removeNamespace", xml_removeNamespace, 1,1,0,0), - JS_FN("replace", xml_replace, 2,2,0,0), - JS_FN("setChildren", xml_setChildren, 1,1,0,0), - JS_FN("setLocalName", xml_setLocalName, 1,1,0,0), - JS_FN("setName", xml_setName, 1,1,0,0), - JS_FN("setNamespace", xml_setNamespace, 1,1,0,0), - JS_FN(js_text_str, xml_text, 0,0,0,0), - JS_FN(js_toString_str, xml_toString, 0,0,0,0), - JS_FN(js_toXMLString_str, xml_toXMLString, 0,0,0,0), - JS_FN(js_toSource_str, xml_toXMLString, 0,0,0,0), - JS_FN(js_valueOf_str, xml_valueOf, 0,0,0,0), + JS_FN("addNamespace", xml_addNamespace, 1,1,0), + JS_FN("appendChild", xml_appendChild, 1,1,0), + JS_FN(js_attribute_str, xml_attribute, 1,1,0), + JS_FN("attributes", xml_attributes, 0,0,0), + JS_FN("child", xml_child, 1,1,0), + JS_FN("childIndex", xml_childIndex, 0,0,0), + JS_FN("children", xml_children, 0,0,0), + JS_FN("comments", xml_comments, 0,0,0), + JS_FN("contains", xml_contains, 1,1,0), + JS_FN("copy", xml_copy, 0,0,0), + JS_FN("descendants", xml_descendants, 0,1,0), + JS_FN("elements", xml_elements, 0,1,0), + JS_FN("hasOwnProperty", xml_hasOwnProperty, 1,1,0), + JS_FN("hasComplexContent", xml_hasComplexContent, 1,1,0), + JS_FN("hasSimpleContent", xml_hasSimpleContent, 1,1,0), + JS_FN("inScopeNamespaces", xml_inScopeNamespaces, 0,0,0), + JS_FN("insertChildAfter", xml_insertChildAfter, 2,2,0), + JS_FN("insertChildBefore", xml_insertChildBefore, 2,2,0), + JS_FN(js_length_str, xml_length, 0,0,0), + JS_FN(js_localName_str, xml_localName, 0,0,0), + JS_FN(js_name_str, xml_name, 0,0,0), + JS_FN(js_namespace_str, xml_namespace, 0,1,0), + JS_FN("namespaceDeclarations", xml_namespaceDeclarations, 0,0,0), + JS_FN("nodeKind", xml_nodeKind, 0,0,0), + JS_FN("normalize", xml_normalize, 0,0,0), + JS_FN(js_xml_parent_str, xml_parent, 0,0,0), + JS_FN("processingInstructions",xml_processingInstructions,0,1,0), + JS_FN("prependChild", xml_prependChild, 1,1,0), + JS_FN("propertyIsEnumerable", xml_propertyIsEnumerable, 1,1,0), + JS_FN("removeNamespace", xml_removeNamespace, 1,1,0), + JS_FN("replace", xml_replace, 2,2,0), + JS_FN("setChildren", xml_setChildren, 1,1,0), + JS_FN("setLocalName", xml_setLocalName, 1,1,0), + JS_FN("setName", xml_setName, 1,1,0), + JS_FN("setNamespace", xml_setNamespace, 1,1,0), + JS_FN(js_text_str, xml_text, 0,0,0), + JS_FN(js_toString_str, xml_toString, 0,0,0), + JS_FN(js_toXMLString_str, xml_toXMLString, 0,0,0), + JS_FN(js_toSource_str, xml_toXMLString, 0,0,0), + JS_FN(js_valueOf_str, xml_valueOf, 0,0,0), JS_FS_END }; @@ -7306,9 +7306,9 @@ xml_defaultSettings(JSContext *cx, uintN argc, jsval *vp) } static JSFunctionSpec xml_static_methods[] = { - JS_FN("settings", xml_settings, 0,0,0,0), - JS_FN("setSettings", xml_setSettings, 1,1,0,0), - JS_FN("defaultSettings", xml_defaultSettings, 0,0,0,0), + JS_FN("settings", xml_settings, 0,0,0), + JS_FN("setSettings", xml_setSettings, 1,1,0), + JS_FN("defaultSettings", xml_defaultSettings, 0,0,0), JS_FS_END };