diff --git a/js/src/builtins.tbl b/js/src/builtins.tbl index 655955c7c1d1..aaccbd629c7c 100644 --- a/js/src/builtins.tbl +++ b/js/src/builtins.tbl @@ -47,3 +47,4 @@ BUILTIN1(Math_sin, F, F, jsdouble, jsdouble, BUILTIN1(Math_cos, F, F, jsdouble, jsdouble, 1, 1) BUILTIN2(Math_pow, F, F, F, jsdouble, jsdouble, jsdouble, 1, 1) BUILTIN1(Math_sqrt, F, F, jsdouble, jsdouble, 1, 1) +BUILTIN4(Array_dense_setelem, LO, LO, LO, LO, LO, bool, JSContext*, JSObject*, jsint, jsval, 1, 1) diff --git a/js/src/jsbuiltins.cpp b/js/src/jsbuiltins.cpp index 5abba6df33e7..179f6fdaafce 100644 --- a/js/src/jsbuiltins.cpp +++ b/js/src/jsbuiltins.cpp @@ -42,6 +42,8 @@ #include #include "jsapi.h" +#include "jsarray.h" +#include "jsbool.h" #include "jsnum.h" #include "jsgc.h" #include "jscntxt.h" @@ -151,6 +153,23 @@ jsdouble FASTCALL builtin_Math_sqrt(jsdouble d) return sqrt(d); } +bool FASTCALL builtin_Array_dense_setelem(JSContext *cx, JSObject *obj, jsint i, jsval v) +{ + JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj)); + + jsuint length = ARRAY_DENSE_LENGTH(obj); + if ((jsuint)i < length) { + if (obj->dslots[i] == JSVAL_HOLE) { + if (i >= obj->fslots[JSSLOT_ARRAY_LENGTH]) + obj->fslots[JSSLOT_ARRAY_LENGTH] = i + 1; + obj->fslots[JSSLOT_ARRAY_COUNT]++; + } + obj->dslots[i] = v; + return true; + } + return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSID(i), &v); +} + #define LO ARGSIZE_LO #define F ARGSIZE_F #define Q ARGSIZE_Q @@ -167,6 +186,8 @@ jsdouble FASTCALL builtin_Math_sqrt(jsdouble d) { (intptr_t)&builtin_##op, (at0 << 4) | (at1 << 2) | atr, cse, fold NAME(op) }, #define BUILTIN3(op, at0, at1, at2, atr, tr, t0, t1, t2, cse, fold) \ { (intptr_t)&builtin_##op, (at0 << 6) | (at1 << 4) | (at2 << 2) | atr, cse, fold NAME(op) }, +#define BUILTIN4(op, at0, at1, at2, at3, atr, tr, t0, t1, t2, t3, cse, fold) \ + { (intptr_t)&builtin_##op, (at0 << 8) | (at1 << 6) | (at2 << 4) | (at3 << 2) | atr, cse, fold NAME(op) }, struct CallInfo builtins[] = { #include "builtins.tbl" diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 0505bf206e97..aafb1a07075f 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -2326,31 +2326,19 @@ bool TraceRecorder::record_JSOP_SETELEM() ABORT_TRACE("not a dense array"); /* check that the index is within bounds */ - jsint idx = JSVAL_TO_INT(r); LIns* idx_ins = f2i(get(&r)); /* we have to check that its really an integer, but this check will to go away once we peel the loop type down to integer for this slot */ guard(true, lir->ins2(LIR_feq, get(&r), lir->ins1(LIR_i2f, idx_ins))); - if (!guardDenseArrayIndexWithinBounds(obj, idx, obj_ins, dslots_ins, idx_ins)) - ABORT_TRACE("index out of bounds"); - - /* get us the address of the array slot */ - LIns* addr = lir->ins2(LIR_add, dslots_ins, - lir->ins2i(LIR_lsh, idx_ins, JS_BYTES_PER_WORD_LOG2)); - LIns* oldval = lir->insLoad(LIR_ld, addr, 0); - LIns* isHole = lir->ins2(LIR_eq, oldval, lir->insImmPtr((void*)JSVAL_HOLE)); - LIns* count = lir->insLoadi(obj_ins, - offsetof(JSObject, fslots[JSSLOT_ARRAY_COUNT])); - lir->insStorei(lir->ins2(LIR_add, count, isHole), obj_ins, - offsetof(JSObject, fslots[JSSLOT_ARRAY_COUNT])); - /* ok, box the value we are storing, store it and we are done */ LIns* v_ins = get(&v); LIns* boxed_ins = v_ins; if (!box_jsval(v, boxed_ins)) return false; - lir->insStorei(boxed_ins, addr, 0); + LIns* args[] = { boxed_ins, idx_ins, obj_ins, cx_ins }; + LIns* res_ins = lir->insCall(F_Array_dense_setelem, args); + guard(false, lir->ins_eq0(res_ins)); set(&l, v_ins); return true; } diff --git a/js/src/nanojit/vm_fops.h b/js/src/nanojit/vm_fops.h index 738211f05efd..7bc47ac6793d 100644 --- a/js/src/nanojit/vm_fops.h +++ b/js/src/nanojit/vm_fops.h @@ -38,6 +38,7 @@ #define BUILTIN1(op, at0, atr, tr, t0, cse, fold) F_##op, #define BUILTIN2(op, at0, at1, atr, tr, t0, t1, cse, fold) F_##op, #define BUILTIN3(op, at0, at1, at2, atr, tr, t0, t1, t2, cse, fold) F_##op, +#define BUILTIN4(op, at0, at1, at2, at3, atr, tr, t0, t1, t2, t3, cse, fold) F_##op, INTERP_FOPCODE_LIST_BEGIN #include "builtins.tbl" @@ -46,3 +47,4 @@ INTERP_FOPCODE_LIST_END #undef BUILTIN1 #undef BUILTIN2 #undef BUILTIN3 +#undef BUILTIN4