Backed out 4 changesets (bug 1643948) for hazard failures on CacheIR.cpp. CLOSED TREE

Backed out changeset 3acf673e3bc1 (bug 1643948)
Backed out changeset e8a33b1a8a73 (bug 1643948)
Backed out changeset ebc80496d7c1 (bug 1643948)
Backed out changeset cdbe54a4b28f (bug 1643948)
This commit is contained in:
Csoregi Natalia 2020-09-25 16:21:49 +03:00
parent 598bc5feef
commit 5aa05eeefe
18 changed files with 17 additions and 580 deletions

View file

@ -1,33 +0,0 @@
function mapped() {
var Iterator = {};
// First overwrite the iterator.
arguments[Symbol.iterator] = Iterator;
// And then redefine a property attribute.
Object.defineProperty(arguments, Symbol.iterator, {
writable: false
});
// Make sure redefining an attribute doesn't reset the iterator value.
assertEq(arguments[Symbol.iterator], Iterator);
}
mapped();
function unmapped() {
"use strict";
var Iterator = {};
// First overwrite the iterator.
arguments[Symbol.iterator] = Iterator;
// And then redefine a property attribute.
Object.defineProperty(arguments, Symbol.iterator, {
writable: false
});
// Make sure redefining an attribute doesn't reset the iterator value.
assertEq(arguments[Symbol.iterator], Iterator);
}
unmapped();

View file

@ -1,171 +0,0 @@
// Test iteration with a mapped arguments object.
function simple() {
function f() {
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i < 100; ++i) {
assertEq(f(1, 2, 3), 6);
}
}
simple();
function spreadCall() {
function f() {
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
function g() {
return f(...arguments);
}
for (var i = 0; i < 100; ++i) {
assertEq(g(1, 2, 3), 6);
}
}
spreadCall();
function spreadArray() {
function f() {
var arr = [...arguments];
var sum = 0;
for (var v of arr) {
sum += v;
}
return sum;
}
for (var i = 0; i < 100; ++i) {
assertEq(f(1, 2, 3), 6);
}
}
spreadArray();
function reifyIterator() {
var reify = false;
function f() {
if (reify) {
// Redefining any property attributes will reify the iterator property.
Object.defineProperty(arguments, Symbol.iterator, {
writable: false
});
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i <= 100; ++i) {
reify = i >= 50;
assertEq(f(1, 2, 3), 6);
}
}
reifyIterator();
function overwriteIterator() {
var callCount = 0;
function Iterator() {
callCount += 1;
return Array.prototype[Symbol.iterator].call(this);
}
var overwrite = false;
function f() {
if (overwrite) {
arguments[Symbol.iterator] = Iterator;
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i <= 100; ++i) {
overwrite = i > 50;
assertEq(f(1, 2, 3), 6);
}
assertEq(callCount, 50);
}
overwriteIterator();
function deleteIterator() {
var remove = false;
function f() {
// Deleting Symbol.iterator won't change the shape of the arguments object.
// That's why we need to use a separate guard instruction to check if the
// iterator property was modified.
if (remove) {
delete arguments[Symbol.iterator];
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
var error;
try {
for (var i = 0; i <= 100; ++i) {
remove = i === 100;
assertEq(f(1, 2, 3), 6);
}
} catch (e) {
error = e;
}
assertEq(error instanceof TypeError, true);
}
deleteIterator();
function deleteIteratorInherit() {
var callCount = 0;
function Iterator() {
callCount += 1;
return Array.prototype[Symbol.iterator].call(this);
}
Object.prototype[Symbol.iterator] = Iterator;
var remove = false;
function f() {
// Deleting Symbol.iterator won't change the shape of the arguments object.
// That's why we need to use a separate guard instruction to check if the
// iterator property was modified.
if (remove) {
delete arguments[Symbol.iterator];
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i <= 100; ++i) {
remove = i === 100;
assertEq(f(1, 2, 3), 6);
}
assertEq(callCount, 1);
delete Object.prototype[Symbol.iterator];
}
deleteIteratorInherit();
// Don't add tests below this point because |Object.prototype[Symbol.iterator]|
// was modified, which may lead to engine-wide deoptimisations.

View file

@ -1,184 +0,0 @@
// Test iteration with an unmapped arguments object.
function simple() {
function f() {
"use strict";
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i < 100; ++i) {
assertEq(f(1, 2, 3), 6);
}
}
simple();
function spreadCall() {
function f() {
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
function g() {
"use strict";
return f(...arguments);
}
for (var i = 0; i < 100; ++i) {
assertEq(g(1, 2, 3), 6);
}
}
spreadCall();
function spreadArray() {
function f() {
"use strict";
var arr = [...arguments];
var sum = 0;
for (var v of arr) {
sum += v;
}
return sum;
}
for (var i = 0; i < 100; ++i) {
assertEq(f(1, 2, 3), 6);
}
}
spreadArray();
function reifyIterator() {
var reify = false;
function f() {
"use strict";
if (reify) {
// Redefining any property attributes will reify the iterator property.
Object.defineProperty(arguments, Symbol.iterator, {
writable: false
});
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i <= 100; ++i) {
reify = i >= 50;
assertEq(f(1, 2, 3), 6);
}
}
reifyIterator();
function overwriteIterator() {
var callCount = 0;
function Iterator() {
callCount += 1;
return Array.prototype[Symbol.iterator].call(this);
}
var overwrite = false;
function f() {
"use strict";
if (overwrite) {
arguments[Symbol.iterator] = Iterator;
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i <= 100; ++i) {
overwrite = i > 50;
assertEq(f(1, 2, 3), 6);
}
assertEq(callCount, 50);
}
overwriteIterator();
function deleteIterator() {
var remove = false;
function f() {
"use strict";
// Deleting Symbol.iterator won't change the shape of the arguments object.
// That's why we need to use a separate guard instruction to check if the
// iterator property was modified.
if (remove) {
delete arguments[Symbol.iterator];
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
var error;
try {
for (var i = 0; i <= 100; ++i) {
remove = i === 100;
assertEq(f(1, 2, 3), 6);
}
} catch (e) {
error = e;
}
assertEq(error instanceof TypeError, true);
}
deleteIterator();
function deleteIteratorInherit() {
var callCount = 0;
function Iterator() {
callCount += 1;
return Array.prototype[Symbol.iterator].call(this);
}
Object.prototype[Symbol.iterator] = Iterator;
var remove = false;
function f() {
"use strict";
// Deleting Symbol.iterator won't change the shape of the arguments object.
// That's why we need to use a separate guard instruction to check if the
// iterator property was modified.
if (remove) {
delete arguments[Symbol.iterator];
}
var sum = 0;
for (var v of arguments) {
sum += v;
}
return sum;
}
for (var i = 0; i <= 100; ++i) {
remove = i === 100;
assertEq(f(1, 2, 3), 6);
}
assertEq(callCount, 1);
delete Object.prototype[Symbol.iterator];
}
deleteIteratorInherit();
// Don't add tests below this point because |Object.prototype[Symbol.iterator]|
// was modified, which may lead to engine-wide deoptimisations.

View file

@ -159,7 +159,6 @@ static inline const MDefinition* GetObject(const MDefinition* ins) {
case MDefinition::Opcode::ArgumentsObjectLength:
case MDefinition::Opcode::FunctionLength:
case MDefinition::Opcode::FunctionName:
case MDefinition::Opcode::GuardArgumentsObjectNotOverriddenIterator:
object = ins->getOperand(0);
break;
case MDefinition::Opcode::GetPropertyCache:

View file

@ -922,6 +922,7 @@ bool BaselineCacheIRCompiler::emitStoreSlotShared(bool isFixed,
ObjOperandId objId,
uint32_t offsetOffset,
ValOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Address offsetAddr = stubAddress(offsetOffset);
// Allocate the fixed registers first. These need to be fixed for
@ -977,6 +978,7 @@ bool BaselineCacheIRCompiler::emitAddAndStoreSlotShared(
CacheOp op, ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId,
bool changeGroup, uint32_t newGroupOffset, uint32_t newShapeOffset,
Maybe<uint32_t> numNewSlotsOffset) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Address offsetAddr = stubAddress(offsetOffset);
// Allocate the fixed registers first. These need to be fixed for

View file

@ -369,7 +369,6 @@ AttachDecision GetPropIRGenerator::tryAttachStub() {
TRY_ATTACH(
tryAttachXrayCrossCompartmentWrapper(obj, objId, id, receiverId));
TRY_ATTACH(tryAttachFunction(obj, objId, id));
TRY_ATTACH(tryAttachArgumentsObjectIterator(obj, objId, id));
TRY_ATTACH(tryAttachProxy(obj, objId, id, receiverId));
trackAttached(IRGenerator::NotAttached);
@ -2015,46 +2014,6 @@ AttachDecision GetPropIRGenerator::tryAttachFunction(HandleObject obj,
return AttachDecision::Attach;
}
AttachDecision GetPropIRGenerator::tryAttachArgumentsObjectIterator(
HandleObject obj, ObjOperandId objId, HandleId id) {
if (!obj->is<ArgumentsObject>()) {
return AttachDecision::NoAction;
}
if (!JSID_IS_SYMBOL(id) ||
JSID_TO_SYMBOL(id) != cx_->wellKnownSymbols().iterator) {
return AttachDecision::NoAction;
}
auto* args = &obj->as<ArgumentsObject>();
if (args->hasOverriddenIterator()) {
return AttachDecision::NoAction;
}
RootedValue iterator(cx_);
if (!ArgumentsObject::getArgumentsIterator(cx_, &iterator)) {
cx_->recoverFromOutOfMemory();
return AttachDecision::NoAction;
}
MOZ_ASSERT(iterator.isObject());
maybeEmitIdGuard(id);
if (args->is<MappedArgumentsObject>()) {
writer.guardClass(objId, GuardClassKind::MappedArguments);
} else {
MOZ_ASSERT(args->is<UnmappedArgumentsObject>());
writer.guardClass(objId, GuardClassKind::UnmappedArguments);
}
writer.guardArgumentsObjectNotOverriddenIterator(objId);
ObjOperandId iterId = writer.loadObject(&iterator.toObject());
writer.loadObjectResult(iterId);
writer.typeMonitorResult();
trackAttached("ArgumentsObjectIterator");
return AttachDecision::Attach;
}
AttachDecision GetPropIRGenerator::tryAttachModuleNamespace(HandleObject obj,
ObjOperandId objId,
HandleId id) {

View file

@ -1299,9 +1299,6 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator {
ValOperandId receiverId);
AttachDecision tryAttachFunction(HandleObject obj, ObjOperandId objId,
HandleId id);
AttachDecision tryAttachArgumentsObjectIterator(HandleObject obj,
ObjOperandId objId,
HandleId id);
AttachDecision tryAttachGenericProxy(HandleObject obj, ObjOperandId objId,
HandleId id, bool handleDOMProxies);

View file

@ -29,7 +29,6 @@
#include "js/friend/XrayJitInfo.h" // js::jit::GetXrayJitInfo
#include "js/ScalarType.h" // js::Scalar::Type
#include "proxy/Proxy.h"
#include "vm/ArgumentsObject.h"
#include "vm/ArrayBufferObject.h"
#include "vm/ArrayBufferViewObject.h"
#include "vm/BigIntType.h"
@ -2881,7 +2880,6 @@ bool CacheIRCompiler::emitInt32NegationResult(Int32OperandId inputId) {
}
bool CacheIRCompiler::emitInt32IncResult(Int32OperandId inputId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
Register input = allocator.useRegister(masm, inputId);
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
@ -2899,7 +2897,6 @@ bool CacheIRCompiler::emitInt32IncResult(Int32OperandId inputId) {
}
bool CacheIRCompiler::emitInt32DecResult(Int32OperandId inputId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
Register input = allocator.useRegister(masm, inputId);
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
@ -2975,12 +2972,10 @@ bool CacheIRCompiler::emitDoubleIncDecResult(bool isInc,
}
bool CacheIRCompiler::emitDoubleIncResult(NumberOperandId inputId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
return emitDoubleIncDecResult(true, inputId);
}
bool CacheIRCompiler::emitDoubleDecResult(NumberOperandId inputId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
return emitDoubleIncDecResult(false, inputId);
}
@ -3570,7 +3565,6 @@ bool CacheIRCompiler::emitGuardObjectGroupNotPretenured(uint32_t groupOffset) {
bool CacheIRCompiler::emitGuardFunctionHasJitEntry(ObjOperandId funId,
bool constructing) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register fun = allocator.useRegister(masm, funId);
FailurePath* failure;
@ -3640,7 +3634,6 @@ bool CacheIRCompiler::emitGuardFunctionIsConstructor(ObjOperandId funId) {
}
bool CacheIRCompiler::emitGuardNotClassConstructor(ObjOperandId funId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register fun = allocator.useRegister(masm, funId);
AutoScratchRegister scratch(allocator, masm);
@ -3655,7 +3648,6 @@ bool CacheIRCompiler::emitGuardNotClassConstructor(ObjOperandId funId) {
}
bool CacheIRCompiler::emitGuardArrayIsPacked(ObjOperandId arrayId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register array = allocator.useRegister(masm, arrayId);
AutoScratchRegister scratch(allocator, masm);
AutoScratchRegister scratch2(allocator, masm);
@ -3669,22 +3661,6 @@ bool CacheIRCompiler::emitGuardArrayIsPacked(ObjOperandId arrayId) {
return true;
}
bool CacheIRCompiler::emitGuardArgumentsObjectNotOverriddenIterator(
ObjOperandId objId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register obj = allocator.useRegister(masm, objId);
AutoScratchRegister scratch(allocator, masm);
FailurePath* failure;
if (!addFailurePath(&failure)) {
return false;
}
masm.branchArgumentsObjectHasOverridenIterator(obj, scratch,
failure->label());
return true;
}
bool CacheIRCompiler::emitLoadDenseElementHoleResult(ObjOperandId objId,
Int32OperandId indexId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
@ -4710,6 +4686,7 @@ bool CacheIRCompiler::emitStoreTypedElement(ObjOperandId objId,
Scalar::Type elementType,
Int32OperandId indexId,
uint32_t rhsId, bool handleOOB) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
Register obj = allocator.useRegister(masm, objId);
Register index = allocator.useRegister(masm, indexId);
@ -4806,7 +4783,6 @@ bool CacheIRCompiler::emitStoreTypedArrayElement(ObjOperandId objId,
Int32OperandId indexId,
uint32_t rhsId,
bool handleOOB) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
return emitStoreTypedElement(objId, TypedThingLayout::TypedArray, elementType,
indexId, rhsId, handleOOB);
}
@ -4816,7 +4792,6 @@ bool CacheIRCompiler::emitStoreTypedObjectElement(ObjOperandId objId,
Scalar::Type elementType,
Int32OperandId indexId,
uint32_t rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
return emitStoreTypedElement(objId, layout, elementType, indexId, rhsId,
false);
}
@ -4854,6 +4829,7 @@ static void EmitAllocateBigInt(MacroAssembler& masm, Register result,
bool CacheIRCompiler::emitLoadTypedElementResult(
ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout,
Scalar::Type elementType, bool handleOOB, bool allowDoubleForUint32) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
Register obj = allocator.useRegister(masm, objId);
Register index = allocator.useRegister(masm, indexId);
@ -4981,7 +4957,6 @@ bool CacheIRCompiler::emitLoadTypedElementResult(
bool CacheIRCompiler::emitLoadTypedArrayElementResult(
ObjOperandId objId, Int32OperandId indexId, Scalar::Type elementType,
bool handleOOB, bool allowDoubleForUint32) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
return emitLoadTypedElementResult(objId, indexId,
TypedThingLayout::TypedArray, elementType,
handleOOB, allowDoubleForUint32);
@ -4990,7 +4965,6 @@ bool CacheIRCompiler::emitLoadTypedArrayElementResult(
bool CacheIRCompiler::emitLoadTypedObjectElementResult(
ObjOperandId objId, Int32OperandId indexId, TypedThingLayout layout,
Scalar::Type elementType) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
return emitLoadTypedElementResult(objId, indexId, layout, elementType,
/* handleOOB = */ false,
/* allowDoubleForUint32 = */ true);

View file

@ -663,13 +663,6 @@
args:
array: ObjId
- name: GuardArgumentsObjectNotOverriddenIterator
shared: true
transpile: true
cost_estimate: 1
args:
obj: ObjId
- name: LoadObject
shared: true
transpile: true

View file

@ -8092,16 +8092,6 @@ void CodeGenerator::visitArgumentsObjectLength(LArgumentsObjectLength* lir) {
bailoutFrom(&bail, lir->snapshot());
}
void CodeGenerator::visitGuardArgumentsObjectNotOverriddenIterator(
LGuardArgumentsObjectNotOverriddenIterator* lir) {
Register argsObj = ToRegister(lir->getArgsObject());
Register temp = ToRegister(lir->temp());
Label bail;
masm.branchArgumentsObjectHasOverridenIterator(argsObj, temp, &bail);
bailoutFrom(&bail, lir->snapshot());
}
void CodeGenerator::visitReturnFromCtor(LReturnFromCtor* lir) {
ValueOperand value = ToValue(lir, LReturnFromCtor::ValueIndex);
Register obj = ToRegister(lir->getObject());

View file

@ -345,18 +345,6 @@ void LIRGenerator::visitArgumentsObjectLength(MArgumentsObjectLength* ins) {
define(lir, ins);
}
void LIRGenerator::visitGuardArgumentsObjectNotOverriddenIterator(
MGuardArgumentsObjectNotOverriddenIterator* ins) {
MDefinition* argsObj = ins->getArgsObject();
MOZ_ASSERT(argsObj->type() == MIRType::Object);
auto* lir = new (alloc())
LGuardArgumentsObjectNotOverriddenIterator(useRegister(argsObj), temp());
assignSnapshot(lir, BailoutKind::ArgumentsObjectAccess);
add(lir, ins);
redefine(ins, argsObj);
}
void LIRGenerator::visitReturnFromCtor(MReturnFromCtor* ins) {
LReturnFromCtor* lir = new (alloc())
LReturnFromCtor(useBox(ins->getValue()), useRegister(ins->getObject()));

View file

@ -3787,36 +3787,6 @@ class MArgumentsObjectLength : public MUnaryInstruction,
}
};
// Guard that the |ArgumentsObject::ITERATOR_OVERRIDDEN_BIT| flag isn't set.
class MGuardArgumentsObjectNotOverriddenIterator
: public MUnaryInstruction,
public SingleObjectPolicy::Data {
explicit MGuardArgumentsObjectNotOverriddenIterator(MDefinition* argsObj)
: MUnaryInstruction(classOpcode, argsObj) {
setResultType(MIRType::Object);
setResultTypeSet(argsObj->resultTypeSet());
setMovable();
setGuard();
}
public:
INSTRUCTION_HEADER(GuardArgumentsObjectNotOverriddenIterator)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, getArgsObject))
bool congruentTo(const MDefinition* ins) const override {
return congruentIfOperandsEqual(ins);
}
AliasSet getAliasSet() const override {
// Even though the "iterator" property is lazily resolved, it acts similar
// to a normal property load, so we can treat this operation like any other
// property read.
return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot |
AliasSet::DynamicSlot);
}
};
// Given a MIRType::Value A and a MIRType::Object B:
// If the Value may be safely unboxed to an Object, return Object(A).
// Otherwise, return B.

View file

@ -4283,17 +4283,6 @@ void MacroAssembler::loadArgumentsObjectLength(Register obj, Register output,
rshift32(Imm32(ArgumentsObject::PACKED_BITS_COUNT), output);
}
void MacroAssembler::branchArgumentsObjectHasOverridenIterator(Register obj,
Register temp,
Label* label) {
// Get initial length value.
unboxInt32(Address(obj, ArgumentsObject::getInitialLengthSlotOffset()), temp);
// Ensure no overridden iterator.
branchTest32(Assembler::NonZero, temp,
Imm32(ArgumentsObject::ITERATOR_OVERRIDDEN_BIT), label);
}
static constexpr bool ValidateShiftRange(Scalar::Type from, Scalar::Type to) {
for (Scalar::Type type = from; type < to; type = Scalar::Type(type + 1)) {
if (TypedArrayShift(type) != TypedArrayShift(from)) {

View file

@ -3644,9 +3644,6 @@ class MacroAssembler : public MacroAssemblerSpecific {
void loadArgumentsObjectLength(Register obj, Register output, Label* fail);
void branchArgumentsObjectHasOverridenIterator(Register obj, Register temp,
Label* label);
void typedArrayElementShift(Register obj, Register output);
void branchIfClassIsNotTypedArray(Register clasp, Label* notTypedArray);

View file

@ -834,17 +834,6 @@ bool WarpCacheIRTranspiler::emitGuardArrayIsPacked(ObjOperandId arrayId) {
return true;
}
bool WarpCacheIRTranspiler::emitGuardArgumentsObjectNotOverriddenIterator(
ObjOperandId objId) {
MDefinition* obj = getOperand(objId);
auto* ins = MGuardArgumentsObjectNotOverriddenIterator::New(alloc(), obj);
add(ins);
setOperand(objId, ins);
return true;
}
bool WarpCacheIRTranspiler::emitLoadFrameCalleeResult() {
if (const CallInfo* callInfo = builder_->inlineCallInfo()) {
pushResult(callInfo->callee());

View file

@ -927,23 +927,6 @@ class LArgumentsObjectLength : public LInstructionHelper<1, 1, 0> {
const LAllocation* getArgsObject() { return getOperand(0); }
};
// Guard that the arguments object has no overridden iterator.
class LGuardArgumentsObjectNotOverriddenIterator
: public LInstructionHelper<0, 1, 1> {
public:
LIR_HEADER(GuardArgumentsObjectNotOverriddenIterator)
explicit LGuardArgumentsObjectNotOverriddenIterator(
const LAllocation& argsObj, const LDefinition& temp)
: LInstructionHelper(classOpcode) {
setOperand(0, argsObj);
setTemp(0, temp);
}
const LAllocation* getArgsObject() { return getOperand(0); }
const LDefinition* temp() { return this->getTemp(0); }
};
// If the Value is an Object, return unbox(Value).
// Otherwise, return the other Object.
class LReturnFromCtor : public LInstructionHelper<1, BOX_PIECES + 1, 0> {

View file

@ -538,13 +538,18 @@ static bool MappedArgSetter(JSContext* cx, HandleObject obj, HandleId id,
NativeDefineDataProperty(cx, argsobj, id, v, attrs, result);
}
/* static */
bool ArgumentsObject::getArgumentsIterator(JSContext* cx,
MutableHandleValue val) {
static bool DefineArgumentsIterator(JSContext* cx,
Handle<ArgumentsObject*> argsobj) {
RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
HandlePropertyName shName = cx->names().ArrayValues;
RootedAtom name(cx, cx->names().values);
return GlobalObject::getSelfHostedFunction(cx, cx->global(), shName, name, 0,
val);
RootedValue val(cx);
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), shName, name, 0,
&val)) {
return false;
}
return NativeDefineDataProperty(cx, argsobj, iteratorId, val,
JSPROP_RESOLVING);
}
/* static */
@ -570,12 +575,7 @@ bool ArgumentsObject::reifyIterator(JSContext* cx,
return true;
}
RootedId iteratorId(cx, SYMBOL_TO_JSID(cx->wellKnownSymbols().iterator));
RootedValue val(cx);
if (!ArgumentsObject::getArgumentsIterator(cx, &val)) {
return false;
}
if (!NativeDefineDataProperty(cx, obj, iteratorId, val, JSPROP_RESOLVING)) {
if (!DefineArgumentsIterator(cx, obj)) {
return false;
}
@ -594,7 +594,7 @@ bool MappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj,
return true;
}
if (!reifyIterator(cx, argsobj)) {
if (!DefineArgumentsIterator(cx, argsobj)) {
return false;
}
*resolvedp = true;
@ -817,7 +817,7 @@ bool UnmappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj,
return true;
}
if (!reifyIterator(cx, argsobj)) {
if (!DefineArgumentsIterator(cx, argsobj)) {
return false;
}
*resolvedp = true;

View file

@ -277,11 +277,6 @@ class ArgumentsObject : public NativeObject {
*/
static bool reifyIterator(JSContext* cx, Handle<ArgumentsObject*> obj);
/*
* Return the arguments iterator function.
*/
static bool getArgumentsIterator(JSContext* cx, MutableHandleValue val);
/* True iff any element has been assigned or its attributes
* changed. */
bool hasOverriddenElement() const {