зеркало из https://github.com/mozilla/pjs.git
Merge tracemonkey to mozilla-central.
This commit is contained in:
Коммит
a72263da19
|
@ -624,7 +624,7 @@ static struct {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
static struct {
|
static struct {
|
||||||
jsbytecode custom_iter_next[10];
|
jsbytecode custom_iter_next[12];
|
||||||
jsbytecode native_iter_next[12];
|
jsbytecode native_iter_next[12];
|
||||||
} nextiter_imacros = {
|
} nextiter_imacros = {
|
||||||
{
|
{
|
||||||
|
@ -632,8 +632,10 @@ static struct {
|
||||||
/* 1*/ JSOP_DUP,
|
/* 1*/ JSOP_DUP,
|
||||||
/* 2*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(next),
|
/* 2*/ JSOP_CALLPROP, 0, COMMON_ATOM_INDEX(next),
|
||||||
/* 5*/ JSOP_CALL, 0, 0,
|
/* 5*/ JSOP_CALL, 0, 0,
|
||||||
/* 8*/ JSOP_TRUE,
|
/* 8*/ JSOP_DUP,
|
||||||
/* 9*/ JSOP_STOP,
|
/* 9*/ JSOP_HOLE,
|
||||||
|
/*10*/ JSOP_STRICTNE,
|
||||||
|
/*11*/ JSOP_STOP,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* 0*/ JSOP_POP,
|
/* 0*/ JSOP_POP,
|
||||||
|
|
|
@ -674,7 +674,9 @@
|
||||||
dup # iterobj iterobj
|
dup # iterobj iterobj
|
||||||
callprop next # iterobj fun iterobj
|
callprop next # iterobj fun iterobj
|
||||||
call 0 # iterobj nextval
|
call 0 # iterobj nextval
|
||||||
true # iterobj nextval true
|
dup # iterobj nextval? nextval?
|
||||||
|
hole # iterobj nextval? nextval? hole
|
||||||
|
strictne # iterobj nextval? boolean
|
||||||
stop
|
stop
|
||||||
.end
|
.end
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,7 @@ struct JSTraceableNative {
|
||||||
#define _JS_CTYPE_CALLEE _JS_CTYPE(JSObject *, _JS_PTR,"f","", INFALLIBLE)
|
#define _JS_CTYPE_CALLEE _JS_CTYPE(JSObject *, _JS_PTR,"f","", INFALLIBLE)
|
||||||
#define _JS_CTYPE_CALLEE_PROTOTYPE _JS_CTYPE(JSObject *, _JS_PTR,"p","", INFALLIBLE)
|
#define _JS_CTYPE_CALLEE_PROTOTYPE _JS_CTYPE(JSObject *, _JS_PTR,"p","", INFALLIBLE)
|
||||||
#define _JS_CTYPE_PC _JS_CTYPE(jsbytecode *, _JS_PTR,"P", "", INFALLIBLE)
|
#define _JS_CTYPE_PC _JS_CTYPE(jsbytecode *, _JS_PTR,"P", "", INFALLIBLE)
|
||||||
|
#define _JS_CTYPE_JSVALPTR _JS_CTYPE(jsval *, _JS_PTR,"P", "", INFALLIBLE)
|
||||||
#define _JS_CTYPE_JSVAL _JS_JSVAL_CTYPE( _JS_PTR, "","v", INFALLIBLE)
|
#define _JS_CTYPE_JSVAL _JS_JSVAL_CTYPE( _JS_PTR, "","v", INFALLIBLE)
|
||||||
#define _JS_CTYPE_JSVAL_RETRY _JS_JSVAL_CTYPE( _JS_PTR, --, --, FAIL_COOKIE)
|
#define _JS_CTYPE_JSVAL_RETRY _JS_JSVAL_CTYPE( _JS_PTR, --, --, FAIL_COOKIE)
|
||||||
#define _JS_CTYPE_JSVAL_FAIL _JS_JSVAL_CTYPE( _JS_PTR, --, --, FAIL_STATUS)
|
#define _JS_CTYPE_JSVAL_FAIL _JS_JSVAL_CTYPE( _JS_PTR, --, --, FAIL_STATUS)
|
||||||
|
|
|
@ -5036,8 +5036,23 @@ js_Interpret(JSContext *cx)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
regs.sp = vp + 1;
|
regs.sp = vp + 1;
|
||||||
if (!ok)
|
if (!ok) {
|
||||||
goto error;
|
/*
|
||||||
|
* If we are executing the JSOP_NEXTITER imacro and a Stopiteration
|
||||||
|
* exception is raised, transform it into a JSVAL_HOLE return value.
|
||||||
|
* The tracer generates equivalent code by calling CatchStopIteration_tn.
|
||||||
|
*/
|
||||||
|
if (fp->imacpc && *fp->imacpc == JSOP_NEXTITER &&
|
||||||
|
cx->throwing && js_ValueIsStopIteration(cx->exception)) {
|
||||||
|
// pc may point to JSOP_DUP here due to bug 474854.
|
||||||
|
JS_ASSERT(*regs.pc == JSOP_CALL || *regs.pc == JSOP_DUP);
|
||||||
|
cx->throwing = JS_FALSE;
|
||||||
|
cx->exception = JSVAL_VOID;
|
||||||
|
regs.sp[-1] = JSVAL_HOLE;
|
||||||
|
} else {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
TRACE_0(FastNativeCallComplete);
|
TRACE_0(FastNativeCallComplete);
|
||||||
goto end_call;
|
goto end_call;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,11 @@
|
||||||
#if defined(XP_WIN) || defined(XP_OS2)
|
#if defined(XP_WIN) || defined(XP_OS2)
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef XP_OS2
|
||||||
|
#define _PC_53 PC_53
|
||||||
|
#define _MCW_EM MCW_EM
|
||||||
|
#define _MCW_PC MCW_PC
|
||||||
|
#endif
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
|
@ -980,9 +980,9 @@ PushOff(SprintStack *ss, ptrdiff_t off, JSOp op)
|
||||||
|
|
||||||
/* The opcodes stack must contain real bytecodes that index js_CodeSpec. */
|
/* The opcodes stack must contain real bytecodes that index js_CodeSpec. */
|
||||||
ss->offsets[top] = off;
|
ss->offsets[top] = off;
|
||||||
ss->opcodes[top] = (op == JSOP_GETPROP2) ? (jsbytecode) JSOP_GETPROP
|
ss->opcodes[top] = jsbytecode((op == JSOP_GETPROP2) ? JSOP_GETPROP
|
||||||
: (op == JSOP_GETELEM2) ? (jsbytecode) JSOP_GETELEM
|
: (op == JSOP_GETELEM2) ? JSOP_GETELEM
|
||||||
: (jsbytecode) op;
|
: op);
|
||||||
ss->top = ++top;
|
ss->top = ++top;
|
||||||
AddParenSlop(ss);
|
AddParenSlop(ss);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
|
|
|
@ -1068,13 +1068,12 @@ js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are clearing sprop to force an existing property to be
|
* If we are clearing sprop to force the existing property that it
|
||||||
* overwritten (apart from a duplicate formal parameter), we must
|
* describes to be overwritten, then we have to unlink sprop from the
|
||||||
* unlink it from the ancestor line at scope->lastProp, lazily if
|
* ancestor line at scope->lastProp, lazily if sprop is not lastProp.
|
||||||
* sprop is not lastProp. And we must remove the entry at *spp,
|
* And we must remove the entry at *spp, precisely so the lazy "middle
|
||||||
* precisely so the lazy "middle delete" fixup code further below
|
* delete" fixup code further below won't find sprop in scope->table,
|
||||||
* won't find sprop in scope->table, in spite of sprop being on
|
* in spite of sprop being on the ancestor line.
|
||||||
* the ancestor line.
|
|
||||||
*
|
*
|
||||||
* When we finally succeed in finding or creating a new sprop
|
* When we finally succeed in finding or creating a new sprop
|
||||||
* and storing its pointer at *spp, we'll use the |overwriting|
|
* and storing its pointer at *spp, we'll use the |overwriting|
|
||||||
|
@ -1130,15 +1129,22 @@ js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
|
||||||
JS_ASSERT(scope->table);
|
JS_ASSERT(scope->table);
|
||||||
CHECK_ANCESTOR_LINE(scope, JS_TRUE);
|
CHECK_ANCESTOR_LINE(scope, JS_TRUE);
|
||||||
|
|
||||||
splen = scope->entryCount;
|
JSBool conflicts = JS_FALSE;
|
||||||
if (splen == 0) {
|
for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
|
||||||
JS_ASSERT(scope->lastProp == NULL);
|
if (sprop->id == id) {
|
||||||
} else {
|
conflicts = JS_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conflicts) {
|
||||||
/*
|
/*
|
||||||
* Enumerate live entries in scope->table using a temporary
|
* Enumerate live entries in scope->table using a temporary
|
||||||
* vector, by walking the (possibly sparse, due to deletions)
|
* vector, by walking the (possibly sparse, due to deletions)
|
||||||
* ancestor line from scope->lastProp.
|
* ancestor line from scope->lastProp.
|
||||||
*/
|
*/
|
||||||
|
splen = scope->entryCount;
|
||||||
|
JS_ASSERT(splen != 0);
|
||||||
spvec = (JSScopeProperty **)
|
spvec = (JSScopeProperty **)
|
||||||
JS_malloc(cx, SCOPE_TABLE_NBYTES(splen));
|
JS_malloc(cx, SCOPE_TABLE_NBYTES(splen));
|
||||||
if (!spvec)
|
if (!spvec)
|
||||||
|
@ -1148,41 +1154,16 @@ js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
|
||||||
JS_ASSERT(sprop);
|
JS_ASSERT(sprop);
|
||||||
do {
|
do {
|
||||||
/*
|
/*
|
||||||
* NB: test SCOPE_GET_PROPERTY, not SCOPE_HAS_PROPERTY --
|
* NB: test SCOPE_GET_PROPERTY, not SCOPE_HAS_PROPERTY,
|
||||||
* the latter insists that sprop->id maps to sprop, while
|
* as the latter macro insists that sprop->id maps to
|
||||||
* the former simply tests whether sprop->id is bound in
|
* sprop, while the former simply tests whether sprop->id
|
||||||
* scope. We must allow for duplicate formal parameters
|
* is bound in scope.
|
||||||
* along the ancestor line, and fork them as needed.
|
|
||||||
*/
|
*/
|
||||||
if (!SCOPE_GET_PROPERTY(scope, sprop->id))
|
if (!SCOPE_GET_PROPERTY(scope, sprop->id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
JS_ASSERT(sprop != overwriting);
|
JS_ASSERT(sprop != overwriting);
|
||||||
if (i == 0) {
|
JS_ASSERT(i != 0);
|
||||||
/*
|
|
||||||
* If our original splen estimate, scope->entryCount,
|
|
||||||
* is less than the ancestor line height, there must
|
|
||||||
* be duplicate formal parameters in this (function
|
|
||||||
* object) scope. Count remaining ancestors in order
|
|
||||||
* to realloc spvec.
|
|
||||||
*/
|
|
||||||
JSScopeProperty *tmp = sprop;
|
|
||||||
do {
|
|
||||||
if (SCOPE_GET_PROPERTY(scope, tmp->id))
|
|
||||||
i++;
|
|
||||||
} while ((tmp = tmp->parent) != NULL);
|
|
||||||
spp2 = (JSScopeProperty **)
|
|
||||||
JS_realloc(cx, spvec, SCOPE_TABLE_NBYTES(splen+i));
|
|
||||||
if (!spp2) {
|
|
||||||
JS_free(cx, spvec);
|
|
||||||
goto fail_overwrite;
|
|
||||||
}
|
|
||||||
|
|
||||||
spvec = spp2;
|
|
||||||
memmove(spvec + i, spvec, SCOPE_TABLE_NBYTES(splen));
|
|
||||||
splen += i;
|
|
||||||
}
|
|
||||||
|
|
||||||
spvec[--i] = sprop;
|
spvec[--i] = sprop;
|
||||||
} while ((sprop = sprop->parent) != NULL);
|
} while ((sprop = sprop->parent) != NULL);
|
||||||
JS_ASSERT(i == 0);
|
JS_ASSERT(i == 0);
|
||||||
|
@ -1212,15 +1193,13 @@ js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
|
||||||
/*
|
/*
|
||||||
* Now sprop points to the last property in scope, where the
|
* Now sprop points to the last property in scope, where the
|
||||||
* ancestor line from sprop to the root is dense w.r.t. scope:
|
* ancestor line from sprop to the root is dense w.r.t. scope:
|
||||||
* it contains no nodes not mapped by scope->table, apart from
|
* it contains no nodes not mapped by scope->table.
|
||||||
* any stinking ECMA-mandated duplicate formal parameters.
|
|
||||||
*/
|
*/
|
||||||
scope->lastProp = sprop;
|
scope->lastProp = sprop;
|
||||||
CHECK_ANCESTOR_LINE(scope, JS_FALSE);
|
CHECK_ANCESTOR_LINE(scope, JS_FALSE);
|
||||||
JS_RUNTIME_METER(cx->runtime, middleDeleteFixups);
|
JS_RUNTIME_METER(cx->runtime, middleDeleteFixups);
|
||||||
|
SCOPE_CLR_MIDDLE_DELETE(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCOPE_CLR_MIDDLE_DELETE(scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1489,6 +1468,8 @@ js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id)
|
||||||
break;
|
break;
|
||||||
sprop = SCOPE_LAST_PROP(scope);
|
sprop = SCOPE_LAST_PROP(scope);
|
||||||
} while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop));
|
} while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop));
|
||||||
|
if (!SCOPE_LAST_PROP(scope))
|
||||||
|
SCOPE_CLR_MIDDLE_DELETE(scope);
|
||||||
} else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) {
|
} else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) {
|
||||||
SCOPE_SET_MIDDLE_DELETE(scope);
|
SCOPE_SET_MIDDLE_DELETE(scope);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5043,8 +5043,10 @@ TraceRecorder::ifop()
|
||||||
bool cond;
|
bool cond;
|
||||||
LIns* x;
|
LIns* x;
|
||||||
|
|
||||||
/* Objects always evaluate to true since we specialize the Null type on trace. */
|
if (JSVAL_IS_NULL(v)) {
|
||||||
if (JSVAL_TAG(v) == JSVAL_OBJECT) {
|
cond = false;
|
||||||
|
x = lir->insImm(0);
|
||||||
|
} else if (!JSVAL_IS_PRIMITIVE(v)) {
|
||||||
cond = true;
|
cond = true;
|
||||||
x = lir->insImm(1);
|
x = lir->insImm(1);
|
||||||
} else if (JSVAL_TAG(v) == JSVAL_BOOLEAN) {
|
} else if (JSVAL_TAG(v) == JSVAL_BOOLEAN) {
|
||||||
|
@ -5709,6 +5711,7 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
|
||||||
// typically to find Array.prototype methods.
|
// typically to find Array.prototype methods.
|
||||||
JSObject* aobj = obj;
|
JSObject* aobj = obj;
|
||||||
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||||
|
guardDenseArray(obj, obj_ins, BRANCH_EXIT);
|
||||||
aobj = OBJ_GET_PROTO(cx, obj);
|
aobj = OBJ_GET_PROTO(cx, obj);
|
||||||
obj_ins = stobj_get_fslot(obj_ins, JSSLOT_PROTO);
|
obj_ins = stobj_get_fslot(obj_ins, JSSLOT_PROTO);
|
||||||
}
|
}
|
||||||
|
@ -7755,6 +7758,21 @@ TraceRecorder::record_JSOP_APPLY()
|
||||||
return call_imacro(call_imacro_table[argc]);
|
return call_imacro(call_imacro_table[argc]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSBool FASTCALL
|
||||||
|
CatchStopIteration_tn(JSContext* cx, JSBool ok, jsval* vp)
|
||||||
|
{
|
||||||
|
if (!ok && cx->throwing && js_ValueIsStopIteration(cx->exception)) {
|
||||||
|
cx->throwing = JS_FALSE;
|
||||||
|
cx->exception = JSVAL_VOID;
|
||||||
|
*vp = JSVAL_HOLE;
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_DEFINE_TRCINFO_1(CatchStopIteration_tn,
|
||||||
|
(3, (static, BOOL, CatchStopIteration_tn, CONTEXT, BOOL, JSVALPTR, 0, 0)))
|
||||||
|
|
||||||
JS_REQUIRES_STACK bool
|
JS_REQUIRES_STACK bool
|
||||||
TraceRecorder::record_FastNativeCallComplete()
|
TraceRecorder::record_FastNativeCallComplete()
|
||||||
{
|
{
|
||||||
|
@ -7788,6 +7806,16 @@ TraceRecorder::record_FastNativeCallComplete()
|
||||||
if (pendingTraceableNative == generatedTraceableNative) {
|
if (pendingTraceableNative == generatedTraceableNative) {
|
||||||
LIns* ok_ins = v_ins;
|
LIns* ok_ins = v_ins;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Custom implementations of Iterator.next() throw a StopIteration exception.
|
||||||
|
* Catch and clear it and set the return value to JSVAL_HOLE in this case.
|
||||||
|
*/
|
||||||
|
if (uintptr_t(cx->fp->regs->pc - nextiter_imacros.custom_iter_next) <
|
||||||
|
sizeof(nextiter_imacros.custom_iter_next)) {
|
||||||
|
LIns* args[] = { invokevp_ins, ok_ins, cx_ins }; /* reverse order */
|
||||||
|
ok_ins = lir->insCall(&CatchStopIteration_tn_ci, args);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we run a generic traceable native, the return value is in the argument
|
* 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
|
* vector. The actual return value of the fast native is a JSBool indicated
|
||||||
|
@ -8382,10 +8410,11 @@ TraceRecorder::record_JSOP_NEXTITER()
|
||||||
jsval& iterobj_val = stackval(-2);
|
jsval& iterobj_val = stackval(-2);
|
||||||
if (JSVAL_IS_PRIMITIVE(iterobj_val))
|
if (JSVAL_IS_PRIMITIVE(iterobj_val))
|
||||||
ABORT_TRACE("for-in on a primitive value");
|
ABORT_TRACE("for-in on a primitive value");
|
||||||
|
JSObject* iterobj = JSVAL_TO_OBJECT(iterobj_val);
|
||||||
|
JSClass* clasp = STOBJ_GET_CLASS(iterobj);
|
||||||
LIns* iterobj_ins = get(&iterobj_val);
|
LIns* iterobj_ins = get(&iterobj_val);
|
||||||
if (guardClass(JSVAL_TO_OBJECT(iterobj_val), iterobj_ins, &js_IteratorClass,
|
if (clasp == &js_IteratorClass || clasp == &js_GeneratorClass) {
|
||||||
snapshot(BRANCH_EXIT))) {
|
guardClass(iterobj, iterobj_ins, clasp, snapshot(BRANCH_EXIT));
|
||||||
return call_imacro(nextiter_imacros.native_iter_next);
|
return call_imacro(nextiter_imacros.native_iter_next);
|
||||||
}
|
}
|
||||||
return call_imacro(nextiter_imacros.custom_iter_next);
|
return call_imacro(nextiter_imacros.custom_iter_next);
|
||||||
|
|
|
@ -3315,7 +3315,7 @@ DeepCopyInLRS(JSContext *cx, JSXML *xml, uintN flags)
|
||||||
|
|
||||||
JS_CHECK_RECURSION(cx, return NULL);
|
JS_CHECK_RECURSION(cx, return NULL);
|
||||||
|
|
||||||
copy = js_NewXML(cx, (JSXMLClass) xml->xml_class);
|
copy = js_NewXML(cx, JSXMLClass(xml->xml_class));
|
||||||
if (!copy)
|
if (!copy)
|
||||||
return NULL;
|
return NULL;
|
||||||
qn = xml->name;
|
qn = xml->name;
|
||||||
|
@ -3755,7 +3755,7 @@ Replace(JSContext *cx, JSXML *xml, uint32 i, jsval v)
|
||||||
vxml = (JSXML *) JS_GetPrivate(cx, vobj);
|
vxml = (JSXML *) JS_GetPrivate(cx, vobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (vxml ? (JSXMLClass) vxml->xml_class : JSXML_CLASS_LIMIT) {
|
switch (vxml ? JSXMLClass(vxml->xml_class) : JSXML_CLASS_LIMIT) {
|
||||||
case JSXML_CLASS_ELEMENT:
|
case JSXML_CLASS_ELEMENT:
|
||||||
/* OPTION: enforce that descendants have superset namespaces. */
|
/* OPTION: enforce that descendants have superset namespaces. */
|
||||||
if (!CheckCycle(cx, xml, vxml))
|
if (!CheckCycle(cx, xml, vxml))
|
||||||
|
|
|
@ -4740,6 +4740,39 @@ testNewString.jitstats = {
|
||||||
};
|
};
|
||||||
test(testNewString);
|
test(testNewString);
|
||||||
|
|
||||||
|
function testWhileObjectOrNull()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
var o = { p: { p: null } };
|
||||||
|
while (o.p)
|
||||||
|
o = o.p;
|
||||||
|
}
|
||||||
|
return "pass";
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
return "threw exception: " + e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testWhileObjectOrNull.expected = "pass";
|
||||||
|
test(testWhileObjectOrNull);
|
||||||
|
|
||||||
|
function testDenseArrayProp()
|
||||||
|
{
|
||||||
|
[].__proto__.x = 1;
|
||||||
|
({}).__proto__.x = 2;
|
||||||
|
var a = [[],[],[],({}).__proto__];
|
||||||
|
for (var i = 0; i < a.length; ++i)
|
||||||
|
uneval(a[i].x);
|
||||||
|
delete [].__proto__.x;
|
||||||
|
delete ({}).__proto__.x;
|
||||||
|
return "ok";
|
||||||
|
}
|
||||||
|
testDenseArrayProp.expected = "ok";
|
||||||
|
test(testDenseArrayProp);
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* *
|
* *
|
||||||
|
@ -5053,4 +5086,4 @@ test(testGlobalProtoAccess);
|
||||||
if (gReportSummary) {
|
if (gReportSummary) {
|
||||||
print("\npassed:", passes.length && passes.join(","));
|
print("\npassed:", passes.length && passes.join(","));
|
||||||
print("\nFAILED:", fails.length && fails.join(","));
|
print("\nFAILED:", fails.length && fails.join(","));
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче