diff --git a/js/src/Makefile.in b/js/src/Makefile.in index e416af2dea2a..b23813ab0ebc 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -234,6 +234,12 @@ CPPSRCS += \ jsbuiltins.cpp \ $(NULL) +ifdef WINCE +# don't need -c +AS_DASH_C_FLAG = +ASFILES += jswince.asm +endif + ifdef DEBUG CPPSRCS += TraceTreeDrawer.cpp endif diff --git a/js/src/configure.in b/js/src/configure.in index b49bce4f83b6..5b53bdc3be46 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -1865,10 +1865,8 @@ case "$target" in AR_EXTRACT="$AR -extract" AR_DELETE="$AR d" AR_FLAGS='-OUT:"$@"' + AS="$AS_BIN" - if test -z "$AS_BIN"; then - AS="$AS_BIN" - fi DSO_CFLAGS= DSO_PIC_CFLAGS= DLL_SUFFIX=.dll @@ -3015,25 +3013,6 @@ if test ! "$GNU_CXX"; then fi AC_CHECK_LIB(socket, socket) -dnl Enable VFP support on ARM -MOZ_ARG_DISABLE_BOOL(arm-vfp, -[ --disable-arm-vfp Disable ARM VFP instructions in JavaScript JIT], - MOZ_ARM_VFP=, MOZ_ARM_VFP=1, MOZ_ARM_VFP=1) -if test "$MOZ_ARM_VFP"; then - AC_DEFINE(NJ_ARM_VFP) -fi - -AC_MSG_CHECKING(for ARM SIMD support) -AC_TRY_COMPILE([], - [asm("uqadd8 r1, r1, r2");], - result="yes", result="no") -AC_MSG_RESULT("$result") -if test "$result" = "yes"; then - AC_DEFINE(HAVE_ARM_SIMD) - HAVE_ARM_SIMD=1 -fi -AC_SUBST(HAVE_ARM_SIMD) - dnl ======================================================== dnl = pthread support dnl = Start by checking whether the system support pthreads diff --git a/js/src/imacros.c.out b/js/src/imacros.c.out index c5dbd564ac7f..c5b19080cc61 100644 --- a/js/src/imacros.c.out +++ b/js/src/imacros.c.out @@ -278,6 +278,31 @@ static struct { /*38*/ JSOP_STOP, }, }; +static struct { + jsbytecode String[39]; +} new_imacros = { + { +/* 0*/ JSOP_DUP, +/* 1*/ JSOP_DUP, +/* 2*/ JSOP_GETPROP, 0, COMMON_ATOM_INDEX(toString), +/* 5*/ JSOP_IFPRIMTOP, 0, 13, +/* 8*/ JSOP_SWAP, +/* 9*/ JSOP_CALL, 0, 0, +/*12*/ JSOP_IFPRIMTOP, 0, 21, +/*15*/ JSOP_GOTO, 0, 4, +/*18*/ JSOP_POP, +/*19*/ JSOP_POP, +/*20*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(valueOf), +/*23*/ JSOP_STRING, 0, COMMON_TYPE_ATOM_INDEX(JSTYPE_STRING), +/*26*/ JSOP_CALL, 0, 1, +/*29*/ JSOP_PRIMTOP, +/*30*/ JSOP_GOTO, 0, 5, +/*33*/ JSOP_SWAP, +/*34*/ JSOP_POP, +/*35*/ JSOP_NEW, 0, 1, +/*38*/ JSOP_STOP, + }, +}; static struct { jsbytecode apply0[8]; jsbytecode apply1[12]; @@ -640,6 +665,29 @@ static struct { /* 9*/ JSOP_STOP, }, }; +static struct { + jsbytecode callprop[12]; + jsbytecode callelem[12]; +} callelem_imacros = { + { +/* 0*/ JSOP_SWAP, +/* 1*/ JSOP_DUP, +/* 2*/ JSOP_CALLBUILTIN, ((JSBUILTIN_GetProperty) & 0xff00) >> 8, ((JSBUILTIN_GetProperty) & 0xff), +/* 5*/ JSOP_PICK, 3, +/* 7*/ JSOP_CALL, 0, 1, +/*10*/ JSOP_SWAP, +/*11*/ JSOP_STOP, + }, + { +/* 0*/ JSOP_SWAP, +/* 1*/ JSOP_DUP, +/* 2*/ JSOP_CALLBUILTIN, ((JSBUILTIN_GetElement) & 0xff00) >> 8, ((JSBUILTIN_GetElement) & 0xff), +/* 5*/ JSOP_PICK, 3, +/* 7*/ JSOP_CALL, 0, 1, +/*10*/ JSOP_SWAP, +/*11*/ JSOP_STOP, + }, +}; static struct { jsbytecode setprop[15]; jsbytecode setelem[15]; @@ -773,7 +821,7 @@ uint8 js_opcode2extra[JSOP_LIMIT] = { 0, /* JSOP_SWAP */ 0, /* JSOP_OBJECT */ 0, /* JSOP_POP */ - 0, /* JSOP_NEW */ + 2, /* JSOP_NEW */ 0, /* JSOP_TRAP */ 0, /* JSOP_GETARG */ 0, /* JSOP_SETARG */ @@ -885,7 +933,7 @@ uint8 js_opcode2extra[JSOP_LIMIT] = { 0, /* JSOP_RESETBASE0 */ 0, /* JSOP_STARTXML */ 0, /* JSOP_STARTXMLEXPR */ - 0, /* JSOP_CALLELEM */ + 3, /* JSOP_CALLELEM */ 0, /* JSOP_STOP */ 0, /* JSOP_GETXPROP */ 0, /* JSOP_CALLXMLNAME */ @@ -951,5 +999,7 @@ uint8 js_opcode2extra[JSOP_LIMIT] = { || x == JSOP_ITER \ || x == JSOP_NEXTITER \ || x == JSOP_APPLY \ + || x == JSOP_NEW \ || x == JSOP_INITELEM \ + || x == JSOP_CALLELEM \ ) diff --git a/js/src/imacros.jsasm b/js/src/imacros.jsasm index a74b56437678..55fc795879b3 100644 --- a/js/src/imacros.jsasm +++ b/js/src/imacros.jsasm @@ -320,6 +320,32 @@ .end +.igroup new JSOP_NEW + + .imacro String # String this obj + dup # String this obj obj + dup # String this obj obj obj + getprop toString # String this obj obj toString + ifprimtop 1 # String this obj obj toString + swap # String this obj toString obj + call 0 # String this obj rval + ifprimtop 3 # String this obj rval + goto 2 +1: pop # String this obj obj +2: pop # String this obj + callprop valueOf # String this valueOf obj + string string # String this valueOf obj "string" + call 1 # String this rval + primtop # String this rval + goto 4 # String this rval +3: swap # String this rval obj + pop # String this rval +4: new 1 # strobj + stop # strobj + .end + +.end + .igroup apply JSOP_APPLY .imacro apply0 # apply fun this arr pick 3 # fun this arr apply @@ -685,6 +711,30 @@ .end +.igroup callelem JSOP_CALLELEM + + .imacro callprop # obj name + swap # name obj + dup # name obj obj + callbuiltin (JSBUILTIN_GetProperty) # name obj fun obj + pick 3 # obj fun obj name + call 1 # obj propval + swap # propval obj + stop + .end + + .imacro callelem # obj i + swap # i obj + dup # i obj obj + callbuiltin (JSBUILTIN_GetElement) # i obj fun obj + pick 3 # obj fun obj i + call 1 # obj propval + swap # propval obj + stop + .end + +.end + .igroup setelem JSOP_SETELEM .imacro setprop # obj name val diff --git a/js/src/js.msg b/js/src/js.msg index ebe7d9366469..d6fd866a1fc8 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -155,7 +155,7 @@ MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 72, 0, JSEXN_SYNTAXERR, "missing { before MSG_DEF(JSMSG_CURLY_AFTER_BODY, 73, 0, JSEXN_SYNTAXERR, "missing } after function body") MSG_DEF(JSMSG_PAREN_BEFORE_COND, 74, 0, JSEXN_SYNTAXERR, "missing ( before condition") MSG_DEF(JSMSG_PAREN_AFTER_COND, 75, 0, JSEXN_SYNTAXERR, "missing ) after condition") -MSG_DEF(JSMSG_UNUSED76, 76, 0, JSEXN_NONE, "unused76") +MSG_DEF(JSMSG_DESTRUCT_DUP_ARG, 76, 0, JSEXN_SYNTAXERR, "duplicate argument is mixed with destructuring pattern") MSG_DEF(JSMSG_NAME_AFTER_DOT, 77, 0, JSEXN_SYNTAXERR, "missing name after . operator") MSG_DEF(JSMSG_BRACKET_IN_INDEX, 78, 0, JSEXN_SYNTAXERR, "missing ] in index expression") MSG_DEF(JSMSG_UNUSED79, 79, 0, JSEXN_NONE, "unused79") diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index c096e8d4d99f..8b62ac0c3ea6 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -788,8 +788,6 @@ JS_NewRuntime(uint32 maxbytes) if (!js_InitDeflatedStringCache(rt)) goto bad; #ifdef JS_THREADSAFE - if (!js_InitThreadPrivateIndex(js_ThreadDestructorCB)) - goto bad; rt->gcLock = JS_NEW_LOCK(); if (!rt->gcLock) goto bad; @@ -818,10 +816,8 @@ JS_NewRuntime(uint32 maxbytes) #endif if (!js_InitPropertyTree(rt)) goto bad; - -#if !defined JS_THREADSAFE && defined JS_TRACER - js_InitJIT(&rt->traceMonitor); -#endif + if (!js_InitThreads(rt)) + goto bad; return rt; @@ -850,10 +846,7 @@ JS_DestroyRuntime(JSRuntime *rt) } #endif -#if !defined JS_THREADSAFE && defined JS_TRACER - js_FinishJIT(&rt->traceMonitor); -#endif - + js_FinishThreads(rt); js_FreeRuntimeScriptState(rt); js_FinishAtomState(rt); @@ -885,8 +878,6 @@ JS_DestroyRuntime(JSRuntime *rt) JS_DESTROY_CONDVAR(rt->titleSharingDone); if (rt->debuggerLock) JS_DESTROY_LOCK(rt->debuggerLock); -#else - GSN_CACHE_CLEAR(&rt->gsnCache); #endif js_FinishPropertyTree(rt); free(rt); @@ -903,7 +894,6 @@ JS_ShutDown(void) js_FinishDtoa(); #ifdef JS_THREADSAFE - js_CleanupThreadPrivateData(); /* Fixes bug 464828. */ js_CleanupLocks(); #endif PRMJ_NowShutdown(); @@ -927,7 +917,7 @@ JS_BeginRequest(JSContext *cx) #ifdef JS_THREADSAFE JSRuntime *rt; - JS_ASSERT(cx->thread->id == js_CurrentThreadId()); + JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread)); if (!cx->requestDepth) { JS_ASSERT(cx->gcLocalFreeLists == &js_GCEmptyFreeListSet); @@ -935,7 +925,6 @@ JS_BeginRequest(JSContext *cx) rt = cx->runtime; JS_LOCK_GC(rt); - /* NB: we use cx->thread here, not js_GetCurrentThread(). */ if (rt->gcThread != cx->thread) { while (rt->gcLevel > 0) JS_AWAIT_GC_DONE(rt); @@ -962,6 +951,7 @@ JS_EndRequest(JSContext *cx) JSBool shared; CHECK_REQUEST(cx); + JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread)); JS_ASSERT(cx->requestDepth > 0); JS_ASSERT(cx->outstandingRequests > 0); if (cx->requestDepth == 1) { @@ -1935,14 +1925,8 @@ JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval) JS_PUBLIC_API(JSBool) JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval) { - jsint i; - CHECK_REQUEST(cx); - if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) { - *rval = INT_TO_JSVAL(i); - return JS_TRUE; - } - return JS_NewDoubleValue(cx, d, rval); + return js_NewWeaklyRootedNumber(cx, d, rval); } #undef JS_AddRoot @@ -2851,19 +2835,6 @@ JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto) { CHECK_REQUEST(cx); JS_ASSERT(obj != proto); -#ifdef DEBUG - /* - * FIXME: bug 408416. The cycle-detection required for script-writeable - * __proto__ lives in js_SetProtoOrParent over in jsobj.c, also known as - * js_ObjectOps.setProto. This hook must detect cycles, to prevent scripts - * from ilooping SpiderMonkey trivially. But the overhead of detecting - * cycles is high enough, and the threat from JS-API-calling C++ code is - * low enough, that it's not worth burdening the non-DEBUG callers. Same - * goes for JS_SetParent, below. - */ - if (obj->map->ops->setProto) - return obj->map->ops->setProto(cx, obj, JSSLOT_PROTO, proto); -#else if (OBJ_IS_NATIVE(obj)) { JS_LOCK_OBJ(cx, obj); if (!js_GetMutableScope(cx, obj)) { @@ -2874,7 +2845,6 @@ JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto) JS_UNLOCK_OBJ(cx, obj); return JS_TRUE; } -#endif OBJ_SET_PROTO(cx, obj, proto); return JS_TRUE; } @@ -2895,11 +2865,6 @@ JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent) { CHECK_REQUEST(cx); JS_ASSERT(obj != parent); -#ifdef DEBUG - /* FIXME: bug 408416, see JS_SetPrototype just above. */ - if (obj->map->ops->setParent) - return obj->map->ops->setParent(cx, obj, JSSLOT_PARENT, parent); -#endif OBJ_SET_PARENT(cx, obj, parent); return JS_TRUE; } @@ -5934,25 +5899,17 @@ JS_SetContextThread(JSContext *cx) #ifdef JS_THREADSAFE JS_ASSERT(cx->requestDepth == 0); if (cx->thread) { - JS_ASSERT(cx->thread->id == js_CurrentThreadId()); + JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread)); return cx->thread->id; } - JSRuntime *rt = cx->runtime; - JSThread *thread = js_GetCurrentThread(rt); - if (!thread) { + if (!js_InitContextThread(cx)) { js_ReportOutOfMemory(cx); return -1; } - /* - * We must not race with a GC that accesses cx->thread for all threads, - * see bug 476934. - */ - JS_LOCK_GC(rt); - js_WaitForGC(rt); - js_InitContextThread(cx, thread); - JS_UNLOCK_GC(rt); + /* Here the GC lock is still held after js_InitContextThread took it. */ + JS_UNLOCK_GC(cx->runtime); #endif return 0; } @@ -5969,8 +5926,8 @@ JS_ClearContextThread(JSContext *cx) JS_ASSERT(cx->requestDepth == 0); if (!cx->thread) return 0; + JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread)); jsword old = cx->thread->id; - JS_ASSERT(old == js_CurrentThreadId()); /* * We must not race with a GC that accesses cx->thread for all threads, @@ -5979,9 +5936,8 @@ JS_ClearContextThread(JSContext *cx) JSRuntime *rt = cx->runtime; JS_LOCK_GC(rt); js_WaitForGC(rt); - JS_REMOVE_AND_INIT_LINK(&cx->threadLinks); - cx->thread = NULL; - JS_UNLOCK_GC(cx->runtime); + js_ClearContextThread(cx); + JS_UNLOCK_GC(rt); return old; #else return 0; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 953997129d68..1bf930ba2f6e 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1545,8 +1545,8 @@ struct JSFunctionSpec { * frame when activated. */ #define JS_FN(name,fastcall,nargs,flags) \ - {name, (JSNative)(fastcall), nargs, \ - (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS, 0} + JS_FS(name, (JSNative)(fastcall), nargs, \ + (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS, 0) extern JS_PUBLIC_API(JSObject *) JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 5060b6ee3cd5..7fa5b39f26d7 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -238,13 +238,9 @@ js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp) } static JSBool -IndexToValue(JSContext *cx, jsuint index, jsval *vp) +IndexToValue(JSContext *cx, jsdouble index, jsval *vp) { - if (index <= JSVAL_INT_MAX) { - *vp = INT_TO_JSVAL(index); - return JS_TRUE; - } - return JS_NewDoubleValue(cx, (jsdouble)index, vp); + return js_NewWeaklyRootedNumber(cx, index, vp); } JSBool JS_FASTCALL @@ -384,6 +380,37 @@ EnsureCapacity(JSContext *cx, JSObject *obj, uint32 capacity) return JS_TRUE; } +static bool +ReallyBigIndexToId(JSContext* cx, jsdouble index, jsid* idp) +{ + JSAutoTempValueRooter dval(cx); + if (!js_NewDoubleInRootedValue(cx, index, dval.addr()) || + !js_ValueToStringId(cx, dval.value(), idp)) { + return JS_FALSE; + } + return JS_TRUE; +} + +static bool +IndexToId(JSContext* cx, JSObject* obj, jsdouble index, JSBool* hole, jsid* idp, + JSBool createAtom = JS_FALSE) +{ + if (index <= JSVAL_INT_MAX) { + *idp = INT_TO_JSID(index); + return JS_TRUE; + } + + if (index <= jsuint(-1)) { + if (!BigIndexToId(cx, obj, jsuint(index), createAtom, idp)) + return JS_FALSE; + if (hole && JSVAL_IS_VOID(*idp)) + *hole = JS_TRUE; + return JS_TRUE; + } + + return ReallyBigIndexToId(cx, index, idp); +} + /* * If the property at the given index exists, get its value into location * pointed by vp and set *hole to false. Otherwise set *hole to true and *vp @@ -391,39 +418,36 @@ EnsureCapacity(JSContext *cx, JSObject *obj, uint32 capacity) * properly rooted and can be used as GC-protected storage for temporaries. */ static JSBool -GetArrayElement(JSContext *cx, JSObject *obj, jsuint index, JSBool *hole, +GetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, JSBool *hole, jsval *vp) { - jsid id; - JSObject *obj2; - JSProperty *prop; - + JS_ASSERT(index >= 0); if (OBJ_IS_DENSE_ARRAY(cx, obj) && index < js_DenseArrayCapacity(obj) && - (*vp = obj->dslots[index]) != JSVAL_HOLE) { + (*vp = obj->dslots[jsuint(index)]) != JSVAL_HOLE) { *hole = JS_FALSE; return JS_TRUE; } - if (index <= JSVAL_INT_MAX) { - id = INT_TO_JSID(index); - } else { - if (!BigIndexToId(cx, obj, index, JS_FALSE, &id)) - return JS_FALSE; - if (JSVAL_IS_VOID(id)) { - *hole = JS_TRUE; - *vp = JSVAL_VOID; - return JS_TRUE; - } + JSAutoTempIdRooter idr(cx); + + *hole = JS_FALSE; + if (!IndexToId(cx, obj, index, hole, idr.addr())) + return JS_FALSE; + if (*hole) { + *vp = JSVAL_VOID; + return JS_TRUE; } - if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) + JSObject *obj2; + JSProperty *prop; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, idr.id(), &obj2, &prop)) return JS_FALSE; if (!prop) { *hole = JS_TRUE; *vp = JSVAL_VOID; } else { OBJ_DROP_PROPERTY(cx, obj2, prop); - if (!OBJ_GET_PROPERTY(cx, obj, id, vp)) + if (!OBJ_GET_PROPERTY(cx, obj, idr.id(), vp)) return JS_FALSE; *hole = JS_FALSE; } @@ -434,61 +458,66 @@ GetArrayElement(JSContext *cx, JSObject *obj, jsuint index, JSBool *hole, * Set the value of the property at the given index to v assuming v is rooted. */ static JSBool -SetArrayElement(JSContext *cx, JSObject *obj, jsuint index, jsval v) +SetArrayElement(JSContext *cx, JSObject *obj, jsdouble index, jsval v) { - jsid id; + JS_ASSERT(index >= 0); if (OBJ_IS_DENSE_ARRAY(cx, obj)) { - /* Predicted/prefeched code should favor the remains-dense case. */ - if (!INDEX_TOO_SPARSE(obj, index)) { - if (!EnsureCapacity(cx, obj, index + 1)) - return JS_FALSE; - if (index >= (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH]) - obj->fslots[JSSLOT_ARRAY_LENGTH] = index + 1; - if (obj->dslots[index] == JSVAL_HOLE) - obj->fslots[JSSLOT_ARRAY_COUNT]++; - obj->dslots[index] = v; - return JS_TRUE; + /* Predicted/prefetched code should favor the remains-dense case. */ + if (index <= jsuint(-1)) { + jsuint idx = jsuint(index); + if (!INDEX_TOO_SPARSE(obj, idx)) { + JS_ASSERT(idx + 1 > idx); + if (!EnsureCapacity(cx, obj, idx + 1)) + return JS_FALSE; + if (index >= uint32(obj->fslots[JSSLOT_ARRAY_LENGTH])) + obj->fslots[JSSLOT_ARRAY_LENGTH] = idx + 1; + if (obj->dslots[idx] == JSVAL_HOLE) + obj->fslots[JSSLOT_ARRAY_COUNT]++; + obj->dslots[idx] = v; + return JS_TRUE; + } } if (!js_MakeArraySlow(cx, obj)) return JS_FALSE; } - if (index <= JSVAL_INT_MAX) { - id = INT_TO_JSID(index); - } else { - if (!BigIndexToId(cx, obj, index, JS_TRUE, &id)) - return JS_FALSE; - JS_ASSERT(!JSVAL_IS_VOID(id)); - } - return OBJ_SET_PROPERTY(cx, obj, id, &v); + JSAutoTempIdRooter idr(cx); + + if (!IndexToId(cx, obj, index, NULL, idr.addr(), JS_TRUE)) + return JS_FALSE; + JS_ASSERT(!JSVAL_IS_VOID(idr.id())); + + return OBJ_SET_PROPERTY(cx, obj, idr.id(), &v); } static JSBool -DeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index) +DeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index) { - jsid id; - jsval junk; - + JS_ASSERT(index >= 0); if (OBJ_IS_DENSE_ARRAY(cx, obj)) { - if (index < js_DenseArrayCapacity(obj)) { - if (obj->dslots[index] != JSVAL_HOLE) - obj->fslots[JSSLOT_ARRAY_COUNT]--; - obj->dslots[index] = JSVAL_HOLE; + if (index <= jsuint(-1)) { + jsuint idx = jsuint(index); + if (!INDEX_TOO_SPARSE(obj, idx) && idx < js_DenseArrayCapacity(obj)) { + if (obj->dslots[idx] != JSVAL_HOLE) + obj->fslots[JSSLOT_ARRAY_COUNT]--; + obj->dslots[idx] = JSVAL_HOLE; + return JS_TRUE; + } } return JS_TRUE; } - if (index <= JSVAL_INT_MAX) { - id = INT_TO_JSID(index); - } else { - if (!BigIndexToId(cx, obj, index, JS_FALSE, &id)) - return JS_FALSE; - if (JSVAL_IS_VOID(id)) - return JS_TRUE; - } - return OBJ_DELETE_PROPERTY(cx, obj, id, &junk); + JSAutoTempIdRooter idr(cx); + + if (!IndexToId(cx, obj, index, NULL, idr.addr())) + return JS_FALSE; + if (JSVAL_IS_VOID(idr.id())) + return JS_TRUE; + + jsval junk; + return OBJ_DELETE_PROPERTY(cx, obj, idr.id(), &junk); } /* @@ -496,7 +525,7 @@ DeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index) * its value to v assuming v is rooted. */ static JSBool -SetOrDeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index, +SetOrDeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index, JSBool hole, jsval v) { if (hole) { @@ -507,7 +536,7 @@ SetOrDeleteArrayElement(JSContext *cx, JSObject *obj, jsuint index, } JSBool -js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length) +js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length) { jsval v; jsid id; @@ -1553,26 +1582,61 @@ array_toLocaleString(JSContext *cx, uintN argc, jsval *vp) } static JSBool -InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint end, - jsval *vector) +InitArrayElements(JSContext *cx, JSObject *obj, jsuint start, jsuint count, jsval *vector) { - if (OBJ_IS_DENSE_ARRAY(cx, obj)) { - if (!EnsureCapacity(cx, obj, end)) + JS_ASSERT(count < MAXINDEX); + /* + * Optimize for dense arrays so long as adding the given set of elements + * wouldn't otherwise make the array slow. + */ + if (OBJ_IS_DENSE_ARRAY(cx, obj) && start <= MAXINDEX - count && + !INDEX_TOO_BIG(start + count)) { + jsuint newlen = start + count; + JS_ASSERT(jsdouble(start) + count == jsdouble(newlen)); + if (!EnsureCapacity(cx, obj, newlen)) return JS_FALSE; - if (end > (uint32)obj->fslots[JSSLOT_ARRAY_LENGTH]) - obj->fslots[JSSLOT_ARRAY_LENGTH] = end; + if (newlen > uint32(obj->fslots[JSSLOT_ARRAY_LENGTH])) + obj->fslots[JSSLOT_ARRAY_LENGTH] = newlen; - memcpy(obj->dslots + start, vector, sizeof(jsval) * (end - start)); + JS_ASSERT(count < size_t(-1) / sizeof(jsval)); + memcpy(obj->dslots + start, vector, sizeof(jsval) * count); + JS_ASSERT_IF(count != 0, obj->dslots[newlen - 1] != JSVAL_HOLE); return JS_TRUE; } - while (start != end) { + jsval* end = vector + count; + while (vector != end && start < MAXINDEX) { if (!JS_CHECK_OPERATION_LIMIT(cx) || !SetArrayElement(cx, obj, start++, *vector++)) { return JS_FALSE; } } + + if (vector == end) + return JS_TRUE; + + /* Finish out any remaining elements past the max array index. */ + if (!ENSURE_SLOW_ARRAY(cx, obj)) + return JS_FALSE; + + JS_ASSERT(start == MAXINDEX); + jsval tmp[2] = {JSVAL_NULL, JSVAL_NULL}; + jsdouble* dp = js_NewWeaklyRootedDouble(cx, MAXINDEX); + if (!dp) + return JS_FALSE; + tmp[0] = DOUBLE_TO_JSVAL(dp); + JSAutoTempValueRooter(cx, JS_ARRAY_LENGTH(tmp), tmp); + JSAutoTempIdRooter idr(cx); + do { + tmp[1] = *vector++; + if (!js_ValueToStringId(cx, tmp[0], idr.addr()) || + !js_SetProperty(cx, obj, idr.id(), &tmp[1])) { + return JS_FALSE; + } + *dp += 1; + } while (vector != end); + return JS_TRUE; } @@ -2171,15 +2235,15 @@ array_sort(JSContext *cx, uintN argc, jsval *vp) static JSBool array_push_slowly(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - jsuint length, newlength; + jsuint length; if (!js_GetLengthProperty(cx, obj, &length)) return JS_FALSE; - newlength = length + argc; - if (!InitArrayElements(cx, obj, length, newlength, argv)) + if (!InitArrayElements(cx, obj, length, argc, argv)) return JS_FALSE; /* Per ECMA-262, return the new array length. */ + jsdouble newlength = length + jsdouble(argc); if (!IndexToValue(cx, newlength, rval)) return JS_FALSE; return js_SetLengthProperty(cx, obj, newlength); @@ -2374,13 +2438,15 @@ array_unshift(JSContext *cx, uintN argc, jsval *vp) { JSObject *obj; jsval *argv; - jsuint length, last; + jsuint length; JSBool hole, ok; JSTempValueRooter tvr; + jsdouble last, newlen; obj = JS_THIS_OBJECT(cx, vp); if (!obj || !js_GetLengthProperty(cx, obj, &length)) return JS_FALSE; + newlen = length; if (argc > 0) { /* Slide up the array to make room for argc at the bottom. */ argv = JS_ARGV(cx, vp); @@ -2406,13 +2472,13 @@ array_unshift(JSContext *cx, uintN argc, jsval *vp) if (!InitArrayElements(cx, obj, 0, argc, argv)) return JS_FALSE; - length += argc; - if (!js_SetLengthProperty(cx, obj, length)) + newlen += argc; + if (!js_SetLengthProperty(cx, obj, newlen)) return JS_FALSE; } /* Follow Perl by returning the new array length. */ - return IndexToValue(cx, length, vp); + return IndexToValue(cx, newlen, vp); } static JSBool @@ -2533,7 +2599,7 @@ array_splice(JSContext *cx, uintN argc, jsval *vp) } /* Copy from argv into the hole to complete the splice. */ - ok = InitArrayElements(cx, obj, begin, begin + argc, argv); + ok = InitArrayElements(cx, obj, begin, argc, argv); if (!ok) goto out; diff --git a/js/src/jsarray.h b/js/src/jsarray.h index 0b0e61d4f89e..058932195f55 100644 --- a/js/src/jsarray.h +++ b/js/src/jsarray.h @@ -122,7 +122,7 @@ extern JSBool js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); extern JSBool -js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length); +js_SetLengthProperty(JSContext *cx, JSObject *obj, jsdouble length); extern JSBool js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); diff --git a/js/src/jsbuiltins.h b/js/src/jsbuiltins.h index 219fc75ed8f8..c9b989ba5128 100644 --- a/js/src/jsbuiltins.h +++ b/js/src/jsbuiltins.h @@ -427,6 +427,7 @@ JS_DECLARE_CALLINFO(js_NewUninitializedArray) JS_DECLARE_CALLINFO(js_NumberToString) /* Defined in jsstr.cpp. */ +JS_DECLARE_CALLINFO(js_String_tn) JS_DECLARE_CALLINFO(js_CompareStrings) JS_DECLARE_CALLINFO(js_ConcatStrings) JS_DECLARE_CALLINFO(js_EqualStrings) diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 63d1c1b77cc1..511ac0e2c4df 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -69,142 +69,232 @@ #include "jsstr.h" #include "jstracer.h" -#ifdef JS_THREADSAFE -#include "prtypes.h" +static void +FreeContext(JSContext *cx); -/* - * The index for JSThread info, returned by PR_NewThreadPrivateIndex. The - * index value is visible and shared by all threads, but the data associated - * with it is private to each thread. - */ -static PRUintn threadTPIndex; -static JSBool tpIndexInited = JS_FALSE; - -JS_BEGIN_EXTERN_C -JSBool -js_InitThreadPrivateIndex(void (*ptr)(void *)) +static void +InitThreadData(JSThreadData *data) { - PRStatus status; - - if (tpIndexInited) - return JS_TRUE; - - status = PR_NewThreadPrivateIndex(&threadTPIndex, ptr); - - if (status == PR_SUCCESS) - tpIndexInited = JS_TRUE; - return status == PR_SUCCESS; +#ifdef DEBUG + /* The data must be already zeroed. */ + for (size_t i = 0; i != sizeof(*data); ++i) + JS_ASSERT(reinterpret_cast(data)[i] == 0); +#endif +#ifdef JS_TRACER + js_InitJIT(&data->traceMonitor); +#endif } -JS_END_EXTERN_C -JS_BEGIN_EXTERN_C -JSBool -js_CleanupThreadPrivateData() +static void +FinishThreadData(JSThreadData *data) { - if (!tpIndexInited) - return JS_TRUE; - return PR_SetThreadPrivate(threadTPIndex, NULL) == PR_SUCCESS; +#ifdef DEBUG + /* All GC-related things must be already removed at this point. */ + for (size_t i = 0; i != JS_ARRAY_LENGTH(data->scriptsToGC); ++i) + JS_ASSERT(!data->scriptsToGC[i]); +#endif + + js_FinishGSNCache(&data->gsnCache); + js_FinishPropertyCache(&data->propertyCache); +#if defined JS_TRACER + js_FinishJIT(&data->traceMonitor); +#endif } -JS_END_EXTERN_C -/* - * Callback function to delete a JSThread info when the thread that owns it - * is destroyed. - */ -void -js_ThreadDestructorCB(void *ptr) +static void +PurgeThreadData(JSContext *cx, JSThreadData *data) { - JSThread *thread = (JSThread *)ptr; - - if (!thread) - return; +# ifdef JS_TRACER + JSTraceMonitor *tm = &data->traceMonitor; + tm->reservedDoublePoolPtr = tm->reservedDoublePool; + tm->needFlush = JS_TRUE; /* - * Check that this thread properly called either JS_DestroyContext or - * JS_ClearContextThread on each JSContext it created or used. + * We want to keep tm->reservedObjects after the GC. So, unless we are + * shutting down, we don't purge them here and rather mark them during + * the GC, see MarkReservedObjects in jsgc.cpp. */ - JS_ASSERT(JS_CLIST_IS_EMPTY(&thread->contextList)); - GSN_CACHE_CLEAR(&thread->gsnCache); -#if defined JS_TRACER - js_FinishJIT(&thread->traceMonitor); -#endif - free(thread); + if (cx->runtime->state == JSRTS_LANDING) + tm->reservedObjects = NULL; +# endif + + /* Destroy eval'ed scripts. */ + js_DestroyScriptsToGC(cx, data); + + js_PurgeGSNCache(&data->gsnCache); + js_PurgePropertyCache(cx, &data->propertyCache); } -/* - * Get current thread-local JSThread info, creating one if it doesn't exist. - * Each thread has a unique JSThread pointer. - * - * Since we are dealing with thread-local data, no lock is needed. - * - * Return a pointer to the thread local info, NULL if the system runs out - * of memory, or it failed to set thread private data (neither case is very - * likely; both are probably due to out-of-memory). It is up to the caller - * to report an error, if possible. - */ -JSThread * -js_GetCurrentThread(JSRuntime *rt) +#ifdef JS_THREADSAFE + +static JSThread * +NewThread(jsword id) { - JSThread *thread; - - thread = (JSThread *)PR_GetThreadPrivate(threadTPIndex); - if (!thread) { - thread = (JSThread *) malloc(sizeof(JSThread)); - if (!thread) - return NULL; -#ifdef DEBUG - memset(thread, JS_FREE_PATTERN, sizeof(JSThread)); -#endif - if (PR_FAILURE == PR_SetThreadPrivate(threadTPIndex, thread)) { - free(thread); - return NULL; - } - - JS_INIT_CLIST(&thread->contextList); - thread->id = js_CurrentThreadId(); - thread->gcMallocBytes = 0; -#ifdef JS_TRACER - memset(&thread->traceMonitor, 0, sizeof(thread->traceMonitor)); - js_InitJIT(&thread->traceMonitor); -#endif - memset(thread->scriptsToGC, 0, sizeof thread->scriptsToGC); - - /* - * js_InitContextThread initializes the remaining fields as necessary. - */ - } + JS_ASSERT(js_CurrentThreadId() == id); + JSThread *thread = (JSThread *) calloc(1, sizeof(JSThread)); + if (!thread) + return NULL; + JS_INIT_CLIST(&thread->contextList); + thread->id = id; + InitThreadData(&thread->data); return thread; } -/* - * Sets current thread as owning thread of a context by assigning the - * thread-private info to the context. - */ -void -js_InitContextThread(JSContext *cx, JSThread *thread) +static void +DestroyThread(JSThread *thread) +{ + /* The thread must have zero contexts. */ + JS_ASSERT(JS_CLIST_IS_EMPTY(&thread->contextList)); + FinishThreadData(&thread->data); + free(thread); +} + +JSBool +js_InitContextThread(JSContext *cx) { - JS_ASSERT(CURRENT_THREAD_IS_ME(thread)); JS_ASSERT(!cx->thread); - JS_ASSERT(cx->requestDepth == 0); + jsword id = js_CurrentThreadId(); + JSRuntime *rt = cx->runtime; + JS_LOCK_GC(rt); /* - * Clear caches on each transition from 0 to 1 context active on the - * current thread. See bug 425828. + * We must not race with a GC that accesses cx->thread for JSContext + * instances on all threads, see bug 476934. */ - if (JS_CLIST_IS_EMPTY(&thread->contextList)) { - memset(&thread->gsnCache, 0, sizeof thread->gsnCache); - memset(&thread->propertyCache, 0, sizeof thread->propertyCache); -#ifdef DEBUG - memset(&thread->evalCacheMeter, 0, sizeof thread->evalCacheMeter); -#endif + js_WaitForGC(rt); + JSThreadsHashEntry *entry = (JSThreadsHashEntry *) + JS_DHashTableOperate(&rt->threads, + (const void *) id, + JS_DHASH_LOOKUP); + JSThread *thread; + if (JS_DHASH_ENTRY_IS_BUSY(&entry->base)) { + thread = entry->thread; + JS_ASSERT(thread->id == id); + } else { + JS_UNLOCK_GC(rt); + thread = NewThread(id); + if (!thread) + return false; + JS_LOCK_GC(rt); + js_WaitForGC(rt); + entry = (JSThreadsHashEntry *) + JS_DHashTableOperate(&rt->threads, (const void *) id, + JS_DHASH_ADD); + if (!entry) { + JS_UNLOCK_GC(rt); + DestroyThread(thread); + return false; + } + + /* Another thread cannot initialize entry->thread. */ + JS_ASSERT(!entry->thread); + entry->thread = thread; } JS_APPEND_LINK(&cx->threadLinks, &thread->contextList); cx->thread = thread; + return true; +} + +void +js_ClearContextThread(JSContext *cx) +{ + JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread)); + JS_REMOVE_AND_INIT_LINK(&cx->threadLinks); + cx->thread = NULL; +} + +static JSBool +thread_matchEntry(JSDHashTable *table, + const JSDHashEntryHdr *hdr, + const void *key) +{ + const JSThreadsHashEntry *entry = (const JSThreadsHashEntry *) hdr; + + return entry->thread->id == (jsword) key; +} + +static const JSDHashTableOps threads_ops = { + JS_DHashAllocTable, + JS_DHashFreeTable, + JS_DHashVoidPtrKeyStub, + thread_matchEntry, + JS_DHashMoveEntryStub, + JS_DHashClearEntryStub, + JS_DHashFinalizeStub, + NULL +}; + +static JSDHashOperator +thread_destroyer(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 /* index */, + void * /* arg */) +{ + JSThreadsHashEntry *entry = (JSThreadsHashEntry *) hdr; + JSThread *thread = entry->thread; + + JS_ASSERT(JS_CLIST_IS_EMPTY(&thread->contextList)); + DestroyThread(thread); + return JS_DHASH_REMOVE; +} + +static JSDHashOperator +thread_purger(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 /* index */, + void *arg) +{ + JSContext* cx = (JSContext *) arg; + JSThread *thread = ((JSThreadsHashEntry *) hdr)->thread; + + if (JS_CLIST_IS_EMPTY(&thread->contextList)) { + JS_ASSERT(cx->thread != thread); + js_DestroyScriptsToGC(cx, &thread->data); + DestroyThread(thread); + return JS_DHASH_REMOVE; + } + PurgeThreadData(cx, &thread->data); + return JS_DHASH_NEXT; } #endif /* JS_THREADSAFE */ +JSBool +js_InitThreads(JSRuntime *rt) +{ +#ifdef JS_THREADSAFE + if (!JS_DHashTableInit(&rt->threads, &threads_ops, NULL, + sizeof(JSThreadsHashEntry), 4)) { + rt->threads.ops = NULL; + return false; + } +#else + InitThreadData(&rt->threadData); +#endif + return true; +} + +void +js_FinishThreads(JSRuntime *rt) +{ +#ifdef JS_THREADSAFE + if (!rt->threads.ops) + return; + JS_DHashTableEnumerate(&rt->threads, thread_destroyer, NULL); + JS_DHashTableFinish(&rt->threads); + rt->threads.ops = NULL; +#else + FinishThreadData(&rt->threadData); +#endif +} + +void +js_PurgeThreads(JSContext *cx) +{ +#ifdef JS_THREADSAFE + JS_DHashTableEnumerate(&cx->runtime->threads, thread_purger, cx); +#else + PurgeThreadData(cx, &cx->runtime->threadData); +#endif +} + /* * JSOPTION_XML and JSOPTION_ANONFUNFIX must be part of the JS version * associated with scripts, so in addition to storing them in cx->options we @@ -261,12 +351,6 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize) JSContext *cx; JSBool ok, first; JSContextCallback cxCallback; -#ifdef JS_THREADSAFE - JSThread *thread = js_GetCurrentThread(rt); - - if (!thread) - return NULL; -#endif /* * We need to initialize the new context fully before adding it to the @@ -285,7 +369,6 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize) cx->scriptStackQuota = JS_DEFAULT_SCRIPT_STACK_QUOTA; #ifdef JS_THREADSAFE cx->gcLocalFreeLists = (JSGCFreeListSet *) &js_GCEmptyFreeListSet; - js_InitContextThread(cx, thread); #endif JS_STATIC_ASSERT(JSVERSION_DEFAULT == 0); JS_ASSERT(cx->version == JSVERSION_DEFAULT); @@ -300,12 +383,18 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize) js_InitRegExpStatics(cx); JS_ASSERT(cx->resolveFlags == 0); - JS_LOCK_GC(rt); +#ifdef JS_THREADSAFE + if (!js_InitContextThread(cx)) { + FreeContext(cx); + return NULL; + } +#endif + + /* + * Here the GC lock is still held after js_InitContextThread took it and + * the GC is not running on another thread. + */ for (;;) { - /* - * Ensure that we don't race with the GC on other threads, bug 478336. - */ - js_WaitForGC(rt); if (rt->state == JSRTS_UP) { JS_ASSERT(!JS_CLIST_IS_EMPTY(&rt->contextList)); first = JS_FALSE; @@ -318,6 +407,15 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize) break; } JS_WAIT_CONDVAR(rt->stateChange, JS_NO_TIMEOUT); + + /* + * During the above wait after we are notified about the state change + * but before we wake up, another thread could enter the GC from + * js_DestroyContext, bug 478336. So we must wait here to ensure that + * when we exit the loop with the first flag set to true, that GC is + * finished. + */ + js_WaitForGC(rt); } JS_APPEND_LINK(&cx->link, &rt->contextList); JS_UNLOCK_GC(rt); @@ -404,7 +502,7 @@ DumpEvalCacheMeter(JSContext *cx) EVAL_CACHE_METER_LIST(frob) #undef frob }; - JSEvalCacheMeter *ecm = &JS_CACHE_LOCUS(cx)->evalCacheMeter; + JSEvalCacheMeter *ecm = &JS_THREAD_DATA(cx)->evalCacheMeter; static AutoFile fp; if (!fp) { @@ -439,9 +537,6 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode) JSRuntime *rt; JSContextCallback cxCallback; JSBool last; - JSArgumentFormatMap *map; - JSLocalRootStack *lrs; - JSLocalRootChunk *lrc; #ifdef JS_THREADSAFE JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread)); @@ -478,73 +573,99 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode) last = (rt->contextList.next == &rt->contextList); if (last) rt->state = JSRTS_LANDING; - JS_UNLOCK_GC(rt); - - if (last) { + if (last || mode == JSDCM_FORCE_GC || mode == JSDCM_MAYBE_GC #ifdef JS_THREADSAFE - /* - * If cx is not in a request already, begin one now so that we wait - * for any racing GC started on a not-last context to finish, before - * we plow ahead and unpin atoms. Note that even though we begin a - * request here if necessary, we end all requests on cx below before - * forcing a final GC. This lets any not-last context destruction - * racing in another thread try to force or maybe run the GC, but by - * that point, rt->state will not be JSRTS_UP, and that GC attempt - * will return early. - */ - if (cx->requestDepth == 0) - JS_BeginRequest(cx); + || cx->requestDepth != 0 #endif - - /* Unlock and clear GC things held by runtime pointers. */ - js_FinishRuntimeNumberState(cx); - js_FinishRuntimeStringState(cx); - - /* Unpin all common atoms before final GC. */ - js_FinishCommonAtoms(cx); - - /* Clear debugging state to remove GC roots. */ - JS_ClearAllTraps(cx); - JS_ClearAllWatchPoints(cx); - } - - /* Remove more GC roots in regExpStatics, then collect garbage. */ - JS_ClearRegExpRoots(cx); - -#ifdef JS_THREADSAFE - /* - * Destroying a context implicitly calls JS_EndRequest(). Also, we must - * end our request here in case we are "last" -- in that event, another - * js_DestroyContext that was not last might be waiting in the GC for our - * request to end. We'll let it run below, just before we do the truly - * final GC and then free atom state. - */ - while (cx->requestDepth != 0) - JS_EndRequest(cx); -#endif - - if (last) { - js_GC(cx, GC_LAST_CONTEXT); - DUMP_EVAL_CACHE_METER(cx); - - /* - * Free the script filename table if it exists and is empty. Do this - * after the last GC to avoid finalizers tripping on free memory. - */ - if (rt->scriptFilenameTable && rt->scriptFilenameTable->nentries == 0) - js_FinishRuntimeScriptState(rt); - - /* Take the runtime down, now that it has no contexts or atoms. */ - JS_LOCK_GC(rt); - rt->state = JSRTS_DOWN; - JS_NOTIFY_ALL_CONDVAR(rt->stateChange); + ) { JS_UNLOCK_GC(rt); - } else { - if (mode == JSDCM_FORCE_GC) - js_GC(cx, GC_NORMAL); - else if (mode == JSDCM_MAYBE_GC) - JS_MaybeGC(cx); + + if (last) { +#ifdef JS_THREADSAFE + /* + * If cx is not in a request already, begin one now so that we wait + * for any racing GC started on a not-last context to finish, before + * we plow ahead and unpin atoms. Note that even though we begin a + * request here if necessary, we end all requests on cx below before + * forcing a final GC. This lets any not-last context destruction + * racing in another thread try to force or maybe run the GC, but by + * that point, rt->state will not be JSRTS_UP, and that GC attempt + * will return early. + */ + if (cx->requestDepth == 0) + JS_BeginRequest(cx); +#endif + + /* Unlock and clear GC things held by runtime pointers. */ + js_FinishRuntimeNumberState(cx); + js_FinishRuntimeStringState(cx); + + /* Unpin all common atoms before final GC. */ + js_FinishCommonAtoms(cx); + + /* Clear debugging state to remove GC roots. */ + JS_ClearAllTraps(cx); + JS_ClearAllWatchPoints(cx); + } + + /* Remove more GC roots in regExpStatics, then collect garbage. */ + JS_ClearRegExpRoots(cx); + +#ifdef JS_THREADSAFE + /* + * Destroying a context implicitly calls JS_EndRequest(). Also, we must + * end our request here in case we are "last" -- in that event, another + * js_DestroyContext that was not last might be waiting in the GC for our + * request to end. We'll let it run below, just before we do the truly + * final GC and then free atom state. + */ + while (cx->requestDepth != 0) + JS_EndRequest(cx); +#endif + + if (last) { + js_GC(cx, GC_LAST_CONTEXT); + DUMP_EVAL_CACHE_METER(cx); + + /* + * Free the script filename table if it exists and is empty. Do this + * after the last GC to avoid finalizers tripping on free memory. + */ + if (rt->scriptFilenameTable && + rt->scriptFilenameTable->nentries == 0) { + js_FinishRuntimeScriptState(rt); + } + + /* Take the runtime down, now that it has no contexts or atoms. */ + JS_LOCK_GC(rt); + rt->state = JSRTS_DOWN; + JS_NOTIFY_ALL_CONDVAR(rt->stateChange); + } else { + if (mode == JSDCM_FORCE_GC) + js_GC(cx, GC_NORMAL); + else if (mode == JSDCM_MAYBE_GC) + JS_MaybeGC(cx); + JS_LOCK_GC(rt); + js_WaitForGC(rt); + } } +#ifdef JS_THREADSAFE + js_ClearContextThread(cx); +#endif + JS_UNLOCK_GC(rt); + FreeContext(cx); +} + +static void +FreeContext(JSContext *cx) +{ + JSArgumentFormatMap *map; + JSLocalRootStack *lrs; + JSLocalRootChunk *lrc; + +#ifdef JS_THREADSAFE + JS_ASSERT(!cx->thread); +#endif /* Free the stuff hanging off of cx. */ js_FreeRegExpStatics(cx); @@ -578,16 +699,6 @@ js_DestroyContext(JSContext *cx, JSDestroyContextMode mode) JS_free(cx, lrs); } -#ifdef JS_THREADSAFE - /* - * Since cx is not on rt->contextList, it cannot be accessed by the GC - * running on another thread. Thus, compared with JS_ClearContextThread, - * we can safely unlink cx from from JSThread.contextList without taking - * the GC lock. - */ - JS_REMOVE_LINK(&cx->threadLinks); -#endif - /* Finally, free cx itself. */ free(cx); } @@ -1504,3 +1615,33 @@ js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp) } return NULL; } + +jsbytecode* +js_GetCurrentBytecodePC(JSContext* cx) +{ + jsbytecode *pc, *imacpc; + +#ifdef JS_TRACER + if (JS_ON_TRACE(cx)) { + pc = cx->bailExit->pc; + imacpc = cx->bailExit->imacpc; + } else +#endif + { + JS_ASSERT_NOT_ON_TRACE(cx); /* for static analysis */ + JSStackFrame* fp = cx->fp; + if (fp && fp->regs) { + pc = fp->regs->pc; + imacpc = fp->imacpc; + } else { + return NULL; + } + } + + /* + * If we are inside GetProperty_tn or similar, return a pointer to the + * current instruction in the script, not the CALL instruction in the + * imacro, for the benefit of callers doing bytecode inspection. + */ + return (*pc == JSOP_CALL && imacpc) ? imacpc : pc; +} diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index c3203c3d389d..011b375f6aa4 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -72,25 +72,20 @@ typedef struct JSGSNCache { uint32 hits; uint32 misses; uint32 fills; - uint32 clears; + uint32 purges; # define GSN_CACHE_METER(cache,cnt) (++(cache)->cnt) #else # define GSN_CACHE_METER(cache,cnt) /* nothing */ #endif } JSGSNCache; -#define GSN_CACHE_CLEAR(cache) \ - JS_BEGIN_MACRO \ - (cache)->code = NULL; \ - if ((cache)->table.ops) { \ - JS_DHashTableFinish(&(cache)->table); \ - (cache)->table.ops = NULL; \ - } \ - GSN_CACHE_METER(cache, clears); \ - JS_END_MACRO +#define js_FinishGSNCache(cache) js_PurgeGSNCache(cache) + +extern void +js_PurgeGSNCache(JSGSNCache *cache); /* These helper macros take a cx as parameter and operate on its GSN cache. */ -#define JS_CLEAR_GSN_CACHE(cx) GSN_CACHE_CLEAR(&JS_GSN_CACHE(cx)) +#define JS_PURGE_GSN_CACHE(cx) js_PurgeGSNCache(&JS_GSN_CACHE(cx)) #define JS_METER_GSN_CACHE(cx,cnt) GSN_CACHE_METER(&JS_GSN_CACHE(cx), cnt) typedef struct InterpState InterpState; @@ -125,7 +120,7 @@ struct GlobalState { * JS_THREADSAFE) has an associated trace monitor that keeps track of loop * frequencies for all JavaScript code loaded into that runtime. */ -typedef struct JSTraceMonitor { +struct JSTraceMonitor { /* * Flag set when running (or recording) JIT-compiled code. This prevents * both interpreter activation and last-ditch garbage collection when up @@ -176,7 +171,7 @@ typedef struct JSTraceMonitor { /* Keep a list of recorders we need to abort on cache flush. */ CLS(TraceRecorder) abortStack; -} JSTraceMonitor; +}; typedef struct InterpStruct InterpStruct; @@ -206,11 +201,31 @@ typedef struct JSEvalCacheMeter { } JSEvalCacheMeter; # undef ID -# define DECLARE_EVAL_CACHE_METER JSEvalCacheMeter evalCacheMeter; -#else -# define DECLARE_EVAL_CACHE_METER /* nothing */ #endif +struct JSThreadData { + /* + * The GSN cache is per thread since even multi-cx-per-thread embeddings + * do not interleave js_GetSrcNote calls. + */ + JSGSNCache gsnCache; + + /* Property cache for faster call/get/set invocation. */ + JSPropertyCache propertyCache; + +#ifdef JS_TRACER + /* Trace-tree JIT recorder/interpreter state. */ + JSTraceMonitor traceMonitor; +#endif + + /* Lock-free hashed lists of scripts created by eval to garbage-collect. */ + JSScript *scriptsToGC[JS_EVAL_CACHE_SIZE]; + +#ifdef JS_EVAL_CACHE_METERING + JSEvalCacheMeter evalCacheMeter; +#endif +}; + #ifdef JS_THREADSAFE /* @@ -230,39 +245,29 @@ struct JSThread { */ uint32 gcMallocBytes; - /* - * Store the GSN cache in struct JSThread, not struct JSContext, both to - * save space and to simplify cleanup in js_GC. Any embedding (Firefox - * or another Gecko application) that uses many contexts per thread is - * unlikely to interleave js_GetSrcNote-intensive loops in the decompiler - * among two or more contexts running script in one thread. - */ - JSGSNCache gsnCache; - - /* Property cache for faster call/get/set invocation. */ - JSPropertyCache propertyCache; - -#ifdef JS_TRACER - /* Trace-tree JIT recorder/interpreter state. */ - JSTraceMonitor traceMonitor; -#endif - - /* Lock-free hashed lists of scripts created by eval to garbage-collect. */ - JSScript *scriptsToGC[JS_EVAL_CACHE_SIZE]; - - DECLARE_EVAL_CACHE_METER + JSThreadData data; }; -#define JS_CACHE_LOCUS(cx) ((cx)->thread) +#define JS_THREAD_DATA(cx) (&(cx)->thread->data) +struct JSThreadsHashEntry { + JSDHashEntryHdr base; + JSThread *thread; +}; + +/* + * The function takes the GC lock and does not release in successful return. + * On error (out of memory) the function releases the lock but delegates + * the error reporting to the caller. + */ +extern JSBool +js_InitContextThread(JSContext *cx); + +/* + * On entrance the GC lock must be held and it will be held on exit. + */ extern void -js_ThreadDestructorCB(void *ptr); - -extern void -js_InitContextThread(JSContext *cx, JSThread *thread); - -extern JSThread * -js_GetCurrentThread(JSRuntime *rt); +js_ClearContextThread(JSContext *cx); #endif /* JS_THREADSAFE */ @@ -474,6 +479,8 @@ struct JSRuntime { * case too. */ PRLock *debuggerLock; + + JSDHashTable threads; #endif /* JS_THREADSAFE */ uint32 debuggerMutations; @@ -523,26 +530,9 @@ struct JSRuntime { JSNativeEnumerator *nativeEnumerators; #ifndef JS_THREADSAFE - /* - * For thread-unsafe embeddings, the GSN cache lives in the runtime and - * not each context, since we expect it to be filled once when decompiling - * a longer script, then hit repeatedly as js_GetSrcNote is called during - * the decompiler activation that filled it. - */ - JSGSNCache gsnCache; + JSThreadData threadData; - /* Property cache for faster call/get/set invocation. */ - JSPropertyCache propertyCache; - - /* Trace-tree JIT recorder/interpreter state. */ - JSTraceMonitor traceMonitor; - - /* Lock-free hashed lists of scripts created by eval to garbage-collect. */ - JSScript *scriptsToGC[JS_EVAL_CACHE_SIZE]; - - DECLARE_EVAL_CACHE_METER - -#define JS_CACHE_LOCUS(cx) ((cx)->runtime) +#define JS_THREAD_DATA(cx) (&(cx)->runtime->threadData) #endif /* @@ -652,13 +642,13 @@ struct JSRuntime { }; /* Common macros to access thread-local caches in JSThread or JSRuntime. */ -#define JS_GSN_CACHE(cx) (JS_CACHE_LOCUS(cx)->gsnCache) -#define JS_PROPERTY_CACHE(cx) (JS_CACHE_LOCUS(cx)->propertyCache) -#define JS_TRACE_MONITOR(cx) (JS_CACHE_LOCUS(cx)->traceMonitor) -#define JS_SCRIPTS_TO_GC(cx) (JS_CACHE_LOCUS(cx)->scriptsToGC) +#define JS_GSN_CACHE(cx) (JS_THREAD_DATA(cx)->gsnCache) +#define JS_PROPERTY_CACHE(cx) (JS_THREAD_DATA(cx)->propertyCache) +#define JS_TRACE_MONITOR(cx) (JS_THREAD_DATA(cx)->traceMonitor) +#define JS_SCRIPTS_TO_GC(cx) (JS_THREAD_DATA(cx)->scriptsToGC) #ifdef JS_EVAL_CACHE_METERING -# define EVAL_CACHE_METER(x) (JS_CACHE_LOCUS(cx)->evalCacheMeter.x++) +# define EVAL_CACHE_METER(x) (JS_THREAD_DATA(cx)->evalCacheMeter.x++) #else # define EVAL_CACHE_METER(x) ((void) 0) #endif @@ -1142,22 +1132,14 @@ class JSAutoResolveFlags #define JS_HAS_XML_OPTION(cx) ((cx)->version & JSVERSION_HAS_XML || \ JSVERSION_NUMBER(cx) >= JSVERSION_1_6) -/* - * Initialize a library-wide thread private data index, and remember that it - * has already been done, so that it happens only once ever. Returns true on - * success. - */ extern JSBool -js_InitThreadPrivateIndex(void (*ptr)(void *)); +js_InitThreads(JSRuntime *rt); -/* - * Clean up thread-private data on the current thread. NSPR automatically - * cleans up thread-private data for every thread except the main thread - * (see bug 383977) on shutdown. Thus, this function should be called for - * exactly those threads that survive JS_ShutDown, including the main thread. - */ -extern JSBool -js_CleanupThreadPrivateData(); +extern void +js_FinishThreads(JSRuntime *rt); + +extern void +js_PurgeThreads(JSContext *cx); /* * Ensures the JSOPTION_XML and JSOPTION_ANONFUNFIX bits of cx->options are @@ -1388,6 +1370,9 @@ js_InvokeOperationCallback(JSContext *cx); extern JSStackFrame * js_GetScriptedCaller(JSContext *cx, JSStackFrame *fp); +extern jsbytecode* +js_GetCurrentBytecodePC(JSContext* cx); + #ifdef JS_TRACER /* * Reconstruct the JS stack and clear cx->onTrace. We must be currently diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp index 698dfdb5140f..e7921d9c46fd 100644 --- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -124,7 +124,7 @@ js_UntrapScriptCode(JSContext *cx, JSScript *script) if (!code) break; memcpy(code, script->code, nbytes); - JS_CLEAR_GSN_CACHE(cx); + JS_PURGE_GSN_CACHE(cx); } code[trap->pc - script->code] = trap->op; } diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 64a0625ad4d3..4267c6a50489 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -2713,4 +2713,8 @@ js_FreezeLocalNames(JSContext *cx, JSFunction *fun) if (array) fun->u.i.names.array = array; } +#ifdef DEBUG + if (n > MAX_ARRAY_LOCALS) + JS_DHashMarkTableImmutable(&fun->u.i.names.map->names); +#endif } diff --git a/js/src/jsfun.h b/js/src/jsfun.h index 403db075ebf7..ba84eb73db74 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -121,8 +121,8 @@ struct JSFunction { #ifdef JS_TRACER /* MSVC demands the intermediate (void *) cast here. */ # define JS_TN(name,fastcall,nargs,flags,trcinfo) \ - {name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs, \ - (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRACEABLE, 0} + JS_FN(name, JS_DATA_TO_FUNC_PTR(JSNative, trcinfo), nargs, \ + (flags) | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRACEABLE) #else # define JS_TN(name,fastcall,nargs,flags,trcinfo) \ JS_FN(name, fastcall, nargs, flags) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 2953df335771..78b0f52580d2 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -3110,24 +3110,34 @@ js_TraceContext(JSTracer *trc, JSContext *acx) js_TraceRegExpStatics(trc, acx); } -void -js_TraceTraceMonitor(JSTracer *trc, JSTraceMonitor *tm) +#ifdef JS_TRACER + +static void +MarkReservedObjects(JSTraceMonitor *tm) { - if (IS_GC_MARKING_TRACER(trc)) { - tm->reservedDoublePoolPtr = tm->reservedDoublePool; - - tm->needFlush = JS_TRUE; - - /* Keep the reserved objects. */ - for (JSObject *obj = tm->reservedObjects; obj; obj = JSVAL_TO_OBJECT(obj->fslots[0])) { - uint8 *flagp = GetGCThingFlags(obj); - JS_ASSERT((*flagp & GCF_TYPEMASK) == GCX_OBJECT); - JS_ASSERT(*flagp != GCF_FINAL); - *flagp |= GCF_MARK; - } + /* Keep the reserved objects. */ + for (JSObject *obj = tm->reservedObjects; obj; obj = JSVAL_TO_OBJECT(obj->fslots[0])) { + uint8 *flagp = GetGCThingFlags(obj); + JS_ASSERT((*flagp & GCF_TYPEMASK) == GCX_OBJECT); + JS_ASSERT(*flagp != GCF_FINAL); + *flagp |= GCF_MARK; } } +#ifdef JS_THREADSAFE +static JSDHashOperator +reserved_objects_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, + uint32, void *) +{ + JSThread *thread = ((JSThreadsHashEntry *) hdr)->thread; + + MarkReservedObjects(&thread->data.traceMonitor); + return JS_DHASH_NEXT; +} +#endif + +#endif + JS_REQUIRES_STACK void js_TraceRuntime(JSTracer *trc, JSBool allAtoms) { @@ -3154,16 +3164,15 @@ js_TraceRuntime(JSTracer *trc, JSBool allAtoms) JS_CALL_OBJECT_TRACER(trc, rt->builtinFunctions[i], "builtin function"); } + /* Mark the reserved objects unless we are shutting down. */ + if (IS_GC_MARKING_TRACER(trc) && rt->state != JSRTS_LANDING) { #ifdef JS_THREADSAFE - /* Trace the loop table(s) which can contain pointers to code objects. */ - while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) { - if (!acx->thread) - continue; - js_TraceTraceMonitor(trc, &acx->thread->traceMonitor); - } + JS_DHashTableEnumerate(&rt->threads, reserved_objects_marker, NULL); #else - js_TraceTraceMonitor(trc, &rt->traceMonitor); + MarkReservedObjects(&rt->threadData.traceMonitor); #endif + } + #endif } @@ -3242,15 +3251,18 @@ ProcessSetSlotRequest(JSContext *cx, JSSetSlotRequest *ssr) STOBJ_SET_DELEGATE(pobj); } -static void -DestroyScriptsToGC(JSContext *cx, JSScript **listp) +void +js_DestroyScriptsToGC(JSContext *cx, JSThreadData *data) { - JSScript *script; + JSScript **listp, *script; - while ((script = *listp) != NULL) { - *listp = script->u.nextToGC; - script->u.nextToGC = NULL; - js_DestroyScript(cx, script); + for (size_t i = 0; i != JS_ARRAY_LENGTH(data->scriptsToGC); ++i) { + listp = &data->scriptsToGC[i]; + while ((script = *listp) != NULL) { + *listp = script->u.nextToGC; + script->u.nextToGC = NULL; + js_DestroyScript(cx, script); + } } } @@ -3282,7 +3294,14 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind) JS_ASSERT_IF(gckind == GC_LAST_DITCH, !JS_ON_TRACE(cx)); rt = cx->runtime; + #ifdef JS_THREADSAFE + /* + * We allow js_GC calls outside a request but the context must be bound + * to the current thread. + */ + JS_ASSERT(CURRENT_THREAD_IS_ME(cx->thread)); + /* Avoid deadlock. */ JS_ASSERT(!JS_IS_RUNTIME_LOCKED(rt)); #endif @@ -3358,11 +3377,10 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind) /* * If we're in one or more requests (possibly on more than one context) * running on the current thread, indicate, temporarily, that all these - * requests are inactive. If cx->thread is NULL, then cx is not using - * the request model, and does not contribute to rt->requestCount. + * requests are inactive. */ requestDebit = 0; - if (cx->thread) { + { JSCList *head, *link; /* @@ -3376,17 +3394,6 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind) if (acx->requestDepth) requestDebit++; } - } else { - /* - * We assert, but check anyway, in case someone is misusing the API. - * Avoiding the loop over all of rt's contexts is a win in the event - * that the GC runs only on request-less contexts with null threads, - * in a special thread such as might be used by the UI/DOM/Layout - * "mozilla" or "main" thread in Mozilla-the-browser. - */ - JS_ASSERT(cx->requestDepth == 0); - if (cx->requestDepth) - requestDebit = 1; } if (requestDebit) { JS_ASSERT(requestDebit <= rt->requestCount); @@ -3496,43 +3503,10 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind) } #endif - /* Clear property and JIT oracle caches (only for cx->thread if JS_THREADSAFE). */ - js_FlushPropertyCache(cx); #ifdef JS_TRACER - js_FlushJITOracle(cx); -#endif - - /* Destroy eval'ed scripts. */ - for (i = 0; i < JS_ARRAY_LENGTH(JS_SCRIPTS_TO_GC(cx)); i++) - DestroyScriptsToGC(cx, &JS_SCRIPTS_TO_GC(cx)[i]); - -#ifdef JS_THREADSAFE - /* - * Clear thread-based caches. To avoid redundant clearing we unroll the - * current thread's step. - * - * In case a JSScript wrapped within an object was finalized, we null - * acx->thread->gsnCache.script and finish the cache's hashtable. Note - * that js_DestroyScript, called from script_finalize, will have already - * cleared cx->thread->gsnCache above during finalization, so we don't - * have to here. - */ - iter = NULL; - while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) { - if (!acx->thread || acx->thread == cx->thread) - continue; - GSN_CACHE_CLEAR(&acx->thread->gsnCache); - js_FlushPropertyCache(acx); -#ifdef JS_TRACER - js_FlushJITOracle(acx); -#endif - for (i = 0; i < JS_ARRAY_LENGTH(acx->thread->scriptsToGC); i++) - DestroyScriptsToGC(cx, &acx->thread->scriptsToGC[i]); - } -#else - /* The thread-unsafe case just has to clear the runtime's GSN cache. */ - GSN_CACHE_CLEAR(&rt->gsnCache); + js_PurgeJITOracle(); #endif + js_PurgeThreads(cx); restart: rt->gcNumber++; diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 1487f964d689..8eb9382c75f1 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -340,6 +340,9 @@ extern const JSGCFreeListSet js_GCEmptyFreeListSet; extern void js_RevokeGCLocalFreeLists(JSContext *cx); +extern void +js_DestroyScriptsToGC(JSContext *cx, JSThreadData *data); + struct JSWeakRoots { /* Most recently created things by type, members of the GC's root set. */ void *newborn[GCX_NTYPES]; diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 4c0fe46447cf..e3ce221179f9 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -170,7 +170,13 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape, tmp = obj; for (;;) { tmp = OBJ_GET_PROTO(cx, tmp); - if (!tmp) { + + /* + * We cannot cache properties coming from native objects behind + * non-native ones on the prototype chain. The non-natives can + * mutate in arbitrary way without changing any shapes. + */ + if (!tmp || !OBJ_IS_NATIVE(tmp)) { PCMETER(cache->noprotos++); *entryp = NULL; return; @@ -426,11 +432,8 @@ js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc, JS_STATIC_ASSERT(PCVAL_NULL == 0); void -js_FlushPropertyCache(JSContext *cx) +js_PurgePropertyCache(JSContext *cx, JSPropertyCache *cache) { - JSPropertyCache *cache; - - cache = &JS_PROPERTY_CACHE(cx); if (cache->empty) { ASSERT_CACHE_IS_EMPTY(cache); return; @@ -498,7 +501,7 @@ js_FlushPropertyCache(JSContext *cx) } void -js_FlushPropertyCacheForScript(JSContext *cx, JSScript *script) +js_PurgePropertyCacheForScript(JSContext *cx, JSScript *script) { JSPropertyCache *cache; JSPropCacheEntry *entry; @@ -564,6 +567,9 @@ js_AllocRawStack(JSContext *cx, uintN nslots, void **markp) { jsval *sp; + JS_ASSERT(nslots != 0); + js_LeaveTrace(cx); + if (!cx->stackPool.first.next) { int64 *timestamp; @@ -5086,7 +5092,6 @@ js_Interpret(JSContext *cx) if (!cx->rval2set) { op2 = js_GetOpcode(cx, script, regs.pc + JSOP_SETCALL_LENGTH); if (op2 != JSOP_DELELEM) { - JS_ASSERT(!(js_CodeSpec[op2].format & JOF_DEL)); JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_LEFTSIDE_OF_ASS); goto error; diff --git a/js/src/jsinterp.h b/js/src/jsinterp.h index b8e38fe2f8cd..6d5653b42317 100644 --- a/js/src/jsinterp.h +++ b/js/src/jsinterp.h @@ -390,11 +390,14 @@ js_FullTestPropertyCache(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject **pobjp, JSPropCacheEntry **entryp); -extern void -js_FlushPropertyCache(JSContext *cx); +/* The property cache does not need a destructor. */ +#define js_FinishPropertyCache(cache) ((void) 0) extern void -js_FlushPropertyCacheForScript(JSContext *cx, JSScript *script); +js_PurgePropertyCache(JSContext *cx, JSPropertyCache *cache); + +extern void +js_PurgePropertyCacheForScript(JSContext *cx, JSScript *script); extern void js_DisablePropertyCache(JSContext *cx); diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index ee6ff7e92f10..a17e3c1ad4a3 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -787,6 +787,17 @@ js_NewNumberInRootedValue(JSContext *cx, jsdouble d, jsval *vp) return js_NewDoubleInRootedValue(cx, d, vp); } +JSBool +js_NewWeaklyRootedNumber(JSContext *cx, jsdouble d, jsval *rval) +{ + jsint i; + if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) { + *rval = INT_TO_JSVAL(i); + return JS_TRUE; + } + return JS_NewDoubleValue(cx, d, rval); +} + /* * Convert a number to C string. The buf must be large enough to accommodate * the result, including '-' and '\0', if base == 10 or d is an integer that diff --git a/js/src/jsnum.h b/js/src/jsnum.h index b2a8e294e9b6..08dec279a011 100644 --- a/js/src/jsnum.h +++ b/js/src/jsnum.h @@ -178,6 +178,13 @@ extern const char js_parseInt_str[]; extern JSBool js_NewNumberInRootedValue(JSContext *cx, jsdouble d, jsval *vp); +/* + * Create a weakly rooted integer or double jsval as appropriate for the given + * jsdouble. + */ +extern JSBool +js_NewWeaklyRootedNumber(JSContext *cx, jsdouble d, jsval *vp); + /* Convert a number to a GC'ed string. */ extern JSString * JS_FASTCALL js_NumberToString(JSContext *cx, jsdouble d); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index d805bb2cc342..a266d39ca91a 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -4203,35 +4203,6 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp) return JS_TRUE; } -static jsbytecode* -js_GetCurrentBytecodePC(JSContext* cx) -{ - jsbytecode *pc, *imacpc; - -#ifdef JS_TRACER - if (JS_ON_TRACE(cx)) { - pc = cx->bailExit->pc; - imacpc = cx->bailExit->imacpc; - } else -#endif - { - JS_ASSERT_NOT_ON_TRACE(cx); /* for static analysis */ - if (cx->fp && cx->fp->regs) { - pc = cx->fp->regs->pc; - imacpc = cx->fp->imacpc; - } else { - return NULL; - } - } - - /* - * If we are inside GetProperty_tn or similar, return a pointer to the - * current instruction in the script, not the CALL instruction in the - * imacro, for the benefit of callers doing bytecode inspection. - */ - return (*pc == JSOP_CALL && imacpc) ? imacpc : pc; -} - JSBool js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp, JSPropCacheEntry **entryp) diff --git a/js/src/jsparse.cpp b/js/src/jsparse.cpp index b1b9fe2ff078..e2801b757ced 100644 --- a/js/src/jsparse.cpp +++ b/js/src/jsparse.cpp @@ -996,29 +996,6 @@ struct BindData { } u; }; -static JSBool -BindArg(JSContext *cx, JSAtom *atom, JSTreeContext *tc) -{ - const char *name; - - /* - * Check for a duplicate parameter name, a "feature" required by ECMA-262. - */ - JS_ASSERT(tc->flags & TCF_IN_FUNCTION); - if (js_LookupLocal(cx, tc->u.fun, atom, NULL) != JSLOCAL_NONE) { - name = js_AtomToPrintableString(cx, atom); - if (!name || - !js_ReportCompileErrorNumber(cx, TS(tc->parseContext), NULL, - JSREPORT_WARNING | JSREPORT_STRICT, - JSMSG_DUPLICATE_FORMAL, - name)) { - return JS_FALSE; - } - } - - return js_AddLocal(cx, tc->u.fun, atom, JSLOCAL_ARG); -} - static JSBool BindLocalVariable(JSContext *cx, JSFunction *fun, JSAtom *atom, JSLocalKind localKind) @@ -1050,7 +1027,6 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc) { JSAtomListElement *ale; - const char *name; JS_ASSERT(tc->flags & TCF_IN_FUNCTION); ATOM_LIST_SEARCH(ale, &tc->decls, atom); @@ -1062,19 +1038,11 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom, } if (js_LookupLocal(cx, tc->u.fun, atom, NULL) != JSLOCAL_NONE) { - name = js_AtomToPrintableString(cx, atom); - if (!name || - !js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn, - JSREPORT_WARNING | JSREPORT_STRICT, - JSMSG_DUPLICATE_FORMAL, - name)) { - return JS_FALSE; - } - } else { - if (!BindLocalVariable(cx, tc->u.fun, atom, JSLOCAL_VAR)) - return JS_FALSE; + js_ReportCompileErrorNumber(cx, TS(tc->parseContext), NULL, + JSREPORT_ERROR, JSMSG_DESTRUCT_DUP_ARG); + return JS_FALSE; } - return JS_TRUE; + return BindLocalVariable(cx, tc->u.fun, atom, JSLOCAL_VAR); } #endif /* JS_HAS_DESTRUCTURING */ @@ -1131,6 +1099,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, JSTreeContext funtc; #if JS_HAS_DESTRUCTURING JSParseNode *item, *list = NULL; + bool destructuringArg = false, duplicatedArg = false; #endif /* Make a TOK_FUNCTION node. */ @@ -1255,6 +1224,11 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, JSParseNode *lhs, *rhs; jsint slot; + /* See comment below in the TOK_NAME case. */ + if (duplicatedArg) + goto report_dup_and_destructuring; + destructuringArg = true; + /* * A destructuring formal parameter turns into one or more * local variables initialized from properties of a single @@ -1305,14 +1279,48 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, #endif /* JS_HAS_DESTRUCTURING */ case TOK_NAME: - if (!BindArg(cx, CURRENT_TOKEN(ts).t_atom, &funtc)) + { + /* + * Check for a duplicate parameter name, a "feature" that + * ECMA-262 requires. Still if any argument is a destructuring + * pattern, we will report error either now or later, when we + * find the first pattern. + */ + JSAtom *atom = CURRENT_TOKEN(ts).t_atom; + if (js_LookupLocal(cx, fun, atom, NULL) != JSLOCAL_NONE) { +#if JS_HAS_DESTRUCTURING + if (destructuringArg) + goto report_dup_and_destructuring; + duplicatedArg = true; +#endif + const char *name = js_AtomToPrintableString(cx, atom); + if (!name || + !js_ReportCompileErrorNumber(cx, TS(tc->parseContext), + NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_DUPLICATE_FORMAL, + name)) { + return NULL; + } + } + if (!js_AddLocal(cx, fun, atom, JSLOCAL_ARG)) return NULL; break; + } default: js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, JSMSG_MISSING_FORMAL); return NULL; + +#if JS_HAS_DESTRUCTURING + report_dup_and_destructuring: + js_ReportCompileErrorNumber(cx, TS(tc->parseContext), NULL, + JSREPORT_ERROR, + JSMSG_DESTRUCT_DUP_ARG); + return NULL; +#endif } } while (js_MatchToken(cx, ts, TOK_COMMA)); diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index 0243f0254db8..36f70a526023 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -101,10 +101,12 @@ typedef struct JSPropCacheEntry JSPropCacheEntry; typedef struct JSSharpObjectMap JSSharpObjectMap; typedef struct JSTempValueRooter JSTempValueRooter; typedef struct JSThread JSThread; +typedef struct JSThreadData JSThreadData; typedef struct JSToken JSToken; typedef struct JSTokenPos JSTokenPos; typedef struct JSTokenPtr JSTokenPtr; typedef struct JSTokenStream JSTokenStream; +typedef struct JSTraceMonitor JSTraceMonitor; typedef struct JSTreeContext JSTreeContext; typedef struct JSTryNote JSTryNote; typedef struct JSWeakRoots JSWeakRoots; diff --git a/js/src/jsregexp.cpp b/js/src/jsregexp.cpp index 052e488758b7..fcae5a976b1f 100644 --- a/js/src/jsregexp.cpp +++ b/js/src/jsregexp.cpp @@ -1267,7 +1267,14 @@ ParseTerm(CompilerState *state) /* Treat this as an octal escape. */ goto doOctal; } - JS_ASSERT(1 <= num && num <= 0x10000); + + /* + * When FindParenCount calls the regex parser recursively (to find + * the number of backrefs) num can be arbitrary and the maximum + * supported number of backrefs does not bound it. + */ + JS_ASSERT_IF(!(state->flags & JSREG_FIND_PAREN_COUNT), + 1 <= num && num <= 0x10000); state->result = NewRENode(state, REOP_BACKREF); if (!state->result) return JS_FALSE; diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 4028e8733232..40c11963398f 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1579,13 +1579,13 @@ js_DestroyScript(JSContext *cx, JSScript *script) JSPRINCIPALS_DROP(cx, script->principals); if (JS_GSN_CACHE(cx).code == script->code) - JS_CLEAR_GSN_CACHE(cx); + JS_PURGE_GSN_CACHE(cx); /* * The GC flushes all property caches, so no need to purge just the * entries for this script. * - * JS_THREADSAFE note: js_FlushPropertyCacheForScript flushes only the + * JS_THREADSAFE note: js_PurgePropertyCacheForScript purges only the * current thread's property cache, so a script not owned by a function * or object, which hands off lifetime management for that script to the * GC, must be used by only one thread over its lifetime. @@ -1606,9 +1606,9 @@ js_DestroyScript(JSContext *cx, JSScript *script) #ifdef CHECK_SCRIPT_OWNER JS_ASSERT(script->owner == cx->thread); #endif - js_FlushPropertyCacheForScript(cx, script); + js_PurgePropertyCacheForScript(cx, script); #ifdef JS_TRACER - js_FlushScriptFragments(cx, script); + js_PurgeScriptFragments(cx, script); #endif } } @@ -1677,6 +1677,17 @@ typedef struct GSNCacheEntry { #define GSN_CACHE_THRESHOLD 100 +void +js_PurgeGSNCache(JSGSNCache *cache) +{ + cache->code = NULL; + if (cache->table.ops) { + JS_DHashTableFinish(&cache->table); + cache->table.ops = NULL; + } + GSN_CACHE_METER(cache, purges); +} + jssrcnote * js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc) { @@ -1714,7 +1725,7 @@ js_GetSrcNoteCached(JSContext *cx, JSScript *script, jsbytecode *pc) if (JS_GSN_CACHE(cx).code != script->code && script->length >= GSN_CACHE_THRESHOLD) { - JS_CLEAR_GSN_CACHE(cx); + JS_PURGE_GSN_CACHE(cx); nsrcnotes = 0; for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index a7e567ca0eca..a27a777fb5e9 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -167,16 +167,6 @@ js_ConcatStrings(JSContext *cx, JSString *left, JSString *right) n = ln + rn; s[n] = 0; -#ifdef JS_TRACER - /* - * Lame hack to avoid trying to deep-bail (@js_ReportAllocationOverflow) - * when called directly from trace. Instead, retry from the interpreter. - * See bug 477351. - */ - if (n > JSSTRING_LENGTH_MASK && JS_ON_TRACE(cx) && !cx->bailExit) - return NULL; -#endif - str = js_NewString(cx, s, n); if (!str) { /* Out of memory: clean up any space we (re-)allocated. */ @@ -608,21 +598,7 @@ str_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSString *str, *str1; jsint slot; - if (flags & JSRESOLVE_ASSIGNING) - return JS_TRUE; - - if (id == ATOM_KEY(cx->runtime->atomState.lengthAtom)) { - v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); - str = JSVAL_TO_STRING(v); - if (!OBJ_DEFINE_PROPERTY(cx, obj, id, INT_TO_JSVAL(17), NULL, NULL, - JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED, NULL)) { - return JS_FALSE; - } - *objp = obj; - return JS_TRUE; - } - - if (!JSVAL_IS_INT(id)) + if (!JSVAL_IS_INT(id) || (flags & JSRESOLVE_ASSIGNING)) return JS_TRUE; v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); @@ -809,24 +785,6 @@ String_p_toString(JSContext* cx, JSObject* obj) JS_ASSERT(JSVAL_IS_STRING(v)); return JSVAL_TO_STRING(v); } - -static JSString* FASTCALL -String_p_substring(JSContext* cx, JSString* str, int32 begin, int32 end) -{ - JS_ASSERT(JS_ON_TRACE(cx)); - - size_t length = JSSTRING_LENGTH(str); - return SubstringTail(cx, str, length, begin, end); -} - -static JSString* FASTCALL -String_p_substring_1(JSContext* cx, JSString* str, int32 begin) -{ - JS_ASSERT(JS_ON_TRACE(cx)); - - size_t length = JSSTRING_LENGTH(str); - return SubstringTail(cx, str, length, begin, length); -} #endif JSString* JS_FASTCALL @@ -1498,39 +1456,9 @@ StringMatchHelper(JSContext *cx, uintN argc, jsval *vp, jsbytecode *pc) static JSBool str_match(JSContext *cx, uintN argc, jsval *vp) { - JSStackFrame *fp; - - for (fp = js_GetTopStackFrame(cx); fp && !fp->regs; fp = fp->down) - JS_ASSERT(!fp->script); - return StringMatchHelper(cx, argc, vp, fp ? fp->regs->pc : NULL); + return StringMatchHelper(cx, argc, vp, js_GetCurrentBytecodePC(cx)); } -#ifdef JS_TRACER -static jsval FASTCALL -String_p_match(JSContext* cx, JSString* str, jsbytecode *pc, JSObject* regexp) -{ - jsval vp[3] = { JSVAL_NULL, STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) }; - JSAutoTempValueRooter tvr(cx, 3, vp); - if (!StringMatchHelper(cx, 1, vp, pc)) { - cx->builtinStatus |= JSBUILTIN_ERROR; - return JSVAL_VOID; - } - return vp[0]; -} - -static jsval FASTCALL -String_p_match_obj(JSContext* cx, JSObject* str, jsbytecode *pc, JSObject* regexp) -{ - jsval vp[3] = { JSVAL_NULL, OBJECT_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp) }; - JSAutoTempValueRooter tvr(cx, 3, vp); - if (!StringMatchHelper(cx, 1, vp, pc)) { - cx->builtinStatus |= JSBUILTIN_ERROR; - return JSVAL_VOID; - } - return vp[0]; -} -#endif - static JSBool str_search(JSContext *cx, uintN argc, jsval *vp) { @@ -1612,7 +1540,7 @@ interpret_dollar(JSContext *cx, jschar *dp, jschar *ep, ReplaceData *rdata, return NULL; } -static JSBool +static JS_REQUIRES_STACK JSBool find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep) { JSString *repstr; @@ -1628,8 +1556,6 @@ find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep) void *mark; JSBool ok; - JS_ASSERT_NOT_ON_TRACE(cx); - /* * Save the regExpStatics from the current regexp, since they may be * clobbered by a RegExp usage in the lambda function. Note that all @@ -1778,7 +1704,7 @@ replace_destroy(JSContext *cx, GlobData *data) rdata->chars = NULL; } -static JSBool +static JS_REQUIRES_STACK JSBool replace_glob(JSContext *cx, jsint count, GlobData *data) { ReplaceData *rdata; @@ -1814,7 +1740,7 @@ replace_glob(JSContext *cx, jsint count, GlobData *data) return JS_TRUE; } -static JSBool +static JS_REQUIRES_STACK JSBool str_replace(JSContext *cx, uintN argc, jsval *vp) { JSObject *lambda; @@ -1833,51 +1759,7 @@ str_replace(JSContext *cx, uintN argc, jsval *vp) return js_StringReplaceHelper(cx, argc, lambda, repstr, vp); } -#ifdef JS_TRACER -static JSString* FASTCALL -String_p_replace_str(JSContext* cx, JSString* str, JSObject* regexp, JSString* repstr) -{ - /* Make sure we will not call regexp.toString() later. This is not a _FAIL builtin. */ - if (OBJ_GET_CLASS(cx, regexp) != &js_RegExpClass) - return NULL; - - jsval vp[4] = { - JSVAL_NULL, STRING_TO_JSVAL(str), OBJECT_TO_JSVAL(regexp), STRING_TO_JSVAL(repstr) - }; - if (!js_StringReplaceHelper(cx, 2, NULL, repstr, vp)) - return NULL; - JS_ASSERT(JSVAL_IS_STRING(vp[0])); - return JSVAL_TO_STRING(vp[0]); -} - -static JSString* FASTCALL -String_p_replace_str2(JSContext* cx, JSString* str, JSString* patstr, JSString* repstr) -{ - jsval vp[4] = { - JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(patstr), STRING_TO_JSVAL(repstr) - }; - if (!js_StringReplaceHelper(cx, 2, NULL, repstr, vp)) - return NULL; - JS_ASSERT(JSVAL_IS_STRING(vp[0])); - return JSVAL_TO_STRING(vp[0]); -} - -static JSString* FASTCALL -String_p_replace_str3(JSContext* cx, JSString* str, JSString* patstr, JSString* repstr, - JSString* flagstr) -{ - jsval vp[5] = { - JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(patstr), STRING_TO_JSVAL(repstr), - STRING_TO_JSVAL(flagstr) - }; - if (!js_StringReplaceHelper(cx, 3, NULL, repstr, vp)) - return NULL; - JS_ASSERT(JSVAL_IS_STRING(vp[0])); - return JSVAL_TO_STRING(vp[0]); -} -#endif - -JSBool +JSBool JS_REQUIRES_STACK js_StringReplaceHelper(JSContext *cx, uintN argc, JSObject *lambda, JSString *repstr, jsval *vp) { @@ -2178,19 +2060,6 @@ str_split(JSContext *cx, uintN argc, jsval *vp) return ok; } -#ifdef JS_TRACER -static JSObject* FASTCALL -String_p_split(JSContext* cx, JSString* str, JSString* sepstr) -{ - // FIXME: Avoid building and then parsing this array. - jsval vp[4] = { JSVAL_NULL, STRING_TO_JSVAL(str), STRING_TO_JSVAL(sepstr), JSVAL_VOID }; - if (!str_split(cx, 2, vp)) - return NULL; - JS_ASSERT(JSVAL_IS_OBJECT(vp[0])); - return JSVAL_TO_OBJECT(vp[0]); -} -#endif - #if JS_HAS_PERL_SUBSTR static JSBool str_substr(JSContext *cx, uintN argc, jsval *vp) @@ -2269,39 +2138,6 @@ str_concat(JSContext *cx, uintN argc, jsval *vp) return JS_TRUE; } -#ifdef JS_TRACER -static JSString* FASTCALL -String_p_concat_1int(JSContext* cx, JSString* str, int32 i) -{ - // FIXME: should be able to use stack buffer and avoid istr... - JSString* istr = js_NumberToString(cx, i); - if (!istr) - return NULL; - return js_ConcatStrings(cx, str, istr); -} - -static JSString* FASTCALL -String_p_concat_2str(JSContext* cx, JSString* str, JSString* a, JSString* b) -{ - str = js_ConcatStrings(cx, str, a); - if (str) - return js_ConcatStrings(cx, str, b); - return NULL; -} - -static JSString* FASTCALL -String_p_concat_3str(JSContext* cx, JSString* str, JSString* a, JSString* b, JSString* c) -{ - str = js_ConcatStrings(cx, str, a); - if (str) { - str = js_ConcatStrings(cx, str, b); - if (str) - return js_ConcatStrings(cx, str, c); - } - return NULL; -} -#endif - static JSBool str_slice(JSContext *cx, uintN argc, jsval *vp) { @@ -2552,32 +2388,13 @@ JS_DEFINE_CALLINFO_2(extern, INT32, js_CompareStrings, STRING, STRING, JS_DEFINE_TRCINFO_1(str_toString, (2, (extern, STRING_RETRY, String_p_toString, CONTEXT, THIS, 1, 1))) -JS_DEFINE_TRCINFO_2(str_substring, - (4, (static, STRING_RETRY, String_p_substring, CONTEXT, THIS_STRING, INT32, INT32, 1, 1)), - (3, (static, STRING_RETRY, String_p_substring_1, CONTEXT, THIS_STRING, INT32, 1, 1))) JS_DEFINE_TRCINFO_1(str_charAt, (3, (extern, STRING_RETRY, js_String_getelem, CONTEXT, THIS_STRING, INT32, 1, 1))) JS_DEFINE_TRCINFO_2(str_charCodeAt, (1, (extern, DOUBLE, js_String_p_charCodeAt0, THIS_STRING, 1, 1)), (2, (extern, DOUBLE, js_String_p_charCodeAt, THIS_STRING, DOUBLE, 1, 1))) -JS_DEFINE_TRCINFO_4(str_concat, - (3, (static, STRING_RETRY, String_p_concat_1int, CONTEXT, THIS_STRING, INT32, 1, 1)), - (3, (extern, STRING_RETRY, js_ConcatStrings, CONTEXT, THIS_STRING, STRING, 1, 1)), - (4, (static, STRING_RETRY, String_p_concat_2str, CONTEXT, THIS_STRING, STRING, STRING, 1, 1)), - (5, (static, STRING_RETRY, String_p_concat_3str, CONTEXT, THIS_STRING, STRING, STRING, STRING, 1, 1))) -JS_DEFINE_TRCINFO_2(str_match, - (4, (static, JSVAL_FAIL, String_p_match, CONTEXT, THIS_STRING, PC, REGEXP, 1, 1)), - (4, (static, JSVAL_FAIL, String_p_match_obj, CONTEXT, THIS, PC, REGEXP, 1, 1))) -JS_DEFINE_TRCINFO_3(str_replace, - (4, (static, STRING_RETRY, String_p_replace_str, CONTEXT, THIS_STRING, REGEXP, STRING, 1, 1)), - (4, (static, STRING_RETRY, String_p_replace_str2, CONTEXT, THIS_STRING, STRING, STRING, 1, 1)), - (5, (static, STRING_RETRY, String_p_replace_str3, CONTEXT, THIS_STRING, STRING, STRING, STRING, 1, 1))) -JS_DEFINE_TRCINFO_1(str_split, - (3, (static, OBJECT_RETRY, String_p_split, CONTEXT, THIS_STRING, STRING, 0, 0))) -JS_DEFINE_TRCINFO_1(str_toLowerCase, - (2, (extern, STRING_RETRY, js_toLowerCase, CONTEXT, THIS_STRING, 1, 1))) -JS_DEFINE_TRCINFO_1(str_toUpperCase, - (2, (extern, STRING_RETRY, js_toUpperCase, CONTEXT, THIS_STRING, 1, 1))) +JS_DEFINE_TRCINFO_1(str_concat, + (3, (extern, STRING_RETRY, js_ConcatStrings, CONTEXT, THIS_STRING, STRING, 1, 1))) #define GENERIC JSFUN_GENERIC_NATIVE #define PRIMITIVE JSFUN_THISP_PRIMITIVE @@ -2593,9 +2410,9 @@ static JSFunctionSpec string_methods[] = { JS_TN(js_toString_str, str_toString, 0,JSFUN_THISP_STRING, str_toString_trcinfo), JS_FN(js_valueOf_str, str_toString, 0,JSFUN_THISP_STRING), JS_FN(js_toJSON_str, str_toString, 0,JSFUN_THISP_STRING), - JS_TN("substring", str_substring, 2,GENERIC_PRIMITIVE, str_substring_trcinfo), - JS_TN("toLowerCase", str_toLowerCase, 0,GENERIC_PRIMITIVE, str_toLowerCase_trcinfo), - JS_TN("toUpperCase", str_toUpperCase, 0,GENERIC_PRIMITIVE, str_toUpperCase_trcinfo), + JS_FN("substring", str_substring, 2,GENERIC_PRIMITIVE), + JS_FN("toLowerCase", str_toLowerCase, 0,GENERIC_PRIMITIVE), + JS_FN("toUpperCase", str_toUpperCase, 0,GENERIC_PRIMITIVE), JS_TN("charAt", str_charAt, 1,GENERIC_PRIMITIVE, str_charAt_trcinfo), JS_TN("charCodeAt", str_charCodeAt, 1,GENERIC_PRIMITIVE, str_charCodeAt_trcinfo), JS_FN("indexOf", str_indexOf, 1,GENERIC_PRIMITIVE), @@ -2608,10 +2425,10 @@ static JSFunctionSpec string_methods[] = { JS_FN("localeCompare", str_localeCompare, 1,GENERIC_PRIMITIVE), /* Perl-ish methods (search is actually Python-esque). */ - JS_TN("match", str_match, 1,GENERIC_PRIMITIVE, str_match_trcinfo), + JS_FN("match", str_match, 1,GENERIC_PRIMITIVE), JS_FN("search", str_search, 1,GENERIC_PRIMITIVE), - JS_TN("replace", str_replace, 2,GENERIC_PRIMITIVE, str_replace_trcinfo), - JS_TN("split", str_split, 2,GENERIC_PRIMITIVE, str_split_trcinfo), + JS_FN("replace", str_replace, 2,GENERIC_PRIMITIVE), + JS_FN("split", str_split, 2,GENERIC_PRIMITIVE), #if JS_HAS_PERL_SUBSTR JS_FN("substr", str_substr, 2,GENERIC_PRIMITIVE), #endif @@ -2657,10 +2474,28 @@ js_String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) *rval = STRING_TO_JSVAL(str); return JS_TRUE; } - STOBJ_SET_SLOT(obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str)); + obj->fslots[JSSLOT_PRIVATE] = STRING_TO_JSVAL(str); return JS_TRUE; } +#ifdef JS_TRACER + +JSObject* FASTCALL +js_String_tn(JSContext* cx, JSObject* proto, JSString* str) +{ + JS_ASSERT(JS_ON_TRACE(cx)); + JSObject* obj = js_NewNativeObject(cx, &js_StringClass, proto, JSSLOT_PRIVATE + 1); + if (!obj) + return NULL; + + obj->fslots[JSSLOT_PRIVATE] = STRING_TO_JSVAL(str); + return obj; +} + +JS_DEFINE_CALLINFO_3(extern, OBJECT, js_String_tn, CONTEXT, CALLEE_PROTOTYPE, STRING, 0, 0) + +#endif /* !JS_TRACER */ + static JSBool str_fromCharCode(JSContext *cx, uintN argc, jsval *vp) { @@ -2872,8 +2707,14 @@ js_InitStringClass(JSContext *cx, JSObject *obj) NULL, string_static_methods); if (!proto) return NULL; - STOBJ_SET_SLOT(proto, JSSLOT_PRIVATE, - STRING_TO_JSVAL(cx->runtime->emptyString)); + proto->fslots[JSSLOT_PRIVATE] = STRING_TO_JSVAL(cx->runtime->emptyString); + if (!js_DefineNativeProperty(cx, proto, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom), + JSVAL_VOID, NULL, NULL, + JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED, 0, 0, + NULL)) { + return JS_FALSE; + } + return proto; } diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 94578ef44d69..bf7c5684b90e 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -133,7 +133,7 @@ static const char tagChar[] = "OIDISIBI"; MAX_CALL_STACK_ENTRIES * sizeof(JSInlineFrame)) /* Max number of branches per tree. */ -#define MAX_BRANCHES 16 +#define MAX_BRANCHES 32 #ifdef JS_JIT_SPEW #define debug_only_a(x) if (js_verboseAbort || js_verboseDebug ) { x; } @@ -240,10 +240,7 @@ js_DumpPeerStability(JSTraceMonitor* tm, const void* ip, uint32 globalShape); #endif /* We really need a better way to configure the JIT. Shaver, where is my fancy JIT object? */ -static bool nesting_enabled = true; -#if defined(NANOJIT_IA32) -static bool did_we_check_sse2 = false; -#endif +static bool did_we_check_processor_features = false; #ifdef JS_JIT_SPEW bool js_verboseDebug = getenv("TRACEMONKEY") && strstr(getenv("TRACEMONKEY"), "verbose"); @@ -570,25 +567,22 @@ js_AttemptCompilation(JSTraceMonitor* tm, JSObject* globalObj, jsbytecode* pc) } } -#if defined(NJ_SOFTFLOAT) JS_DEFINE_CALLINFO_1(static, DOUBLE, i2f, INT32, 1, 1) JS_DEFINE_CALLINFO_1(static, DOUBLE, u2f, UINT32, 1, 1) -#endif static bool isi2f(LInsp i) { if (i->isop(LIR_i2f)) return true; -#if defined(NJ_SOFTFLOAT) - if (i->isop(LIR_qjoin) && + if (nanojit::AvmCore::config.soft_float && + i->isop(LIR_qjoin) && i->oprnd1()->isop(LIR_call) && i->oprnd2()->isop(LIR_callh)) { if (i->oprnd1()->callInfo() == &i2f_ci) return true; } -#endif return false; } @@ -598,25 +592,25 @@ static bool isu2f(LInsp i) if (i->isop(LIR_u2f)) return true; -#if defined(NJ_SOFTFLOAT) - if (i->isop(LIR_qjoin) && + if (nanojit::AvmCore::config.soft_float && + i->isop(LIR_qjoin) && i->oprnd1()->isop(LIR_call) && i->oprnd2()->isop(LIR_callh)) { if (i->oprnd1()->callInfo() == &u2f_ci) return true; } -#endif return false; } static LInsp iu2fArg(LInsp i) { -#if defined(NJ_SOFTFLOAT) - if (i->isop(LIR_qjoin)) + if (nanojit::AvmCore::config.soft_float && + i->isop(LIR_qjoin)) + { return i->oprnd1()->arg(0); -#endif + } return i->oprnd1(); } @@ -675,8 +669,7 @@ static bool overflowSafe(LIns* i) ((c->constval() > 0))); } -#if defined(NJ_SOFTFLOAT) -/* soft float */ +/* soft float support */ JS_DEFINE_CALLINFO_1(static, DOUBLE, fneg, DOUBLE, 1, 1) JS_DEFINE_CALLINFO_2(static, INT32, fcmpeq, DOUBLE, DOUBLE, 1, 1) @@ -830,8 +823,6 @@ public: } }; -#endif // NJ_SOFTFLOAT - class FuncFilter: public LirWriter { public: @@ -959,7 +950,7 @@ public: } else if (ci == &js_BoxDouble_ci) { JS_ASSERT(s0->isQuad()); if (isi2f(s0)) { - LIns* args2[] = { s0->oprnd1(), args[1] }; + LIns* args2[] = { iu2fArg(s0), args[1] }; return out->insCall(&js_BoxInt32_ci, args2); } if (s0->isCall() && s0->callInfo() == &js_UnboxDouble_ci) @@ -1213,6 +1204,9 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* _anchor, Fragment* _frag { JS_ASSERT(!_fragment->vmprivate && ti); + /* Reset the fragment state we care about in case we got a recycled fragment. */ + _fragment->lastIns = NULL; + this->cx = cx; this->traceMonitor = &JS_TRACE_MONITOR(cx); this->globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain); @@ -1226,19 +1220,22 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* _anchor, Fragment* _frag this->deepAborted = false; this->trashSelf = false; this->global_dslots = this->globalObj->dslots; - this->terminate = false; + this->loop = true; /* default assumption is we are compiling a loop */ this->wasRootFragment = _fragment == _fragment->root; this->outer = outer; - + this->generatedTraceableNative = new JSTraceableNative(); + JS_ASSERT(generatedTraceableNative); + debug_only_v(printf("recording starting from %s:%u@%u\n", ti->treeFileName, ti->treeLineNumber, ti->treePCOffset);) debug_only_v(printf("globalObj=%p, shape=%d\n", (void*)this->globalObj, OBJ_SHAPE(this->globalObj));) lir = lir_buf_writer = new (&gc) LirBufWriter(lirbuf); debug_only_v(lir = verbose_filter = new (&gc) VerboseWriter(&gc, lir, lirbuf->names);) -#ifdef NJ_SOFTFLOAT - lir = float_filter = new (&gc) SoftFloatFilter(lir); -#endif + if (nanojit::AvmCore::config.soft_float) + lir = float_filter = new (&gc) SoftFloatFilter(lir); + else + float_filter = 0; lir = cse_filter = new (&gc) CseFilter(lir, &gc); lir = expr_filter = new (&gc) ExprFilter(lir); lir = func_filter = new (&gc) FuncFilter(lir); @@ -1323,10 +1320,9 @@ TraceRecorder::~TraceRecorder() delete cse_filter; delete expr_filter; delete func_filter; -#ifdef NJ_SOFTFLOAT delete float_filter; -#endif delete lir_buf_writer; + delete generatedTraceableNative; } void TraceRecorder::removeFragmentoReferences() @@ -1969,55 +1965,6 @@ TraceRecorder::checkForGlobalObjectReallocation() } } -/* Determine whether the current branch instruction terminates the loop. */ -static bool -js_IsLoopExit(jsbytecode* pc, jsbytecode* header) -{ - switch (*pc) { - case JSOP_LT: - case JSOP_GT: - case JSOP_LE: - case JSOP_GE: - case JSOP_NE: - case JSOP_EQ: - /* These ops try to dispatch a JSOP_IFEQ or JSOP_IFNE that follows. */ - JS_ASSERT(js_CodeSpec[*pc].length == 1); - pc++; - break; - - default: - for (;;) { - if (*pc == JSOP_AND || *pc == JSOP_OR) - pc += GET_JUMP_OFFSET(pc); - else if (*pc == JSOP_ANDX || *pc == JSOP_ORX) - pc += GET_JUMPX_OFFSET(pc); - else - break; - } - } - - switch (*pc) { - case JSOP_IFEQ: - case JSOP_IFNE: - /* - * Forward jumps are usually intra-branch, but for-in loops jump to the - * trailing enditer to clean up, so check for that case here. - */ - if (pc[GET_JUMP_OFFSET(pc)] == JSOP_ENDITER) - return true; - return pc + GET_JUMP_OFFSET(pc) == header; - - case JSOP_IFEQX: - case JSOP_IFNEX: - if (pc[GET_JUMPX_OFFSET(pc)] == JSOP_ENDITER) - return true; - return pc + GET_JUMPX_OFFSET(pc) == header; - - default:; - } - return false; -} - /* Determine whether the current branch is a loop edge (taken or not taken). */ static JS_REQUIRES_STACK bool js_IsLoopEdge(jsbytecode* pc, jsbytecode* header) @@ -2106,8 +2053,6 @@ TraceRecorder::snapshot(ExitType exitType) JSStackFrame* fp = cx->fp; JSFrameRegs* regs = fp->regs; jsbytecode* pc = regs->pc; - if (exitType == BRANCH_EXIT && js_IsLoopExit(pc, (jsbytecode*)fragment->root->ip)) - exitType = LOOP_EXIT; /* Check for a return-value opcode that needs to restart at the next instruction. */ const JSCodeSpec& cs = js_CodeSpec[*pc]; @@ -2496,13 +2441,6 @@ checktype_fail_2: return false; } -/* Check whether the current pc location is the loop header of the loop this recorder records. */ -JS_REQUIRES_STACK bool -TraceRecorder::isLoopHeader(JSContext* cx) const -{ - return cx->fp->regs->pc == fragment->root->ip; -} - /* Compile the current fragment. */ JS_REQUIRES_STACK void TraceRecorder::compile(JSTraceMonitor* tm) @@ -2573,9 +2511,16 @@ js_JoinPeersIfCompatible(Fragmento* frago, Fragment* stableFrag, TreeInfo* stabl } /* Complete and compile a trace and link it to the existing tree if appropriate. */ -JS_REQUIRES_STACK bool +JS_REQUIRES_STACK void TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote) { + /* + * We should have arrived back at the loop header, and hence we don't want to be in an imacro + * here and the opcode should be either JSOP_LOOP, or in case this loop was blacklisted in the + * meantime JSOP_NOP. + */ + JS_ASSERT((*cx->fp->regs->pc == JSOP_LOOP || *cx->fp->regs->pc == JSOP_NOP) && !cx->fp->imacpc); + bool stable; LIns* exitIns; Fragment* peer; @@ -2590,28 +2535,29 @@ TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote) debug_only_v(printf("Blacklisted: stack depth mismatch, possible recursion.\n");) js_Blacklist(fragment->root); trashSelf = true; - return false; + return; } JS_ASSERT(exit->numStackSlots == treeInfo->nStackTypes); peer_root = getLoop(traceMonitor, fragment->root->ip, treeInfo->globalShape); JS_ASSERT(peer_root != NULL); + stable = deduceTypeStability(peer_root, &peer, demote); - #if DEBUG +#if DEBUG if (!stable) AUDIT(unstableLoopVariable); - #endif +#endif if (trashSelf) { debug_only_v(printf("Trashing tree from type instability.\n");) - return false; + return; } if (stable && demote) { JS_ASSERT(fragment->kind == LoopTrace); - return false; + return; } if (!stable) { @@ -2634,15 +2580,6 @@ TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote) uexit->exit = exit; uexit->next = treeInfo->unstableExits; treeInfo->unstableExits = uexit; - - /* - * If we walked out of a loop, this exit is wrong. We need to back - * up to the if operation. - */ - if (walkedOutOfLoop()) { - exit->pc = terminate_pc; - exit->imacpc = terminate_imacpc; - } } else { JS_ASSERT(peer->code()); exit->target = peer; @@ -2651,16 +2588,14 @@ TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote) ((TreeInfo*)peer->vmprivate)->dependentTrees.addUnique(fragment->root); treeInfo->linkedTrees.addUnique(peer); } - - compile(tm); } else { exit->target = fragment->root; fragment->lastIns = lir->insGuard(LIR_loop, lir->insImm(1), exitIns); - compile(tm); } + compile(tm); if (fragmento->assm()->error() != nanojit::None) - return false; + return; joinEdgesToEntry(fragmento, peer_root); @@ -2679,7 +2614,6 @@ TraceRecorder::closeLoop(JSTraceMonitor* tm, bool& demote) cx->fp->script->filename, js_FramePCToLineNumber(cx, cx->fp), FramePCOffset(cx->fp));) - return true; } JS_REQUIRES_STACK void @@ -2885,57 +2819,90 @@ TraceRecorder::trackCfgMerges(jsbytecode* pc) /* Invert the direction of the guard if this is a loop edge that is not taken (thin loop). */ JS_REQUIRES_STACK void -TraceRecorder::flipIf(jsbytecode* pc, bool& cond) +TraceRecorder::emitIf(jsbytecode* pc, bool cond, LIns* x) { + ExitType exitType; if (js_IsLoopEdge(pc, (jsbytecode*)fragment->root->ip)) { - switch (*pc) { - case JSOP_IFEQ: - case JSOP_IFEQX: - if (!cond) - return; - break; - case JSOP_IFNE: - case JSOP_IFNEX: - if (cond) - return; - break; - default: - JS_NOT_REACHED("flipIf"); - } - /* We are about to walk out of the loop, so terminate it with - an inverse loop condition. */ - debug_only_v(printf("Walking out of the loop, terminating it anyway.\n");) - cond = !cond; - terminate = true; - /* If when we get to closeLoop the tree is decided to be type unstable, we need to - reverse this logic because the loop won't be closed after all. Store the real - value of the IP the interpreter expects, so we can use it in our final LIR_x. + exitType = LOOP_EXIT; + + /* + * If we are about to walk out of the loop, generate code for the inverse loop + * condition, pretending we recorded the case that stays on trace. */ - if (*pc == JSOP_IFEQX || *pc == JSOP_IFNEX) - pc += GET_JUMPX_OFFSET(pc); - else - pc += GET_JUMP_OFFSET(pc); - terminate_pc = pc; - terminate_imacpc = cx->fp->imacpc; + if ((*pc == JSOP_IFEQ || *pc == JSOP_IFEQX) == cond) { + JS_ASSERT(*pc == JSOP_IFNE || *pc == JSOP_IFNEX || *pc == JSOP_IFEQ || *pc == JSOP_IFEQX); + debug_only_v(printf("Walking out of the loop, terminating it anyway.\n");) + cond = !cond; + } + + /* + * Conditional guards do not have to be emitted if the condition is constant. We + * make a note whether the loop condition is true or false here, so we later know + * whether to emit a loop edge or a loop end. + */ + if (x->isconst()) { + loop = (x->constval() == cond); + return; + } + } else { + exitType = BRANCH_EXIT; } + if (!x->isconst()) + guard(cond, x, exitType); } /* Emit code for a fused IFEQ/IFNE. */ JS_REQUIRES_STACK void TraceRecorder::fuseIf(jsbytecode* pc, bool cond, LIns* x) { - if (x->isconst()) // no need to guard if condition is constant - return; - if (*pc == JSOP_IFEQ) { - flipIf(pc, cond); - guard(cond, x, BRANCH_EXIT); - trackCfgMerges(pc); - } else if (*pc == JSOP_IFNE) { - flipIf(pc, cond); - guard(cond, x, BRANCH_EXIT); + if (*pc == JSOP_IFEQ || *pc == JSOP_IFNE) { + emitIf(pc, cond, x); + if (*pc == JSOP_IFEQ) + trackCfgMerges(pc); } } +/* Check whether we have reached the end of the trace. */ +JS_REQUIRES_STACK bool +TraceRecorder::checkTraceEnd(jsbytecode *pc) +{ + if (js_IsLoopEdge(pc, (jsbytecode*)fragment->root->ip)) { + /* + * If we compile a loop, the trace should have a zero stack balance at the loop + * edge. Currently we are parked on a comparison op or IFNE/IFEQ, so advance + * pc to the loop header and adjust the stack pointer and pretend we have + * reached the loop header. + */ + if (loop) { + JS_ASSERT(!cx->fp->imacpc && (pc == cx->fp->regs->pc || pc == cx->fp->regs->pc + 1)); + bool fused = pc != cx->fp->regs->pc; + JSFrameRegs orig = *cx->fp->regs; + + cx->fp->regs->pc = (jsbytecode*)fragment->root->ip; + cx->fp->regs->sp -= fused ? 2 : 1; + + bool demote = false; + closeLoop(traceMonitor, demote); + + *cx->fp->regs = orig; + + /* + * If compiling this loop generated new oracle information which will likely + * lead to a different compilation result, immediately trigger another + * compiler run. This is guaranteed to converge since the oracle only + * accumulates adverse information but never drops it (except when we + * flush it during garbage collection.) + */ + if (demote) + js_AttemptCompilation(traceMonitor, globalObj, outer); + } else { + endLoop(traceMonitor); + } + return false; + } + return true; +} + bool TraceRecorder::hasMethod(JSObject* obj, jsid id) { @@ -3563,42 +3530,6 @@ static JS_REQUIRES_STACK VMSideExit* js_ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount, VMSideExit** innermostNestedGuardp); -static JS_REQUIRES_STACK bool -js_CloseLoop(JSContext* cx) -{ - JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx); - Fragmento* fragmento = tm->fragmento; - TraceRecorder* r = tm->recorder; - JS_ASSERT(fragmento && r); - bool walkedOutOfLoop = r->walkedOutOfLoop(); - - if (fragmento->assm()->error()) { - js_AbortRecording(cx, "Error during recording"); - return false; - } - - bool demote = false; - Fragment* f = r->getFragment(); - TreeInfo* ti = r->getTreeInfo(); - uint32 globalShape = ti->globalShape; - SlotList* globalSlots = ti->globalSlots; - r->closeLoop(tm, demote); - - /* - * If js_DeleteRecorder flushed the code cache, we can't rely on f any more. - */ - if (!js_DeleteRecorder(cx)) - return false; - - /* - * If we just walked out of a thin loop, we can't immediately start the - * compiler again here since we didn't return to the loop header. - */ - if (demote && !walkedOutOfLoop) - return js_RecordTree(cx, tm, f, NULL, globalShape, globalSlots); - return false; -} - JS_REQUIRES_STACK bool js_RecordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCallCount) { @@ -3608,117 +3539,118 @@ js_RecordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCallCount) return false; /* we stay away from shared global objects */ } #endif + JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx); TreeInfo* ti = r->getTreeInfo(); + /* Process deep abort requests. */ if (r->wasDeepAborted()) { js_AbortRecording(cx, "deep abort requested"); return false; } - /* If we hit our own loop header, close the loop and compile the trace. */ - if (r->isLoopHeader(cx)) - return js_CloseLoop(cx); - /* does this branch go to an inner loop? */ + + JS_ASSERT(r->getFragment() && !r->getFragment()->lastIns); + + /* Does this branch go to an inner loop? */ Fragment* f = getLoop(&JS_TRACE_MONITOR(cx), cx->fp->regs->pc, ti->globalShape); - if (nesting_enabled && f) { - - /* Cannot handle treecalls with callDepth > 0 and argc > nargs, see bug 480244. */ - if (r->getCallDepth() > 0 && - cx->fp->argc > cx->fp->fun->nargs) { - js_AbortRecording(cx, "Can't call inner tree with extra args in pending frame"); - return false; - } - - /* Make sure inner tree call will not run into an out-of-memory condition. */ - if (tm->reservedDoublePoolPtr < (tm->reservedDoublePool + MAX_NATIVE_STACK_SLOTS) && - !js_ReplenishReservedPool(cx, tm)) { - js_AbortRecording(cx, "Couldn't call inner tree (out of memory)"); - return false; - } - - /* Make sure the shape of the global object still matches (this might flush - the JIT cache). */ - JSObject* globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain); - uint32 globalShape = -1; - SlotList* globalSlots = NULL; - if (!js_CheckGlobalObjectShape(cx, tm, globalObj, &globalShape, &globalSlots)) { - js_AbortRecording(cx, "Couldn't call inner tree (prep failed)"); - return false; - } - - debug_only_v(printf("Looking for type-compatible peer (%s:%d@%d)\n", - cx->fp->script->filename, - js_FramePCToLineNumber(cx, cx->fp), - FramePCOffset(cx->fp));) - - /* Find an acceptable peer, make sure our types fit. */ - Fragment* empty; - bool success = false; - - f = r->findNestedCompatiblePeer(f, &empty); - if (f && f->code()) - success = r->adjustCallerTypes(f); - - if (!success) { - AUDIT(noCompatInnerTrees); - - jsbytecode* outer = (jsbytecode*)tm->recorder->getFragment()->root->ip; - js_AbortRecording(cx, "No compatible inner tree"); - - f = empty; - if (!f) { - f = getAnchor(tm, cx->fp->regs->pc, globalShape); - if (!f) { - js_FlushJITCache(cx); - return false; - } - } - return js_RecordTree(cx, tm, f, outer, globalShape, globalSlots); - } - - r->prepareTreeCall(f); - VMSideExit* innermostNestedGuard = NULL; - VMSideExit* lr = js_ExecuteTree(cx, f, inlineCallCount, &innermostNestedGuard); - if (!lr || r->wasDeepAborted()) { - if (!lr) - js_AbortRecording(cx, "Couldn't call inner tree"); - return false; - } - jsbytecode* outer = (jsbytecode*)tm->recorder->getFragment()->root->ip; - switch (lr->exitType) { - case LOOP_EXIT: - /* If the inner tree exited on an unknown loop exit, grow the tree around it. */ - if (innermostNestedGuard) { - js_AbortRecording(cx, "Inner tree took different side exit, abort current " - "recording and grow nesting tree"); - return js_AttemptToExtendTree(cx, innermostNestedGuard, lr, outer); - } - /* emit a call to the inner tree and continue recording the outer tree trace */ - r->emitTreeCall(f, lr); - return true; - case UNSTABLE_LOOP_EXIT: - /* abort recording so the inner loop can become type stable. */ - js_AbortRecording(cx, "Inner tree is trying to stabilize, abort outer recording"); - return js_AttemptToStabilizeTree(cx, lr, outer); - case BRANCH_EXIT: - /* abort recording the outer tree, extend the inner tree */ - js_AbortRecording(cx, "Inner tree is trying to grow, abort outer recording"); - return js_AttemptToExtendTree(cx, lr, NULL, outer); - default: - debug_only_v(printf("exit_type=%d\n", lr->exitType);) - js_AbortRecording(cx, "Inner tree not suitable for calling"); - return false; - } + if (!f) { + /* Not an inner loop we can call, abort trace. */ + AUDIT(returnToDifferentLoopHeader); + JS_ASSERT(!cx->fp->imacpc); + debug_only_v(printf("loop edge to %d, header %d\n", + cx->fp->regs->pc - cx->fp->script->code, + (jsbytecode*)r->getFragment()->root->ip - cx->fp->script->code)); + js_AbortRecording(cx, "Loop edge does not return to header"); + return false; } - /* not returning to our own loop header, not an inner loop we can call, abort trace */ - AUDIT(returnToDifferentLoopHeader); - JS_ASSERT(!cx->fp->imacpc); - debug_only_v(printf("loop edge to %d, header %d\n", - cx->fp->regs->pc - cx->fp->script->code, - (jsbytecode*)r->getFragment()->root->ip - cx->fp->script->code)); - js_AbortRecording(cx, "Loop edge does not return to header"); - return false; + /* Cannot handle treecalls with callDepth > 0 and argc > nargs, see bug 480244. */ + if (r->getCallDepth() > 0 && cx->fp->argc > cx->fp->fun->nargs) { + js_AbortRecording(cx, "Can't call inner tree with extra args in pending frame"); + return false; + } + + /* Make sure inner tree call will not run into an out-of-memory condition. */ + if (tm->reservedDoublePoolPtr < (tm->reservedDoublePool + MAX_NATIVE_STACK_SLOTS) && + !js_ReplenishReservedPool(cx, tm)) { + js_AbortRecording(cx, "Couldn't call inner tree (out of memory)"); + return false; + } + + /* Make sure the shape of the global object still matches (this might flush + the JIT cache). */ + JSObject* globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain); + uint32 globalShape = -1; + SlotList* globalSlots = NULL; + if (!js_CheckGlobalObjectShape(cx, tm, globalObj, &globalShape, &globalSlots)) { + js_AbortRecording(cx, "Couldn't call inner tree (prep failed)"); + return false; + } + + debug_only_v(printf("Looking for type-compatible peer (%s:%d@%d)\n", + cx->fp->script->filename, + js_FramePCToLineNumber(cx, cx->fp), + FramePCOffset(cx->fp));) + + /* Find an acceptable peer, make sure our types fit. */ + Fragment* empty; + bool success = false; + + f = r->findNestedCompatiblePeer(f, &empty); + if (f && f->code()) + success = r->adjustCallerTypes(f); + + if (!success) { + AUDIT(noCompatInnerTrees); + + jsbytecode* outer = (jsbytecode*)tm->recorder->getFragment()->root->ip; + js_AbortRecording(cx, "No compatible inner tree"); + + f = empty; + if (!f) { + f = getAnchor(tm, cx->fp->regs->pc, globalShape); + if (!f) { + js_FlushJITCache(cx); + return false; + } + } + return js_RecordTree(cx, tm, f, outer, globalShape, globalSlots); + } + + r->prepareTreeCall(f); + VMSideExit* innermostNestedGuard = NULL; + VMSideExit* lr = js_ExecuteTree(cx, f, inlineCallCount, &innermostNestedGuard); + if (!lr || r->wasDeepAborted()) { + if (!lr) + js_AbortRecording(cx, "Couldn't call inner tree"); + return false; + } + + jsbytecode* outer = (jsbytecode*)tm->recorder->getFragment()->root->ip; + switch (lr->exitType) { + case LOOP_EXIT: + /* If the inner tree exited on an unknown loop exit, grow the tree around it. */ + if (innermostNestedGuard) { + js_AbortRecording(cx, "Inner tree took different side exit, abort current " + "recording and grow nesting tree"); + return js_AttemptToExtendTree(cx, innermostNestedGuard, lr, outer); + } + /* emit a call to the inner tree and continue recording the outer tree trace */ + r->emitTreeCall(f, lr); + return true; + case UNSTABLE_LOOP_EXIT: + /* abort recording so the inner loop can become type stable. */ + js_AbortRecording(cx, "Inner tree is trying to stabilize, abort outer recording"); + return js_AttemptToStabilizeTree(cx, lr, outer); + case BRANCH_EXIT: + /* abort recording the outer tree, extend the inner tree */ + js_AbortRecording(cx, "Inner tree is trying to grow, abort outer recording"); + return js_AttemptToExtendTree(cx, lr, NULL, outer); + default: + debug_only_v(printf("exit_type=%d\n", lr->exitType);) + js_AbortRecording(cx, "Inner tree not suitable for calling"); + return false; + } } static bool @@ -4347,77 +4279,38 @@ js_MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount) JS_REQUIRES_STACK JSMonitorRecordingStatus TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op) { - if (tr->lirbuf->outOMem()) { - js_AbortRecording(cx, "no more LIR memory"); - js_FlushJITCache(cx); - return JSMRS_STOP; - } - /* Process deepAbort() requests now. */ if (tr->wasDeepAborted()) { js_AbortRecording(cx, "deep abort requested"); return JSMRS_STOP; } - if (tr->walkedOutOfLoop()) { - if (!js_CloseLoop(cx)) - return JSMRS_STOP; - } else { - /* Clear one-shot state used to communicate between record_JSOP_CALL and post- - opcode-case-guts record hook (record_FastNativeCallComplete). */ - tr->pendingTraceableNative = NULL; + JS_ASSERT(!tr->fragment->lastIns); - jsbytecode* pc = cx->fp->regs->pc; + /* + * Clear one-shot state used to communicate between record_JSOP_CALL and post- + * opcode-case-guts record hook (record_FastNativeCallComplete). + */ + tr->pendingTraceableNative = NULL; - /* If we hit a break, end the loop and generate an always taken loop exit guard. - For other downward gotos (like if/else) continue recording. */ - if (*pc == JSOP_GOTO || *pc == JSOP_GOTOX) { - jssrcnote* sn = js_GetSrcNote(cx->fp->script, pc); - if (sn && SN_TYPE(sn) == SRC_BREAK) { - AUDIT(breakLoopExits); - tr->endLoop(&JS_TRACE_MONITOR(cx)); - js_DeleteRecorder(cx); - return JSMRS_STOP; /* done recording */ - } - } - - /* An explicit return from callDepth 0 should end the loop, not abort it. */ - if (*pc == JSOP_RETURN && tr->callDepth == 0) { - AUDIT(returnLoopExits); - tr->endLoop(&JS_TRACE_MONITOR(cx)); - js_DeleteRecorder(cx); - return JSMRS_STOP; /* done recording */ - } - -#ifdef NANOJIT_IA32 - /* Handle tableswitches specially -- prepare a jump table if needed. */ - if (*pc == JSOP_TABLESWITCH || *pc == JSOP_TABLESWITCHX) { - LIns* guardIns = tr->tableswitch(); - if (guardIns) { - tr->fragment->lastIns = guardIns; - tr->compile(&JS_TRACE_MONITOR(cx)); - js_DeleteRecorder(cx); - return JSMRS_STOP; - } - } -#endif - } + debug_only_v(js_Disassemble1(cx, cx->fp->script, cx->fp->regs->pc, + (cx->fp->imacpc) + ? 0 + : cx->fp->regs->pc - cx->fp->script->code, + !cx->fp->imacpc, stdout);) /* If op is not a break or a return from a loop, continue recording and follow the trace. We check for imacro-calling bytecodes inside each switch case to resolve the if (JSOP_IS_IMACOP(x)) conditions at compile time. */ bool flag; +#ifdef DEBUG + bool wasInImacro = (cx->fp->imacpc != NULL); +#endif switch (op) { - default: goto abort_recording; + default: goto stop_recording; # define OPDEF(x,val,name,token,length,nuses,ndefs,prec,format) \ case x: \ - debug_only_v( \ - js_Disassemble1(cx, cx->fp->script, cx->fp->regs->pc, \ - (cx->fp->imacpc) \ - ? 0 \ - : cx->fp->regs->pc - cx->fp->script->code, \ - !cx->fp->imacpc, stdout);) \ flag = tr->record_##x(); \ if (JSOP_IS_IMACOP(x)) \ goto imacro; \ @@ -4426,9 +4319,29 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op) # undef OPDEF } + JS_ASSERT_IF(!wasInImacro, cx->fp->imacpc == NULL); + + /* Process deepAbort() requests now. */ + if (tr->wasDeepAborted()) { + js_AbortRecording(cx, "deep abort requested"); + return JSMRS_STOP; + } + + if (JS_TRACE_MONITOR(cx).fragmento->assm()->error()) { + js_AbortRecording(cx, "error during recording"); + return JSMRS_STOP; + } + + if (tr->lirbuf->outOMem()) { + js_AbortRecording(cx, "no more LIR memory"); + js_FlushJITCache(cx); + return JSMRS_STOP; + } + if (flag) return JSMRS_CONTINUE; - goto abort_recording; + + goto stop_recording; imacro: /* We save macro-generated code size also via bool TraceRecorder::record_JSOP_* @@ -4443,7 +4356,14 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op) return JSMRS_IMACRO; } - abort_recording: + stop_recording: + /* If we recorded the end of the trace, destroy the recorder now. */ + if (tr->fragment->lastIns) { + js_DeleteRecorder(cx); + return JSMRS_STOP; + } + + /* Looks like we encountered an error condition. Abort recording. */ js_AbortRecording(cx, js_CodeName[op]); return JSMRS_STOP; } @@ -4529,16 +4449,139 @@ js_CheckForSSE2() } #endif +#if defined(NANOJIT_ARM) + +#if defined(_MSC_VER) && defined(WINCE) + +// these come in from jswince.asm +extern "C" int js_arm_try_armv6t2_op(); +extern "C" int js_arm_try_vfp_op(); + +static bool +js_arm_check_armv6t2() { + bool ret = false; + __try { + js_arm_try_armv6t2_op(); + ret = true; + } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) { + ret = false; + } + return ret; +} + +static bool +js_arm_check_vfp() { + bool ret = false; + __try { + js_arm_try_vfp_op(); + ret = true; + } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) { + ret = false; + } + return ret; +} + +#elif defined(__GNUC__) && defined(AVMPLUS_LINUX) + +#include +#include +#include +#include +#include +#include +#include +#include + +static bool arm_has_v7 = false; +static bool arm_has_v6 = false; +static bool arm_has_vfp = false; +static bool arm_has_neon = false; +static bool arm_has_iwmmxt = false; +static bool arm_tests_initialized = false; + +static void +arm_read_auxv() { + int fd; + Elf32_auxv_t aux; + + fd = open("/proc/self/auxv", O_RDONLY); + if (fd > 0) { + while (read(fd, &aux, sizeof(Elf32_auxv_t))) { + if (aux.a_type == AT_HWCAP) { + uint32_t hwcap = aux.a_un.a_val; + if (getenv("ARM_FORCE_HWCAP")) + hwcap = strtoul(getenv("ARM_FORCE_HWCAP"), NULL, 0); + // hardcode these values to avoid depending on specific versions + // of the hwcap header, e.g. HWCAP_NEON + arm_has_vfp = (hwcap & 64) != 0; + arm_has_iwmmxt = (hwcap & 512) != 0; + // this flag is only present on kernel 2.6.29 + arm_has_neon = (hwcap & 4096) != 0; + } else if (aux.a_type == AT_PLATFORM) { + const char *plat = (const char*) aux.a_un.a_val; + if (getenv("ARM_FORCE_PLATFORM")) + plat = getenv("ARM_FORCE_PLATFORM"); + if (strncmp(plat, "v7l", 3) == 0) { + arm_has_v7 = true; + arm_has_v6 = true; + } else if (strncmp(plat, "v6l", 3) == 0) { + arm_has_v6 = true; + } + } + } + close (fd); + + // if we don't have 2.6.29, we have to do this hack; set + // the env var to trust HWCAP. + if (!getenv("ARM_TRUST_HWCAP") && arm_has_v7) + arm_has_neon = true; + } + + arm_tests_initialized = true; +} + +static bool +js_arm_check_armv6t2() { + if (!arm_tests_initialized) + arm_read_auxv(); + + return arm_has_v7; +} + +static bool +js_arm_check_vfp() { + if (!arm_tests_initialized) + arm_read_auxv(); + + return arm_has_vfp; +} + +#else +#warning Not sure how to check for armv6t2 and vfp on your platform, assuming neither present. +static bool +js_arm_check_armv6t2() { return false; } +static bool +js_arm_check_vfp() { return false; } +#endif + +#endif /* NANOJIT_ARM */ + void js_InitJIT(JSTraceMonitor *tm) { + if (!did_we_check_processor_features) { #if defined NANOJIT_IA32 - if (!did_we_check_sse2) { avmplus::AvmCore::config.use_cmov = avmplus::AvmCore::config.sse2 = js_CheckForSSE2(); - did_we_check_sse2 = true; - } #endif +#if defined NANOJIT_ARM + avmplus::AvmCore::config.vfp = js_arm_check_vfp(); + avmplus::AvmCore::config.soft_float = !avmplus::AvmCore::config.vfp; + avmplus::AvmCore::config.v6t2 = js_arm_check_armv6t2(); +#endif + did_we_check_processor_features = true; + } + if (!tm->fragmento) { JS_ASSERT(!tm->reservedDoublePool); Fragmento* fragmento = new (&gc) Fragmento(core, 24); @@ -4641,19 +4684,17 @@ TraceRecorder::popAbortStack() } void -js_FlushJITOracle(JSContext* cx) +js_PurgeJITOracle() { - if (!TRACING_ENABLED(cx)) - return; oracle.clear(); } JS_REQUIRES_STACK void -js_FlushScriptFragments(JSContext* cx, JSScript* script) +js_PurgeScriptFragments(JSContext* cx, JSScript* script) { if (!TRACING_ENABLED(cx)) return; - debug_only_v(printf("Flushing fragments for JSScript %p.\n", (void*)script);) + debug_only_v(printf("Purging fragments for JSScript %p.\n", (void*)script);) JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx); for (size_t i = 0; i < FRAGMENT_TABLE_SIZE; ++i) { for (VMFragment **f = &(tm->vmfragments[i]); *f; ) { @@ -4991,15 +5032,11 @@ TraceRecorder::ifop() bool cond; LIns* x; - /* No need to guard if condition is constant. */ - if (v_ins->isconst() || v_ins->isconstq()) - return true; - - /* No need to guard if type strictly determines true or false value. */ - if (JSVAL_TAG(v) == JSVAL_OBJECT) - return true; - - if (JSVAL_TAG(v) == JSVAL_BOOLEAN) { + /* Objects always evaluate to true since we specialize the Null type on trace. */ + if (JSVAL_TAG(v) == JSVAL_OBJECT) { + cond = true; + x = lir->insImm(1); + } else if (JSVAL_TAG(v) == JSVAL_BOOLEAN) { /* Test for boolean is true, negate later if we are testing for false. */ cond = JSVAL_TO_PSEUDO_BOOLEAN(v) == JS_TRUE; x = lir->ins2i(LIR_eq, v_ins, 1); @@ -5020,9 +5057,10 @@ TraceRecorder::ifop() JS_NOT_REACHED("ifop"); return false; } - flipIf(cx->fp->regs->pc, cond); - guard(cond, x, BRANCH_EXIT); - return true; + + jsbytecode* pc = cx->fp->regs->pc; + emitIf(pc, cond, x); + return checkTraceEnd(pc); } #ifdef NANOJIT_IA32 @@ -5385,13 +5423,22 @@ TraceRecorder::equalityHelper(jsval l, jsval r, LIns* l_ins, LIns* r_ins, cond = !cond; } + jsbytecode* pc = cx->fp->regs->pc; + /* * Don't guard if the same path is always taken. If it isn't, we have to * fuse comparisons and the following branch, because the interpreter does * that. */ - if (tryBranchAfterCond && !x->isconst()) - fuseIf(cx->fp->regs->pc + 1, cond, x); + if (tryBranchAfterCond) + fuseIf(pc + 1, cond, x); + + /* + * There is no need to write out the result of this comparison if the trace + * ends on this operation. + */ + if ((pc[1] == JSOP_IFNE || pc[1] == JSOP_IFEQ) && !checkTraceEnd(pc + 1)) + return false; /* * We update the stack after the guard. This is safe since the guard bails @@ -5400,6 +5447,7 @@ TraceRecorder::equalityHelper(jsval l, jsval r, LIns* l_ins, LIns* r_ins, * calculated and saved on the stack in most cases. */ set(&rval, x); + return true; } @@ -5505,13 +5553,22 @@ TraceRecorder::relational(LOpcode op, bool tryBranchAfterCond) } x = lir->ins2(op, l_ins, r_ins); + jsbytecode* pc = cx->fp->regs->pc; + /* * Don't guard if the same path is always taken. If it isn't, we have to * fuse comparisons and the following branch, because the interpreter does * that. */ - if (tryBranchAfterCond && !x->isconst()) - fuseIf(cx->fp->regs->pc + 1, cond, x); + if (tryBranchAfterCond) + fuseIf(pc + 1, cond, x); + + /* + * There is no need to write out the result of this comparison if the trace + * ends on this operation. + */ + if ((pc[1] == JSOP_IFNE || pc[1] == JSOP_IFEQ) && !checkTraceEnd(pc + 1)) + return false; /* * We update the stack after the guard. This is safe since the guard bails @@ -5520,6 +5577,7 @@ TraceRecorder::relational(LOpcode op, bool tryBranchAfterCond) * calculated and saved on the stack in most cases. */ set(&l, x); + return true; } @@ -6166,6 +6224,14 @@ TraceRecorder::record_JSOP_LEAVEWITH() JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_RETURN() { + /* A return from callDepth 0 terminates the current loop. */ + if (callDepth == 0) { + AUDIT(returnLoopExits); + endLoop(traceMonitor); + return false; + } + + /* If we inlined this function call, make the return value available to the caller code. */ jsval& rval = stackval(-1); JSStackFrame *fp = cx->fp; if ((cx->fp->flags & JSFRAME_CONSTRUCTING) && JSVAL_IS_PRIMITIVE(rval)) { @@ -6176,12 +6242,24 @@ TraceRecorder::record_JSOP_RETURN() } debug_only_v(printf("returning from %s\n", js_AtomToPrintableString(cx, cx->fp->fun->atom));) clearFrameSlotsFromCache(); + return true; } JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_GOTO() { + /* + * If we hit a break, end the loop and generate an always taken loop exit guard. + * For other downward gotos (like if/else) continue recording. + */ + jssrcnote* sn = js_GetSrcNote(cx->fp->script, cx->fp->regs->pc); + + if (sn && SN_TYPE(sn) == SRC_BREAK) { + AUDIT(breakLoopExits); + endLoop(traceMonitor); + return false; + } return true; } @@ -6600,71 +6678,95 @@ TraceRecorder::newArray(JSObject *ctor, uint32 argc, jsval *argv, jsval *rval) return true; } -JS_REQUIRES_STACK bool -TraceRecorder::functionCall(bool constructing, uintN argc) +bool +TraceRecorder::newString(JSObject* ctor, jsval& arg, jsval* rval) { + if (!JSVAL_IS_PRIMITIVE(arg)) + return call_imacro(new_imacros.String); + + LIns* proto_ins; + if (!getClassPrototype(ctor, proto_ins)) + return false; + + LIns* args[] = { stringify(arg), proto_ins, cx_ins }; + LIns* obj_ins = lir->insCall(&js_String_tn_ci, args); + guard(false, lir->ins_eq0(obj_ins), OOM_EXIT); + + set(rval, obj_ins); + return true; +} + +JS_REQUIRES_STACK bool +TraceRecorder::emitNativeCall(JSTraceableNative* known, uintN argc, LIns* args[]) +{ + bool constructing = known->flags & JSTN_CONSTRUCTOR; + + if (JSTN_ERRTYPE(known) == FAIL_STATUS) { + // This needs to capture the pre-call state of the stack. So do not set + // pendingTraceableNative before taking this snapshot. + JS_ASSERT(!pendingTraceableNative); + + // Take snapshot for deep LeaveTree and store it in cx->bailExit. + LIns* rec_ins = snapshot(DEEP_BAIL_EXIT); + GuardRecord* rec = (GuardRecord *) rec_ins->payload(); + JS_ASSERT(rec->exit); + lir->insStorei(INS_CONSTPTR(rec->exit), cx_ins, offsetof(JSContext, bailExit)); + + // Tell nanojit not to discard or defer stack writes before this call. + lir->insGuard(LIR_xbarrier, rec_ins, rec_ins); + } + + LIns* res_ins = lir->insCall(known->builtin, args); + if (!constructing) + rval_ins = res_ins; + switch (JSTN_ERRTYPE(known)) { + case FAIL_NULL: + guard(false, lir->ins_eq0(res_ins), OOM_EXIT); + break; + case FAIL_NEG: + res_ins = lir->ins1(LIR_i2f, res_ins); + guard(false, lir->ins2(LIR_flt, res_ins, lir->insImmq(0)), OOM_EXIT); + break; + case FAIL_VOID: + guard(false, lir->ins2i(LIR_eq, res_ins, JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID)), OOM_EXIT); + break; + case FAIL_COOKIE: + guard(false, lir->ins2(LIR_eq, res_ins, INS_CONST(JSVAL_ERROR_COOKIE)), OOM_EXIT); + break; + default:; + } + + set(&stackval(0 - (2 + argc)), res_ins); + + if (!constructing) { + /* + * The return value will be processed by FastNativeCallComplete since + * we have to know the actual return value type for calls that return + * jsval (like Array_p_pop). + */ + pendingTraceableNative = known; + } + + return true; +} + +/* + * Check whether we have a specialized implementation for this fast native invocation. + */ +JS_REQUIRES_STACK bool +TraceRecorder::callTraceableNative(JSFunction* fun, uintN argc, bool constructing) +{ + JSTraceableNative* known = FUN_TRCINFO(fun); + JS_ASSERT(known && (JSFastNative)fun->u.n.native == known->native); + JSStackFrame* fp = cx->fp; jsbytecode *pc = fp->regs->pc; jsval& fval = stackval(0 - (2 + argc)); - JS_ASSERT(&fval >= StackBase(fp)); + jsval& tval = stackval(0 - (1 + argc)); - if (!VALUE_IS_FUNCTION(cx, fval)) - ABORT_TRACE("callee is not a function"); - - jsval& tval = stackval(0 - (argc + 1)); LIns* this_ins = get(&tval); - /* - * If this is NULL, this is a shapeless call. If we observe a shapeless call - * at recording time, the call at this point will always be shapeless so we - * can make the decision based on recording-time introspection of this. - */ - if (tval == JSVAL_NULL && !guardCallee(fval)) - return false; - - /* - * Require that the callee be a function object, to avoid guarding on its - * class here. We know if the callee and this were pushed by JSOP_CALLNAME - * or JSOP_CALLPROP that callee is a *particular* function, since these hit - * the property cache and guard on the object (this) in which the callee - * was found. So it's sufficient to test here that the particular function - * is interpreted, not guard on that condition. - * - * Bytecode sequences that push shapeless callees must guard on the callee - * class being Function and the function being interpreted. - */ - JSFunction* fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(fval)); - - if (FUN_INTERPRETED(fun)) { - if (constructing) { - LIns* args[] = { get(&fval), cx_ins }; - LIns* tv_ins = lir->insCall(&js_NewInstance_ci, args); - guard(false, lir->ins_eq0(tv_ins), OOM_EXIT); - set(&tval, tv_ins); - } - return interpretedFunctionCall(fval, fun, argc, constructing); - } - - if (FUN_SLOW_NATIVE(fun)) { - JSNative native = fun->u.n.native; - if (native == js_Array) - return newArray(FUN_OBJECT(fun), argc, &tval + 1, &fval); - if (native == js_String && argc == 1 && !constructing) { - jsval& v = stackval(0 - argc); - if (!JSVAL_IS_PRIMITIVE(v)) - return call_imacro(call_imacros.String); - set(&fval, stringify(v)); - return true; - } - } - - if (!(fun->flags & JSFUN_TRACEABLE)) - ABORT_TRACE("untraceable native"); - - JSTraceableNative* known = FUN_TRCINFO(fun); - JS_ASSERT(known && (JSFastNative)fun->u.n.native == known->native); - LIns* args[5]; do { if (((known->flags & JSTN_CONSTRUCTOR) != 0) != constructing) @@ -6754,65 +6856,124 @@ TraceRecorder::functionCall(bool constructing, uintN argc) next_specialization:; } while ((known++)->flags & JSTN_MORE); - if (!constructing) - ABORT_TRACE("unknown native"); - if (!(fun->flags & JSFUN_TRACEABLE) && FUN_CLASP(fun)) - ABORT_TRACE("can't trace native constructor"); - ABORT_TRACE("can't trace unknown constructor"); + return false; success: #if defined _DEBUG JS_ASSERT(args[0] != (LIns *)0xcdcdcdcd); #endif - if (JSTN_ERRTYPE(known) == FAIL_STATUS) { - // This needs to capture the pre-call state of the stack. So do not set - // pendingTraceableNative before taking this snapshot. - JS_ASSERT(!pendingTraceableNative); + return emitNativeCall(known, argc, args); +} - // Take snapshot for deep LeaveTree and store it in cx->bailExit. - LIns* rec_ins = snapshot(DEEP_BAIL_EXIT); - GuardRecord* rec = (GuardRecord *) rec_ins->payload(); - JS_ASSERT(rec->exit); - lir->insStorei(INS_CONSTPTR(rec->exit), cx_ins, offsetof(JSContext, bailExit)); - - // Tell nanojit not to discard or defer stack writes before this call. - lir->insGuard(LIR_xbarrier, rec_ins, rec_ins); +bool +TraceRecorder::callNative(JSFunction* fun, uintN argc, bool constructing) +{ + if (fun->flags & JSFUN_TRACEABLE) { + if (callTraceableNative(fun, argc, constructing)) + return true; } - LIns* res_ins = lir->insCall(known->builtin, args); - if (!constructing) - rval_ins = res_ins; - switch (JSTN_ERRTYPE(known)) { - case FAIL_NULL: - guard(false, lir->ins_eq0(res_ins), OOM_EXIT); - break; - case FAIL_NEG: - { - res_ins = lir->ins1(LIR_i2f, res_ins); - guard(false, lir->ins2(LIR_flt, res_ins, lir->insImmq(0)), OOM_EXIT); - break; - } - case FAIL_VOID: - guard(false, lir->ins2i(LIR_eq, res_ins, JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID)), OOM_EXIT); - break; - case FAIL_COOKIE: - guard(false, lir->ins2(LIR_eq, res_ins, INS_CONST(JSVAL_ERROR_COOKIE)), OOM_EXIT); - break; - default:; - } - set(&fval, res_ins); + if (!(fun->flags & JSFUN_FAST_NATIVE)) + ABORT_TRACE("untraceable slow native"); - if (!constructing) { - /* - * The return value will be processed by FastNativeCallComplete since - * we have to know the actual return value type for calls that return - * jsval (like Array_p_pop). - */ - pendingTraceableNative = known; + if (constructing) + ABORT_TRACE("untraceable fast native constructor"); + + jsval* vp = &stackval(0 - (2 + argc)); + invokevp_ins = lir->insAlloc((2 + argc) * sizeof(jsval)); + + /* + * For a very long argument list we might run out of LIR space, so better check while + * looping over the argument list. + */ + for (jsint n = 0; n < jsint(2 + argc) && !lirbuf->outOMem(); ++n) { + LIns* i = get(&vp[n]); + box_jsval(vp[n], i); + lir->insStorei(i, invokevp_ins, n * sizeof(jsval)); } - return true; + LIns* args[] = { invokevp_ins, lir->insImm(argc), cx_ins }; + + CallInfo* ci = (CallInfo*) lir->skip(sizeof(struct CallInfo))->payload(); + ci->_address = uintptr_t(fun->u.n.native); + ci->_argtypes = ARGSIZE_LO | ARGSIZE_LO << 2 | ARGSIZE_LO << 4 | ARGSIZE_LO << 6; + ci->_cse = ci->_fold = 0; + ci->_abi = ABI_CDECL; +#ifdef DEBUG + ci->_name = "JSFastNative"; +#endif + + // Generate a JSTraceableNative structure on the fly. + generatedTraceableNative->builtin = ci; + generatedTraceableNative->native = (JSFastNative)fun->u.n.native; + generatedTraceableNative->flags = FAIL_STATUS | JSTN_UNBOX_AFTER; + generatedTraceableNative->prefix = generatedTraceableNative->argtypes = NULL; + + // argc is the original argc here. It is used to calculate where to place the return value. + return emitNativeCall(generatedTraceableNative, argc, args); +} + +JS_REQUIRES_STACK bool +TraceRecorder::functionCall(bool constructing, uintN argc) +{ + jsval& fval = stackval(0 - (2 + argc)); + JS_ASSERT(&fval >= StackBase(cx->fp)); + + if (!VALUE_IS_FUNCTION(cx, fval)) + ABORT_TRACE("callee is not a function"); + + jsval& tval = stackval(0 - (1 + argc)); + + /* + * If callee is not constant, it's a shapeless call and we have to guard + * explicitly that we will get this callee again at runtime. + */ + if (!get(&fval)->isconst() && !guardCallee(fval)) + return false; + + /* + * Require that the callee be a function object, to avoid guarding on its + * class here. We know if the callee and this were pushed by JSOP_CALLNAME + * or JSOP_CALLPROP that callee is a *particular* function, since these hit + * the property cache and guard on the object (this) in which the callee + * was found. So it's sufficient to test here that the particular function + * is interpreted, not guard on that condition. + * + * Bytecode sequences that push shapeless callees must guard on the callee + * class being Function and the function being interpreted. + */ + JSFunction* fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(fval)); + + if (FUN_INTERPRETED(fun)) { + if (constructing) { + LIns* args[] = { get(&fval), cx_ins }; + LIns* tv_ins = lir->insCall(&js_NewInstance_ci, args); + guard(false, lir->ins_eq0(tv_ins), OOM_EXIT); + set(&tval, tv_ins); + } + return interpretedFunctionCall(fval, fun, argc, constructing); + } + + if (FUN_SLOW_NATIVE(fun)) { + JSNative native = fun->u.n.native; + if (native == js_Array) + return newArray(JSVAL_TO_OBJECT(fval), argc, &tval + 1, &fval); + if (native == js_String) { + if (argc != 1) + ABORT_TRACE("can't trace String when not called with a single argument"); + + jsval& v = stackval(0 - argc); + if (constructing) + return newString(JSVAL_TO_OBJECT(fval), v, &fval); + if (!JSVAL_IS_PRIMITIVE(v)) + return call_imacro(call_imacros.String); + set(&fval, stringify(v)); + return true; + } + } + + return callNative(fun, argc, constructing); } JS_REQUIRES_STACK bool @@ -7144,6 +7305,8 @@ JS_DEFINE_TRCINFO_1(GetElement, JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_GETELEM() { + bool call = *cx->fp->regs->pc == JSOP_CALLELEM; + jsval& idx = stackval(-1); jsval& lval = stackval(-2); @@ -7152,6 +7315,8 @@ TraceRecorder::record_JSOP_GETELEM() // Special case for array-like access of strings. if (JSVAL_IS_STRING(lval) && isInt32(idx)) { + if (call) + ABORT_TRACE("JSOP_CALLELEM on a string"); int i = asInt32(idx); if (size_t(i) >= JSSTRING_LENGTH(JSVAL_TO_STRING(lval))) ABORT_TRACE("Invalid string index in JSOP_GETELEM"); @@ -7187,7 +7352,7 @@ TraceRecorder::record_JSOP_GETELEM() if (!guardNotGlobalObject(obj, obj_ins)) return false; - return call_imacro(getelem_imacros.getprop); + return call_imacro(call ? callelem_imacros.callprop : getelem_imacros.getprop); } // Invalid dense array index or not a dense array. @@ -7195,7 +7360,7 @@ TraceRecorder::record_JSOP_GETELEM() if (!guardNotGlobalObject(obj, obj_ins)) return false; - return call_imacro(getelem_imacros.getelem); + return call_imacro(call ? callelem_imacros.callelem : getelem_imacros.getelem); } // Fast path for dense arrays accessed with a non-negative integer index. @@ -7204,6 +7369,8 @@ TraceRecorder::record_JSOP_GETELEM() if (!elem(lval, idx, vp, v_ins, addr_ins)) return false; set(&lval, v_ins); + if (call) + set(&idx, obj_ins); return true; } @@ -7582,6 +7749,12 @@ TraceRecorder::record_FastNativeCallComplete() { JS_ASSERT(pendingTraceableNative); + JS_ASSERT(*cx->fp->regs->pc == JSOP_CALL || + *cx->fp->regs->pc == JSOP_APPLY); + + jsval& v = stackval(-1); + LIns* v_ins = get(&v); + /* At this point the generated code has already called the native function and we can no longer fail back to the original pc location (JSOP_CALL) because that would cause the interpreter to re-execute the native @@ -7600,18 +7773,41 @@ TraceRecorder::record_FastNativeCallComplete() // Keep cx->bailExit null when it's invalid. lir->insStorei(INS_CONSTPTR(NULL), cx_ins, (int) offsetof(JSContext, bailExit)); #endif + LIns* status = lir->insLoad(LIR_ld, cx_ins, (int) offsetof(JSContext, builtinStatus)); + if (pendingTraceableNative == generatedTraceableNative) { + LIns* ok_ins = v_ins; + + /* + * If we run a generic traceable native, the return value is in the argument + * vector. The actual return value of the fast native is a JSBool indicated + * the error status. + */ + v_ins = lir->insLoad(LIR_ld, invokevp_ins, 0); + set(&v, v_ins); + + /* + * If this is a generic traceable native invocation, propagate the boolean return + * value of the fast native into builtinStatus. If the return value (v_ins) + * is true, status' == status. Otherwise status' = status | JSBUILTIN_ERROR. + * We calculate (rval&1)^1, which is 1 if rval is JS_FALSE (error), and then + * shift that by 1 which is JSBUILTIN_ERROR. + */ + JS_STATIC_ASSERT((1 - JS_TRUE) << 1 == 0); + JS_STATIC_ASSERT((1 - JS_FALSE) << 1 == JSBUILTIN_ERROR); + status = lir->ins2(LIR_or, + status, + lir->ins2i(LIR_lsh, + lir->ins2i(LIR_xor, + lir->ins2i(LIR_and, ok_ins, 1), + 1), + 1)); + lir->insStorei(status, cx_ins, (int) offsetof(JSContext, builtinStatus)); + } guard(true, - lir->ins_eq0( - lir->insLoad(LIR_ld, cx_ins, (int) offsetof(JSContext, builtinStatus))), + lir->ins_eq0(status), STATUS_EXIT); } - JS_ASSERT(*cx->fp->regs->pc == JSOP_CALL || - *cx->fp->regs->pc == JSOP_APPLY); - - jsval& v = stackval(-1); - LIns* v_ins = get(&v); - bool ok = true; if (pendingTraceableNative->flags & JSTN_UNBOX_AFTER) { unbox_jsval(v, v_ins); @@ -7947,7 +8143,13 @@ JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_TABLESWITCH() { #ifdef NANOJIT_IA32 - return true; + /* Handle tableswitches specially -- prepare a jump table if needed. */ + LIns* guardIns = tableswitch(); + if (guardIns) { + fragment->lastIns = guardIns; + compile(&JS_TRACE_MONITOR(cx)); + } + return false; #else return switchop(); #endif @@ -8535,7 +8737,7 @@ TraceRecorder::record_JSOP_DEFLOCALFUN() JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_GOTOX() { - return true; + return record_JSOP_GOTO(); } JS_REQUIRES_STACK bool @@ -8584,11 +8786,7 @@ TraceRecorder::record_JSOP_DEFAULTX() JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_TABLESWITCHX() { -#ifdef NANOJIT_IA32 - return true; -#else - return switchop(); -#endif + return record_JSOP_TABLESWITCH(); } JS_REQUIRES_STACK bool @@ -8986,7 +9184,7 @@ TraceRecorder::record_JSOP_RESETBASE0() JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_CALLELEM() { - return false; + return record_JSOP_GETELEM(); } JS_REQUIRES_STACK bool @@ -9384,8 +9582,10 @@ TraceRecorder::record_JSOP_LENGTH() LIns* v_ins; if (OBJ_IS_ARRAY(cx, obj)) { if (OBJ_IS_DENSE_ARRAY(cx, obj)) { - if (!guardDenseArray(obj, obj_ins, BRANCH_EXIT)) + if (!guardDenseArray(obj, obj_ins, BRANCH_EXIT)) { JS_NOT_REACHED("OBJ_IS_DENSE_ARRAY but not?!?"); + return false; + } } else { if (!guardClass(obj, obj_ins, &js_SlowArrayClass, snapshot(BRANCH_EXIT))) ABORT_TRACE("can't trace length property access on non-array"); diff --git a/js/src/jstracer.h b/js/src/jstracer.h index 6bd4f53cae6a..7e44a54052ee 100644 --- a/js/src/jstracer.h +++ b/js/src/jstracer.h @@ -155,7 +155,7 @@ public: #ifdef JS_JIT_SPEW extern bool js_verboseDebug; -#define debug_only_v(x) if (js_verboseDebug) { x; } +#define debug_only_v(x) if (js_verboseDebug) { x; fflush(stdout); } #else #define debug_only_v(x) #endif @@ -397,27 +397,25 @@ class TraceRecorder : public avmplus::GCObject { nanojit::LirWriter* cse_filter; nanojit::LirWriter* expr_filter; nanojit::LirWriter* func_filter; -#ifdef NJ_SOFTFLOAT nanojit::LirWriter* float_filter; -#endif nanojit::LIns* cx_ins; nanojit::LIns* eos_ins; nanojit::LIns* eor_ins; nanojit::LIns* globalObj_ins; nanojit::LIns* rval_ins; nanojit::LIns* inner_sp_ins; + nanojit::LIns* invokevp_ins; bool deepAborted; bool trashSelf; Queue whichTreesToTrash; Queue cfgMerges; jsval* global_dslots; + JSTraceableNative* generatedTraceableNative; JSTraceableNative* pendingTraceableNative; - bool terminate; - jsbytecode* terminate_pc; - jsbytecode* terminate_imacpc; TraceRecorder* nextRecorderToAbort; bool wasRootFragment; jsbytecode* outer; + bool loop; bool isGlobal(jsval* p) const; ptrdiff_t nativeGlobalOffset(jsval* p) const; @@ -540,13 +538,19 @@ class TraceRecorder : public avmplus::GCObject { JS_REQUIRES_STACK bool guardCallee(jsval& callee); JS_REQUIRES_STACK bool getClassPrototype(JSObject* ctor, nanojit::LIns*& proto_ins); JS_REQUIRES_STACK bool newArray(JSObject* ctor, uint32 argc, jsval* argv, jsval* vp); + JS_REQUIRES_STACK bool newString(JSObject* ctor, jsval& arg, jsval* rval); JS_REQUIRES_STACK bool interpretedFunctionCall(jsval& fval, JSFunction* fun, uintN argc, bool constructing); + JS_REQUIRES_STACK bool emitNativeCall(JSTraceableNative* known, uintN argc, + nanojit::LIns* args[]); + JS_REQUIRES_STACK bool callTraceableNative(JSFunction* fun, uintN argc, bool constructing); + JS_REQUIRES_STACK bool callNative(JSFunction* fun, uintN argc, bool constructing); JS_REQUIRES_STACK bool functionCall(bool constructing, uintN argc); JS_REQUIRES_STACK void trackCfgMerges(jsbytecode* pc); - JS_REQUIRES_STACK void flipIf(jsbytecode* pc, bool& cond); + JS_REQUIRES_STACK void emitIf(jsbytecode* pc, bool cond, nanojit::LIns* x); JS_REQUIRES_STACK void fuseIf(jsbytecode* pc, bool cond, nanojit::LIns* x); + JS_REQUIRES_STACK bool checkTraceEnd(jsbytecode* pc); bool hasMethod(JSObject* obj, jsid id); JS_REQUIRES_STACK bool hasIteratorMethod(JSObject* obj); @@ -564,9 +568,8 @@ public: JS_REQUIRES_STACK nanojit::LIns* snapshot(ExitType exitType); nanojit::Fragment* getFragment() const { return fragment; } TreeInfo* getTreeInfo() const { return treeInfo; } - JS_REQUIRES_STACK bool isLoopHeader(JSContext* cx) const; JS_REQUIRES_STACK void compile(JSTraceMonitor* tm); - JS_REQUIRES_STACK bool closeLoop(JSTraceMonitor* tm, bool& demote); + JS_REQUIRES_STACK void closeLoop(JSTraceMonitor* tm, bool& demote); JS_REQUIRES_STACK void endLoop(JSTraceMonitor* tm); JS_REQUIRES_STACK void joinEdgesToEntry(nanojit::Fragmento* fragmento, nanojit::Fragment* peer_root); @@ -590,7 +593,6 @@ public: void deepAbort() { deepAborted = true; } bool wasDeepAborted() { return deepAborted; } - bool walkedOutOfLoop() { return terminate; } TreeInfo* getTreeInfo() { return treeInfo; } #define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \ @@ -637,13 +639,13 @@ extern void js_FinishJIT(JSTraceMonitor *tm); extern void -js_FlushScriptFragments(JSContext* cx, JSScript* script); +js_PurgeScriptFragments(JSContext* cx, JSScript* script); extern void js_FlushJITCache(JSContext* cx); extern void -js_FlushJITOracle(JSContext* cx); +js_PurgeJITOracle(); extern JSObject * js_GetBuiltinFunction(JSContext *cx, uintN index); diff --git a/js/src/jswince.asm b/js/src/jswince.asm new file mode 100644 index 000000000000..07553334476a --- /dev/null +++ b/js/src/jswince.asm @@ -0,0 +1,44 @@ + INCLUDE kxarm.h + + area js_msvc, code, readonly + + MACRO + FUNC_HEADER $Name +FuncName SETS VBar:CC:"$Name":CC:VBar +PrologName SETS VBar:CC:"$Name":CC:"_Prolog":CC:VBar +FuncEndName SETS VBar:CC:"$Name":CC:"_end":CC:VBar + + AREA |.pdata|,ALIGN=2,PDATA + DCD $FuncName + DCD (($PrologName-$FuncName)/4) :OR: ((($FuncEndName-$FuncName)/4):SHL:8) :OR: 0x40000000 + AREA $AreaName,CODE,READONLY + ALIGN 2 + GLOBAL $FuncName + EXPORT $FuncName +$FuncName + ROUT +$PrologName + MEND + + export js_arm_try_armv6t2_op + + ;; I'm not smart enough to figure out which flags to pass to armasm to get it + ;; to understand movt and fmdrr/vmov; the disassembler figures them out just fine! + + FUNC_HEADER js_arm_try_armv6t2_op + ;; movt r0,#0xFFFF + DCD 0xE34F0FFF + mov pc,lr + ENTRY_END + endp + + export js_arm_try_vfp_op + + FUNC_HEADER js_arm_try_vfp_op + ;; fmdrr d0, r0, r1 + DCD 0xEC410B10 + mov pc,lr + ENTRY_END + endp + + end diff --git a/js/src/nanojit/Assembler.cpp b/js/src/nanojit/Assembler.cpp index 8449d55e8a69..ae4fbc580db9 100644 --- a/js/src/nanojit/Assembler.cpp +++ b/js/src/nanojit/Assembler.cpp @@ -55,7 +55,7 @@ extern "C" void sync_instruction_memory(caddr_t v, u_int len); namespace nanojit { - + int UseSoftfloat = 0; class DeadCodeFilter: public LirFilter { @@ -602,7 +602,11 @@ namespace nanojit Register s = resv->reg = registerAlloc(prefer); _allocator.addActive(s, i); if ((rmask(r) & GpRegs) && (rmask(s) & GpRegs)) { +#ifdef NANOJIT_ARM + MOV(r, s); +#else MR(r, s); +#endif } else { asm_nongp_copy(r, s); @@ -1238,7 +1242,6 @@ namespace nanojit asm_arith(ins); break; } -#ifndef NJ_SOFTFLOAT case LIR_fneg: { countlir_fpu(); @@ -1266,7 +1269,6 @@ namespace nanojit asm_u2f(ins); break; } -#endif // NJ_SOFTFLOAT case LIR_st: case LIR_sti: { @@ -1417,7 +1419,6 @@ namespace nanojit break; } -#ifndef NJ_SOFTFLOAT case LIR_feq: case LIR_fle: case LIR_flt: @@ -1428,7 +1429,6 @@ namespace nanojit asm_fcond(ins); break; } -#endif case LIR_eq: case LIR_ov: case LIR_cs: @@ -1446,10 +1446,8 @@ namespace nanojit break; } -#ifndef NJ_SOFTFLOAT case LIR_fcall: case LIR_fcalli: -#endif #if defined NANOJIT_64BIT case LIR_callh: #endif @@ -1458,7 +1456,6 @@ namespace nanojit { countlir_call(); Register rr = UnknownReg; -#ifndef NJ_SOFTFLOAT if ((op&LIR64)) { // fcall or fcalli @@ -1466,7 +1463,6 @@ namespace nanojit rr = asm_prep_fcall(rR, ins); } else -#endif { rr = retRegs[0]; prepResultReg(ins, rmask(rr)); @@ -1947,13 +1943,12 @@ namespace nanojit for (uint32_t i = 0; i < MAXARGS; i++) { argt >>= 2; ArgSize a = ArgSize(argt&3); -#ifdef NJ_SOFTFLOAT - if (a == ARGSIZE_F) { + if (AvmCore::config.soft_float && a == ARGSIZE_F) { sizes[argc++] = ARGSIZE_LO; sizes[argc++] = ARGSIZE_LO; continue; } -#endif + if (a != ARGSIZE_NONE) { sizes[argc++] = a; } else { diff --git a/js/src/nanojit/LIR.cpp b/js/src/nanojit/LIR.cpp index 516e10e936b6..46d87a172bc6 100644 --- a/js/src/nanojit/LIR.cpp +++ b/js/src/nanojit/LIR.cpp @@ -1102,26 +1102,27 @@ namespace nanojit ArgSize sizes[2*MAXARGS]; int32_t argc = ci->get_sizes(sizes); -#ifdef NJ_SOFTFLOAT - if (op == LIR_fcall) - op = LIR_callh; - LInsp args2[MAXARGS*2]; // arm could require 2 args per double - int32_t j = 0; - int32_t i = 0; - while (j < argc) { - argt >>= 2; - ArgSize a = ArgSize(argt&3); - if (a == ARGSIZE_F) { - LInsp q = args[i++]; - args2[j++] = ins1(LIR_qhi, q); - args2[j++] = ins1(LIR_qlo, q); - } else { - args2[j++] = args[i++]; + if (AvmCore::config.soft_float) { + if (op == LIR_fcall) + op = LIR_callh; + LInsp args2[MAXARGS*2]; // arm could require 2 args per double + int32_t j = 0; + int32_t i = 0; + while (j < argc) { + argt >>= 2; + ArgSize a = ArgSize(argt&3); + if (a == ARGSIZE_F) { + LInsp q = args[i++]; + args2[j++] = ins1(LIR_qhi, q); + args2[j++] = ins1(LIR_qlo, q); + } else { + args2[j++] = args[i++]; + } } + args = args2; + NanoAssert(j == argc); } - args = args2; - NanoAssert(j == argc); -#endif + // // An example of the what we're trying to serialize: // diff --git a/js/src/nanojit/NativeARM.cpp b/js/src/nanojit/NativeARM.cpp index 956130c96435..681409dd9015 100644 --- a/js/src/nanojit/NativeARM.cpp +++ b/js/src/nanojit/NativeARM.cpp @@ -48,6 +48,8 @@ #endif #if defined(AVMPLUS_LINUX) +#include +#include #include extern "C" void __clear_cache(char *BEG, char *END); #endif @@ -58,21 +60,16 @@ namespace nanojit { #ifdef NJ_VERBOSE -const char* regNames[] = {"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","FP","IP","SP","LR","PC", +const char* regNames[] = {"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","fp","ip","sp","lr","pc", "d0","d1","d2","d3","d4","d5","d6","d7","s14"}; +const char* condNames[] = {"eq","ne","cs","cc","mi","pl","vs","vc","hi","ls","ge","lt","gt","le",""/*al*/,"nv"}; +const char* shiftNames[] = { "lsl", "lsl", "lsr", "lsr", "asr", "asr", "ror", "ror" }; #endif const Register Assembler::argRegs[] = { R0, R1, R2, R3 }; const Register Assembler::retRegs[] = { R0, R1 }; const Register Assembler::savedRegs[] = { R4, R5, R6, R7, R8, R9, R10 }; -const char *ccName(ConditionCode cc) -{ - const char *ccNames[] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", - "hi", "ls", "ge", "lt", "gt", "le", "al", "nv" }; - return ccNames[(int)cc]; -} - void Assembler::nInit(AvmCore*) { @@ -88,9 +85,9 @@ Assembler::genPrologue() // NJ_RESV_OFFSET is space at the top of the stack for us // to use for parameter passing (8 bytes at the moment) uint32_t stackNeeded = STACK_GRANULARITY * _activation.highwatermark + NJ_STACK_OFFSET; + uint32_t savingCount = 2; uint32_t savingMask = rmask(FP) | rmask(LR); - uint32_t savingCount = 2; if (!_thisfrag->lirbuf->explicitSavedRegs) { for (int i = 0; i < NumSavedRegs; ++i) @@ -105,13 +102,13 @@ Assembler::genPrologue() // Make room on stack for what we are doing if (amt) - SUBi(SP, amt); + SUBi(SP, SP, amt); verbose_only( verbose_outputf(" %p:",_nIns); ) verbose_only( verbose_output(" patch entry"); ) NIns *patchEntry = _nIns; - MR(FP, SP); + MOV(FP, SP); PUSH_mask(savingMask); return patchEntry; } @@ -139,7 +136,7 @@ Assembler::nFragExit(LInsp guard) } // pop the stack frame first - MR(SP, FP); + MOV(SP, FP); #ifdef NJ_VERBOSE if (_frago->core()->config.show_stats) { @@ -170,10 +167,10 @@ Assembler::genEpilogue() POP_mask(savingMask); // regs - MR(SP,FP); + MOV(SP,FP); // this is needed if we jump here from nFragExit - MR(R0,R2); // return LinkRecord* + MOV(R0,R2); // return LinkRecord* return _nIns; } @@ -201,9 +198,8 @@ Assembler::asm_call(LInsp ins) uint32_t roffset = 0; // skip return type -#ifdef NJ_ARM_VFP ArgSize rsize = (ArgSize)(atypes & 3); -#endif + atypes >>= 2; bool arg0IsInt32FollowedByFloat = false; @@ -224,8 +220,7 @@ Assembler::asm_call(LInsp ins) } #endif -#ifdef NJ_ARM_VFP - if (rsize == ARGSIZE_F) { + if (AvmCore::config.vfp && rsize == ARGSIZE_F) { NanoAssert(ins->opcode() == LIR_fcall); NanoAssert(callRes); @@ -244,7 +239,6 @@ Assembler::asm_call(LInsp ins) STR(R1, FP, d+4); } } -#endif BL((NIns*)(call->_address)); @@ -257,50 +251,35 @@ Assembler::asm_call(LInsp ins) // pre-assign registers R0-R3 for arguments (if they fit) Register r = (i + roffset) < 4 ? argRegs[i+roffset] : UnknownReg; -#ifdef NJ_ARM_VFP if (sz == ARGSIZE_F) { + Register rlo = UnknownReg; + Register rhi = UnknownReg; + #ifdef UNDER_CE if (r >= R0 && r <= R2) { - // we can use up r0/r1, r1/r2, r2/r3 without anything special + rlo = r; + rhi = nextreg(r); roffset++; - FMRRD(r, nextreg(r), sr); } else if (r == R3) { - // to use R3 gets complicated; we need to move the high dword - // into R3, and the low dword on the stack. - STR_preindex(Scratch, SP, -4); - FMRDL(Scratch, sr); - FMRDH(r, sr); - } else { - asm_pusharg(arg); + rlo = r; + rhi = UnknownReg; } #else if (r == R0 || r == R2) { + rlo = r; + rhi = nextreg(r); roffset++; } else if (r == R1) { - r = R2; - roffset++; - } else { - r = UnknownReg; - } - - // XXX move this into asm_farg - Register sr = findRegFor(arg, FpRegs); - - if (r != UnknownReg) { - // stick it into our scratch fp reg, and then copy into the base reg - //fprintf (stderr, "FMRRD: %d %d <- %d\n", r, nextreg(r), sr); - FMRRD(r, nextreg(r), sr); - } else { - asm_pusharg(arg); + rlo = R2; + rhi = nextreg(r); + roffset += 2; } #endif + + asm_arm_farg(arg, rlo, rhi); } else { asm_arg(sz, arg, r); } -#else - NanoAssert(sz == ARGSIZE_LO || sz == ARGSIZE_Q); - asm_arg(sz, arg, r); -#endif // Under CE, arg0IsInt32FollowedByFloat will always be false if (i == 0 && arg0IsInt32FollowedByFloat) @@ -311,23 +290,22 @@ Assembler::asm_call(LInsp ins) void Assembler::nMarkExecute(Page* page, int flags) { - NanoAssert(sizeof(Page) == NJ_PAGE_SIZE); + NanoAssert(sizeof(Page) == NJ_PAGE_SIZE); #ifdef UNDER_CE - static const DWORD kProtFlags[4] = - { - PAGE_READONLY, // 0 - PAGE_READWRITE, // PAGE_WRITE - PAGE_EXECUTE_READ, // PAGE_EXEC - PAGE_EXECUTE_READWRITE // PAGE_EXEC|PAGE_WRITE - }; - DWORD prot = kProtFlags[flags & (PAGE_WRITE|PAGE_EXEC)]; + static const DWORD kProtFlags[4] = { + PAGE_READONLY, // 0 + PAGE_READWRITE, // PAGE_WRITE + PAGE_EXECUTE_READ, // PAGE_EXEC + PAGE_EXECUTE_READWRITE // PAGE_EXEC|PAGE_WRITE + }; + DWORD prot = kProtFlags[flags & (PAGE_WRITE|PAGE_EXEC)]; DWORD dwOld; BOOL res = VirtualProtect(page, NJ_PAGE_SIZE, prot, &dwOld); - if (!res) - { - // todo: we can't abort or assert here, we have to fail gracefully. - NanoAssertMsg(false, "FATAL ERROR: VirtualProtect() failed\n"); - } + if (!res) + { + // todo: we can't abort or assert here, we have to fail gracefully. + NanoAssertMsg(false, "FATAL ERROR: VirtualProtect() failed\n"); + } #endif #ifdef AVMPLUS_PORTING_API NanoJIT_PortAPI_MarkExecutable(page, (void*)((char*)page+NJ_PAGE_SIZE), flags); @@ -371,9 +349,8 @@ Assembler::nRegisterResetAll(RegAlloc& a) rmask(R0) | rmask(R1) | rmask(R2) | rmask(R3) | rmask(R4) | rmask(R5) | rmask(R6) | rmask(R7) | rmask(R8) | rmask(R9) | rmask(R10); -#ifdef NJ_ARM_VFP - a.free |= FpRegs; -#endif + if (AvmCore::config.vfp) + a.free |= FpRegs; debug_only(a.managed = a.free); } @@ -472,18 +449,21 @@ Assembler::asm_store32(LIns *value, int dr, LIns *base) void Assembler::asm_restore(LInsp i, Reservation *resv, Register r) { - (void)resv; - int d = findMemFor(i); - - if (IsFpReg(r)) { - if (isS8(d >> 2)) { - FLDD(r, FP, d); - } else { - FLDD(r, Scratch, 0); - arm_ADDi(Scratch, FP, d); - } + if (i->isop(LIR_alloc)) { + asm_add_imm(r, FP, disp(resv)); } else { - LDR(r, FP, d); + int d = findMemFor(i); + + if (IsFpReg(r)) { + if (isS8(d >> 2)) { + FLDD(r, FP, d); + } else { + FLDD(r, IP, 0); + ADDi(IP, FP, d); + } + } else { + LDR(r, FP, d); + } } verbose_only( @@ -502,8 +482,8 @@ Assembler::asm_spill(Register rr, int d, bool pop, bool quad) if (isS8(d >> 2)) { FSTD(rr, FP, d); } else { - FSTD(rr, Scratch, 0); - arm_ADDi(Scratch, FP, d); + FSTD(rr, IP, 0); + ADDi(IP, FP, d); } } else { STR(rr, FP, d); @@ -525,30 +505,30 @@ Assembler::asm_load64(LInsp ins) freeRsrcOf(ins, false); -#ifdef NJ_ARM_VFP - Register rb = findRegFor(base, GpRegs); + if (AvmCore::config.vfp) { + Register rb = findRegFor(base, GpRegs); - NanoAssert(rb != UnknownReg); - NanoAssert(rr == UnknownReg || IsFpReg(rr)); + NanoAssert(rb != UnknownReg); + NanoAssert(rr == UnknownReg || IsFpReg(rr)); - if (rr != UnknownReg) { - if (!isS8(offset >> 2) || (offset&3) != 0) { - FLDD(rr,Scratch,0); - arm_ADDi(Scratch, rb, offset); + if (rr != UnknownReg) { + if (!isS8(offset >> 2) || (offset&3) != 0) { + FLDD(rr,IP,0); + ADDi(IP, rb, offset); + } else { + FLDD(rr,rb,offset); + } } else { - FLDD(rr,rb,offset); + asm_mmq(FP, d, rb, offset); } + + // *(FP+dr) <- *(rb+db) } else { + NanoAssert(resv->reg == UnknownReg && d != 0); + Register rb = findRegFor(base, GpRegs); asm_mmq(FP, d, rb, offset); } - // *(FP+dr) <- *(rb+db) -#else - NanoAssert(resv->reg == UnknownReg && d != 0); - Register rb = findRegFor(base, GpRegs); - asm_mmq(FP, d, rb, offset); -#endif - //asm_output(">>> load64"); } @@ -557,54 +537,57 @@ Assembler::asm_store64(LInsp value, int dr, LInsp base) { //asm_output("<<< store64 (dr: %d)", dr); -#ifdef NJ_ARM_VFP - //Reservation *valResv = getresv(value); - Register rb = findRegFor(base, GpRegs); + if (AvmCore::config.vfp) { + //Reservation *valResv = getresv(value); + Register rb = findRegFor(base, GpRegs); - if (value->isconstq()) { - const int32_t* p = (const int32_t*) (value-2); + if (value->isconstq()) { + const int32_t* p = (const int32_t*) (value-2); - STR(Scratch, rb, dr); - LD32_nochk(Scratch, p[0]); - STR(Scratch, rb, dr+4); - LD32_nochk(Scratch, p[1]); + underrunProtect(LD32_size*2 + 8); - return; + // XXX use another reg, get rid of dependency + STR(IP, rb, dr); + LD32_nochk(IP, p[0]); + STR(IP, rb, dr+4); + LD32_nochk(IP, p[1]); + + return; + } + + Register rv = findRegFor(value, FpRegs); + + NanoAssert(rb != UnknownReg); + NanoAssert(rv != UnknownReg); + + Register baseReg = rb; + intptr_t baseOffset = dr; + + if (!isS8(dr)) { + baseReg = IP; + baseOffset = 0; + } + + FSTD(rv, baseReg, baseOffset); + + if (!isS8(dr)) { + ADDi(IP, rb, dr); + } + + // if it's a constant, make sure our baseReg/baseOffset location + // has the right value + if (value->isconstq()) { + const int32_t* p = (const int32_t*) (value-2); + + underrunProtect(4*4); + asm_quad_nochk(rv, p); + } + } else { + int da = findMemFor(value); + Register rb = findRegFor(base, GpRegs); + asm_mmq(rb, dr, FP, da); } - Register rv = findRegFor(value, FpRegs); - - NanoAssert(rb != UnknownReg); - NanoAssert(rv != UnknownReg); - - Register baseReg = rb; - intptr_t baseOffset = dr; - - if (!isS8(dr)) { - baseReg = Scratch; - baseOffset = 0; - } - - FSTD(rv, baseReg, baseOffset); - - if (!isS8(dr)) { - arm_ADDi(Scratch, rb, dr); - } - - // if it's a constant, make sure our baseReg/baseOffset location - // has the right value - if (value->isconstq()) { - const int32_t* p = (const int32_t*) (value-2); - - underrunProtect(12); - - asm_quad_nochk(rv, p); - } -#else - int da = findMemFor(value); - Register rb = findRegFor(base, GpRegs); - asm_mmq(rb, dr, FP, da); -#endif //asm_output(">>> store64"); } @@ -645,41 +628,22 @@ Assembler::asm_quad(LInsp ins) const int32_t* p = (const int32_t*) (ins-2); -#ifdef NJ_ARM_VFP freeRsrcOf(ins, false); - if (rr == UnknownReg) { - underrunProtect(12); - - // asm_mmq might spill a reg, so don't call it; - // instead do the equivalent directly. - //asm_mmq(FP, d, PC, -16); - - STR(Scratch, FP, d+4); - LDR(Scratch, PC, -20); - STR(Scratch, FP, d); - LDR(Scratch, PC, -16); - - *(--_nIns) = (NIns) p[1]; - *(--_nIns) = (NIns) p[0]; - JMP_nochk(_nIns+2); - } else { + if (AvmCore::config.vfp && + rr != UnknownReg) + { if (d) FSTD(rr, FP, d); - underrunProtect(16); + underrunProtect(4*4); asm_quad_nochk(rr, p); + } else { + STR(IP, FP, d+4); + asm_ld_imm(IP, p[1]); + STR(IP, FP, d); + asm_ld_imm(IP, p[0]); } -#else - freeRsrcOf(ins, false); - if (d) { - underrunProtect(LD32_size * 2 + 8); - STR(Scratch, FP, d+4); - LD32_nochk(Scratch, p[1]); - STR(Scratch, FP, d); - LD32_nochk(Scratch, p[0]); - } -#endif //asm_output("<<< asm_quad"); } @@ -717,7 +681,7 @@ Assembler::asm_mmq(Register rd, int dd, Register rs, int ds) // put it in an FPU reg just to load & store it. // Don't use this with PC-relative loads; the registerAlloc might - // end up spilling a reg (and this the offset could end up being + // end up spilling a reg (and thus the offset could end up being // bogus)! NanoAssert(rs != PC); @@ -727,9 +691,9 @@ Assembler::asm_mmq(Register rd, int dd, Register rs, int ds) // XXX maybe figure out if we can use LDRD/STRD -- hard to // ensure right register allocation - STR(Scratch, rd, dd+4); + STR(IP, rd, dd+4); STR(t, rd, dd); - LDR(Scratch, rs, ds+4); + LDR(IP, rs, ds+4); LDR(t, rs, ds); } @@ -744,19 +708,19 @@ Assembler::asm_pusharg(LInsp arg) STR_preindex(argRes->reg, SP, -4); } else { FSTD(argRes->reg, SP, 0); - SUBi(SP, 8); + SUBi(SP, SP, 8); } } else { int d = findMemFor(arg); if (!quad) { - STR_preindex(Scratch, SP, -4); - LDR(Scratch, FP, d); + STR_preindex(IP, SP, -4); + LDR(IP, FP, d); } else { - STR_preindex(Scratch, SP, -4); - LDR(Scratch, FP, d+4); - STR_preindex(Scratch, SP, -4); - LDR(Scratch, FP, d); + STR_preindex(IP, SP, -4); + LDR(IP, FP, d+4); + STR_preindex(IP, SP, -4); + LDR(IP, FP, d); } } } @@ -788,10 +752,13 @@ Assembler::nativePageSetup() } } +// Note: underrunProtect should not touch any registers, even IP; it +// might need to allocate a new page in the middle of an IP-using +// sequence. void Assembler::underrunProtect(int bytes) { - NanoAssertMsg(bytes<=LARGEST_UNDERRUN_PROT, "constant LARGEST_UNDERRUN_PROT is too small"); + NanoAssertMsg(bytes<=LARGEST_UNDERRUN_PROT, "constant LARGEST_UNDERRUN_PROT is too small"); intptr_t u = bytes + sizeof(PageHeader)/sizeof(NIns) + 8; if ( (samepage(_nIns,_nSlot) && (((intptr_t)_nIns-u) <= intptr_t(_nSlot+1))) || (!samepage((intptr_t)_nIns-u,_nIns)) ) @@ -883,7 +850,16 @@ void Assembler::LD32_nochk(Register r, int32_t imm) { if (imm == 0) { - XOR(r, r); + EOR(r, r, r); + return; + } + + if (AvmCore::config.v6t2) { + // We can just emit a movw/movt pair + // the movt is only necessary if the high 16 bits are nonzero + if (((imm >> 16) & 0xFFFF) != 0) + MOVT(r, (imm >> 16) & 0xFFFF); + MOVW(r, imm & 0xFFFF); return; } @@ -903,6 +879,44 @@ Assembler::LD32_nochk(Register r, int32_t imm) LDR_nochk(r,PC,offset); } +void +Assembler::asm_ldr_chk(Register d, Register b, int32_t off, bool chk) +{ + if (IsFpReg(d)) { + FLDD_chk(d,b,off,chk); + return; + } + + if (off > -4096 && off < 4096) { + if (chk) underrunProtect(4); + *(--_nIns) = (NIns)( COND_AL | ((off < 0 ? 0x51 : 0x59)<<20) | (b<<16) | (d<<12) | ((off < 0 ? -off : off)&0xFFF) ); + } else { + if (chk) underrunProtect(4+LD32_size); + NanoAssert(b != IP); + *(--_nIns) = (NIns)( COND_AL | (0x79<<20) | (b<<16) | (d<<12) | IP ); + LD32_nochk(IP, off); + } + + asm_output("ldr %s, [%s, #%d]",gpn(d),gpn(b),(off)); +} + +void +Assembler::asm_ld_imm(Register d, int32_t imm) +{ + if (imm == 0) { + EOR(d, d, d); + } else if (isS8(imm) || isU8(imm)) { + underrunProtect(4); + if (imm < 0) + *(--_nIns) = (NIns)( COND_AL | 0x3E<<20 | d<<12 | (imm^0xFFFFFFFF)&0xFF ); + else + *(--_nIns) = (NIns)( COND_AL | 0x3B<<20 | d<<12 | imm&0xFF ); + asm_output("ld %s,0x%x",gpn(d), imm); + } else { + underrunProtect(LD32_size); + LD32_nochk(d, imm); + } +} // Branch to target address _t with condition _c, doing underrun // checks (_chk == 1) or skipping them (_chk == 0). @@ -922,12 +936,17 @@ Assembler::B_cond_chk(ConditionCode _c, NIns* _t, bool _chk) { int32_t offs = PC_OFFSET_FROM(_t,_nIns-1); //fprintf(stderr, "B_cond_chk target: 0x%08x offset: %d @0x%08x\n", _t, offs, _nIns-1); + + // optimistically check if this will fit in 24 bits if (isS24(offs>>2)) { if (_chk) underrunProtect(4); + // recalculate the offset, because underrunProtect may have + // moved _nIns to a new page offs = PC_OFFSET_FROM(_t,_nIns-1); } if (isS24(offs>>2)) { + // the underrunProtect for this was done above *(--_nIns) = (NIns)( ((_c)<<28) | (0xA<<24) | (((offs)>>2) & 0xFFFFFF) ); } else if (_c == AL) { if(_chk) underrunProtect(8); @@ -946,13 +965,12 @@ Assembler::B_cond_chk(ConditionCode _c, NIns* _t, bool _chk) *(--_nIns) = (NIns)( ((_c)<<28) | (0x51<<20) | (PC<<16) | (PC<<12) | 0x0 ); } - asm_output("%s %p", _c == AL ? "jmp" : "b(cnd)", (void*)(_t)); + asm_output("b%s %p", condNames[_c], (void*)(_t)); } void -Assembler::asm_add_imm(Register rd, Register rn, int32_t imm) +Assembler::asm_add_imm(Register rd, Register rn, int32_t imm, int stat) { - int rot = 16; uint32_t immval; bool pos; @@ -973,22 +991,53 @@ Assembler::asm_add_imm(Register rd, Register rn, int32_t imm) rot &= 0xf; if (immval < 256) { - underrunProtect(4); - if (pos) - *(--_nIns) = (NIns)( COND_AL | OP_IMM | OP_STAT | (1<<23) | (rn<<16) | (rd<<12) | (rot << 8) | immval ); - else - *(--_nIns) = (NIns)( COND_AL | OP_IMM | OP_STAT | (1<<22) | (rn<<16) | (rd<<12) | (rot << 8) | immval ); - asm_output("add %s,%s,%d",gpn(rd),gpn(rn),imm); - } else { + if (pos) { + ALUi_rot(AL, add, stat, rd, rn, immval, rot); + } else { + ALUi_rot(AL, sub, stat, rd, rn, immval, rot); + } + } else { // add scratch to rn, after loading the value into scratch. + // make sure someone isn't trying to use IP as an operand + NanoAssert(rn != IP); + ALUr(AL, add, stat, rd, rn, IP); + asm_ld_imm(IP, imm); + } +} - // make sure someone isn't trying to use Scratch as an operand - NanoAssert(rn != Scratch); - - *(--_nIns) = (NIns)( COND_AL | OP_STAT | (1<<23) | (rn<<16) | (rd<<12) | (Scratch)); - asm_output("add %s,%s,%s",gpn(rd),gpn(rn),gpn(Scratch)); - - LD32_nochk(Scratch, imm); +void +Assembler::asm_sub_imm(Register rd, Register rn, int32_t imm, int stat) +{ + if (imm > -256 && imm < 256) { + if (imm >= 0) + ALUi(AL, sub, stat, rd, rn, imm); + else + ALUi(AL, add, stat, rd, rn, -imm); + } else if (imm >= 0) { + if (imm <= 510) { + /* between 0 and 510, inclusive */ + int rem = imm - 255; + NanoAssert(rem < 256); + ALUi(AL, sub, stat, rd, rn, rem & 0xff); + ALUi(AL, sub, stat, rd, rn, 0xff); + } else { + /* more than 510 */ + NanoAssert(rn != IP); + ALUr(AL, sub, stat, rd, rn, IP); + asm_ld_imm(IP, imm); + } + } else { + if (imm >= -510) { + /* between -510 and -1, inclusive */ + int rem = -imm - 255; + ALUi(AL, add, stat, rd, rn, rem & 0xff); + ALUi(AL, add, stat, rd, rn, 0xff); + } else { + /* less than -510 */ + NanoAssert(rn != IP); + ALUr(AL, add, stat, rd, rn, IP); + asm_ld_imm(IP, -imm); + } } } @@ -1112,6 +1161,7 @@ Assembler::asm_branch(bool branchOnFalse, LInsp cond, NIns* targ, bool isfar) case LIR_fgt: cc = LE; break; case LIR_fle: cc = HI; break; case LIR_fge: cc = LT; break; + default: NanoAssert(0); break; } } else { switch (condop) { @@ -1120,6 +1170,7 @@ Assembler::asm_branch(bool branchOnFalse, LInsp cond, NIns* targ, bool isfar) case LIR_fgt: cc = GT; break; case LIR_fle: cc = LS; break; case LIR_fge: cc = GE; break; + default: NanoAssert(0); break; } } @@ -1208,10 +1259,11 @@ Assembler::asm_cmp(LIns *cond) Register r = findRegFor(lhs, GpRegs); TEST(r,r); // No 64-bit immediates so fall-back to below - } - else if (!rhs->isQuad()) { + } else if (!rhs->isQuad()) { Register r = getBaseReg(lhs, c, GpRegs); - CMPi(r, c); + asm_cmpi(r, c); + } else { + NanoAssert(0); } } else { findRegFor2(GpRegs, lhs, rA, rhs, rB); @@ -1221,6 +1273,26 @@ Assembler::asm_cmp(LIns *cond) } } +void +Assembler::asm_cmpi(Register r, int32_t imm) +{ + if (imm < 0) { + if (imm > -256) { + ALUi(AL, cmn, 1, 0, r, -imm); + } else { + CMP(r, IP); + asm_ld_imm(IP, imm); + } + } else { + if (imm < 256) { + ALUi(AL, cmp, 1, 0, r, imm); + } else { + CMP(r, IP); + asm_ld_imm(IP, imm); + } + } +} + void Assembler::asm_loop(LInsp ins, NInsList& loopJumps) { @@ -1232,7 +1304,7 @@ Assembler::asm_loop(LInsp ins, NInsList& loopJumps) // If the target we are looping to is in a different fragment, we have to restore // SP since we will target fragEntry and not loopEntry. if (ins->record()->exit->target != _thisfrag) - MR(SP,FP); + MOV(SP,FP); } void @@ -1247,6 +1319,7 @@ Assembler::asm_fcond(LInsp ins) case LIR_fgt: SET(r,GT,LE); break; case LIR_fle: SET(r,LS,HI); break; case LIR_fge: SET(r,GE,LT); break; + default: NanoAssert(0); break; } asm_fcmp(ins); @@ -1323,55 +1396,53 @@ Assembler::asm_arith(LInsp ins) if (rA == 0 || (ra = rA->reg) == UnknownReg) ra = findSpecificRegFor(lhs, rr); // else, rA already has a register assigned. + NanoAssert(ra != UnknownReg); if (forceReg) { if (lhs == rhs) rb = ra; if (op == LIR_add || op == LIR_addp) - ADD(rr, rb); + ADDs(rr, ra, rb, 1); else if (op == LIR_sub) - SUB(rr, rb); + SUB(rr, ra, rb); else if (op == LIR_mul) MUL(rr, rb); else if (op == LIR_and) - AND(rr, rb); + AND(rr, ra, rb); else if (op == LIR_or) - OR(rr, rb); + ORR(rr, ra, rb); else if (op == LIR_xor) - XOR(rr, rb); + EOR(rr, ra, rb); else if (op == LIR_lsh) - SHL(rr, rb); + SHL(rr, ra, rb); else if (op == LIR_rsh) - SAR(rr, rb); + SAR(rr, ra, rb); else if (op == LIR_ush) - SHR(rr, rb); + SHR(rr, ra, rb); else NanoAssertMsg(0, "Unsupported"); } else { int c = rhs->constval(); if (op == LIR_add || op == LIR_addp) - ADDi(rr, c); + ADDi(rr, ra, c); else if (op == LIR_sub) - SUBi(rr, c); + SUBi(rr, ra, c); else if (op == LIR_and) - ANDi(rr, c); + ANDi(rr, ra, c); else if (op == LIR_or) - ORi(rr, c); + ORRi(rr, ra, c); else if (op == LIR_xor) - XORi(rr, c); + EORi(rr, ra, c); else if (op == LIR_lsh) - SHLi(rr, c); + SHLi(rr, ra, c); else if (op == LIR_rsh) - SARi(rr, c); + SARi(rr, ra, c); else if (op == LIR_ush) - SHRi(rr, c); + SHRi(rr, ra, c); else NanoAssertMsg(0, "Unsupported"); } - - if (rr != ra) - MR(rr,ra); } void @@ -1387,14 +1458,12 @@ Assembler::asm_neg_not(LInsp ins) if (rA == 0 || (ra=rA->reg) == UnknownReg) ra = findSpecificRegFor(lhs, rr); // else, rA already has a register assigned. + NanoAssert(ra != UnknownReg); if (op == LIR_not) - NOT(rr); + MVN(rr, ra); else - NEG(rr); - - if ( rr != ra ) - MR(rr,ra); + RSBS(rr, ra); } void @@ -1431,7 +1500,7 @@ Assembler::asm_ld(LInsp ins) void Assembler::asm_cmov(LInsp ins) { - LOpcode op = ins->opcode(); + NanoAssert(ins->opcode() == LIR_cmov); LIns* condval = ins->oprnd1(); NanoAssert(condval->isCmp()); @@ -1441,31 +1510,27 @@ Assembler::asm_cmov(LInsp ins) LIns* iftrue = values->oprnd1(); LIns* iffalse = values->oprnd2(); - NanoAssert(op == LIR_qcmov || (!iftrue->isQuad() && !iffalse->isQuad())); + NanoAssert(!iftrue->isQuad() && !iffalse->isQuad()); const Register rr = prepResultReg(ins, GpRegs); // this code assumes that neither LD nor MR nor MRcc set any of the condition flags. // (This is true on Intel, is it true on all architectures?) const Register iffalsereg = findRegFor(iffalse, GpRegs & ~rmask(rr)); - if (op == LIR_cmov) { - switch (condval->opcode()) { - // note that these are all opposites... - case LIR_eq: MRNE(rr, iffalsereg); break; - case LIR_ov: MRNO(rr, iffalsereg); break; - case LIR_cs: MRNC(rr, iffalsereg); break; - case LIR_lt: MRGE(rr, iffalsereg); break; - case LIR_le: MRG(rr, iffalsereg); break; - case LIR_gt: MRLE(rr, iffalsereg); break; - case LIR_ge: MRL(rr, iffalsereg); break; - case LIR_ult: MRAE(rr, iffalsereg); break; - case LIR_ule: MRA(rr, iffalsereg); break; - case LIR_ugt: MRBE(rr, iffalsereg); break; - case LIR_uge: MRB(rr, iffalsereg); break; - default: debug_only( NanoAssert(0) ); break; - } - } else if (op == LIR_qcmov) { - NanoAssert(0); + switch (condval->opcode()) { + // note that these are all opposites... + case LIR_eq: MOVNE(rr, iffalsereg); break; + case LIR_ov: MOVVC(rr, iffalsereg); break; + case LIR_cs: MOVNC(rr, iffalsereg); break; + case LIR_lt: MOVGE(rr, iffalsereg); break; + case LIR_le: MOVGT(rr, iffalsereg); break; + case LIR_gt: MOVLE(rr, iffalsereg); break; + case LIR_ge: MOVLT(rr, iffalsereg); break; + case LIR_ult: MOVCS(rr, iffalsereg); break; + case LIR_ule: MOVHI(rr, iffalsereg); break; + case LIR_ugt: MOVLS(rr, iffalsereg); break; + case LIR_uge: MOVCC(rr, iffalsereg); break; + default: debug_only( NanoAssert(0) ); break; } /*const Register iftruereg =*/ findSpecificRegFor(iftrue, rr); asm_cmp(condval); @@ -1538,7 +1603,7 @@ Assembler::asm_short(LInsp ins) Register rr = prepResultReg(ins, GpRegs); int32_t val = ins->imm16(); if (val == 0) - XOR(rr,rr); + EOR(rr,rr,rr); else LDi(rr, val); } @@ -1549,64 +1614,11 @@ Assembler::asm_int(LInsp ins) Register rr = prepResultReg(ins, GpRegs); int32_t val = ins->imm32(); if (val == 0) - XOR(rr,rr); + EOR(rr,rr,rr); else LDi(rr, val); } -#if 0 -void -Assembler::asm_quad(LInsp ins) -{ - Reservation *rR = getresv(ins); - Register rr = rR->reg; - if (rr != UnknownReg) - { - // @todo -- add special-cases for 0 and 1 - _allocator.retire(rr); - rR->reg = UnknownReg; - NanoAssert((rmask(rr) & FpRegs) != 0); - - const double d = ins->constvalf(); - const uint64_t q = ins->constvalq(); - if (rmask(rr) & XmmRegs) { - if (q == 0.0) { - // test (int64)0 since -0.0 == 0.0 - SSE_XORPDr(rr, rr); - } else if (d == 1.0) { - // 1.0 is extremely frequent and worth special-casing! - static const double k_ONE = 1.0; - LDSDm(rr, &k_ONE); - } else { - findMemFor(ins); - const int d = disp(rR); - SSE_LDQ(rr, d, FP); - } - } else { - if (q == 0.0) { - // test (int64)0 since -0.0 == 0.0 - FLDZ(); - } else if (d == 1.0) { - FLD1(); - } else { - findMemFor(ins); - int d = disp(rR); - FLDQ(d,FP); - } - } - } - - // @todo, if we used xor, ldsd, fldz, etc above, we don't need mem here - int d = disp(rR); - freeRsrcOf(ins, false); - if (d) { - const int32_t* p = (const int32_t*) (ins-2); - STi(FP,d+4,p[1]); - STi(FP,d,p[0]); - } -} -#endif - void Assembler::asm_arg(ArgSize sz, LInsp p, Register r) { @@ -1631,13 +1643,13 @@ Assembler::asm_arg(ArgSize sz, LInsp p, Register r) // load it into the arg reg int d = findMemFor(p); if (p->isop(LIR_alloc)) { - LEA(r, d, FP); + asm_add_imm(r, FP, d); } else { LD(r, d, FP); } } else { // it must be in a saved reg - MR(r, rA->reg); + MOV(r, rA->reg); } } else { // this is the last use, so fine to assign it @@ -1654,5 +1666,67 @@ Assembler::asm_arg(ArgSize sz, LInsp p, Register r) } } +void +Assembler::asm_arm_farg(LInsp arg, Register rlo, Register rhi) +{ + if (AvmCore::config.vfp) { + Register sr = findRegFor(arg, FpRegs); + + if (rlo != UnknownReg && rhi != UnknownReg) { + NanoAssert(sr != UnknownReg); + FMRRD(rlo, rhi, sr); + } else if (rlo != UnknownReg && rhi == UnknownReg) { + NanoAssert(sr != UnknownReg); + STR_preindex(IP, SP, -4); + FMRDL(IP, sr); + FMRDH(rhi, sr); + } else { + asm_pusharg(arg); + } + + return; + } + + NanoAssert(arg->opcode() == LIR_qjoin || arg->opcode() == LIR_quad); + + if (rlo != UnknownReg && rhi != UnknownReg) { + if (arg->opcode() == LIR_qjoin) { + LIns* lo = arg->oprnd1(); + LIns* hi = arg->oprnd2(); + + findSpecificRegFor(lo, rlo); + findSpecificRegFor(hi, rhi); + } else { + // LIR_quad + const int32_t* p = (const int32_t*) (arg-2); + + asm_ld_imm(rhi, p[1]); + asm_ld_imm(rlo, p[0]); + } + } else if (rlo != UnknownReg && rhi == UnknownReg) { + if (arg->opcode() == LIR_qjoin) { + LIns* lo = arg->oprnd1(); + LIns* hi = arg->oprnd2(); + + int d = findMemFor(hi); + + findSpecificRegFor(lo, rlo); + + STR_preindex(IP, SP, -4); + LDR(IP, FP, d); + } else { + // LIR_quad + const int32_t* p = (const int32_t*) (arg-2); + + STR_preindex(IP, SP, -4); + asm_ld_imm(IP, p[1]); + asm_ld_imm(rlo, p[0]); + } + } else { + asm_pusharg(arg); + } } + +} + #endif /* FEATURE_NANOJIT */ diff --git a/js/src/nanojit/NativeARM.h b/js/src/nanojit/NativeARM.h index 3ac7ceac0f1c..be34f5d343ca 100644 --- a/js/src/nanojit/NativeARM.h +++ b/js/src/nanojit/NativeARM.h @@ -58,25 +58,8 @@ namespace nanojit const int NJ_LOG2_PAGE_SIZE = 12; // 4K -// If NJ_ARM_VFP is defined, then VFP is assumed to -// be present. If it's not defined, then softfloat -// is used, and NJ_SOFTFLOAT is defined. -// When nanojit is used as part of Mozilla's JavaScript engine, this is -// #defined or left #undefined by js/src/configure.in. -//#define NJ_ARM_VFP - -#ifdef NJ_ARM_VFP - -// only d0-d7; we'll use d7 as s14-s15 for i2f/u2f/etc. +// only d0-d6 are actually used; we'll use d7 as s14-s15 for i2f/u2f/etc. #define NJ_VFP_MAX_REGISTERS 8 - -#else - -#define NJ_VFP_MAX_REGISTERS 0 -#define NJ_SOFTFLOAT - -#endif - #define NJ_MAX_REGISTERS (11 + NJ_VFP_MAX_REGISTERS) #define NJ_MAX_STACK_ENTRY 256 #define NJ_MAX_PARAMETERS 16 @@ -124,12 +107,7 @@ typedef enum { LastFloatReg = 22, FirstReg = 0, -#ifdef NJ_ARM_VFP LastReg = 23, -#else - LastReg = 10, -#endif - Scratch = IP, UnknownReg = 31, // special value referring to S14 @@ -156,8 +134,6 @@ typedef enum { NV = 0xF // NeVer } ConditionCode; -const char *ccName(ConditionCode cc); - typedef int RegisterMask; typedef struct _FragInfo { RegisterMask needRestoring; @@ -175,7 +151,7 @@ static const RegisterMask GpRegs = 0x07FF; static const RegisterMask AllowableFlagRegs = 1<= ARM_tst && ARM_##op <= ARM_cmn) {\ + NanoAssert(S==1);\ + asm_output("%s%s %s, #0x%X", #op, condNames[cond], gpn(rl), (imm));\ + } else\ + asm_output("%s%s%s %s, %s, #0x%X", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rl), (imm));\ + } while (0) -// _r = _r AND _imm -#define ANDi(_r,_imm) do { \ - if (isU8((_imm))) { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | OP_IMM | ((_r)<<16) | ((_r)<<12) | ((_imm)&0xFF) ); \ - asm_output("and %s,%d",gpn(_r),(_imm));} \ - else if ((_imm)<0 && (_imm)>-256) { \ - underrunProtect(8); \ - *(--_nIns) = (NIns)( COND_AL | ((_r)<<16) | ((_r)<<12) | (Scratch) ); \ - asm_output("and %s,%s",gpn(_r),gpn(Scratch)); \ - *(--_nIns) = (NIns)( COND_AL | (0x3E<<20) | ((Scratch)<<12) | (((_imm)^0xFFFFFFFF)&0xFF) ); \ - asm_output("mvn %s,%d",gpn(Scratch),(_imm));} \ - else NanoAssert(0); \ +// ALU operation with register and rotated 8-bit immediate arguments +// S - bit, 0 or 1, whether the CPSR register is updated +// rd - destination register +// rl - first (left) operand register +// imm - immediate (max 8 bits) +// rot - rotation to apply to imm +#define ALUi_rot(cond, op, S, rd, rl, imm, rot) do {\ + underrunProtect(4);\ + NanoAssert(isU8(imm));\ + *(--_nIns) = (NIns) ((cond)<<28 | OP_IMM | (ARM_##op)<<21 | (S)<<20 | (rl)<<16 | (rd)<<12 | (rot)<<8 | (imm));\ + if (ARM_##op == ARM_mov || ARM_##op == ARM_mvn)\ + asm_output("%s%s%s %s, #0x%X, %d", #op, condNames[cond], (S)?"s":"", gpn(rd), (imm), (rot)*2);\ + else if (ARM_##op >= ARM_tst && ARM_##op <= ARM_cmn) {\ + NanoAssert(S==1);\ + asm_output("%s%s %s, #0x%X, %d", #op, condNames[cond], gpn(rl), (imm), (rot)*2);\ + } else\ + asm_output("%s%s%s %s, %s, #0x%X, %d", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rl), (imm), (rot)*2);\ } while (0) -// _l = _l XOR _r -#define XOR(_l,_r) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (1<<21) | ((_r)<<16) | ((_l)<<12) | (_l)); \ - asm_output("eor %s,%s",gpn(_l),gpn(_r)); } while(0) - -// _r = _r XOR _imm -#define XORi(_r,_imm) do { \ - NanoAssert(isU8((_imm))); \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<21) | ((_r)<<16) | ((_r)<<12) | ((_imm)&0xFF) ); \ - asm_output("eor %s,%d",gpn(_r),(_imm)); } while(0) - -// _d = _n + _m -#define arm_ADD(_d,_n,_m) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | OP_STAT | (1<<23) | ((_n)<<16) | ((_d)<<12) | (_m)); \ - asm_output("add %s,%s+%s",gpn(_d),gpn(_n),gpn(_m)); } while(0) - -// _l = _l + _r -#define ADD(_l,_r) arm_ADD(_l,_l,_r) - -// Note that this sometimes converts negative immediate values to a to a sub. -// _d = _r + _imm -#define arm_ADDi(_d,_n,_imm) asm_add_imm(_d,_n,_imm) -#define ADDi(_r,_imm) arm_ADDi(_r,_r,_imm) - -// _l = _l - _r -#define SUB(_l,_r) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (1<<22) | ((_l)<<16) | ((_l)<<12) | (_r)); \ - asm_output("sub %s,%s",gpn(_l),gpn(_r)); } while(0) - -// _r = _r - _imm -#define SUBi(_r,_imm) do { \ - if ((_imm)>-256 && (_imm)<256) { \ - underrunProtect(4); \ - if ((_imm)>=0) *(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<22) | ((_r)<<16) | ((_r)<<12) | ((_imm)&0xFF) ); \ - else *(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<23) | ((_r)<<16) | ((_r)<<12) | ((-(_imm))&0xFF) ); \ - } else { \ - if ((_imm)>=0) { \ - if ((_imm)<=510) { \ - underrunProtect(8); \ - int rem = (_imm) - 255; \ - NanoAssert(rem<256); \ - *(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<22) | ((_r)<<16) | ((_r)<<12) | (rem&0xFF) ); \ - *(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<22) | ((_r)<<16) | ((_r)<<12) | (0xFF) ); \ - } else { \ - underrunProtect(4+LD32_size); \ - *(--_nIns) = (NIns)( COND_AL | (1<<22) | ((_r)<<16) | ((_r)<<12) | (Scratch)); \ - LD32_nochk(Scratch, _imm); \ - } \ - } else { \ - if ((_imm)>=-510) { \ - underrunProtect(8); \ - int rem = -(_imm) - 255; \ - *(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<23) | ((_r)<<16) | ((_r)<<12) | ((rem)&0xFF) ); \ - *(--_nIns) = (NIns)( COND_AL | OP_IMM | (1<<23) | ((_r)<<16) | ((_r)<<12) | (0xFF) ); \ - } else { \ - underrunProtect(4+LD32_size); \ - *(--_nIns) = (NIns)( COND_AL | (1<<23) | ((_r)<<16) | ((_r)<<12) | (Scratch)); \ - LD32_nochk(Scratch, -(_imm)); \ - } \ - } \ - } \ - asm_output("sub %s,%d",gpn(_r),(_imm)); \ +// ALU operation with two register arguments +// S - bit, 0 or 1, whether the CPSR register is updated +// rd - destination register +// rl - first (left) operand register +// rr - first (left) operand register +#define ALUr(cond, op, S, rd, rl, rr) do {\ + underrunProtect(4);\ + *(--_nIns) = (NIns) ((cond)<<28 |(ARM_##op)<<21 | (S)<<20 | (rl)<<16 | (rd)<<12 | (rr));\ + if (ARM_##op == ARM_mov || ARM_##op == ARM_mvn)\ + asm_output("%s%s%s %s, %s", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rr));\ + else if (ARM_##op >= ARM_tst && ARM_##op <= ARM_cmn) {\ + NanoAssert(S==1);\ + asm_output("%s%s %s, %s", #op, condNames[cond], gpn(rl), gpn(rr));\ + } else\ + asm_output("%s%s%s %s, %s, %s", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rl), gpn(rr));\ } while (0) +// ALU operation with two register arguments, with rr operated on by a shift and shift immediate +// S - bit, 0 or 1, whether the CPSR register is updated +// rd - destination register +// rl - first (left) operand register +// rr - first (left) operand register +// sh - a ShiftOperator +// imm - immediate argument to shift operator, 5 bits (0..31) +#define ALUr_shi(cond, op, S, rd, rl, rr, sh, imm) do {\ + underrunProtect(4);\ + NanoAssert((imm)>=0 && (imm)<32);\ + *(--_nIns) = (NIns) ((cond)<<28 |(ARM_##op)<<21 | (S)<<20 | (rl)<<16 | (rd)<<12 | (imm)<<7 | (sh)<<4 | (rr));\ + if (ARM_##op == ARM_mov || ARM_##op == ARM_mvn)\ + asm_output("%s%s%s %s, %s, %s #%d", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rr), shiftNames[sh], (imm));\ + else if (ARM_##op >= ARM_tst && ARM_##op <= ARM_cmn) {\ + NanoAssert(S==1);\ + asm_output("%s%s %s, %s, %s #%d", #op, condNames[cond], gpn(rl), gpn(rr), shiftNames[sh], (imm));\ + } else\ + asm_output("%s%s%s %s, %s, %s, %s #%d", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rl), gpn(rr), shiftNames[sh], (imm));\ + } while (0) + +// ALU operation with two register arguments, with rr operated on by a shift and shift register +// S - bit, 0 or 1, whether the CPSR register is updated +// rd - destination register +// rl - first (left) operand register +// rr - first (left) operand register +// sh - a ShiftOperator +// rs - shift operand register +#define ALUr_shr(cond, op, S, rd, rl, rr, sh, rs) do {\ + underrunProtect(4);\ + *(--_nIns) = (NIns) ((cond)<<28 |(ARM_##op)<<21 | (S)<<20 | (rl)<<16 | (rd)<<12 | (rs)<<8 | (sh)<<4 | (rr));\ + if (ARM_##op == ARM_mov || ARM_##op == ARM_mvn)\ + asm_output("%s%s%s %s, %s, %s %s", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rr), shiftNames[sh], gpn(rs));\ + else if (ARM_##op >= ARM_tst && ARM_##op <= ARM_cmn) {\ + NanoAssert(S==1);\ + asm_output("%s%s %s, %s, %s %s", #op, condNames[cond], gpn(rl), gpn(rr), shiftNames[sh], gpn(rs));\ + } else\ + asm_output("%s%s%s %s, %s, %s, %s %s", #op, condNames[cond], (S)?"s":"", gpn(rd), gpn(rl), gpn(rr), shiftNames[sh], gpn(rs));\ + } while (0) + +// _d = _l OR _r +#define ORR(_d,_l,_r) ALUr(AL, orr, 0, _d, _l, _r) + +// _d = _l OR _imm +#define ORRi(_d,_l,_imm) ALUi(AL, orr, 0, _d, _l, _imm) + +// _d = _l AND _r +#define AND(_d,_l,_r) ALUr(AL, and, 0, _d, _l, _r) + +// _d = _l AND _imm +#define ANDi(_d,_l,_imm) ALUi(AL, and, 0, _d, _l, _imm) + +// _d = _l ^ _r +#define EOR(_d,_l,_r) ALUr(AL, eor, 0, _d, _l, _r) + +// _d = _l ^ _imm +#define EORi(_d,_l,_imm) ALUi(AL, eor, 0, _d, _l, _imm) + +// _d = _l + _r; update flags +#define ADD(_d,_l,_r) ALUr(AL, add, 1, _d, _l, _r) + +// _d = _l + _r; update flags if _stat == 1 +#define ADDs(_d,_l,_r,_stat) ALUr(AL, add, _stat, _d, _l, _r) + +// _d = _l + _imm; update flags +#define ADDi(_d,_l,_imm) asm_add_imm(_d, _l, _imm, 1) + +// _d = _l + _imm; update flags if _stat == 1 +#define ADDis(_d,_l,_imm,_stat) asm_add_imm(_d, _l, _imm, _stat) + +// _d = _l - _r; update flags +#define SUB(_d,_l,_r) ALUr(AL, sub, 1, _d, _l, _r) + +// _d = _l - _imm; update flags +#define SUBi(_d,_l,_imm) asm_sub_imm(_d, _l, _imm, 1) + // _l = _l * _r #define MUL(_l,_r) do { \ underrunProtect(4); \ *(--_nIns) = (NIns)( COND_AL | (_l)<<16 | (_l)<<8 | 0x90 | (_r) ); \ asm_output("mul %s,%s",gpn(_l),gpn(_r)); } while(0) +// _d = 0 - _r +#define RSBS(_d,_r) ALUi(AL, rsb, 1, _d, _r, 0) -// RSBS -// _r = -_r -#define NEG(_r) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x27<<20) | ((_r)<<16) | ((_r)<<12) ); \ - asm_output("neg %s",gpn(_r)); } while(0) +// _d = ~_r (one's compliment) +#define MVN(_d,_r) ALUr(AL, mvn, 0, _d, 0, _r) -// MVNS -// _r = !_r -#define NOT(_r) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x1F<<20) | ((_r)<<12) | (_r) ); \ - asm_output("mvn %s",gpn(_r)); } while(0) +// MOVS _d, _r, LSR <_s> +// _d = _r >> _s +#define SHR(_d,_r,_s) ALUr_shr(AL, mov, 1, _d, 0, _r, LSR_reg, _s) -// MOVS _r, _r, LSR <_s> -// _r = _r >> _s -#define SHR(_r,_s) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x1B<<20) | ((_r)<<12) | ((_s)<<8) | (LSR_reg<<4) | (_r) ); \ - asm_output("shr %s,%s",gpn(_r),gpn(_s)); } while(0) - -// MOVS _r, _r, LSR #_imm -// _r = _r >> _imm -#define SHRi(_r,_imm) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x1B<<20) | ((_r)<<12) | ((_imm)<<7) | (LSR_imm<<4) | (_r) ); \ - asm_output("shr %s,%d",gpn(_r),_imm); } while(0) - -// MOVS _r, _r, ASR <_s> -// _r = _r >> _s -#define SAR(_r,_s) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x1B<<20) | ((_r)<<12) | ((_s)<<8) | (ASR_reg<<4) | (_r) ); \ - asm_output("asr %s,%s",gpn(_r),gpn(_s)); } while(0) +// MOVS _d, _r, LSR #_imm +// _d = _r >> _imm +#define SHRi(_d,_r,_imm) ALUr_shi(AL, mov, 1, _d, 0, _r, LSR_imm, _imm) +// MOVS _d, _r, ASR <_s> +// _d = _r >> _s +#define SAR(_d,_r,_s) ALUr_shr(AL, mov, 1, _d, 0, _r, ASR_reg, _s) // MOVS _r, _r, ASR #_imm -// _r = _r >> _imm -#define SARi(_r,_imm) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x1B<<20) | ((_r)<<12) | ((_imm)<<7) | (ASR_imm<<4) | (_r) ); \ - asm_output("asr %s,%d",gpn(_r),_imm); } while(0) +// _d = _r >> _imm +#define SARi(_d,_r,_imm) ALUr_shi(AL, mov, 1, _d, 0, _r, ASR_imm, _imm) -// MOVS _r, _r, LSL <_s> -// _r = _r << _s -#define SHL(_r,_s) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x1B<<20) | ((_r)<<12) | ((_s)<<8) | (LSL_reg<<4) | (_r) ); \ - asm_output("lsl %s,%s",gpn(_r),gpn(_s)); } while(0) +// MOVS _d, _r, LSL <_s> +// _d = _r << _s +#define SHL(_d, _r, _s) ALUr_shr(AL, mov, 1, _d, 0, _r, LSL_reg, _s) -// MOVS _r, _r, LSL #_imm -// _r = _r << _imm -#define SHLi(_r,_imm) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x1B<<20) | ((_r)<<12) | ((_imm)<<7) | (LSL_imm<<4) | (_r) ); \ - asm_output("lsl %s,%d",gpn(_r),(_imm)); } while(0) +// MOVS _d, _r, LSL #_imm +// _d = _r << _imm +#define SHLi(_d, _r, _imm) ALUr_shi(AL, mov, 1, _d, 0, _r, LSL_imm, _imm) // TST -#define TEST(_d,_s) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x11<<20) | ((_d)<<16) | (_s) ); \ - asm_output("test %s,%s",gpn(_d),gpn(_s)); } while(0) - -#define TSTi(_d,_imm) do { \ - underrunProtect(4); \ - NanoAssert(((_imm) & 0xff) == (_imm)); \ - *(--_nIns) = (NIns)( COND_AL | OP_IMM | (0x11<<20) | ((_d) << 16) | (0xF<<12) | ((_imm) & 0xff) ); \ - asm_output("tst %s,#0x%x", gpn(_d), _imm); \ - } while (0); +#define TEST(_l,_r) ALUr(AL, tst, 1, 0, _l, _r) +#define TSTi(_d,_imm) ALUi(AL, tst, 1, 0, _d, _imm) // CMP -#define CMP(_l,_r) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x015<<20) | ((_l)<<16) | (_r) ); \ - asm_output("cmp %s,%s",gpn(_l),gpn(_r)); } while(0) - -// CMP (or CMN) -#define CMPi(_r,_imm) do { \ - if (_imm<0) { \ - if ((_imm)>-256) { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x37<<20) | ((_r)<<16) | (-(_imm)) ); \ - } else { \ - underrunProtect(4+LD32_size); \ - *(--_nIns) = (NIns)( COND_AL | (0x17<<20) | ((_r)<<16) | (Scratch) ); \ - LD32_nochk(Scratch, (_imm)); \ - } \ - } else { \ - if ((_imm)<256) { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0x035<<20) | ((_r)<<16) | ((_imm)&0xFF) ); \ - } else { \ - underrunProtect(4+LD32_size); \ - *(--_nIns) = (NIns)( COND_AL | (0x015<<20) | ((_r)<<16) | (Scratch) ); \ - LD32_nochk(Scratch, (_imm)); \ - } \ - } \ - asm_output("cmp %s,0x%x",gpn(_r),(_imm)); \ - } while(0) +#define CMP(_l,_r) ALUr(AL, cmp, 1, 0, _l, _r) // MOV -#define MR(_d,_s) do { \ + +#define MOV_cond(_cond,_d,_s) ALUr(_cond, mov, 0, _d, 0, _s) + +#define MOV(dr,sr) MOV_cond(AL, dr, sr) +#define MOVEQ(dr,sr) MOV_cond(EQ, dr, sr) +#define MOVNE(dr,sr) MOV_cond(NE, dr, sr) +#define MOVLT(dr,sr) MOV_cond(LT, dr, sr) +#define MOVLE(dr,sr) MOV_cond(LE, dr, sr) +#define MOVGT(dr,sr) MOV_cond(GT, dr, sr) +#define MOVGE(dr,sr) MOV_cond(GE, dr, sr) +#define MOVCC(dr,sr) MOV_cond(CC, dr, sr) +#define MOVLS(dr,sr) MOV_cond(LS, dr, sr) +#define MOVHI(dr,sr) MOV_cond(HI, dr, sr) +#define MOVCS(dr,sr) MOV_cond(CS, dr, sr) +#define MOVVC(dr,sr) MOV_cond(VC, dr, sr) // overflow clear +#define MOVNC(dr,sr) MOV_cond(CC, dr, sr) // carry clear + +// _d = [_b+off] +#define LDR(_d,_b,_off) asm_ldr_chk(_d,_b,_off,1) +#define LDR_nochk(_d,_b,_off) asm_ldr_chk(_d,_b,_off,0) + +// _d = #_imm +#define LDi(_d,_imm) asm_ld_imm(_d,_imm) + +// MOVW and MOVT are ARMv6T2 or newer only + +// MOVW -- writes _imm into _d, zero-extends. +#define MOVW_cond(_cond,_d,_imm) do { \ + NanoAssert(isU16(_imm) || isS16(_imm)); \ underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (0xD<<21) | ((_d)<<12) | (_s) ); \ - asm_output("mov %s,%s",gpn(_d),gpn(_s)); } while (0) + *(--_nIns) = (NIns)( (_cond)<<28 | 3<<24 | 0<<20 | (((_imm)>>12)&0xf)<<16 | (_d)<<12 | (_imm)&0xfff ); \ + asm_output("movw%s %s, #0x%x", condNames[_cond], gpn(_d), (_imm)); \ + } while (0) +#define MOVW(_d,_imm) MOVW_cond(AL, _d, _imm) -#define MR_cond(_d,_s,_cond,_nm) do { \ +// MOVT -- writes _imm into top halfword of _d, does not affect bottom halfword +#define MOVT_cond(_cond,_d,_imm) do { \ + NanoAssert(isU16(_imm) || isS16(_imm)); \ underrunProtect(4); \ - *(--_nIns) = (NIns)( ((_cond)<<28) | (0xD<<21) | ((_d)<<12) | (_s) ); \ - asm_output(_nm " %s,%s",gpn(_d),gpn(_s)); } while (0) + *(--_nIns) = (NIns)( (_cond)<<28 | 3<<24 | 4<<20 | (((_imm)>>12)&0xf)<<16 | (_d)<<12 | (_imm)&0xfff ); \ + asm_output("movt%s %s, #0x%x", condNames[_cond], gpn(_d), (_imm)); \ + } while (0) -#define MREQ(dr,sr) MR_cond(dr, sr, EQ, "moveq") -#define MRNE(dr,sr) MR_cond(dr, sr, NE, "movne") -#define MRL(dr,sr) MR_cond(dr, sr, LT, "movlt") -#define MRLE(dr,sr) MR_cond(dr, sr, LE, "movle") -#define MRG(dr,sr) MR_cond(dr, sr, GT, "movgt") -#define MRGE(dr,sr) MR_cond(dr, sr, GE, "movge") -#define MRB(dr,sr) MR_cond(dr, sr, CC, "movcc") -#define MRBE(dr,sr) MR_cond(dr, sr, LS, "movls") -#define MRA(dr,sr) MR_cond(dr, sr, HI, "movcs") -#define MRAE(dr,sr) MR_cond(dr, sr, CS, "movhi") -#define MRNO(dr,sr) MR_cond(dr, sr, VC, "movvc") // overflow clear -#define MRNC(dr,sr) MR_cond(dr, sr, CC, "movcc") // carry clear - -#define LDR_chk(_d,_b,_off,_chk) do { \ - if (IsFpReg(_d)) { \ - FLDD_chk(_d,_b,_off,_chk); \ - } else if ((_off) > -4096 && (_off) < 4096) { \ - if (_chk) underrunProtect(4); \ - *(--_nIns) = (NIns)( COND_AL | (((_off) < 0 ? 0x51 : 0x59)<<20) | ((_b)<<16) | ((_d)<<12) | (((_off) < 0 ? -(_off) : (_off))&0xFFF) ); \ - } else { \ - if (_chk) underrunProtect(4+LD32_size); \ - NanoAssert((_b) != IP); \ - *(--_nIns) = (NIns)( COND_AL | (0x79<<20) | ((_b)<<16) | ((_d)<<12) | Scratch ); \ - LD32_nochk(Scratch, _off); \ - } \ - asm_output("ldr %s, [%s, #%d]",gpn(_d),gpn(_b),(_off)); \ - } while(0) - -#define LDR(_d,_b,_off) LDR_chk(_d,_b,_off,1) -#define LDR_nochk(_d,_b,_off) LDR_chk(_d,_b,_off,0) +#define MOVT(_d,_imm) MOVT_cond(AL, _d, _imm) // i386 compat, for Assembler.cpp -#define LD(reg,offset,base) LDR_chk(reg,base,offset,1) +#define MR(d,s) MOV(d,s) +#define LD(reg,offset,base) asm_ldr_chk(reg,base,offset,1) #define ST(base,offset,reg) STR(reg,base,offset) -#define LDi(_d,_imm) do { \ - if ((_imm) == 0) { \ - XOR(_d,_d); \ - } else if (isS8((_imm)) || isU8((_imm))) { \ - underrunProtect(4); \ - if ((_imm)<0) *(--_nIns) = (NIns)( COND_AL | (0x3E<<20) | ((_d)<<12) | (((_imm)^0xFFFFFFFF)&0xFF) ); \ - else *(--_nIns) = (NIns)( COND_AL | (0x3B<<20) | ((_d)<<12) | ((_imm)&0xFF) ); \ - asm_output("ld %s,0x%x",gpn((_d)),(_imm)); \ - } else { \ - underrunProtect(LD32_size); \ - LD32_nochk(_d, (_imm)); \ - asm_output("ld %s,0x%x",gpn((_d)),(_imm)); \ - } \ - } while(0) - - // load 8-bit, zero extend (aka LDRB) note, only 5-bit offsets (!) are // supported for this, but that's all we need at the moment. // (LDRB/LDRH actually allow a 12-bit offset in ARM mode but @@ -577,11 +535,15 @@ typedef enum { asm_output("str %s, [%s], %d", gpn(_d), gpn(_n), (_off)); \ } while(0) - +// There isn't really a LEA on ARM; this basically computes _r = _b + #_d, either as a +// ADD _r, _b, #_d (if _d < 256) +// or as a if (_d <= 1020) +// MOV _r, #(_d>>2) +// ADD _r, _b, _r << 2 #define LEA(_r,_d,_b) do { \ NanoAssert((_d)<=1020); \ NanoAssert(((_d)&3)==0); \ - if (_b!=SP) NanoAssert(0); \ + NanoAssert((_b) == FP); \ if ((_d)<256) { \ underrunProtect(4); \ *(--_nIns) = (NIns)( COND_AL | (0x28<<20) | ((_b)<<16) | ((_r)<<12) | ((_d)&0xFF) ); \ @@ -625,8 +587,8 @@ typedef enum { #define PUSHm(_off,_b) do { \ NanoAssert( (int)(_off)>0 ); \ underrunProtect(8); \ - *(--_nIns) = (NIns)( COND_AL | (0x92<<20) | (SP<<16) | (1<<(Scratch)) ); \ - *(--_nIns) = (NIns)( COND_AL | (0x59<<20) | ((_b)<<16) | ((Scratch)<<12) | ((_off)&0xFFF) ); \ + *(--_nIns) = (NIns)( COND_AL | (0x92<<20) | (SP<<16) | (1<<(IP)) ); \ + *(--_nIns) = (NIns)( COND_AL | (0x59<<20) | ((_b)<<16) | ((IP)<<12) | ((_off)&0xFFF) ); \ asm_output("push %d(%s)",(_off),gpn(_b)); } while (0) #define POPr(_r) do { \ @@ -654,28 +616,28 @@ typedef enum { #define JMP_nochk(_t) \ B_cond_chk(AL,_t,0) -#define JA(t) do {B_cond(HI,t); asm_output("ja 0x%08x",(unsigned int)t); } while(0) -#define JNA(t) do {B_cond(LS,t); asm_output("jna 0x%08x",(unsigned int)t); } while(0) -#define JB(t) do {B_cond(CC,t); asm_output("jb 0x%08x",(unsigned int)t); } while(0) -#define JNB(t) do {B_cond(CS,t); asm_output("jnb 0x%08x",(unsigned int)t); } while(0) -#define JE(t) do {B_cond(EQ,t); asm_output("je 0x%08x",(unsigned int)t); } while(0) -#define JNE(t) do {B_cond(NE,t); asm_output("jne 0x%08x",(unsigned int)t); } while(0) -#define JBE(t) do {B_cond(LS,t); asm_output("jbe 0x%08x",(unsigned int)t); } while(0) -#define JNBE(t) do {B_cond(HI,t); asm_output("jnbe 0x%08x",(unsigned int)t); } while(0) -#define JAE(t) do {B_cond(CS,t); asm_output("jae 0x%08x",(unsigned int)t); } while(0) -#define JNAE(t) do {B_cond(CC,t); asm_output("jnae 0x%08x",(unsigned int)t); } while(0) -#define JL(t) do {B_cond(LT,t); asm_output("jl 0x%08x",(unsigned int)t); } while(0) -#define JNL(t) do {B_cond(GE,t); asm_output("jnl 0x%08x",(unsigned int)t); } while(0) -#define JLE(t) do {B_cond(LE,t); asm_output("jle 0x%08x",(unsigned int)t); } while(0) -#define JNLE(t) do {B_cond(GT,t); asm_output("jnle 0x%08x",(unsigned int)t); } while(0) -#define JGE(t) do {B_cond(GE,t); asm_output("jge 0x%08x",(unsigned int)t); } while(0) -#define JNGE(t) do {B_cond(LT,t); asm_output("jnge 0x%08x",(unsigned int)t); } while(0) -#define JG(t) do {B_cond(GT,t); asm_output("jg 0x%08x",(unsigned int)t); } while(0) -#define JNG(t) do {B_cond(LE,t); asm_output("jng 0x%08x",(unsigned int)t); } while(0) -#define JC(t) do {B_cond(CS,t); asm_output("bcs 0x%08x",(unsigned int)t); } while(0) -#define JNC(t) do {B_cond(CC,t); asm_output("bcc 0x%08x",(unsigned int)t); } while(0) -#define JO(t) do {B_cond(VS,t); asm_output("bvs 0x%08x",(unsigned int)t); } while(0) -#define JNO(t) do {B_cond(VC,t); asm_output("bvc 0x%08x",(unsigned int)t); } while(0) +#define JA(t) B_cond(HI,t) +#define JNA(t) B_cond(LS,t) +#define JB(t) B_cond(CC,t) +#define JNB(t) B_cond(CS,t) +#define JE(t) B_cond(EQ,t) +#define JNE(t) B_cond(NE,t) +#define JBE(t) B_cond(LS,t) +#define JNBE(t) B_cond(HI,t) +#define JAE(t) B_cond(CS,t) +#define JNAE(t) B_cond(CC,t) +#define JL(t) B_cond(LT,t) +#define JNL(t) B_cond(GE,t) +#define JLE(t) B_cond(LE,t) +#define JNLE(t) B_cond(GT,t) +#define JGE(t) B_cond(GE,t) +#define JNGE(t) B_cond(LT,t) +#define JG(t) B_cond(GT,t) +#define JNG(t) B_cond(LE,t) +#define JC(t) B_cond(CS,t) +#define JNC(t) B_cond(CC,t) +#define JO(t) B_cond(VS,t) +#define JNO(t) B_cond(VC,t) // used for testing result of an FP compare on x86; not used on arm. // JP = comparison false @@ -691,8 +653,8 @@ typedef enum { underrunProtect(8); \ *(--_nIns) = (NIns)( (_opp<<28) | (1<<21) | ((_r)<<16) | ((_r)<<12) | (_r) ); \ *(--_nIns) = (NIns)( (_cond<<28) | (0x3A<<20) | ((_r)<<12) | (1) ); \ - asm_output("mov%s %s, #1", ccName(_cond), gpn(r), gpn(r)); \ - asm_output("eor%s %s, %s", ccName(_opp), gpn(r), gpn(r)); \ + asm_output("mov%s %s, #1", condNames[_cond], gpn(r), gpn(r)); \ + asm_output("eor%s %s, %s", condNames[_opp], gpn(r), gpn(r)); \ } while (0) @@ -763,12 +725,6 @@ typedef enum { asm_output("ldmia %s!,{0x%x}", gpn(_b), (_mask)); \ } while (0) -#define MRS(_d) do { \ - underrunProtect(4); \ - *(--_nIns) = (NIns)(COND_AL | (0x10<<20) | (0xF<<16) | ((_d)<<12)); \ - asm_output("msr %s", gpn(_d)); \ - } while (0) - /* * VFP */ @@ -789,11 +745,18 @@ typedef enum { #define FMRDH(_Rd,_Dn) do { \ underrunProtect(4); \ - NanoAssert(IsGpReg(_Rd) && IsFpReg(_Dm)); \ + NanoAssert(IsGpReg(_Rd) && IsFpReg(_Dn)); \ *(--_nIns) = (NIns)( COND_AL | (0xE3<<20) | (FpRegNum(_Dn)<<16) | ((_Rd)<<12) | (0xB<<8) | (1<<4) ); \ asm_output("fmrdh %s,%s", gpn(_Rd), gpn(_Dn)); \ } while (0) +#define FMRDL(_Rd,_Dn) do { \ + underrunProtect(4); \ + NanoAssert(IsGpReg(_Rd) && IsFpReg(_Dn)); \ + *(--_nIns) = (NIns)( COND_AL | (0xE1<<20) | (FpRegNum(_Dn)<<16) | ((_Rd)<<12) | (0xB<<8) | (1<<4) ); \ + asm_output("fmrdh %s,%s", gpn(_Rd), gpn(_Dn)); \ + } while (0) + #define FSTD(_Dd,_Rn,_offs) do { \ underrunProtect(4); \ NanoAssert((((_offs) & 3) == 0) && isS8((_offs) >> 2)); \ diff --git a/js/src/nanojit/Nativei386.cpp b/js/src/nanojit/Nativei386.cpp index 5cb48cdf1b76..554f5aec416e 100644 --- a/js/src/nanojit/Nativei386.cpp +++ b/js/src/nanojit/Nativei386.cpp @@ -834,12 +834,12 @@ namespace nanojit NIns* at = 0; LOpcode condop = cond->opcode(); NanoAssert(cond->isCond()); -#ifndef NJ_SOFTFLOAT + if (condop >= LIR_feq && condop <= LIR_fge) { return asm_jmpcc(branchOnFalse, cond, targ); } -#endif + // produce the branch if (branchOnFalse) { @@ -973,13 +973,11 @@ namespace nanojit // only want certain regs Register r = prepResultReg(ins, AllowableFlagRegs); asm_setcc(r, ins); -#ifdef NJ_ARM_VFP - SETE(r); -#else + // SETcc only sets low 8 bits, so extend MOVZX8(r,r); SETNP(r); -#endif + asm_fcmp(ins); } diff --git a/js/src/nanojit/avmplus.h b/js/src/nanojit/avmplus.h index 9605ce7a90ba..cc5ff8d62979 100644 --- a/js/src/nanojit/avmplus.h +++ b/js/src/nanojit/avmplus.h @@ -333,7 +333,6 @@ namespace avmplus { sse2 = true; use_cmov = true; #endif - tree_opt = 0; } uint32_t tree_opt:1; @@ -344,10 +343,32 @@ namespace avmplus { uint32_t verbose_exits:1; uint32_t show_stats:1; - #if defined (AVMPLUS_IA32) || defined(AVMPLUS_AMD64) - bool sse2; - bool use_cmov; - #endif +#if defined (AVMPLUS_IA32) || defined(AVMPLUS_AMD64) + bool sse2; + bool use_cmov; +#endif + +#if defined (AVMPLUS_ARM) + // whethergenerate VFP instructions +# if defined (NJ_FORCE_SOFTFLOAT) + static const bool vfp = false; +# else + bool vfp; +# endif + + // whether generate ARMv6t2 instructions (MOVT/MOVW) +# if defined (NJ_FORCE_NO_ARM_V6T2) + static const bool v6t2 = false; +# else + bool v6t2; +# endif +#endif + +#if defined (NJ_FORCE_SOFTFLOAT) + static const bool soft_float = true; +#else + bool soft_float; +#endif }; static const int kstrconst_emptyString = 0; diff --git a/js/src/trace-test.js b/js/src/trace-test.js index 61d40cd35b7b..b783ff6b4312 100644 --- a/js/src/trace-test.js +++ b/js/src/trace-test.js @@ -4559,6 +4559,9 @@ function testLengthInString() var res = "length" in s; for (var i = 0; i < 5; i++) res = res && ("length" in s); + res = res && s.hasOwnProperty("length"); + for (var i = 0; i < 5; i++) + res = res && s.hasOwnProperty("length"); return res; } testLengthInString.expected = true; @@ -4655,6 +4658,89 @@ function testNEWINIT_DOUBLE() testNEWINIT_DOUBLE.expected = "ok"; test(testNEWINIT_DOUBLE); +function testIntOverflow() { + // int32_max - 7 + var ival = 2147483647 - 7; + for (var i = 0; i < 30; i++) { + ival += 2; + } + return (ival < 2147483647); +} +testIntOverflow.expected = false; +testIntOverflow.jitstats = { + recorderStarted: 2, + recorderAborted: 0, + traceCompleted: 2, + traceTriggered: 2, +}; +test(testIntOverflow); + +function testIntUnderflow() { + // int32_min + 8 + var ival = -2147483648 + 8; + for (var i = 0; i < 30; i++) { + ival -= 2; + } + return (ival > -2147483648); +} +testIntUnderflow.expected = false; +testIntUnderflow.jitstats = { + recorderStarted: 2, + recorderAborted: 0, + traceCompleted: 2, + traceTriggered: 2, +}; +test(testIntUnderflow); + +function testCALLELEM() +{ + function f() { + return 5; + } + + function g() { + return 7; + } + + var x = [f,f,f,f,g]; + var y = 0; + for (var i = 0; i < 5; ++i) + y = x[i](); + return y; +} +testCALLELEM.expected = 7; +test(testCALLELEM); + +function testNewString() +{ + var o = { toString: function() { return "string"; } }; + var r = []; + for (var i = 0; i < 5; i++) + r.push(typeof new String(o)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(3)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(2.5)); + for (var i = 0; i < 5; i++) + r.push(typeof new String("string")); + for (var i = 0; i < 5; i++) + r.push(typeof new String(null)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(true)); + for (var i = 0; i < 5; i++) + r.push(typeof new String(undefined)); + return r.length === 35 && r.every(function(v) { return v === "object"; }); +} +testNewString.expected = true; +testNewString.jitstats = { + recorderStarted: 7, + recorderAborted: 0, + traceCompleted: 7, + sideExitIntoInterpreter: 7 +}; +test(testNewString); + + /***************************************************************************** * * * _____ _ _ _____ ______ _____ _______ * diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp index e2a236cd1033..23917fb5c572 100644 --- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -1090,23 +1090,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) // these jsids filled in later when we have a JSContext to work with. mStrIDs[0] = 0; - // Call XPCPerThreadData::GetData to initialize - // XPCPerThreadData::gTLSIndex before initializing - // JSRuntime::threadTPIndex in JS_NewRuntime. - // - // XPConnect uses a thread local storage (XPCPerThreadData) indexed by - // XPCPerThreadData::gTLSIndex, and SpiderMonkey GC uses a thread local - // storage indexed by JSRuntime::threadTPIndex. - // - // The destructor for XPCPerThreadData::gTLSIndex may access - // thread local storage indexed by JSRuntime::threadTPIndex. - // Thus, the destructor for JSRuntime::threadTPIndex must be called - // later than the one for XPCPerThreadData::gTLSIndex. - // - // We rely on the implementation of NSPR that calls destructors at - // the same order of calling PR_NewThreadPrivateIndex. - XPCPerThreadData::GetData(nsnull); - mJSRuntime = JS_NewRuntime(32L * 1024L * 1024L); // pref ? if(mJSRuntime) { diff --git a/js/tests/ecma_3/Array/15.5.4.8-01.js b/js/tests/ecma_3/Array/15.5.4.8-01.js new file mode 100644 index 000000000000..6ec11fa1f536 --- /dev/null +++ b/js/tests/ecma_3/Array/15.5.4.8-01.js @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Peter Seliger + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = '15.5.4.8-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 480096; +var summary = 'Array.lastIndexOf'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = '-12'; + actual = 0; + actual += Array.lastIndexOf([2, 3,, 4, 5, 6]); + actual += [2, 3,, 4, 5, 6].lastIndexOf(); + actual += Array.prototype.lastIndexOf.call([2, 3,, 4, 5, 6]); + actual += Array.prototype.lastIndexOf.apply([2, 3,, 4, 5, 6], [, -4]); + actual += Array.prototype.lastIndexOf.apply([2, 3,, 4, 5, 6], [undefined, -4]); + actual += Array.prototype.lastIndexOf.apply([2, 3,, 4, 5, 6], [undefined, -5]); + actual += Array.lastIndexOf([2, 3,, 4, 5, 6], undefined); + actual += Array.lastIndexOf([2, 3,, 4, 5, 6], undefined, 1); + actual += Array.lastIndexOf([2, 3,, 4, 5, 6], undefined, 2); + actual += Array.lastIndexOf([2, 3,, 4, 5, 6], undefined); + actual += Array.lastIndexOf([2, 3,, 4, 5, 6], undefined, 1); + actual += Array.lastIndexOf([2, 3,, 4, 5, 6], undefined, 2); + + actual = String(actual); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/ecma_3/Regress/regress-469937.js b/js/tests/ecma_3/Regress/regress-469937.js new file mode 100755 index 000000000000..59ef61f892d9 --- /dev/null +++ b/js/tests/ecma_3/Regress/regress-469937.js @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-469937.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 469937; +var summary = 'Properties without DontEnum are sometimes not enumerated'; +var actual = false; +var expect = true; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +(function(){ + var o = { } + o.PageLeft = 1; + o.Rect2 = 6; + delete o.Rect2; + for (var p in o); + o.Rect3 = 7; + found = false; + for (var p in o) if (p == 'Rect3') found = true; + actual = found; +})(); + +reportCompare(expect, actual, summary); \ No newline at end of file diff --git a/js/tests/js1_5/Regress/regress-457065-03.js b/js/tests/js1_5/Regress/regress-457065-03.js new file mode 100644 index 000000000000..6eb7041bb6ab --- /dev/null +++ b/js/tests/js1_5/Regress/regress-457065-03.js @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-457065-03.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 457065; +var summary = 'Do not assert: !fp->callee || fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1])'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + (function() { + new function (){ for (var x = 0; x < 3; ++x){} }; + })(); + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_5/Regress/regress-477733.js b/js/tests/js1_5/Regress/regress-477733.js new file mode 100644 index 000000000000..dc56f7cc252d --- /dev/null +++ b/js/tests/js1_5/Regress/regress-477733.js @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-477733.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 477733; +var summary = 'TM: Do not assert: !(fp->flags & JSFRAME_POP_BLOCKS)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + function g() { + []; + } + + try { + d.d.d; + } catch(e) { + void (function(){}); + } + + for (var o in [1, 2, 3]) { + g(); + } + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_5/Regress/regress-480244.js b/js/tests/js1_5/Regress/regress-480244.js new file mode 100644 index 000000000000..16d484f0878d --- /dev/null +++ b/js/tests/js1_5/Regress/regress-480244.js @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Graydon Hoare + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-480244.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 480244; +var summary = 'Do not assert: isInt32(*p)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + function outer() { + var v = 10.234; + for (var i = 0; i < 0xff; ++i) { + inner(v); + } + } + + var g = 0; + var h = 0; + + function inner() { + var v = 10; + for (var k = 0; k < 0xff; ++k) { + g++; + if (g & 0xff == 0xff) + h++; + } + return h; + } + + outer(); + print("g=" + g + " h=" + h); + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_5/Regress/regress-483103.js b/js/tests/js1_5/Regress/regress-483103.js new file mode 100644 index 000000000000..e56bceb013d4 --- /dev/null +++ b/js/tests/js1_5/Regress/regress-483103.js @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-483103.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 483103; +var summary = 'TM: Do not assert: p->isQuad()'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + var t = new String(""); + for (var j = 0; j < 3; ++j) { + var e = t["-1"]; + } + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_5/extensions/regress-479487.js b/js/tests/js1_5/extensions/regress-479487.js new file mode 100644 index 000000000000..34fa70aed68f --- /dev/null +++ b/js/tests/js1_5/extensions/regress-479487.js @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479487.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479487; +var summary = 'js_Array_dense_setelem can call arbitrary JS code'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + Array.prototype[1] = 2; + + Array.prototype.__defineSetter__(32, function() { print("Hello from arbitrary JS");}); + Array.prototype.__defineGetter__(32, function() { return 11; }); + + function f() + { + var a = []; + for (var i = 0; i != 10; ++i) { + a[1 << i] = 9999; + } + return a; + } + + f(); + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_5/extensions/regress-479551.js b/js/tests/js1_5/extensions/regress-479551.js new file mode 100644 index 000000000000..1846af8898f9 --- /dev/null +++ b/js/tests/js1_5/extensions/regress-479551.js @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jeff Walden + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479551.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479551; +var summary = 'Do not assert: (cx)->requestDepth || (cx)->thread == (cx)->runtime->gcThread'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof shapeOf != 'function') + { + print(expect = actual = 'Test skipped: requires shell'); + } + else + { + jit(true); + + var o = {a:3, b:2}; + shapeOf(o); + var p = {}; + p.a =3; + p.b=2; + shapeOf(p); + + jit(false); + + } + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_5/extensions/regress-480579.js b/js/tests/js1_5/extensions/regress-480579.js new file mode 100644 index 000000000000..a406ceed9175 --- /dev/null +++ b/js/tests/js1_5/extensions/regress-480579.js @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-480579.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 480579; +var summary = 'Do not assert: pobj_ == obj2'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = '12'; + + a = {x: 1}; + b = {__proto__: a}; + c = {__proto__: b}; + for (i = 0; i < 2; i++) { + print(actual += c.x); + b.x = 2; + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_5/extensions/regress-481516.js b/js/tests/js1_5/extensions/regress-481516.js new file mode 100644 index 000000000000..e9273798b8a0 --- /dev/null +++ b/js/tests/js1_5/extensions/regress-481516.js @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-481516.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 481516; +var summary = 'TM: pobj_ == obj2'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = '1111222'; + + a = {x: 1}; + b = {__proto__: a}; + c = {__proto__: b}; + objs = [{__proto__: a}, {__proto__: a}, {__proto__: a}, b, {__proto__: a}, + {__proto__: a}]; + for (i = 0; i < 6; i++) { + print(actual += ""+c.x); + objs[i].x = 2; + } + print(actual += c.x); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_6/Regress/regress-476655.js b/js/tests/js1_6/Regress/regress-476655.js new file mode 100644 index 000000000000..69bdb754134a --- /dev/null +++ b/js/tests/js1_6/Regress/regress-476655.js @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-476655.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 476655; +var summary = 'TM: Do not assert: count <= (size_t) (fp->regs->sp - StackBase(fp) - depth)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + try + { + eval( + "(function (){ for (var y in this) {} })();" + + "[''.watch(\"\", function(){}) for each (x in ['', '', eval, '', '']) if " + + "(x)].map(Function)" + ); + } + catch(ex) + { + } + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_6/decompilation/browser.js b/js/tests/js1_6/decompilation/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/tests/js1_8/decompilation/browser.js b/js/tests/js1_8/decompilation/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/tests/js1_8/extensions/browser.js b/js/tests/js1_8/extensions/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/tests/js1_8/extensions/regress-479252.js b/js/tests/js1_8/extensions/regress-479252.js new file mode 100644 index 000000000000..3da52462e81a --- /dev/null +++ b/js/tests/js1_8/extensions/regress-479252.js @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479252.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479252; +var summary = 'Avoid watchdog ticks when idle in shell'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof sleep != 'function' || typeof scatter != 'function' || + typeof timeout != 'function') + { + print(expect = actual = 'Test skipped: requires mulithreads and timeout.'); + } + else + { + expectExitCode(6); + + function f() { sleep(100); } + timeout(1.0); + scatter([f,f,f,f,f]); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/extensions/regress-479381.js b/js/tests/js1_8/extensions/regress-479381.js new file mode 100644 index 000000000000..49436a1dcf57 --- /dev/null +++ b/js/tests/js1_8/extensions/regress-479381.js @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479381.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479381; +var summary = 'Do not crash @ js_FinalizeStringRT with multi-threads.'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof gczeal != 'function' || typeof scatter != 'function') + { + print(expect = actual = 'Test skipped: requires mulithreads'); + } + else + { + expect = actual = 'No Crash'; + + gczeal(2); + + function f() { + var s; + for (var i = 0; i < 9999; i++) + s = 'a' + String(i)[3] + 'b'; + return s; + } + + print(scatter([f, f, f, f])); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/genexps/browser.js b/js/tests/js1_8/genexps/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/tests/js1_8/regress/browser.js b/js/tests/js1_8/regress/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/tests/js1_8/regress/regress-457065-01.js b/js/tests/js1_8/regress/regress-457065-01.js new file mode 100644 index 000000000000..c40ad93a57d2 --- /dev/null +++ b/js/tests/js1_8/regress/regress-457065-01.js @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-457065-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 457065; +var summary = 'Do not assert: !fp->callee || fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1])'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + var e = eval; + for (var a in this) { } + (function() { eval("this; for (let b in [0,1,2]) { }"); })(); + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-457065-02.js b/js/tests/js1_8/regress/regress-457065-02.js new file mode 100644 index 000000000000..8cf2188dcaa6 --- /dev/null +++ b/js/tests/js1_8/regress/regress-457065-02.js @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-457065-02.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 457065; +var summary = 'Do not assert: !fp->callee || fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1])'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + (function(){ eval('this'); (function(){ for(let y in [0,1,2]) 6;})(); })(); + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-471373.js b/js/tests/js1_8/regress/regress-471373.js new file mode 100644 index 000000000000..58771accbe98 --- /dev/null +++ b/js/tests/js1_8/regress/regress-471373.js @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-471373.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 471373; +var summary = 'TM: do not assert: (size_t)(regs.pc - script->code) < script->length'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof window == 'undefined') + { + expectExitCode(5); + } + + jit(true); + + function g() { + var x = ; + for (var b = 0; b < 2; ++b) { + yield x; + for (var c = 0; c < 10;++c) { + x.r = x; + } + } + } + for (let y in g()) { } + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-471660.js b/js/tests/js1_8/regress/regress-471660.js new file mode 100644 index 000000000000..561330221ad8 --- /dev/null +++ b/js/tests/js1_8/regress/regress-471660.js @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-471660.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 471660; +var summary = 'TM: Do not assert: !(fp->flags & JSFRAME_POP_BLOCKS)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + y = ; + + for (var w = 0; w < 5; ++w) { + + let (y) { do break ; while (true); } + for each (let x in [{}, function(){}]) {y} + + } + + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-472528-01.js b/js/tests/js1_8/regress/regress-472528-01.js new file mode 100644 index 000000000000..1d3321dec55b --- /dev/null +++ b/js/tests/js1_8/regress/regress-472528-01.js @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-472528-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 472528; +var summary = 'Do not assert: !js_IsActiveWithOrBlock(cx, fp->scopeChain, 0)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + try + { + for (var i = 0; i < 4; ++i) { + for (let j = 0; j < 2; ++j) { } + let (x) (function(){}); + } + } + catch(ex) + { + } + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-472528-02.js b/js/tests/js1_8/regress/regress-472528-02.js new file mode 100644 index 000000000000..6c150595fc71 --- /dev/null +++ b/js/tests/js1_8/regress/regress-472528-02.js @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-472528-02.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 472528; +var summary = 'Do not assert: !fp->blockChain'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + try + { + for (let i = 0; i < 4; ++i) { + for (let j = 0; j < 2; ++j) { } + let (x) (function(){}); + } + } + catch(ex) + { + } + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-472703.js b/js/tests/js1_8/regress/regress-472703.js new file mode 100644 index 000000000000..dbad1488c141 --- /dev/null +++ b/js/tests/js1_8/regress/regress-472703.js @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-472703.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 472703; +var summary = 'Do not assert: regs.sp[-1] == OBJECT_TO_JSVAL(fp->scopeChain)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + try + { + eval( + 'for (var z = 0; z < 2; ++z) { with({}) for(let y in [1, null]); let(x)' + + '(function(){})(); }' + ); + } + catch(ex) + { + } + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-476655.js b/js/tests/js1_8/regress/regress-476655.js new file mode 100644 index 000000000000..080c9bb1df11 --- /dev/null +++ b/js/tests/js1_8/regress/regress-476655.js @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-476655.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 476655; +var summary = 'Do not assert: depth <= (size_t) (fp->regs->sp - StackBase(fp))'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(true); + + try + { + eval( + "for(let y in ['', '']) try {for(let y in ['', '']) ( /x/g ); } finally {" + + "with({}){} } this.zzz.zzz" + + ); + } + catch(ex) + { + } + jit(false); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8/regress/regress-483749.js b/js/tests/js1_8/regress/regress-483749.js new file mode 100644 index 000000000000..12fe7f704369 --- /dev/null +++ b/js/tests/js1_8/regress/regress-483749.js @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-483749.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 483749; +var summary = 'Do not assert: !js_IsActiveWithOrBlock(cx, fp->scopeChain, 0)'; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +jit(true); + +for each (let x in ['']) { + for (var b = 0; b < 5; ++b) { + if (b % 5 == 3) { + with([]) this; + } + } +} + +jit(false); + +reportCompare(expect, actual, summary); diff --git a/js/tests/js1_8_1/JSON/browser.js b/js/tests/js1_8_1/JSON/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/tests/js1_8_1/decompilation/browser.js b/js/tests/js1_8_1/decompilation/browser.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/js/tests/js1_8_1/regress/regress-452498-006.js b/js/tests/js1_8_1/regress/regress-452498-006.js new file mode 100644 index 000000000000..8ebcc66dcc2f --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-006.js @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Andreas Gal + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-006.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #6 From Andreas Gal :gal + + function foo() { + var x = 4; + var f = (function() { return x++; }); + var g = (function() { return x++; }); + return [f,g]; + } + + var bar = foo(); + + expect = '9'; + actual = 0; + + bar[0](); + bar[1](); + + actual = String(expect); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-027.js b/js/tests/js1_8_1/regress/regress-452498-027.js new file mode 100644 index 000000000000..ea0d00fe4cf9 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-027.js @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Brendan Eich + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-027.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = '5'; + +// ------- Comment #27 From Brendan Eich + + function f(x){function g(y)x+y;return g} + g = f(2); + + actual = String(g(3)); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} + + + diff --git a/js/tests/js1_8_1/regress/regress-452498-030.js b/js/tests/js1_8_1/regress/regress-452498-030.js new file mode 100644 index 000000000000..d1b7cd010075 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-030.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Mike Shaver + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-030.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #30 From Mike Shaver + + function f() { var i = 0; var i = 5; } + f(); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-038.js b/js/tests/js1_8_1/regress/regress-452498-038.js new file mode 100644 index 000000000000..f61845ead372 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-038.js @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-038.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #38 From Jesse Ruderman + + [0 for (a in [])]; + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-039.js b/js/tests/js1_8_1/regress/regress-452498-039.js new file mode 100644 index 000000000000..933181022af3 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-039.js @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-039.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = '10'; + +// ------- Comment #39 From Jesse Ruderman + + const e = 0; + print(actual = ++e); + + actual = String(actual) + e; + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-040.js b/js/tests/js1_8_1/regress/regress-452498-040.js new file mode 100644 index 000000000000..90ec177f99ee --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-040.js @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-040.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #40 From Jesse Ruderman + + function m() + { + function a() { } + function b() { a(); } + this.c = function () { b(); } + } + (new m).c(); + + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-050.js b/js/tests/js1_8_1/regress/regress-452498-050.js new file mode 100644 index 000000000000..d0f73d27c02a --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-050.js @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-050.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #50 From Jason Orendorff + +// Do not crash + +// compiler bug when a block introduces no names + let ({}={}) {} + + try + { +// compiler incorrectly emits GETLOCAL for first `x`, +// triggering decompiler assertion + while (x.y) { let x; } + } + catch(ex) + { + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-051.js b/js/tests/js1_8_1/regress/regress-452498-051.js new file mode 100644 index 000000000000..44bb715c7c44 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-051.js @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-051.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #51 From Jason Orendorff + +// Assertion failure: UPVAR_FRAME_SKIP(uva->vector[i]) == 0 +// at ../jsopcode.cpp:2791 +// +// when decompiling the eval code, which is: +// +// main: +// 00000: 10 getupvar 0 +// 00003: 10 getprop "y" +// 00006: 10 popv +// 00007: 10 stop + try + { + function f() { var x; eval("x.y"); } + f(); + } + catch(ex) + { + } + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-052-a.js b/js/tests/js1_8_1/regress/regress-452498-052-a.js new file mode 100644 index 000000000000..c43daa10c950 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-052-a.js @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-052-a.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #52 From Jason Orendorff + + +// Assertion failure: pn_arity == PN_FUNC || pn_arity == PN_NAME, at ../jsparse.h:444 +// Here the function node has been morphed into a JSOP_TRUE node, but we're in +// FindFunArgs poking it anyway. + if (typeof timeout == 'function') + { + expectExitCode(6); + timeout(3); + while(function(){}); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-052.js b/js/tests/js1_8_1/regress/regress-452498-052.js new file mode 100644 index 000000000000..81d3a4c71be2 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-052.js @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-052.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #52 From Jason Orendorff + +// Crash in NoteLValue, called from BindDestructuringVar. +// NoteLValue assumes pn->pn_lexdef is non-null, but here +// pn is itself the definition of x. + for (var [x]=0 in null) ; + +// This one only crashes when executed from a file. +// Assertion failure: pn != dn->dn_uses, at ../jsparse.cpp:1131 + for (var f in null) + ; + var f = 1; + (f) + +// Assertion failure: pnu->pn_cookie == FREE_UPVAR_COOKIE, at ../jsemit.cpp:1815 +// In EmitEnterBlock. x has one use, which is pnu here. +// pnu is indeed a name, but pnu->pn_cookie is 0. + let (x = 1) { var x; } + +// Assertion failure: cg->upvars.lookup(atom), at ../jsemit.cpp:1992 +// atom="x", upvars is empty. + (1 for each (x in x)); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-053.js b/js/tests/js1_8_1/regress/regress-452498-053.js new file mode 100644 index 000000000000..c7e3c6cb2bf7 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-053.js @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-053.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #53 From Jason Orendorff + +// Assertion failure: (slot) < (uint32)(obj)->dslots[-1] +// at ../jsobj.cpp:5559 +// On the last line of BindLet, we have +// JS_SetReservedSlot(cx, blockObj, index, PRIVATE_TO_JSVAL(pn)); +// but this uses reserved slots as though they were unlimited. +// blockObj only has 2. + let (a=0, b=1, c=2) {} + +// In RecycleTree at ../jsparse.cpp:315, we hit +// JS_NOT_REACHED("RecycleUseDefKids"); +// pn->pn_type is TOK_UNARYOP +// pn->pn_op is JSOP_XMLNAME +// pn->pn_defn is 1 +// pn->pn_used is 1 + try + { + @foo; 0; + } + catch(ex) + { + } +// Calls LinkUseToDef with pn->pn_defn == 1. +// +// If you say "var x;" first, then run this case, it gets further, +// crashing in NoteLValue like the first case in comment 52. +// + try + { + for (var [x] = x in y) var x; + } + catch(ex) + { + } +// Assertion failure: !pn2->pn_defn, at ../jsparse.h:461 +// Another case where some optimization is going on. + try + { + if (true && @foo) ; + } + catch(ex) + { + } +// Assertion failure: scope->object == ctor +// in js_FastNewObject at ../jsbuiltins.cpp:237 +// +// With the patch, we're new-ing a different function each time, and the +// .prototype property is missing. +// + for (var z = 0; z < 3; z++) { (new function(){}); } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-054.js b/js/tests/js1_8_1/regress/regress-452498-054.js new file mode 100644 index 000000000000..17b2e941bc70 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-054.js @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-054.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + +// ------- Comment #54 From Jason Orendorff + +// Assertion failure: cg->flags & TCF_IN_FUNCTION +// at ../jsemit.cpp:1991 +// + function f() { var x; eval("let x, x;"); } + f(); + +// Assertion failure: fp2->fun && fp2->script, +// at ../jsinterp.cpp:5589 +// + eval("let(x) function(){ x = this; }()"); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-058.js b/js/tests/js1_8_1/regress/regress-452498-058.js new file mode 100644 index 000000000000..c10015eee683 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-058.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-058.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #58 From Gary Kwong [:nth10sd] + + function foo(x) { var x = x } + +// Assertion failure: dn->kind() == ((data->op == JSOP_DEFCONST) ? JSDefinition::CONST : JSDefinition::VAR), at ../jsparse.cpp:2595 + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-062.js b/js/tests/js1_8_1/regress/regress-452498-062.js new file mode 100644 index 000000000000..5483cbab239c --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-062.js @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-062.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #62 From Gary Kwong [:nth10sd] + + try + { + eval( + '(function(){' + + ' var x;' + + ' this.init_by_array = function()' + + ' x = 0;' + + '})();' + ); + } + catch(ex) + { + } + +// Assertion failure: ATOM_IS_STRING(atom), at ../jsinterp.cpp:5686 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-063.js b/js/tests/js1_8_1/regress/regress-452498-063.js new file mode 100644 index 000000000000..580f08dc91c3 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-063.js @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Brendan Eich + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-063.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #63 From Brendan Eich + + function f(that) { + for (ix in this) + print(ix); + for (let ix in that) + ; + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-068.js b/js/tests/js1_8_1/regress/regress-452498-068.js new file mode 100644 index 000000000000..2d3cb9da959d --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-068.js @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-068.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #68 From Gary Kwong [:nth10sd] + + try + { + eval("*;", (3/0 ? function(id) { return id } : <>)); + } + catch(ex) + { + } + +// ===== + + foo = "" + new Function("while(\u3056){let \u3056 = x}"); + +// ===== + + function a(){ let c; eval("let c, y"); } + a(); + +// ===== + + try + { + {x: 1e+81 ? c : arguments} + } + catch(ex) + { + } + +// ===== + + (function(q){return q;} for each (\u3056 in [])) + +// ===== + + try + { + for(let x = <{x}/> in ) x2; + } + catch(ex) + { + } + +// ===== + + for( + const NaN; + this.__defineSetter__("x4", function(){}); + (eval("", (p={})))) let ({} = (((x ))(function ([]) {})), x1) y; + +// ===== + + function f(){ var c; eval("{var c = NaN, c;}"); } + f(); + +// ===== + try + { + eval( + ' x\n' + + ' let(x) {\n' + + ' var x\n' + ); + } + catch(ex) + { + } + +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-071.js b/js/tests/js1_8_1/regress/regress-452498-071.js new file mode 100644 index 000000000000..6032699636c0 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-071.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-071.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #71 From Jesse Ruderman + + x; var x +// Assertion failure: pn->pn_op == JSOP_NOP, at ../jsparse.cpp:1118 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-072.js b/js/tests/js1_8_1/regress/regress-452498-072.js new file mode 100644 index 000000000000..ab3c9455b3de --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-072.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-072.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #72 From Jesse Ruderman + + v = function p() { delete p; }; +// Assertion failure: JOF_OPTYPE(op) == JOF_ATOM, at ../jsemit.cpp:1711 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-073.js b/js/tests/js1_8_1/regress/regress-452498-073.js new file mode 100644 index 000000000000..84b9527dfa3b --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-073.js @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-073.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #73 From Jesse Ruderman + + try + { + eval('function() { var arguments }'); + } + catch(ex) + { + } + +// Assertion failure: (uintN)i < ss->top, at ../jsopcode.cpp:2801 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-074.js b/js/tests/js1_8_1/regress/regress-452498-074.js new file mode 100644 index 000000000000..08e9a4811b76 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-074.js @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-074.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = '2'; + +// ------- Comment #74 From Jesse Ruderman + + const [d] = [1]; [d] = [2]; print(actual = d); + + actual = String(actual); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-075.js b/js/tests/js1_8_1/regress/regress-452498-075.js new file mode 100644 index 000000000000..ecf3426fb655 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-075.js @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-075.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #75 From Jesse Ruderman + + (function p(){ p = 3; }); + (function p(){ p = 3; return p; })() +// Assertion failure: regs.sp == StackBase(fp), at ../jsinterp.cpp:2980 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-076.js b/js/tests/js1_8_1/regress/regress-452498-076.js new file mode 100644 index 000000000000..6c617d770ae1 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-076.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-076.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #76 From Jesse Ruderman + + for (let d = 0; d < 4; ++d) { d; } +// 1: ReferenceError: d is not defined + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-077.js b/js/tests/js1_8_1/regress/regress-452498-077.js new file mode 100644 index 000000000000..9a018239224b --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-077.js @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-077.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = '2'; + +// ------- Comment #77 From Brendan Eich + + (function () { const [d] = [1]; [d] = [2]; print(actual = d);})(); + + actual = String(actual); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-079.js b/js/tests/js1_8_1/regress/regress-452498-079.js new file mode 100644 index 000000000000..5fffb04906ea --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-079.js @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jason Orendorff + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-079.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #79 From Jason Orendorff + + x; var x; function x() 0 + +// Assertion failure: !(pn->pn_dflags & flag), at ../jsparse.h:635 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-082.js b/js/tests/js1_8_1/regress/regress-452498-082.js new file mode 100644 index 000000000000..0a436393470c --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-082.js @@ -0,0 +1,188 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-082.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #82 From Gary Kwong [:nth10sd] + +// ===== + + (function(){function x(){} {let x = [] }}); + +// ===== + + var f = new Function("new function x(){ return x |= function(){} } ([], function(){})"); + "" + f; + +// ===== + + var f = new Function("for(let [] = [0]; (y) = *; new (*::*)()) {}"); + "" + f; + +// ===== + + uneval(function(){[y] = [x];}); + +// ===== + + function g(code) + { + var f = new Function(code); + f(); + } + g("for (var x = 0; x < 3; ++x)(new (function(){})());"); + +// ===== + + try + { + (function(){new (function ({}, x) { yield (x(1e-81) for (x4 in undefined)) })()})(); + } + catch(ex) + { + } +// ===== + + try + { + (function(){[(function ([y]) { })() for each (x in [])];})(); + } + catch(ex) + { + } +// ===== + + try + { + eval('(function(){for(var x2 = [function(id) { return id } for each (x in []) if ([])] in functional) function(){};})();'); + } + catch(ex) + { + } + +// ===== + + if (typeof window == 'undefined') + global = this; + else + global = window; + + try + { + eval('(function(){with(global){1e-81; }for(let [x, x3] = global -= x in []) function(){}})();'); + } + catch(ex) + { + } + +// ===== + try + { + eval( + 'for(let [\n' + + 'function x () { M:if([1,,]) }\n' + ); + } + catch(ex) + { + } + +// ===== + + try + { + function foo(code) + { + var c; + eval("const c, x5 = c;"); + } + foo(); + } + catch(ex) + { + } + +// ===== + + var f = new Function("try { with({}) x = x; } catch(\u3056 if (function(){x = x2;})()) { let([] = [1.2e3.valueOf(\"number\")]) ((function(){})()); } "); + "" + f; + +// ===== + + var f = new Function("[] = [( '' )()];"); + "" + f; + +// ===== + + var f = new Function("let ([] = [({ get x5 this (x) {} })]) { for(let y in []) with({}) {} }"); + "" + f; + +// ===== + + try + { + for(let x; + ([,,,] + .toExponential(new Function(), (function(){}))); [] = {}) + for(var [x, x] = * in this.__defineSetter__("", function(){})); + } + catch(ex) + { + } + +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-091.js b/js/tests/js1_8_1/regress/regress-452498-091.js new file mode 100644 index 000000000000..a98de08102d1 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-091.js @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-091.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #91 From Jesse Ruderman + + expect = 'function eval() {\n eval("v");\n}'; + f = (function eval() { eval("v"); }); + actual = f + ''; + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-092.js b/js/tests/js1_8_1/regress/regress-452498-092.js new file mode 100644 index 000000000000..44d599e89ec0 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-092.js @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-092.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #92 From Jesse Ruderman + + expect = 'TypeError: redeclaration of formal parameter e'; + try + { + eval('(function (e) { var e; const e; });'); + } + catch(ex) + { + actual = ex + ''; + } +// Without patch: "TypeError: redeclaration of var e" +// expected new behavior // With patch: "TypeError: redeclaration of formal parameter e:" + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-098.js b/js/tests/js1_8_1/regress/regress-452498-098.js new file mode 100644 index 000000000000..fc2f95ffaa54 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-098.js @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-098.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #98 From Gary Kwong [:nth10sd] + + try + { + for(let [x] = (x) in []) {} +// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818 + } + catch(ex) + { + } + + uneval(function(){(Number(0) for each (NaN in []) for each (x4 in this))}); +// Assertion failure: pos == 0, at ../jsopcode.cpp:2963 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-099-a.js b/js/tests/js1_8_1/regress/regress-452498-099-a.js new file mode 100644 index 000000000000..6f33a107bf5d --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-099-a.js @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-099-a.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #99 From Gary Kwong [:nth10sd] + + if (typeof timeout == 'function') + { + expectExitCode(6); + timeout(3); + + while( getter = function() { return y } for (y in y) )( /x/g ); + } + +// Assertion failure: lexdep->frameLevel() <= funbox->level, at ../jsparse.cpp:1771 +// Crash [@ JSCompiler::setFunctionKinds] near null in opt, -j not required. + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-099.js b/js/tests/js1_8_1/regress/regress-452498-099.js new file mode 100644 index 000000000000..8f10da416a44 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-099.js @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-099.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #99 From Gary Kwong [:nth10sd] + + try + { + eval("(function x(){x.(this)} )();"); + } + catch(ex) + { + } + +// Assertion failure: (uint32)(index_) < atoms_->length, at ../jsinterp.cpp:327 +// Crash [@ js_FullTestPropertyCache] at null in opt, -j not required. + +// ===== + + try + { + (function(){try {x} finally {}; ([x in []] for each (x in x))})(); + } + catch(ex) + { + } + +// Assertion failure: lexdep->frameLevel() <= funbox->level, at ../jsparse.cpp:1735 +// Crash [@ BindNameToSlot] near null in opt, -j not required. + +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-101.js b/js/tests/js1_8_1/regress/regress-452498-101.js new file mode 100644 index 000000000000..b482ad282080 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-101.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-101.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #101 From Gary Kwong [:nth10sd] + + uneval(function(){with({functional: []}){x5, y = this;const y }}); +// Assertion failure: strcmp(rval, with_cookie) == 0, at ../jsopcode.cpp:2567 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-102.js b/js/tests/js1_8_1/regress/regress-452498-102.js new file mode 100644 index 000000000000..e0ee4f303cdc --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-102.js @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-102.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #102 From Gary Kwong [:nth10sd] + +// ===== + + (function(){function x(){} function x()y})(); + +// Assertion failure: JOF_OPTYPE(op) == JOF_ATOM, at ../jsemit.cpp:1710 + +// ===== + function f() { + "" + (function(){ + for( ; [function(){}] ; x = 0) + with({x: ""}) + const x = [] + }); + } + f(); + +// Assertion failure: ss->top - saveTop <= 1U, at ../jsopcode.cpp:2156 + +// ===== + + try + { + function f() { + var x; + eval("const x = [];"); + } + f(); + } + catch(ex) + { + } +// Assertion failure: regs.sp == StackBase(fp), at ../jsinterp.cpp:2984 + +// ===== + try + { + do {x} while([[] for (x in []) ]); + } + catch(ex) + { + } +// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818 +// ===== + + try + { + {x} ((x=[] for (x in []))); x; + } + catch(ex) + { + } +// Assertion failure: cg->staticLevel >= level, at ../jsemit.cpp:2014 +// Crash [@ BindNameToSlot] in opt without -j + +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} + + + diff --git a/js/tests/js1_8_1/regress/regress-452498-103.js b/js/tests/js1_8_1/regress/regress-452498-103.js new file mode 100644 index 000000000000..a2a07086a724 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-103.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-103.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #103 From Jesse Ruderman + + (function(a) { v = 5; let [v] = [3]; (function(){ v; })(); })(); +// Assertion failure: !(pn->pn_dflags & flag), at ../jsparse.h:638 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-104.js b/js/tests/js1_8_1/regress/regress-452498-104.js new file mode 100644 index 000000000000..80fa88a3e2b7 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-104.js @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-104.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #104 From Jesse Ruderman + + (function(a) { function b() { a; } function a() { } })(); +// Assertion failure: pn_defn, at ../jsparse.h:655 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-107.js b/js/tests/js1_8_1/regress/regress-452498-107.js new file mode 100644 index 000000000000..1d87c424839b --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-107.js @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-107.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #107 From Jesse Ruderman + +// bug fix gives new decompilation behavior + + function d() { const d; ++d; } + expect = 'function d() { const d; + d + 1; }'; + actual = d + ''; + + compareSource(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-108.js b/js/tests/js1_8_1/regress/regress-452498-108.js new file mode 100644 index 000000000000..35a51c97274e --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-108.js @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-108.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #108 From Jesse Ruderman + + function p(){p} + + expect = 'function p(){p;}'; + actual = p + ''; + + compareSource(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-110.js b/js/tests/js1_8_1/regress/regress-452498-110.js new file mode 100644 index 000000000000..9a243f177700 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-110.js @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-110.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #110 From Brendan Eich + +// (In reply to comment #107) + + function f(a) { const b = a; print(++b); return b; } + + expect = 'function f(a) { const b = a; print(+ b + 1); return b; }'; + actual = f + ''; + compareSource(expect, actual, 'function f(a) { const b = a; print(++b); return b; }'); + + expect = '21'; + actual = 0; + + function g(a) { const b = a; print(actual = ++b); return b; } + actual = String(actual) + g(1); + reportCompare(expect, actual, 'function g(a) { const b = a; print(actual = ++b); return b; }'); + + expect = '21'; + actual = 0; + + const x = 1; print(actual = ++x); + actual = String(actual) + x; + + reportCompare(expect, actual, 'const x = 1; print(actual = ++x); '); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-111.js b/js/tests/js1_8_1/regress/regress-452498-111.js new file mode 100644 index 000000000000..9321d9af644a --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-111.js @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-111.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #111 From Gary Kwong [:nth10sd] + +options("anonfunfix"); +new Function("{function x(){}}"); + +// Assertion failure: pn->pn_defn || (fun->flags & JSFUN_LAMBDA), at ../jsemit.cpp:4149 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} + + diff --git a/js/tests/js1_8_1/regress/regress-452498-112.js b/js/tests/js1_8_1/regress/regress-452498-112.js new file mode 100644 index 000000000000..3b02be305beb --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-112.js @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-112.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #112 From Jesse Ruderman + + expect = 'TypeError: q is not a function'; + + try + { + q = new Function("(function() { q(3); })(); const q;"); q(); + } + catch(ex) + { + actual = ex + ''; + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-114-a.js b/js/tests/js1_8_1/regress/regress-452498-114-a.js new file mode 100644 index 000000000000..c0d1f3d6d133 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-114-a.js @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-114-a.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #114 From Gary Kwong [:nth10sd] + + if (typeof timeout == 'function') + { + timeout(3); + try + { + eval('while(x|=#3={}) with({}) const x;'); + } + catch(ex) + { + } + reportCompare(expect, actual, ''); + } + +// Assertion failure: cg->stackDepth >= 0, at ../jsemit.cpp:185 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-114.js b/js/tests/js1_8_1/regress/regress-452498-114.js new file mode 100644 index 000000000000..c05ed667fd7f --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-114.js @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-114.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #114 From Gary Kwong [:nth10sd] + + for (var x = 0; x < 3; ++x){ y = function (){} } + +// glorp! +// Assertion failed: "Constantly false guard detected": 0 (../nanojit/LIR.cpp:999) +// (note, this is with -j; I don't know what the glorp! message is about.) + +// ===== + function y([{x: x, y}]){} + +// Assertion failure: UPVAR_FRAME_SKIP(pn->pn_cookie) == (pn->pn_defn ? cg->staticLevel : 0), at ../jsemit.cpp:3547 + +// ===== + + try + { + eval("(1.3.__defineGetter__(\"\"));let (y, x) { var z = true, x = 0; }"); + } + catch(ex) + { + } +// Assertion failure: ATOM_IS_STRING(atom), at ../jsinterp.cpp:5691 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-116.js b/js/tests/js1_8_1/regress/regress-452498-116.js new file mode 100644 index 000000000000..ffe36cd544d7 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-116.js @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-116.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #116 From Gary Kwong [:nth10sd] + +// -j + (new Function("for (var x = 0; x < 3; ++x) { (function(){})() } "))(); + +//Crash [@ js_IsActiveWithOrBlock] + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-117.js b/js/tests/js1_8_1/regress/regress-452498-117.js new file mode 100644 index 000000000000..5fee120f91c3 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-117.js @@ -0,0 +1,171 @@ +03/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-117.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #117 From Gary Kwong [:nth10sd] + +// The following all do not require -j. + +// ===== + + try + { + eval('x; function x(){}; const x;'); + } + catch(ex) + { + } + +// Assertion failure: !pn->isPlaceholder(), at ../jsparse.cpp:4876 +// ===== + (function(){ var x; eval("var x; x = null"); })() + +// Assertion failure: regs.sp == StackBase(fp), at ../jsinterp.cpp:2984 +// ===== + function this ({x}) { function x(){} } + +// Assertion failure: cg->stackDepth == stackDepth, at ../jsemit.cpp:3664 +// ===== + for(let x = [ "" for (y in /x/g ) if (x)] in ("")); + +// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818 +// ===== + (function(){const x = 0, y = delete x;})() + +// Assertion failure: JOF_OPTYPE(op) == JOF_ATOM, at ../jsemit.cpp:1710 +// ===== + try + { + (function(){(yield []) (function(){with({}){x} }); const x;})(); + } + catch(ex) + { + } + +// Assertion failure: cg->upvars.lookup(atom), at ../jsemit.cpp:2022 +// ===== + try + { + (function(){([]) ((function(q) { return q; })for (each in *))})(); + } + catch(ex) + { + } +// Assertion failure: lexdep->frameLevel() <= funbox->level, at ../jsparse.cpp:1782 +// Opt crash [@ JSCompiler::setFunctionKinds] near null +// ===== + + try + { + eval("((x1) > [(x)(function() { x;}) for each (x in x)])()"); + } + catch(ex) + { + } + +// Assertion failure: pnu->pn_lexdef == dn, at ../jsemit.cpp:1817 +// ===== + uneval(function(){for(var [arguments] = ({ get y(){} }) in y ) (x);}); + +// Assertion failure: slot < StackDepth(jp->script), at ../jsopcode.cpp:1318 +// ===== + uneval(function(){([] for ([,,]in <>));}); + +// Assertion failure: n != 0, at ../jsfun.cpp:2689 +// ===== + try + { + eval('(function(){{for(c in (function (){ for(x in (x1))window} )()) {const x;} }})();'); + } + catch(ex) + { + } + +// Assertion failure: op == JSOP_GETLOCAL, at ../jsemit.cpp:4557 +// ===== + try + { + (eval("(function(){let x , x = (x for (x in null))});"))(); + } + catch(ex) + { + } + +// Assertion failure: (fun->u.i.script)->upvarsOffset != 0, at ../jsfun.cpp:1537 +// Opt crash [@ js_NewFlatClosure] near null +// ===== + "" + function(){for(var [x] in x1) ([]); function x(){}} + +// Assertion failure: cg->stackDepth == stackDepth, at ../jsemit.cpp:3664 +// Opt crash [@ JS_ArenaRealloc] near null +// ===== + try + { + eval( + "for (a in (function(){" + + " for each (let x in ['']) { return new function x1 (\u3056) { yield x } ();" + + " }})())" + + " function(){}" + ); + } + catch(ex) + { + } +// Crash [@ js_Interpret] near null +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-118.js b/js/tests/js1_8_1/regress/regress-452498-118.js new file mode 100644 index 000000000000..589da26148f5 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-118.js @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-118.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #118 From Jesse Ruderman + + (function() { (function() { e *= 4; })(); var e; })(); + +//Without patch: no output +//With patch: ReferenceError: reference to undefined property "e" + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-119.js b/js/tests/js1_8_1/regress/regress-452498-119.js new file mode 100644 index 000000000000..05a0c1634c4f --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-119.js @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-119.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #119 From Gary Kwong [:nth10sd] + +// The following additional testcases also do not require -j. + +// ===== + function f() { + var x; + eval("for(let y in [false]) var x, x = 0"); + } + f(); + +// Assertion failure: !JSVAL_IS_PRIMITIVE(regs.sp[-2]), at ../jsinterp.cpp:3243 +// Opt crash [@ JS_GetMethodById] near null +// ===== + new Function("for(x1 in ((function (){ yield x } )())){var c, x = []} function x(){} "); + +// Assertion failure: pn_used, at ../jsparse.h:401 +// Opt crash [@ FindFunArgs] at null +// ===== + uneval(new Function("[(x = x) for (c in []) if ([{} for (x in [])])]")) + +// Assertion failure: (uintN)i < ss->top, at ../jsopcode.cpp:2814 +// ===== + function f() { + var x; + (function(){})(); + eval("if(x|=[]) {const x; }"); + } + f(); + +// Opt crash [@ js_ValueToNumber] at 0xc3510424 +// Dbg crash [@ js_ValueToNumber] at 0xdadadad8 +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-121.js b/js/tests/js1_8_1/regress/regress-452498-121.js new file mode 100644 index 000000000000..c1ece643fd41 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-121.js @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-121.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #121 From Gary Kwong [:nth10sd] + +// without -j + x = function()x; + +// Assertion failure: !(pn->pn_dflags & flag), at ../jsparse.h:651 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-123.js b/js/tests/js1_8_1/regress/regress-452498-123.js new file mode 100644 index 000000000000..77cecb7ea705 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-123.js @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-123.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + +// ------- Comment #123 From Gary Kwong [:nth10sd] + +// Does not require -j: +// ===== + try + { + eval('y = (function (){y} for (x in []);'); + } + catch(ex) + { + } + +// Assertion failure: !(pn->pn_dflags & flag), at ../jsparse.h:651 +// ===== + (function(){for(var x = arguments in []){} function x(){}})(); + +// Assertion failure: dn->pn_defn, at ../jsemit.cpp:1873 +// ===== + + +// Requires -j: +// ===== + (function(){ eval("for (x in ['', {}, '', {}]) { this; }" )})(); + +// Assertion failure: fp->thisp == JSVAL_TO_OBJECT(fp->argv[-1]), at ../jstracer.cpp:4172 +// ===== + for each (let x in ['', '', '']) { (new function(){} )} + +// Assertion failure: scope->object == ctor, at ../jsbuiltins.cpp:236 +// Opt crash [@ js_FastNewObject] near null +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-129.js b/js/tests/js1_8_1/regress/regress-452498-129.js new file mode 100644 index 000000000000..f540c2d1f697 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-129.js @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-129.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #129 From Gary Kwong [:nth10sd] + +// Does not require -j: +// ===== + ({ set x x () { for(x in function(){}){}} }) + +// Assertion failure: JOF_OPTYPE(op) == JOF_ATOM, at ../jsemit.cpp:1710 +// ===== + +try +{ + (function (){ eval("(function(){delete !function(){}});"); })(); +} +catch(ex) +{ +} +// Debug crash [@ JSParseNode::isFunArg] at null +// Opt crash [@ FindFunArgs] near null +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-130.js b/js/tests/js1_8_1/regress/regress-452498-130.js new file mode 100644 index 000000000000..429aff51fe93 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-130.js @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-130.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #130 From Gary Kwong [:nth10sd] + +// Does not require -j: +// ===== + ((function x()x in []) for (y in [])) + +//Assertion failure: lexdep->frameLevel() <= funbox->level, at ../jsparse.cpp:1778 +// Opt crash [@ JSCompiler::setFunctionKinds] +// ===== + let(x=[]) function(){try {x} catch(x) {} } + +// Assertion failure: cg->upvars.lookup(atom), at ../jsemit.cpp:2034 +// ===== + try + { + eval('for(let [y] = (let (x) (y)) in []) function(){}'); + } + catch(ex) + { + } +// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818 +// ===== + + +// Requires -j: +// ===== + for (var x = 0; x < 3; ++x) { new function(){} } + +// Assertion failure: cx->bailExit, at ../jstracer.cpp:4672 +// Opt crash [@ LeaveTree] near null + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-131.js b/js/tests/js1_8_1/regress/regress-452498-131.js new file mode 100644 index 000000000000..ce449355b83f --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-131.js @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-131.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #131 From Gary Kwong [:nth10sd] + +// Does not require -j: +// ===== + try + { + eval('((__defineGetter__, function (x) { function x(){} }) for'); + } + catch(ex) + { + } +// Assertion failure: pn->pn_cookie == FREE_UPVAR_COOKIE, at ../jsparse.cpp:5698 +// ===== + try + { + eval('( "" ? 1.3 : x); *::*; x::x;'); + } + catch(ex) + { + } +// Assertion failure: pn != dn->dn_uses, at ../jsparse.cpp:1171 +// ===== + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-135-a.js b/js/tests/js1_8_1/regress/regress-452498-135-a.js new file mode 100644 index 000000000000..e19fb5b5290d --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-135-a.js @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-135-a.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #135 From Gary Kwong [:nth10sd] + + if (typeof timeout == 'function') + { + expectExitCode(6); + timeout(3); + eval("do ([]); while(y for each (x in []))"); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-135.js b/js/tests/js1_8_1/regress/regress-452498-135.js new file mode 100644 index 000000000000..c6cb0126f7cf --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-135.js @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-135.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #135 From Gary Kwong [:nth10sd] + +// -j is not required: +// === + + for (let i = 0; i < 9; ++i) { + let m = i; + if (i % 3 == 1) { + print('' + (function() { return m; })()); + } + } + +// Assertion failure: fp2->fun && fp2->script, at ../jsinterp.cpp:5633 +// Opt crash [@ js_Interpret] +// === + + try + { + (x for each (c in [])) + x + } + catch(ex) + { + } + +// Assertion failure: dn_kind == JSDefinition::VAR || dn_kind == JSDefinition::CONST, at ../jsemit.cpp:2187 + +// === + "" + (function(){L:if (*::*){ var x } function x(){}}) + +// Assertion failure: slot < StackDepth(jp->script), at ../jsopcode.cpp:1329 +// === + "" + (function(){if (*::*){ var x } function x(){}}) + +// Assertion failure: (uintN)i < ss->top, at ../jsopcode.cpp:2825 +// === + "" + (function(){{; throw ;for(var x = [] in false) return } function x(){}}) + +// Assertion failure: ss->printer->pcstack, at ../jsopcode.cpp:909 +// === + try + { + (function(){for(; (this); ((window for (x in [])) for (y in []))) 0}); + } + catch(ex) + { + } +// Assertion failure: level >= tc->staticLevel, at ../jsparse.cpp:5773 +// === + eval(uneval( function(){ + ((function()y)() for each (x in this)) + } )) + +// Debug & opt crash [@ BindNameToSlot] + +// -j is required: +// === + for (let a=0;a<3;++a) for (let b=0;b<3;++b) if ((g=a|(a%b))) with({}){} + +// Assertion failure: OBJ_IS_CLONED_BLOCK(obj), at ../jsobj.cpp:2392 + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-138.js b/js/tests/js1_8_1/regress/regress-452498-138.js new file mode 100644 index 000000000000..5178cc8523f1 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-138.js @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-138.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #138 From Gary Kwong [:nth10sd] + +// Does not require -j: +// === + ((function x(){ yield (x = undefined) } ) for (y in /x/)); + +// Assertion failure: lexdep->frameLevel() <= funbox->level, at ../jsparse.cpp:1820 +// === + try + { + for(let x in ( x for (y in x) for each (x in []) )) y; + } + catch(ex) + { + } +// Assertion failure: cg->upvars.lookup(atom), at ../jsemit.cpp:2034 +// === + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-139.js b/js/tests/js1_8_1/regress/regress-452498-139.js new file mode 100644 index 000000000000..9394fa3e9837 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-139.js @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-139.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + +// ------- Comment #139 From Gary Kwong [:nth10sd] + +// Does not require -j: +// === + try + { + (function(){var x = x (x() for each (x in []))})(); + } + catch(ex) + { + } +// Assertion failure: (fun->u.i.script)->upvarsOffset != 0, at ../jsfun.cpp:1541 +// Opt crash near null [@ js_NewFlatClosure] +// === + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-452498-155.js b/js/tests/js1_8_1/regress/regress-452498-155.js new file mode 100644 index 000000000000..c1b23722f78b --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-452498-155.js @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Gary Kwong + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-155.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2 regression tests'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + try + { + delete (1 ? window : function(){}); + } + catch(ex) + { + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-479430-01.js b/js/tests/js1_8_1/regress/regress-479430-01.js new file mode 100644 index 000000000000..f248005435f4 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-479430-01.js @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479430-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479430; +var summary = 'Missing operation callback checks'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof timeout == 'function') + { + expectExitCode(6); + + timeout(0.01); + + function f(n) + { + if (n != 0) { + f(n - 1); + f(n - 1); + } + } + + f(100); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-479430-02.js b/js/tests/js1_8_1/regress/regress-479430-02.js new file mode 100644 index 000000000000..2932f1d4a653 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-479430-02.js @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479430-02.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479430; +var summary = 'Missing operation callback checks'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof timeout == 'function') + { + expectExitCode(6); + + timeout(0.01); + + function f(n) + { + if (n != 0) { + try { f(n - 1); } catch (e) {} + try { f(n - 1); } catch (e) {} + } + throw 0; + } + + f(100); + + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-479430-03.js b/js/tests/js1_8_1/regress/regress-479430-03.js new file mode 100644 index 000000000000..8f0a9e1d6d21 --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-479430-03.js @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479430-03.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479430; +var summary = 'Missing operation callback checks'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof timeout == 'function') + { + expectExitCode(6); + + timeout(0.01); + + function f(n) + { + if (n != 0) { + f(n - 1); + f(n - 1); + } + try { + return 0; + } finally { + n++; + } + } + + f(100); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-479430-04.js b/js/tests/js1_8_1/regress/regress-479430-04.js new file mode 100644 index 000000000000..9611ebf95c5a --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-479430-04.js @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479430-04.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479430; +var summary = 'Missing operation callback checks'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof timeout== 'function') + { + expectExitCode(6); + + timeout(0.01); + + function f(n) + { + if (n != 0) { + try { f(n - 1); } catch (e) {} + try { f(n - 1); } catch (e) {} + } + name_that_does_not_exists; + } + + f(100); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/regress/regress-479430-05.js b/js/tests/js1_8_1/regress/regress-479430-05.js new file mode 100644 index 000000000000..13679cc38b6e --- /dev/null +++ b/js/tests/js1_8_1/regress/regress-479430-05.js @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-479430-05.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 479430; +var summary = 'Missing operation callback checks'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + if (typeof timeout == 'function') + { + expectExitCode(6); + + timeout(0.01); + + function f(n) + { + if (n != 0) { + try { f(n - 1); } finally { f(n - 1); } + } + name_that_does_not_exists; + } + + f(100); + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_8_1/trace/regress-452498-01.js b/js/tests/js1_8_1/trace/regress-452498-01.js new file mode 100644 index 000000000000..59a04c8434cb --- /dev/null +++ b/js/tests/js1_8_1/trace/regress-452498-01.js @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Boris Zbarsky + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +var gTestfile = 'regress-452498-01.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 452498; +var summary = 'TM: upvar2: jit heavyweight functions'; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +function complex(aReal, aImag) { + this.r = aReal; + this.i = aImag; + this.square = function() { + return new complex(this.r * this.r - this.i * this.i, + 2 * this.r * this.i); + } + this.dist = function() { + return Math.sqrt(this.r * this.r + this.i * this.i); + } + this.add = function(aComplex) { + return new complex(this.r + aComplex.r, this.i + aComplex.i); + } +} + +function mandelbrotValueOO (aC, aIterMax) { + let Z = new complex(0.0, 0.0); + for (var iter = 0; iter < aIterMax; iter++) { + Z = Z.square().add(aC); + if (Z.r * Z.r + Z.i * Z.i > 256) { break; } + } + return iter; +} + +function f(trace) { + jit(trace); + var start = Date.now(); + const width = 60; + const height = 60; + const max_iters = 50; + var output = []; + for (let img_x = 0; img_x < width; img_x++) { + for (let img_y = 0; img_y < height; img_y++) { + let C = new complex(-2 + (img_x / width) * 3, + -1.5 + (img_y / height) * 3); + var res = mandelbrotValueOO(C, max_iters); + if (output.length > 0 && output[output.length -1][0] == res) { + output[output.length-1][1]++; + } else { + output.push([res, 1]); + } + } + } + jit(false); + const reference = "[[2, 6], [3, 17], [4, 6], [5, 1], [50, 1], [5, 1], [4, 6], [3, 17], [2, 10], [3, 17], [4, 6], [5, 1], [6, 1], [50, 1], [6, 1], [5, 1], [4, 6], [3, 17], [2, 8], [3, 17], [4, 6], [5, 2], [6, 1], [50, 1], [6, 1], [5, 2], [4, 6], [3, 17], [2, 6], [3, 17], [4, 6], [5, 2], [6, 1], [7, 1], [50, 1], [7, 1], [6, 1], [5, 2], [4, 6], [3, 17], [2, 4], [3, 17], [4, 7], [5, 2], [6, 1], [8, 1], [50, 1], [8, 1], [6, 1], [5, 2], [4, 7], [3, 17], [2, 2], [3, 17], [4, 7], [5, 3], [6, 1], [9, 1], [50, 1], [9, 1], [6, 1], [5, 3], [4, 7], [3, 17], [2, 1], [3, 16], [4, 7], [5, 3], [6, 2], [8, 1], [50, 1], [8, 1], [6, 2], [5, 3], [4, 7], [3, 32], [4, 7], [5, 4], [6, 1], [7, 1], [8, 1], [50, 1], [8, 1], [7, 1], [6, 1], [5, 4], [4, 7], [3, 31], [4, 7], [5, 3], [6, 2], [7, 1], [8, 1], [50, 1], [8, 1], [7, 1], [6, 2], [5, 3], [4, 7], [3, 30], [4, 7], [5, 4], [6, 2], [7, 1], [8, 1], [50, 1], [8, 1], [7, 1], [6, 2], [5, 4], [4, 7], [3, 28], [4, 7], [5, 4], [6, 2], [7, 1], [8, 1], [10, 1], [50, 1], [10, 1], [8, 1], [7, 1], [6, 2], [5, 4], [4, 7], [3, 26], [4, 7], [5, 4], [6, 2], [7, 1], [8, 1], [9, 1], [11, 1], [50, 1], [11, 1], [9, 1], [8, 1], [7, 1], [6, 2], [5, 4], [4, 7], [3, 25], [4, 6], [5, 3], [6, 3], [7, 1], [8, 1], [18, 1], [13, 1], [15, 1], [50, 1], [15, 1], [13, 1], [18, 1], [8, 1], [7, 1], [6, 3], [5, 3], [4, 6], [3, 24], [4, 7], [5, 2], [6, 2], [7, 3], [8, 1], [10, 1], [14, 1], [50, 3], [14, 1], [10, 1], [8, 1], [7, 3], [6, 2], [5, 2], [4, 7], [3, 23], [4, 6], [5, 3], [7, 1], [8, 1], [9, 1], [8, 2], [10, 1], [11, 1], [15, 1], [50, 3], [15, 1], [11, 1], [10, 1], [8, 2], [9, 1], [8, 1], [7, 1], [5, 3], [4, 6], [3, 22], [4, 7], [5, 2], [6, 1], [7, 1], [14, 1], [16, 1], [11, 1], [10, 1], [12, 1], [20, 1], [23, 1], [46, 1], [50, 1], [46, 1], [23, 1], [20, 1], [12, 1], [10, 1], [11, 1], [16, 1], [14, 1], [7, 1], [6, 1], [5, 2], [4, 7], [3, 20], [4, 7], [5, 3], [6, 1], [7, 1], [8, 1], [10, 1], [17, 1], [16, 1], [20, 1], [50, 7], [20, 1], [16, 1], [17, 1], [10, 1], [8, 1], [7, 1], [6, 1], [5, 3], [4, 7], [3, 19], [4, 7], [5, 3], [6, 2], [7, 1], [10, 1], [21, 1], [50, 11], [21, 1], [10, 1], [7, 1], [6, 2], [5, 3], [4, 7], [3, 18], [4, 7], [5, 4], [6, 1], [7, 1], [8, 1], [9, 1], [13, 1], [25, 1], [50, 9], [25, 1], [13, 1], [9, 1], [8, 1], [7, 1], [6, 1], [5, 4], [4, 7], [3, 17], [4, 7], [5, 4], [6, 1], [7, 1], [8, 1], [14, 2], [50, 11], [14, 2], [8, 1], [7, 1], [6, 1], [5, 4], [4, 7], [3, 16], [4, 7], [5, 4], [6, 2], [7, 1], [8, 1], [11, 1], [36, 1], [50, 11], [36, 1], [11, 1], [8, 1], [7, 1], [6, 2], [5, 4], [4, 7], [3, 15], [4, 7], [5, 4], [6, 2], [7, 1], [8, 1], [9, 1], [14, 1], [50, 11], [14, 1], [9, 1], [8, 1], [7, 1], [6, 2], [5, 4], [4, 7], [3, 14], [4, 7], [5, 4], [6, 3], [7, 1], [8, 1], [9, 1], [12, 1], [26, 1], [50, 9], [26, 1], [12, 1], [9, 1], [8, 1], [7, 1], [6, 3], [5, 4], [4, 7], [3, 13], [4, 7], [5, 4], [6, 2], [7, 2], [8, 1], [9, 1], [10, 1], [15, 1], [50, 9], [15, 1], [10, 1], [9, 1], [8, 1], [7, 2], [6, 2], [5, 4], [4, 7], [3, 12], [4, 7], [5, 4], [6, 3], [7, 1], [8, 2], [9, 1], [10, 1], [12, 1], [16, 1], [50, 7], [16, 1], [12, 1], [10, 1], [9, 1], [8, 2], [7, 1], [6, 3], [5, 4], [4, 7], [3, 11], [4, 6], [5, 4], [6, 3], [7, 1], [8, 2], [9, 1], [11, 1], [12, 1], [14, 1], [17, 1], [23, 1], [34, 1], [50, 3], [34, 1], [23, 1], [17, 1], [14, 1], [12, 1], [11, 1], [9, 1], [8, 2], [7, 1], [6, 3], [5, 4], [4, 6], [3, 10], [4, 7], [5, 3], [6, 2], [7, 2], [8, 1], [9, 1], [22, 1], [12, 1], [50, 1], [25, 1], [50, 11], [25, 1], [50, 1], [12, 1], [22, 1], [9, 1], [8, 1], [7, 2], [6, 2], [5, 3], [4, 7], [3, 9], [4, 6], [5, 4], [6, 1], [7, 1], [8, 2], [9, 1], [14, 1], [50, 1], [21, 1], [50, 15], [21, 1], [50, 1], [14, 1], [9, 1], [8, 2], [7, 1], [6, 1], [5, 4], [4, 6], [3, 8], [4, 7], [5, 3], [6, 2], [9, 1], [14, 1], [13, 1], [11, 1], [13, 1], [26, 1], [50, 17], [26, 1], [13, 1], [11, 1], [13, 1], [14, 1], [9, 1], [6, 2], [5, 3], [4, 7], [3, 7], [4, 6], [5, 4], [6, 1], [7, 1], [9, 1], [49, 1], [43, 1], [50, 23], [43, 1], [49, 1], [9, 1], [7, 1], [6, 1], [5, 4], [4, 6], [3, 7], [4, 5], [5, 4], [6, 2], [7, 1], [9, 1], [13, 1], [50, 25], [13, 1], [9, 1], [7, 1], [6, 2], [5, 4], [4, 5], [3, 6], [4, 6], [5, 3], [6, 2], [7, 2], [9, 1], [11, 1], [17, 1], [50, 23], [17, 1], [11, 1], [9, 1], [7, 2], [6, 2], [5, 3], [4, 6], [3, 5], [4, 5], [5, 3], [6, 3], [7, 1], [8, 1], [9, 1], [50, 1], [26, 1], [50, 23], [26, 1], [50, 1], [9, 1], [8, 1], [7, 1], [6, 3], [5, 3], [4, 5], [3, 5], [4, 4], [5, 3], [6, 3], [7, 1], [8, 2], [10, 1], [21, 1], [50, 25], [21, 1], [10, 1], [8, 2], [7, 1], [6, 3], [5, 3], [4, 4], [3, 5], [4, 4], [5, 2], [6, 3], [7, 1], [12, 1], [9, 1], [10, 1], [11, 1], [50, 27], [11, 1], [10, 1], [9, 1], [12, 1], [7, 1], [6, 3], [5, 2], [4, 4], [3, 5], [4, 3], [5, 2], [6, 2], [7, 2], [9, 1], [42, 1], [15, 1], [23, 1], [14, 1], [50, 27], [14, 1], [23, 1], [15, 1], [42, 1], [9, 1], [7, 2], [6, 2], [5, 2], [4, 3], [3, 5], [4, 3], [5, 1], [6, 1], [20, 1], [9, 1], [8, 1], [9, 1], [10, 1], [16, 1], [50, 33], [16, 1], [10, 1], [9, 1], [8, 1], [9, 1], [20, 1], [6, 1], [5, 1], [4, 3], [3, 5], [4, 3], [5, 1], [6, 1], [9, 1], [13, 1], [12, 1], [11, 1], [38, 1], [25, 1], [50, 33], [25, 1], [38, 1], [11, 1], [12, 1], [13, 1], [9, 1], [6, 1], [5, 1], [4, 3], [3, 5], [4, 3], [5, 2], [6, 1], [7, 1], [10, 1], [24, 1], [25, 1], [50, 35], [25, 1], [24, 1], [10, 1], [7, 1], [6, 1], [5, 2], [4, 3], [3, 5], [4, 4], [5, 1], [6, 1], [7, 1], [11, 2], [13, 1], [19, 1], [50, 33], [19, 1], [13, 1], [11, 2], [7, 1], [6, 1], [5, 1], [4, 4], [3, 5], [4, 4], [5, 2], [6, 1], [50, 1], [8, 2], [17, 1], [19, 1], [35, 1], [14, 1], [24, 1], [50, 25], [24, 1], [14, 1], [35, 1], [19, 1], [17, 1], [8, 2], [50, 1], [6, 1], [5, 2], [4, 4], [3, 5], [4, 5], [5, 2], [6, 2], [7, 1], [8, 1], [9, 2], [11, 1], [38, 1], [50, 25], [38, 1], [11, 1], [9, 2], [8, 1], [7, 1], [6, 2], [5, 2], [4, 5], [3, 6], [4, 4], [5, 3], [6, 2], [7, 2], [8, 1], [9, 1], [15, 1], [50, 25], [15, 1], [9, 1], [8, 1], [7, 2], [6, 2], [5, 3], [4, 4], [3, 7], [4, 5], [5, 3], [6, 3], [7, 1], [9, 1], [42, 1], [21, 1], [50, 23], [21, 1], [42, 1], [9, 1], [7, 1], [6, 3], [5, 3], [4, 5], [3, 8], [4, 5], [5, 3], [6, 2], [7, 1], [8, 1], [9, 1], [13, 1], [50, 23], [13, 1], [9, 1], [8, 1], [7, 1], [6, 2], [5, 3], [4, 5], [3, 9], [4, 6], [5, 3], [6, 2], [7, 1], [9, 1], [14, 1], [50, 23], [14, 1], [9, 1], [7, 1], [6, 2], [5, 3], [4, 6], [3, 10], [4, 6], [5, 3], [6, 1], [7, 1], [9, 1], [16, 1], [50, 2], [35, 1], [50, 8], [13, 1], [50, 8], [35, 1], [50, 2], [16, 1], [9, 1], [7, 1], [6, 1], [5, 3], [4, 6], [3, 12], [4, 6], [5, 2], [6, 1], [19, 1], [16, 1], [17, 1], [25, 1], [21, 1], [13, 1], [18, 1], [50, 6], [11, 1], [9, 1], [11, 1], [50, 6], [18, 1], [13, 1], [21, 1], [25, 1], [17, 1], [16, 1], [19, 1], [6, 1], [5, 2], [4, 6], [3, 14], [4, 5], [5, 3], [6, 1], [8, 1], [16, 1], [10, 1], [8, 2], [11, 1], [50, 1], [16, 1], [15, 1], [32, 1], [29, 1], [9, 1], [8, 1], [7, 1], [8, 1], [9, 1], [29, 1], [32, 1], [15, 1], [16, 1], [50, 1], [11, 1], [8, 2], [10, 1], [16, 1], [8, 1], [6, 1], [5, 3], [4, 5], [3, 15], [4, 6], [5, 3], [6, 4], [7, 1], [20, 1], [19, 1], [9, 3], [7, 3], [6, 1], [7, 3], [9, 3], [19, 1], [20, 1], [7, 1], [6, 4], [5, 3], [4, 6], [3, 16], [4, 7], [5, 4], [6, 3], [7, 1], [6, 13], [7, 1], [6, 3], [5, 4], [4, 7], [3, 18], [4, 7], [5, 27], [4, 7], [3, 20], [4, 9], [5, 21], [4, 9], [3, 23], [4, 12], [5, 11], [4, 12], [3, 26], [4, 33], [3, 29], [4, 29], [3, 33], [4, 25], [3, 38], [4, 19], [3, 20], [2, 1], [3, 26], [4, 7], [3, 26], [2, 2], [3, 57], [2, 1]]"; + reportCompare(reference, output.toSource(), summary + ': correctness jit=' + trace); + return (Date.now() - start); +} + + +var timenonjit = f(false); +var timejit = f(true); + +expect = true; +actual = timejit < timenonjit/2; + +print('time nonjit: ' + timenonjit + ', time jit: ' + timejit); + +reportCompare(expect, actual, summary); diff --git a/js/tests/test.sh b/js/tests/test.sh index 706972905193..66d1306ac181 100755 --- a/js/tests/test.sh +++ b/js/tests/test.sh @@ -373,15 +373,13 @@ pattern="TEST_BRANCH=($branch|[.][*]), TEST_REPO=($repo|[.][*]), TEST_BUILDTYPE= if [[ -z "$timeouts" ]]; then echo "# exclude tests that time out" >> $excludetestsfile -# echo "$pattern .*TEST_EXITSTATUS=TIMED OUT," >> $excludetestsfile - egrep "$pattern .*TEST_EXITSTATUS=TIMED OUT," failures.txt | \ + egrep "$pattern .*TEST_EXITSTATUS=[^,]*TIMED OUT[^,]*," failures.txt | \ sed 's/.*TEST_ID=\([^,]*\),.*/\1/' | sort -u >> $excludetestsfile fi if [[ -z "$crashes" ]]; then echo "# exclude tests that crash" >> $excludetestsfile -# echo "$pattern .*TEST_EXITSTATUS=(CRASHED|ABNORMAL)" >> $excludetestsfile - egrep "$pattern .*TEST_EXITSTATUS=(CRASHED|ABNORMAL)" failures.txt | \ + egrep "$pattern .*TEST_EXITSTATUS=[^,]*(CRASHED|ABNORMAL)[^,]*" failures.txt | \ sed 's/.*TEST_ID=\([^,]*\),.*/\1/' | sort -u >> $excludetestsfile fi