Bug 956293 - Don't pass RegExp proto to CloneRegExpObject. r=h4writer

This commit is contained in:
Jan de Mooij 2014-01-03 18:58:56 +01:00
parent f4f0130c08
commit f9c8f7cdba
11 changed files with 24 additions and 46 deletions

View File

@ -1197,23 +1197,17 @@ BaselineCompiler::emit_JSOP_OBJECT()
return true;
}
typedef JSObject *(*CloneRegExpObjectFn)(JSContext *, JSObject *, JSObject *);
typedef JSObject *(*CloneRegExpObjectFn)(JSContext *, JSObject *);
static const VMFunction CloneRegExpObjectInfo =
FunctionInfo<CloneRegExpObjectFn>(CloneRegExpObject);
bool
BaselineCompiler::emit_JSOP_REGEXP()
{
RootedObject reObj(cx, script->getRegExp(GET_UINT32_INDEX(pc)));
RootedObject proto(cx, script->global().getOrCreateRegExpPrototype(cx));
if (!proto)
return false;
RootedObject reObj(cx, script->getRegExp(pc));
prepareVMCall();
pushArg(ImmGCPtr(proto));
pushArg(ImmGCPtr(reObj));
if (!callVM(CloneRegExpObjectInfo))
return false;

View File

@ -753,16 +753,13 @@ CodeGenerator::visitDoubleToString(LDoubleToString *lir)
return true;
}
typedef JSObject *(*CloneRegExpObjectFn)(JSContext *, JSObject *, JSObject *);
typedef JSObject *(*CloneRegExpObjectFn)(JSContext *, JSObject *);
static const VMFunction CloneRegExpObjectInfo =
FunctionInfo<CloneRegExpObjectFn>(CloneRegExpObject);
bool
CodeGenerator::visitRegExp(LRegExp *lir)
{
JSObject *proto = lir->mir()->getRegExpPrototype();
pushArg(ImmGCPtr(proto));
pushArg(ImmGCPtr(lir->mir()->source()));
return callVM(CloneRegExpObjectInfo, lir);
}

View File

@ -17,7 +17,7 @@ using namespace jit;
inline RegExpObject *
CompileInfo::getRegExp(jsbytecode *pc) const
{
return script_->getRegExp(GET_UINT32_INDEX(pc));
return script_->getRegExp(pc);
}
inline JSFunction *

View File

@ -9066,9 +9066,7 @@ IonBuilder::jsop_regexp(RegExpObject *reobj)
mustClone = false;
}
JSObject *prototype = reobj->getProto();
MRegExp *regexp = MRegExp::New(alloc(), constraints(), reobj, prototype, mustClone);
MRegExp *regexp = MRegExp::New(alloc(), constraints(), reobj, mustClone);
current->add(regexp);
current->push(regexp);

View File

