mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backout a0016de79bf9 and 862431c42e72 for breakage, r=red
This commit is contained in:
parent
99fb52b198
commit
318b2121cd
@ -2648,6 +2648,11 @@ CodeGenerator::visitNewStringObject(LNewStringObject *lir)
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool(*InitPropFn)(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, HandleValue value);
|
||||
static const VMFunction InitPropInfo =
|
||||
FunctionInfo<InitPropFn>(InitProp);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitParNew(LParNew *lir)
|
||||
{
|
||||
@ -2742,28 +2747,6 @@ CodeGenerator::visitParBailout(LParBailout *lir)
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef bool(*InitElemFn)(JSContext *cx, HandleObject obj,
|
||||
HandleValue id, HandleValue value);
|
||||
static const VMFunction InitElemInfo =
|
||||
FunctionInfo<InitElemFn>(InitElemOperation);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitInitElem(LInitElem *lir)
|
||||
{
|
||||
Register objReg = ToRegister(lir->getObject());
|
||||
|
||||
pushArg(ToValue(lir, LInitElem::ValueIndex));
|
||||
pushArg(ToValue(lir, LInitElem::IdIndex));
|
||||
pushArg(objReg);
|
||||
|
||||
return callVM(InitElemInfo, lir);
|
||||
}
|
||||
|
||||
typedef bool(*InitPropFn)(JSContext *cx, HandleObject obj,
|
||||
HandlePropertyName name, HandleValue value);
|
||||
static const VMFunction InitPropInfo =
|
||||
FunctionInfo<InitPropFn>(InitProp);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitInitProp(LInitProp *lir)
|
||||
{
|
||||
@ -5578,76 +5561,35 @@ CodeGenerator::visitIn(LIn *ins)
|
||||
return callVM(OperatorInInfo, ins);
|
||||
}
|
||||
|
||||
typedef bool (*OperatorInIFn)(JSContext *, uint32_t, HandleObject, JSBool *);
|
||||
static const VMFunction OperatorInIInfo = FunctionInfo<OperatorInIFn>(OperatorInI);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitInArray(LInArray *lir)
|
||||
{
|
||||
const MInArray *mir = lir->mir();
|
||||
Register elements = ToRegister(lir->elements());
|
||||
Register initLength = ToRegister(lir->initLength());
|
||||
Register output = ToRegister(lir->output());
|
||||
|
||||
// When the array is not packed we need to do a hole check in addition to the bounds check.
|
||||
Label falseBranch, done, trueBranch;
|
||||
|
||||
OutOfLineCode *ool = NULL;
|
||||
Label* failedInitLength = &falseBranch;
|
||||
|
||||
Label falseBranch, done;
|
||||
if (lir->index()->isConstant()) {
|
||||
int32_t index = ToInt32(lir->index());
|
||||
|
||||
JS_ASSERT_IF(index < 0, mir->needsNegativeIntCheck());
|
||||
if (mir->needsNegativeIntCheck()) {
|
||||
ool = oolCallVM(OperatorInIInfo, lir,
|
||||
(ArgList(), Imm32(index), ToRegister(lir->object())),
|
||||
StoreRegisterTo(output));
|
||||
failedInitLength = ool->entry();
|
||||
}
|
||||
|
||||
masm.branch32(Assembler::BelowOrEqual, initLength, Imm32(index), failedInitLength);
|
||||
if (mir->needsHoleCheck()) {
|
||||
Address address = Address(elements, index * sizeof(Value));
|
||||
masm.branchTestMagic(Assembler::Equal, address, &falseBranch);
|
||||
masm.branch32(Assembler::BelowOrEqual, initLength, Imm32(ToInt32(lir->index())), &falseBranch);
|
||||
if (lir->mir()->needsHoleCheck()) {
|
||||
masm.branchTestMagic(Assembler::Equal, Address(elements, ToInt32(lir->index()) * sizeof(Value)),
|
||||
&falseBranch);
|
||||
}
|
||||
} else {
|
||||
Label negativeIntCheck;
|
||||
Register index = ToRegister(lir->index());
|
||||
|
||||
if (mir->needsNegativeIntCheck())
|
||||
failedInitLength = &negativeIntCheck;
|
||||
|
||||
masm.branch32(Assembler::BelowOrEqual, initLength, index, failedInitLength);
|
||||
if (mir->needsHoleCheck()) {
|
||||
BaseIndex address = BaseIndex(elements, ToRegister(lir->index()), TimesEight);
|
||||
masm.branchTestMagic(Assembler::Equal, address, &falseBranch);
|
||||
}
|
||||
masm.jump(&trueBranch);
|
||||
|
||||
if (mir->needsNegativeIntCheck()) {
|
||||
masm.bind(&negativeIntCheck);
|
||||
ool = oolCallVM(OperatorInIInfo, lir,
|
||||
(ArgList(), index, ToRegister(lir->object())),
|
||||
StoreRegisterTo(output));
|
||||
|
||||
masm.testl(index, index);
|
||||
masm.j(Assembler::Signed, ool->entry());
|
||||
masm.jump(&falseBranch);
|
||||
masm.branch32(Assembler::BelowOrEqual, initLength, ToRegister(lir->index()), &falseBranch);
|
||||
if (lir->mir()->needsHoleCheck()) {
|
||||
masm.branchTestMagic(Assembler::Equal, BaseIndex(elements, ToRegister(lir->index()), TimesEight),
|
||||
&falseBranch);
|
||||
}
|
||||
}
|
||||
|
||||
masm.bind(&trueBranch);
|
||||
masm.move32(Imm32(1), output);
|
||||
masm.jump(&done);
|
||||
|
||||
masm.bind(&falseBranch);
|
||||
masm.move32(Imm32(0), output);
|
||||
masm.bind(&done);
|
||||
|
||||
if (ool)
|
||||
masm.bind(ool->rejoin());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool visitParNew(LParNew *lir);
|
||||
bool visitParNewDenseArray(LParNewDenseArray *lir);
|
||||
bool visitParBailout(LParBailout *lir);
|
||||
bool visitInitElem(LInitElem *lir);
|
||||
bool visitInitProp(LInitProp *lir);
|
||||
bool visitCreateThis(LCreateThis *lir);
|
||||
bool visitCreateThisWithProto(LCreateThisWithProto *lir);
|
||||
|
@ -952,9 +952,6 @@ IonBuilder::inspectOpcode(JSOp op)
|
||||
return jsop_newobject(baseObj);
|
||||
}
|
||||
|
||||
case JSOP_INITELEM:
|
||||
return jsop_initelem();
|
||||
|
||||
case JSOP_INITELEM_ARRAY:
|
||||
return jsop_initelem_array();
|
||||
|
||||
@ -4782,19 +4779,6 @@ IonBuilder::jsop_newobject(HandleObject baseObj)
|
||||
return resumeAfter(ins);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_initelem()
|
||||
{
|
||||
MDefinition *value = current->pop();
|
||||
MDefinition *id = current->pop();
|
||||
MDefinition *obj = current->peek(-1);
|
||||
|
||||
MInitElem *initElem = MInitElem::New(obj, id, value);
|
||||
current->add(initElem);
|
||||
|
||||
return resumeAfter(initElem);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_initelem_array()
|
||||
{
|
||||
@ -7410,7 +7394,7 @@ IonBuilder::jsop_in_dense()
|
||||
current->add(initLength);
|
||||
|
||||
// Check if id < initLength and elem[id] not a hole.
|
||||
MInArray *ins = MInArray::New(elements, id, initLength, obj, needsHoleCheck);
|
||||
MInArray *ins = MInArray::New(elements, id, initLength, needsHoleCheck);
|
||||
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
|
@ -375,7 +375,6 @@ class IonBuilder : public MIRGenerator
|
||||
bool jsop_delprop(HandlePropertyName name);
|
||||
bool jsop_newarray(uint32_t count);
|
||||
bool jsop_newobject(HandleObject baseObj);
|
||||
bool jsop_initelem();
|
||||
bool jsop_initelem_array();
|
||||
bool jsop_initprop(HandlePropertyName name);
|
||||
bool jsop_regexp(RegExpObject *reobj);
|
||||
|
@ -478,26 +478,6 @@ class LParBailout : public LInstructionHelper<0, 0, 0>
|
||||
LIR_HEADER(ParBailout);
|
||||
};
|
||||
|
||||
class LInitElem : public LCallInstructionHelper<0, 1 + 2*BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(InitElem)
|
||||
|
||||
LInitElem(const LAllocation &object) {
|
||||
setOperand(0, object);
|
||||
}
|
||||
|
||||
static const size_t IdIndex = 1;
|
||||
static const size_t ValueIndex = 1 + BOX_PIECES;
|
||||
|
||||
const LAllocation *getObject() {
|
||||
return getOperand(0);
|
||||
}
|
||||
MInitElem *mir() const {
|
||||
return mir_->toInitElem();
|
||||
}
|
||||
};
|
||||
|
||||
// Takes in an Object and a Value.
|
||||
class LInitProp : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
|
||||
{
|
||||
@ -2738,18 +2718,15 @@ class LLoadElementV : public LInstructionHelper<BOX_PIECES, 2, 0>
|
||||
}
|
||||
};
|
||||
|
||||
class LInArray : public LInstructionHelper<1, 4, 0>
|
||||
class LInArray : public LInstructionHelper<1, 3, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(InArray)
|
||||
|
||||
LInArray(const LAllocation &elements, const LAllocation &index,
|
||||
const LAllocation &initLength, const LAllocation &object)
|
||||
{
|
||||
LInArray(const LAllocation &elements, const LAllocation &index, const LAllocation &initLength) {
|
||||
setOperand(0, elements);
|
||||
setOperand(1, index);
|
||||
setOperand(2, initLength);
|
||||
setOperand(3, object);
|
||||
}
|
||||
const MInArray *mir() const {
|
||||
return mir_->toInArray();
|
||||
@ -2763,9 +2740,6 @@ class LInArray : public LInstructionHelper<1, 4, 0>
|
||||
const LAllocation *initLength() {
|
||||
return getOperand(2);
|
||||
}
|
||||
const LAllocation *object() {
|
||||
return getOperand(3);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
_(ParNewDenseArray) \
|
||||
_(ParNewCallObject) \
|
||||
_(ParBailout) \
|
||||
_(InitElem) \
|
||||
_(InitProp) \
|
||||
_(CheckOverRecursed) \
|
||||
_(ParCheckOverRecursed) \
|
||||
|
@ -237,18 +237,6 @@ LIRGenerator::visitParBailout(MParBailout *ins)
|
||||
return add(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitInitElem(MInitElem *ins)
|
||||
{
|
||||
LInitElem *lir = new LInitElem(useRegisterAtStart(ins->getObject()));
|
||||
if (!useBoxAtStart(lir, LInitElem::IdIndex, ins->getId()))
|
||||
return false;
|
||||
if (!useBoxAtStart(lir, LInitElem::ValueIndex, ins->getValue()))
|
||||
return false;
|
||||
|
||||
return add(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitInitProp(MInitProp *ins)
|
||||
{
|
||||
@ -1831,19 +1819,11 @@ LIRGenerator::visitInArray(MInArray *ins)
|
||||
JS_ASSERT(ins->elements()->type() == MIRType_Elements);
|
||||
JS_ASSERT(ins->index()->type() == MIRType_Int32);
|
||||
JS_ASSERT(ins->initLength()->type() == MIRType_Int32);
|
||||
JS_ASSERT(ins->object()->type() == MIRType_Object);
|
||||
JS_ASSERT(ins->type() == MIRType_Boolean);
|
||||
|
||||
LAllocation object;
|
||||
if (ins->needsNegativeIntCheck())
|
||||
object = useRegister(ins->object());
|
||||
else
|
||||
object = LConstantIndex::Bogus();
|
||||
|
||||
LInArray *lir = new LInArray(useRegister(ins->elements()),
|
||||
useRegisterOrConstant(ins->index()),
|
||||
useRegister(ins->initLength()),
|
||||
object);
|
||||
useRegister(ins->initLength()));
|
||||
return define(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,6 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
bool visitParNewCallObject(MParNewCallObject *ins);
|
||||
bool visitParNewDenseArray(MParNewDenseArray *ins);
|
||||
bool visitParBailout(MParBailout *ins);
|
||||
bool visitInitElem(MInitElem *ins);
|
||||
bool visitInitProp(MInitProp *ins);
|
||||
bool visitCheckOverRecursed(MCheckOverRecursed *ins);
|
||||
bool visitParCheckOverRecursed(MParCheckOverRecursed *ins);
|
||||
|
@ -2007,12 +2007,6 @@ InlinePropertyTable::hasFunction(JSFunction *func) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MInArray::needsNegativeIntCheck() const
|
||||
{
|
||||
return !index()->range() || index()->range()->lower() < 0;
|
||||
}
|
||||
|
||||
MDefinition *
|
||||
MAsmJSUnsignedToDouble::foldsTo(bool useValueNumbers)
|
||||
{
|
||||
|
106
js/src/ion/MIR.h
106
js/src/ion/MIR.h
@ -1243,39 +1243,6 @@ class MInitProp
|
||||
}
|
||||
};
|
||||
|
||||
class MInitElem
|
||||
: public MAryInstruction<3>,
|
||||
public Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, BoxPolicy<2> >
|
||||
{
|
||||
MInitElem(MDefinition *obj, MDefinition *id, MDefinition *value)
|
||||
{
|
||||
setOperand(0, obj);
|
||||
setOperand(1, id);
|
||||
setOperand(2, value);
|
||||
setResultType(MIRType_None);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(InitElem)
|
||||
|
||||
static MInitElem *New(MDefinition *obj, MDefinition *id, MDefinition *value) {
|
||||
return new MInitElem(obj, id, value);
|
||||
}
|
||||
|
||||
MDefinition *getObject() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
MDefinition *getId() const {
|
||||
return getOperand(1);
|
||||
}
|
||||
MDefinition *getValue() const {
|
||||
return getOperand(2);
|
||||
}
|
||||
TypePolicy *typePolicy() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// Designates the start of call frame construction.
|
||||
// Generates code to adjust the stack pointer for the argument vector.
|
||||
// Argc is inferred by checking the use chain during lowering.
|
||||
@ -1687,57 +1654,6 @@ class MTernaryInstruction : public MAryInstruction<3>
|
||||
}
|
||||
};
|
||||
|
||||
class MQuaternaryInstruction : public MAryInstruction<4>
|
||||
{
|
||||
protected:
|
||||
MQuaternaryInstruction(MDefinition *first, MDefinition *second,
|
||||
MDefinition *third, MDefinition *fourth)
|
||||
{
|
||||
setOperand(0, first);
|
||||
setOperand(1, second);
|
||||
setOperand(2, third);
|
||||
setOperand(3, fourth);
|
||||
}
|
||||
|
||||
protected:
|
||||
HashNumber valueHash() const
|
||||
{
|
||||
MDefinition *first = getOperand(0);
|
||||
MDefinition *second = getOperand(1);
|
||||
MDefinition *third = getOperand(2);
|
||||
MDefinition *fourth = getOperand(3);
|
||||
|
||||
return op() ^ first->valueNumber() ^ second->valueNumber() ^
|
||||
third->valueNumber() ^ fourth->valueNumber();
|
||||
}
|
||||
|
||||
bool congruentTo(MDefinition *const &ins) const
|
||||
{
|
||||
if (op() != ins->op())
|
||||
return false;
|
||||
|
||||
if (type() != ins->type())
|
||||
return false;
|
||||
|
||||
if (isEffectful() || ins->isEffectful())
|
||||
return false;
|
||||
|
||||
MDefinition *first = getOperand(0);
|
||||
MDefinition *second = getOperand(1);
|
||||
MDefinition *third = getOperand(2);
|
||||
MDefinition *fourth = getOperand(3);
|
||||
MDefinition *insFirst = ins->getOperand(0);
|
||||
MDefinition *insSecond = ins->getOperand(1);
|
||||
MDefinition *insThird = ins->getOperand(2);
|
||||
MDefinition *insFourth = ins->getOperand(3);
|
||||
|
||||
return first->valueNumber() == insFirst->valueNumber() &&
|
||||
second->valueNumber() == insSecond->valueNumber() &&
|
||||
third->valueNumber() == insThird->valueNumber() &&
|
||||
fourth->valueNumber() == insFourth->valueNumber();
|
||||
}
|
||||
};
|
||||
|
||||
class MCompare
|
||||
: public MBinaryInstruction,
|
||||
public ComparePolicy
|
||||
@ -6379,15 +6295,12 @@ class MIn
|
||||
|
||||
// Test whether the index is in the array bounds or a hole.
|
||||
class MInArray
|
||||
: public MQuaternaryInstruction,
|
||||
public ObjectPolicy<3>
|
||||
: public MTernaryInstruction
|
||||
{
|
||||
bool needsHoleCheck_;
|
||||
|
||||
MInArray(MDefinition *elements, MDefinition *index,
|
||||
MDefinition *initLength, MDefinition *object,
|
||||
bool needsHoleCheck)
|
||||
: MQuaternaryInstruction(elements, index, initLength, object),
|
||||
MInArray(MDefinition *elements, MDefinition *index, MDefinition *initLength, bool needsHoleCheck)
|
||||
: MTernaryInstruction(elements, index, initLength),
|
||||
needsHoleCheck_(needsHoleCheck)
|
||||
{
|
||||
setResultType(MIRType_Boolean);
|
||||
@ -6401,10 +6314,8 @@ class MInArray
|
||||
INSTRUCTION_HEADER(InArray)
|
||||
|
||||
static MInArray *New(MDefinition *elements, MDefinition *index,
|
||||
MDefinition *initLength, MDefinition *object,
|
||||
bool needsHoleCheck)
|
||||
{
|
||||
return new MInArray(elements, index, initLength, object, needsHoleCheck);
|
||||
MDefinition *initLength, bool needsHoleCheck) {
|
||||
return new MInArray(elements, index, initLength, needsHoleCheck);
|
||||
}
|
||||
|
||||
MDefinition *elements() const {
|
||||
@ -6416,19 +6327,12 @@ class MInArray
|
||||
MDefinition *initLength() const {
|
||||
return getOperand(2);
|
||||
}
|
||||
MDefinition *object() const {
|
||||
return getOperand(3);
|
||||
}
|
||||
bool needsHoleCheck() const {
|
||||
return needsHoleCheck_;
|
||||
}
|
||||
bool needsNegativeIntCheck() const;
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::Load(AliasSet::Element);
|
||||
}
|
||||
TypePolicy *typePolicy() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation for instanceof operator with specific rhs.
|
||||
|
@ -81,7 +81,6 @@ namespace ion {
|
||||
_(NewDeclEnvObject) \
|
||||
_(NewCallObject) \
|
||||
_(NewStringObject) \
|
||||
_(InitElem) \
|
||||
_(InitProp) \
|
||||
_(Start) \
|
||||
_(OsrEntry) \
|
||||
|
@ -172,7 +172,6 @@ class ParallelArrayVisitor : public MInstructionVisitor
|
||||
CUSTOM_OP(NewObject)
|
||||
CUSTOM_OP(NewCallObject)
|
||||
CUSTOM_OP(NewParallelArray)
|
||||
UNSAFE_OP(InitElem)
|
||||
UNSAFE_OP(InitProp)
|
||||
SAFE_OP(Start)
|
||||
UNSAFE_OP(OsrEntry)
|
||||
|
@ -399,8 +399,6 @@ ObjectPolicy<Op>::staticAdjustInputs(MInstruction *ins)
|
||||
|
||||
template bool ObjectPolicy<0>::staticAdjustInputs(MInstruction *ins);
|
||||
template bool ObjectPolicy<1>::staticAdjustInputs(MInstruction *ins);
|
||||
template bool ObjectPolicy<2>::staticAdjustInputs(MInstruction *ins);
|
||||
template bool ObjectPolicy<3>::staticAdjustInputs(MInstruction *ins);
|
||||
|
||||
bool
|
||||
CallPolicy::adjustInputs(MInstruction *ins)
|
||||
|
@ -186,20 +186,6 @@ class MixPolicy : public TypePolicy
|
||||
}
|
||||
};
|
||||
|
||||
// Combine three policies.
|
||||
template <class Policy1, class Policy2, class Policy3>
|
||||
class Mix3Policy : public TypePolicy
|
||||
{
|
||||
public:
|
||||
static bool staticAdjustInputs(MInstruction *ins) {
|
||||
return Policy1::staticAdjustInputs(ins) && Policy2::staticAdjustInputs(ins) &&
|
||||
Policy3::staticAdjustInputs(ins);
|
||||
}
|
||||
virtual bool adjustInputs(MInstruction *ins) {
|
||||
return staticAdjustInputs(ins);
|
||||
}
|
||||
};
|
||||
|
||||
class CallSetElementPolicy : public SingleObjectPolicy
|
||||
{
|
||||
public:
|
||||
|
@ -507,13 +507,6 @@ OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, JSBool *out)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
OperatorInI(JSContext *cx, uint32_t index, HandleObject obj, JSBool *out)
|
||||
{
|
||||
RootedValue key(cx, Int32Value(index));
|
||||
return OperatorIn(cx, key, obj, out);
|
||||
}
|
||||
|
||||
bool
|
||||
GetIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue rval)
|
||||
{
|
||||
|
@ -521,7 +521,6 @@ bool SPSEnter(JSContext *cx, HandleScript script);
|
||||
bool SPSExit(JSContext *cx, HandleScript script);
|
||||
|
||||
bool OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, JSBool *out);
|
||||
bool OperatorInI(JSContext *cx, uint32_t index, HandleObject obj, JSBool *out);
|
||||
|
||||
bool GetIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue rval);
|
||||
|
||||
|
@ -1,85 +0,0 @@
|
||||
// |jit-test| no-jm
|
||||
|
||||
// IM has the following fastpaths:
|
||||
// - constant index (constant)
|
||||
// - need negative int check (neg)
|
||||
// - needs hole check (hole)
|
||||
// So to test everything we have to do:
|
||||
// constant | neg | hole
|
||||
// test 1: 0 0 0
|
||||
// test 2: 1 0 0
|
||||
// test 3: 0 1 0
|
||||
// test 4: 1 1 0
|
||||
// test 5: 0 0 1
|
||||
// test 6: 1 0 1
|
||||
// test 7: 0 1 1
|
||||
// test 8: 1 1 1
|
||||
|
||||
function test1(index, a) {
|
||||
if (index < 0)
|
||||
index = -index
|
||||
return index in a;
|
||||
}
|
||||
assertEq(test1(1, [1,2]), true);
|
||||
|
||||
function test2(a) {
|
||||
return 0 in a;
|
||||
}
|
||||
assertEq(test2([1,2]), true);
|
||||
|
||||
function test3(index, a) {
|
||||
return index in a;
|
||||
}
|
||||
|
||||
var arr3 = [];
|
||||
arr3["-1073741828"] = 17;
|
||||
assertEq(test3(-1073741828, arr3), true);
|
||||
|
||||
function test4(a) {
|
||||
return -1073741828 in a;
|
||||
}
|
||||
assertEq(test4(arr3), true);
|
||||
|
||||
|
||||
function test5(index, a) {
|
||||
if (index < 0)
|
||||
index = -index
|
||||
return index in a;
|
||||
}
|
||||
var arr5 = [];
|
||||
arr5[0] = 1
|
||||
arr5[1] = 1
|
||||
arr5[2] = 1
|
||||
arr5[4] = 1
|
||||
assertEq(test5(1, arr5), true);
|
||||
assertEq(test5(3, arr5), false);
|
||||
|
||||
function test7a(a) {
|
||||
return 3 in a;
|
||||
}
|
||||
function test7b(a) {
|
||||
return 4 in a;
|
||||
}
|
||||
assertEq(test7a(arr5), false);
|
||||
assertEq(test7b(arr5), true);
|
||||
|
||||
function test8(index, a) {
|
||||
return index in a;
|
||||
}
|
||||
arr5["-1073741828"] = 17;
|
||||
assertEq(test8(-1073741828, arr5), true);
|
||||
assertEq(test8(3, arr5), false);
|
||||
assertEq(test8(0, arr5), true);
|
||||
|
||||
function test9a(a) {
|
||||
return 0 in a;
|
||||
}
|
||||
function test9b(a) {
|
||||
return 3 in a;
|
||||
}
|
||||
function test9c(a) {
|
||||
return -1073741828 in a;
|
||||
}
|
||||
assertEq(test9a(arr5), true);
|
||||
assertEq(test9b(arr5), false);
|
||||
assertEq(test9c(arr5), true);
|
Loading…
Reference in New Issue
Block a user