Bug 882736 - Ion-compile scripts that use ES5 getter/setter syntax. r=bhackett

This commit is contained in:
Jan de Mooij 2013-07-30 12:52:09 +02:00
Родитель f558a92953
Коммит 7a271ed06a
14 изменённых файлов: 399 добавлений и 190 удалений

Просмотреть файл

@ -1991,7 +1991,7 @@ BaselineCompiler::emit_JSOP_DEFFUN()
}
typedef bool (*InitPropGetterSetterFn)(JSContext *, jsbytecode *, HandleObject, HandlePropertyName,
HandleValue);
HandleObject);
static const VMFunction InitPropGetterSetterInfo =
FunctionInfo<InitPropGetterSetterFn>(InitGetterSetterOperation);
@ -2001,16 +2001,17 @@ BaselineCompiler::emitInitPropGetterSetter()
JS_ASSERT(JSOp(*pc) == JSOP_INITPROP_GETTER ||
JSOp(*pc) == JSOP_INITPROP_SETTER);
// Load value in R0 but keep it on the stack for the decompiler.
// Keep values on the stack for the decompiler.
frame.syncStack(0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
prepareVMCall();
pushArg(R0);
pushArg(ImmGCPtr(script->getName(pc)));
masm.extractObject(frame.addressOfStackValue(frame.peek(-2)), R0.scratchReg());
masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
masm.extractObject(frame.addressOfStackValue(frame.peek(-2)), R1.scratchReg());
pushArg(R0.scratchReg());
pushArg(ImmGCPtr(script->getName(pc)));
pushArg(R1.scratchReg());
pushArg(ImmWord(pc));
if (!callVM(InitPropGetterSetterInfo))
@ -2033,7 +2034,7 @@ BaselineCompiler::emit_JSOP_INITPROP_SETTER()
}
typedef bool (*InitElemGetterSetterFn)(JSContext *, jsbytecode *, HandleObject, HandleValue,
HandleValue);
HandleObject);
static const VMFunction InitElemGetterSetterInfo =
FunctionInfo<InitElemGetterSetterFn>(InitGetterSetterOperation);
@ -2047,11 +2048,11 @@ BaselineCompiler::emitInitElemGetterSetter()
// decompiler.
frame.syncStack(0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R1);
masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R1.scratchReg());
prepareVMCall();
pushArg(R1);
pushArg(R1.scratchReg());
pushArg(R0);
masm.extractObject(frame.addressOfStackValue(frame.peek(-3)), R0.scratchReg());
pushArg(R0.scratchReg());

Просмотреть файл

@ -3172,6 +3172,25 @@ CodeGenerator::visitInitElem(LInitElem *lir)
return callVM(InitElemInfo, lir);
}
typedef bool (*InitElemGetterSetterFn)(JSContext *, jsbytecode *, HandleObject, HandleValue,
HandleObject);
static const VMFunction InitElemGetterSetterInfo =
FunctionInfo<InitElemGetterSetterFn>(InitGetterSetterOperation);
bool
CodeGenerator::visitInitElemGetterSetter(LInitElemGetterSetter *lir)
{
Register obj = ToRegister(lir->object());
Register value = ToRegister(lir->value());
pushArg(value);
pushArg(ToValue(lir, LInitElemGetterSetter::IdIndex));
pushArg(obj);
pushArg(ImmWord(lir->mir()->resumePoint()->pc()));
return callVM(InitElemGetterSetterInfo, lir);
}
typedef bool(*InitPropFn)(JSContext *cx, HandleObject obj,
HandlePropertyName name, HandleValue value);
static const VMFunction InitPropInfo =
@ -3189,6 +3208,25 @@ CodeGenerator::visitInitProp(LInitProp *lir)
return callVM(InitPropInfo, lir);
}
typedef bool(*InitPropGetterSetterFn)(JSContext *, jsbytecode *, HandleObject, HandlePropertyName,
HandleObject);
static const VMFunction InitPropGetterSetterInfo =
FunctionInfo<InitPropGetterSetterFn>(InitGetterSetterOperation);
bool
CodeGenerator::visitInitPropGetterSetter(LInitPropGetterSetter *lir)
{
Register obj = ToRegister(lir->object());
Register value = ToRegister(lir->value());
pushArg(value);
pushArg(ImmGCPtr(lir->mir()->name()));
pushArg(obj);
pushArg(ImmWord(lir->mir()->resumePoint()->pc()));
return callVM(InitPropGetterSetterInfo, lir);
}
typedef bool (*CreateThisFn)(JSContext *cx, HandleObject callee, MutableHandleValue rval);
static const VMFunction CreateThisInfo = FunctionInfo<CreateThisFn>(CreateThis);