@ -4781,17 +4781,13 @@ class MDefFun : public MUnaryInstruction
class MRegExp : public MNullaryInstruction
{
CompilerRoot<RegExpObject *> source_;
CompilerRootObject prototype_;
bool mustClone_;
MRegExp(types::CompilerConstraintList *constraints, RegExpObject *source, JSObject *prototype, bool mustClone)
MRegExp(types::CompilerConstraintList *constraints, RegExpObject *source, bool mustClone)
: source_(source),
prototype_(prototype),
mustClone_(mustClone)
{
setResultType(MIRType_Object);
JS_ASSERT(source->getProto() == prototype);
setResultTypeSet(MakeSingletonTypeSet(constraints, source));
}
@ -4799,10 +4795,9 @@ class MRegExp : public MNullaryInstruction
INSTRUCTION_HEADER(RegExp)
static MRegExp *New(TempAllocator &alloc, types::CompilerConstraintList *constraints,
RegExpObject *source, JSObject *prototype,
bool mustClone)
RegExpObject *source, bool mustClone)
{
return new(alloc) MRegExp(constraints, source, prototype, mustClone);
return new(alloc) MRegExp(constraints, source, mustClone);
}
bool mustClone() const {
@ -4811,9 +4806,6 @@ class MRegExp : public MNullaryInstruction
RegExpObject *source() const {
return source_;
}
JSObject *getRegExpPrototype() const {
return prototype_;
}
AliasSet getAliasSet() const {
return AliasSet::None();
}

View File

@ -2890,11 +2890,7 @@ ASTSerializer::literal(ParseNode *pn, MutableHandleValue dst)
RootedObject re1(cx, pn->as<RegExpLiteral>().objbox()->object);
LOCAL_ASSERT(re1 && re1->is<RegExpObject>());
RootedObject proto(cx);
if (!js_GetClassPrototype(cx, JSProto_RegExp, &proto))
return false;
RootedObject re2(cx, CloneRegExpObject(cx, re1, proto));
RootedObject re2(cx, CloneRegExpObject(cx, re1));
if (!re2)
return false;

View File

@ -1390,6 +1390,7 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
inline JSFunction *functionOrCallerFunction();
inline js::RegExpObject *getRegExp(size_t index);
inline js::RegExpObject *getRegExp(jsbytecode *pc);
const js::Value &getConst(size_t index) {
js::ConstArray *arr = consts();

View File

@ -91,6 +91,13 @@ JSScript::getRegExp(size_t index)
return (js::RegExpObject *) obj;
}
inline js::RegExpObject *
JSScript::getRegExp(jsbytecode *pc)
{
JS_ASSERT(containsPC(pc) && containsPC(pc + sizeof(uint32_t)));
return getRegExp(GET_UINT32_INDEX(pc));
}
inline js::GlobalObject &
JSScript::global() const
{

View File

@ -2779,11 +2779,7 @@ CASE(JSOP_REGEXP)
* Push a regexp object cloned from the regexp literal object mapped by the
* bytecode at pc.
*/
uint32_t index = GET_UINT32_INDEX(REGS.pc);
JSObject *proto = REGS.fp()->global().getOrCreateRegExpPrototype(cx);
if (!proto)
goto error;
JSObject *obj = CloneRegExpObject(cx, script->getRegExp(index), proto);
JSObject *obj = CloneRegExpObject(cx, script->getRegExp(REGS.pc));
if (!obj)
goto error;
PUSH_OBJECT(*obj);

View File

@ -94,11 +94,9 @@ RegExpObjectBuilder::build(HandleAtom source, RegExpFlag flags)
}
RegExpObject *
RegExpObjectBuilder::clone(Handle<RegExpObject *> other, Handle<RegExpObject *> proto)
RegExpObjectBuilder::clone(Handle<RegExpObject *> other)
{
RootedTypeObject type(cx, other->type());
JS_ASSERT(type->proto().toObject() == proto);
if (!getOrCreateClone(type))
return nullptr;
@ -107,7 +105,7 @@ RegExpObjectBuilder::clone(Handle<RegExpObject *> other, Handle<RegExpObject *>
* the clone -- if the |RegExpStatics| provides more flags we'll
* need a different |RegExpShared|.
*/
RegExpStatics *res = proto->getParent()->as<GlobalObject>().getRegExpStatics();
RegExpStatics *res = other->getProto()->getParent()->as<GlobalObject>().getRegExpStatics();
RegExpFlag origFlags = other->getFlags();
RegExpFlag staticsFlags = res->getFlags();
if ((origFlags & staticsFlags) != staticsFlags) {
@ -781,12 +779,11 @@ RegExpCompartment::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
/* Functions */
JSObject *
js::CloneRegExpObject(JSContext *cx, JSObject *obj_, JSObject *proto_)
js::CloneRegExpObject(JSContext *cx, JSObject *obj_)
{
RegExpObjectBuilder builder(cx);
Rooted<RegExpObject*> regex(cx, &obj_->as<RegExpObject>());
Rooted<RegExpObject*> proto(cx, &proto_->as<RegExpObject>());
JSObject *res = builder.clone(regex, proto);
JSObject *res = builder.clone(regex);
JS_ASSERT(res->type() == regex->type());
return res;
}

View File

@ -84,11 +84,11 @@ class RegExpObjectBuilder
RegExpObject *build(HandleAtom source, RegExpShared &shared);
/* Perform a VM-internal clone. */
RegExpObject *clone(Handle<RegExpObject*> other, Handle<RegExpObject*> proto);
RegExpObject *clone(Handle<RegExpObject*> other);
};
JSObject *
CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto);
CloneRegExpObject(JSContext *cx, JSObject *obj);
/*
* A RegExpShared is the compiled representation of a regexp. A RegExpShared is