Просмотреть файл

@ -127,7 +127,9 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitNewDenseArrayPar(LNewDenseArrayPar *lir);
bool visitAbortPar(LAbortPar *lir);
bool visitInitElem(LInitElem *lir);
bool visitInitElemGetterSetter(LInitElemGetterSetter *lir);
bool visitInitProp(LInitProp *lir);
bool visitInitPropGetterSetter(LInitPropGetterSetter *lir);
bool visitCreateThis(LCreateThis *lir);
bool visitCreateThisWithProto(LCreateThisWithProto *lir);
bool visitCreateThisWithTemplate(LCreateThisWithTemplate *lir);

Просмотреть файл

@ -1339,6 +1339,16 @@ IonBuilder::inspectOpcode(JSOp op)
return jsop_initprop(name);
}
case JSOP_INITPROP_GETTER:
case JSOP_INITPROP_SETTER: {
PropertyName *name = info().getAtom(pc)->asPropertyName();
return jsop_initprop_getter_setter(name);
}
case JSOP_INITELEM_GETTER:
case JSOP_INITELEM_SETTER:
return jsop_initelem_getter_setter();
case JSOP_ENDINIT:
return true;
@ -5444,6 +5454,29 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
return resumeAfter(store);
}
bool
IonBuilder::jsop_initprop_getter_setter(PropertyName *name)
{
MDefinition *value = current->pop();
MDefinition *obj = current->peek(-1);
MInitPropGetterSetter *init = MInitPropGetterSetter::New(obj, name, value);
current->add(init);
return resumeAfter(init);
}
bool
IonBuilder::jsop_initelem_getter_setter()
{
MDefinition *value = current->pop();
MDefinition *id = current->pop();
MDefinition *obj = current->peek(-1);
MInitElemGetterSetter *init = MInitElemGetterSetter::New(obj, id, value);
current->add(init);
return resumeAfter(init);
}
MBasicBlock *
IonBuilder::addBlock(MBasicBlock *block, uint32_t loopDepth)
{

Просмотреть файл

@ -422,7 +422,9 @@ class IonBuilder : public MIRGenerator
bool jsop_newobject(HandleObject baseObj);
bool jsop_initelem();
bool jsop_initelem_array();
bool jsop_initelem_getter_setter();
bool jsop_initprop(HandlePropertyName name);
bool jsop_initprop_getter_setter(PropertyName *name);
bool jsop_regexp(RegExpObject *reobj);
bool jsop_object(JSObject *obj);
bool jsop_lambda(JSFunction *fun);

Просмотреть файл

@ -530,6 +530,29 @@ class LInitElem : public LCallInstructionHelper<0, 1 + 2*BOX_PIECES, 0>
}
};
class LInitElemGetterSetter : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0>
{
public:
LIR_HEADER(InitElemGetterSetter)
LInitElemGetterSetter(const LAllocation &object, const LAllocation &value) {
setOperand(0, object);
setOperand(1, value);
}
static const size_t IdIndex = 2;
const LAllocation *object() {
return getOperand(0);
}
const LAllocation *value() {
return getOperand(1);
}
MInitElemGetterSetter *mir() const {
return mir_->toInitElemGetterSetter();
}
};
// Takes in an Object and a Value.
class LInitProp : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
{
@ -554,6 +577,28 @@ class LInitProp : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
}
};
class LInitPropGetterSetter : public LCallInstructionHelper<0, 2, 0>
{
public:
LIR_HEADER(InitPropGetterSetter)
LInitPropGetterSetter(const LAllocation &object, const LAllocation &value) {
setOperand(0, object);
setOperand(1, value);
}
const LAllocation *object() {
return getOperand(0);
}
const LAllocation *value() {
return getOperand(1);
}
MInitPropGetterSetter *mir() const {
return mir_->toInitPropGetterSetter();
}
};
class LCheckOverRecursed : public LInstructionHelper<0, 0, 0>
{
public:

Просмотреть файл

@ -33,7 +33,9 @@
_(NewCallObjectPar) \
_(AbortPar) \
_(InitElem) \
_(InitElemGetterSetter) \
_(InitProp) \
_(InitPropGetterSetter) \
_(CheckOverRecursed) \
_(CheckOverRecursedPar) \
_(DefVar) \

Просмотреть файл

@ -252,6 +252,17 @@ LIRGenerator::visitInitElem(MInitElem *ins)
return add(lir, ins) && assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitInitElemGetterSetter(MInitElemGetterSetter *ins)
{
LInitElemGetterSetter *lir = new LInitElemGetterSetter(useRegisterAtStart(ins->object()),
useRegisterAtStart(ins->value()));
if (!useBoxAtStart(lir, LInitElemGetterSetter::IdIndex, ins->idValue()))
return false;
return add(lir, ins) && assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitInitProp(MInitProp *ins)
{
@ -262,6 +273,14 @@ LIRGenerator::visitInitProp(MInitProp *ins)
return add(lir, ins) && assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitInitPropGetterSetter(MInitPropGetterSetter *ins)
{
LInitPropGetterSetter *lir = new LInitPropGetterSetter(useRegisterAtStart(ins->object()),
useRegisterAtStart(ins->value()));
return add(lir, ins) && assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitPrepareCall(MPrepareCall *ins)
{

Просмотреть файл

@ -94,7 +94,9 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitNewDenseArrayPar(MNewDenseArrayPar *ins);
bool visitAbortPar(MAbortPar *ins);
bool visitInitElem(MInitElem *ins);
bool visitInitElemGetterSetter(MInitElemGetterSetter *ins);
bool visitInitProp(MInitProp *ins);
bool visitInitPropGetterSetter(MInitPropGetterSetter *ins);
bool visitCheckOverRecursed(MCheckOverRecursed *ins);
bool visitCheckOverRecursedPar(MCheckOverRecursedPar *ins);
bool visitDefVar(MDefVar *ins);

Просмотреть файл

@ -681,6 +681,174 @@ class MUnaryInstruction : public MAryInstruction<1>
}
};
class MBinaryInstruction : public MAryInstruction<2>
{
protected:
MBinaryInstruction(MDefinition *left, MDefinition *right)
{
setOperand(0, left);
setOperand(1, right);
}
public:
MDefinition *lhs() const {
return getOperand(0);
}
MDefinition *rhs() const {
return getOperand(1);
}
protected:
HashNumber valueHash() const
{
MDefinition *lhs = getOperand(0);
MDefinition *rhs = getOperand(1);
return op() ^ lhs->valueNumber() ^ rhs->valueNumber();
}
void swapOperands() {
MDefinition *temp = getOperand(0);
replaceOperand(0, getOperand(1));
replaceOperand(1, temp);
}
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 *left = getOperand(0);
MDefinition *right = getOperand(1);
MDefinition *tmp;
if (isCommutative() && left->valueNumber() > right->valueNumber()) {
tmp = right;
right = left;
left = tmp;
}
MBinaryInstruction *bi = static_cast<MBinaryInstruction *>(ins);
MDefinition *insLeft = bi->getOperand(0);
MDefinition *insRight = bi->getOperand(1);
if (isCommutative() && insLeft->valueNumber() > insRight->valueNumber()) {
tmp = insRight;
insRight = insLeft;
insLeft = tmp;
}
return (left->valueNumber() == insLeft->valueNumber()) &&
(right->valueNumber() == insRight->valueNumber());
}
// Return true if the operands to this instruction are both unsigned,
// in which case any wrapping operands were replaced with the underlying
// int32 operands.
bool tryUseUnsignedOperands();
};
class MTernaryInstruction : public MAryInstruction<3>
{
protected:
MTernaryInstruction(MDefinition *first, MDefinition *second, MDefinition *third)
{
setOperand(0, first);
setOperand(1, second);
setOperand(2, third);
}
protected:
HashNumber valueHash() const
{
MDefinition *first = getOperand(0);
MDefinition *second = getOperand(1);
MDefinition *third = getOperand(2);
return op() ^ first->valueNumber() ^ second->valueNumber() ^ third->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;
MTernaryInstruction *ter = static_cast<MTernaryInstruction *>(ins);
MDefinition *first = getOperand(0);
MDefinition *second = getOperand(1);
MDefinition *third = getOperand(2);
MDefinition *insFirst = ter->getOperand(0);
MDefinition *insSecond = ter->getOperand(1);
MDefinition *insThird = ter->getOperand(2);
return first->valueNumber() == insFirst->valueNumber() &&
second->valueNumber() == insSecond->valueNumber() &&
third->valueNumber() == insThird->valueNumber();
}
};
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;
MQuaternaryInstruction *qua = static_cast<MQuaternaryInstruction *>(ins);
MDefinition *first = getOperand(0);
MDefinition *second = getOperand(1);
MDefinition *third = getOperand(2);
MDefinition *fourth = getOperand(3);
MDefinition *insFirst = qua->getOperand(0);
MDefinition *insSecond = qua->getOperand(1);
MDefinition *insThird = qua->getOperand(2);
MDefinition *insFourth = qua->getOperand(3);
return first->valueNumber() == insFirst->valueNumber() &&
second->valueNumber() == insSecond->valueNumber() &&
third->valueNumber() == insThird->valueNumber() &&
fourth->valueNumber() == insFourth->valueNumber();
}
};
// Generates an LSnapshot without further effect.
class MStart : public MNullaryInstruction
{
@ -1327,6 +1495,38 @@ class MInitProp
}
};
class MInitPropGetterSetter
: public MBinaryInstruction,
public MixPolicy<ObjectPolicy<0>, ObjectPolicy<1> >
{
CompilerRootPropertyName name_;
MInitPropGetterSetter(MDefinition *obj, PropertyName *name, MDefinition *value)
: MBinaryInstruction(obj, value),
name_(name)
{ }
public:
INSTRUCTION_HEADER(InitPropGetterSetter)
static MInitPropGetterSetter *New(MDefinition *obj, PropertyName *name, MDefinition *value) {
return new MInitPropGetterSetter(obj, name, value);
}
MDefinition *object() const {
return getOperand(0);
}
MDefinition *value() const {
return getOperand(1);
}
PropertyName *name() const {
return name_;
}
TypePolicy *typePolicy() {
return this;
}
};
class MInitElem
: public MAryInstruction<3>,
public Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, BoxPolicy<2> >
@ -1363,6 +1563,35 @@ class MInitElem
}
};
class MInitElemGetterSetter
: public MTernaryInstruction,
public Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, ObjectPolicy<2> >
{
MInitElemGetterSetter(MDefinition *obj, MDefinition *id, MDefinition *value)
: MTernaryInstruction(obj, id, value)
{ }
public:
INSTRUCTION_HEADER(InitElemGetterSetter)
static MInitElemGetterSetter *New(MDefinition *obj, MDefinition *id, MDefinition *value) {
return new MInitElemGetterSetter(obj, id, value);
}
MDefinition *object() const {
return getOperand(0);
}
MDefinition *idValue() const {
return getOperand(1);
}
MDefinition *value() 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.
@ -1685,174 +1914,6 @@ class MCallDirectEval
jsbytecode *pc_;
};
class MBinaryInstruction : public MAryInstruction<2>
{
protected:
MBinaryInstruction(MDefinition *left, MDefinition *right)
{
setOperand(0, left);
setOperand(1, right);
}
public:
MDefinition *lhs() const {
return getOperand(0);
}
MDefinition *rhs() const {
return getOperand(1);
}
protected:
HashNumber valueHash() const
{
MDefinition *lhs = getOperand(0);
MDefinition *rhs = getOperand(1);
return op() ^ lhs->valueNumber() ^ rhs->valueNumber();
}
void swapOperands() {
MDefinition *temp = getOperand(0);
replaceOperand(0, getOperand(1));
replaceOperand(1, temp);
}
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 *left = getOperand(0);
MDefinition *right = getOperand(1);
MDefinition *tmp;
if (isCommutative() && left->valueNumber() > right->valueNumber()) {
tmp = right;
right = left;
left = tmp;
}
MBinaryInstruction *bi = static_cast<MBinaryInstruction *>(ins);
MDefinition *insLeft = bi->getOperand(0);
MDefinition *insRight = bi->getOperand(1);
if (isCommutative() && insLeft->valueNumber() > insRight->valueNumber()) {
tmp = insRight;
insRight = insLeft;
insLeft = tmp;
}
return (left->valueNumber() == insLeft->valueNumber()) &&
(right->valueNumber() == insRight->valueNumber());
}
// Return true if the operands to this instruction are both unsigned,
// in which case any wrapping operands were replaced with the underlying
// int32 operands.
bool tryUseUnsignedOperands();
};
class MTernaryInstruction : public MAryInstruction<3>
{
protected:
MTernaryInstruction(MDefinition *first, MDefinition *second, MDefinition *third)
{
setOperand(0, first);
setOperand(1, second);
setOperand(2, third);
}
protected:
HashNumber valueHash() const
{
MDefinition *first = getOperand(0);
MDefinition *second = getOperand(1);
MDefinition *third = getOperand(2);
return op() ^ first->valueNumber() ^ second->valueNumber() ^ third->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;
MTernaryInstruction *ter = static_cast<MTernaryInstruction *>(ins);
MDefinition *first = getOperand(0);
MDefinition *second = getOperand(1);
MDefinition *third = getOperand(2);
MDefinition *insFirst = ter->getOperand(0);
MDefinition *insSecond = ter->getOperand(1);
MDefinition *insThird = ter->getOperand(2);
return first->valueNumber() == insFirst->valueNumber() &&
second->valueNumber() == insSecond->valueNumber() &&
third->valueNumber() == insThird->valueNumber();
}
};
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;
MQuaternaryInstruction *qua = static_cast<MQuaternaryInstruction *>(ins);
MDefinition *first = getOperand(0);
MDefinition *second = getOperand(1);
MDefinition *third = getOperand(2);
MDefinition *fourth = getOperand(3);
MDefinition *insFirst = qua->getOperand(0);
MDefinition *insSecond = qua->getOperand(1);
MDefinition *insThird = qua->getOperand(2);
MDefinition *insFourth = qua->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

Просмотреть файл

@ -86,7 +86,9 @@ namespace ion {
_(NewCallObject) \
_(NewStringObject) \
_(InitElem) \
_(InitElemGetterSetter) \
_(InitProp) \
_(InitPropGetterSetter) \
_(Start) \
_(OsrEntry) \
_(Nop) \

Просмотреть файл

@ -175,7 +175,9 @@ class ParallelSafetyVisitor : public MInstructionVisitor
CUSTOM_OP(NewCallObject)
CUSTOM_OP(NewParallelArray)
UNSAFE_OP(InitElem)
UNSAFE_OP(InitElemGetterSetter)
UNSAFE_OP(InitProp)
UNSAFE_OP(InitPropGetterSetter)
SAFE_OP(Start)
UNSAFE_OP(OsrEntry)
SAFE_OP(Nop)

Просмотреть файл

@ -2915,12 +2915,12 @@ BEGIN_CASE(JSOP_INITPROP_SETTER)
{
RootedObject &obj = rootObject0;
RootedPropertyName &name = rootName0;
RootedValue &val = rootValue0;
RootedObject &val = rootObject1;
JS_ASSERT(regs.stackDepth() >= 2);
obj = &regs.sp[-2].toObject();
name = script->getName(regs.pc);
val = regs.sp[-1];
val = &regs.sp[-1].toObject();
if (!InitGetterSetterOperation(cx, regs.pc, obj, name, val))
goto error;
@ -2934,12 +2934,12 @@ BEGIN_CASE(JSOP_INITELEM_SETTER)
{
RootedObject &obj = rootObject0;
RootedValue &idval = rootValue0;
RootedValue &val = rootValue1;
RootedObject &val = rootObject1;
JS_ASSERT(regs.stackDepth() >= 3);
obj = &regs.sp[-3].toObject();
idval = regs.sp[-2];
val = regs.sp[-1];
val = &regs.sp[-1].toObject();
if (!InitGetterSetterOperation(cx, regs.pc, obj, idval, val))
goto error;
@ -3860,9 +3860,9 @@ js::RunOnceScriptPrologue(JSContext *cx, HandleScript script)
bool
js::InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, HandleId id,
HandleValue val)
HandleObject val)
{
JS_ASSERT(js_IsCallable(val));
JS_ASSERT(val->isCallable());
/*
* Getters and setters are just like watchpoints from an access control
@ -3880,13 +3880,13 @@ js::InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, H
JSOp op = JSOp(*pc);
if (op == JSOP_INITPROP_GETTER || op == JSOP_INITELEM_GETTER) {
getter = CastAsPropertyOp(&val.toObject());
getter = CastAsPropertyOp(val);
setter = JS_StrictPropertyStub;
attrs |= JSPROP_GETTER;
} else {
JS_ASSERT(op == JSOP_INITPROP_SETTER || op == JSOP_INITELEM_SETTER);
getter = JS_PropertyStub;
setter = CastAsStrictPropertyOp(&val.toObject());
setter = CastAsStrictPropertyOp(val);
attrs |= JSPROP_SETTER;
}
@ -3896,7 +3896,7 @@ js::InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, H
bool
js::InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj,
HandlePropertyName name, HandleValue val)
HandlePropertyName name, HandleObject val)
{
RootedId id(cx, NameToId(name));
return InitGetterSetterOperation(cx, pc, obj, id, val);
@ -3904,7 +3904,7 @@ js::InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj,
bool
js::InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, HandleValue idval,
HandleValue val)
HandleObject val)
{
RootedId id(cx);
if (!ValueToId<CanGC>(cx, idval, &id))

Просмотреть файл

@ -499,15 +499,15 @@ RunOnceScriptPrologue(JSContext *cx, HandleScript script);
bool
InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, HandleId id,
HandleValue val);
HandleObject val);
bool
InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, HandlePropertyName name,
HandleValue val);
HandleObject val);
bool
InitGetterSetterOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, HandleValue idval,
HandleValue val);
HandleObject val);
inline bool
SetConstOperation(JSContext *cx, HandleObject varobj, HandlePropertyName name, HandleValue rval)