Bug 1067009 - Implement regexp_toShared for CPOWs. r=billm

This commit is contained in:
Bobby Holley 2014-10-01 17:22:15 +02:00
parent f76176b5cc
commit ec9f41d32b
8 changed files with 81 additions and 0 deletions

View File

@ -97,6 +97,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
bool AnswerClassName(const uint64_t &objId, nsString *result) {
return Answer::AnswerClassName(ObjectId::deserialize(objId), result);
}
bool AnswerRegExpToShared(const uint64_t &objId, ReturnStatus *rs, nsString *source, uint32_t *flags) {
return Answer::AnswerRegExpToShared(ObjectId::deserialize(objId), rs, source, flags);
}
bool AnswerGetPropertyNames(const uint64_t &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) {
@ -191,6 +194,11 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
return Base::CallClassName(objId.serialize(), result);
}
bool CallRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
nsString *source, uint32_t *flags) {
return Base::CallRegExpToShared(objId.serialize(), rs, source, flags);
}
bool CallGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) {
return Base::CallGetPropertyNames(objId.serialize(), flags, rs, names);

View File

@ -40,6 +40,7 @@ both:
rpc HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has);
rpc ObjectClassIs(uint64_t objId, uint32_t classValue) returns (bool result);
rpc ClassName(uint64_t objId) returns (nsString name);
rpc RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);
rpc GetPropertyNames(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, nsString[] names);
rpc InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);

View File

@ -552,6 +552,31 @@ WrapperAnswer::AnswerClassName(const ObjectId &objId, nsString *name)
return true;
}
bool
WrapperAnswer::AnswerRegExpToShared(const ObjectId &objId, ReturnStatus *rs,
nsString *source, uint32_t *flags)
{
AutoSafeJSContext cx;
RootedObject obj(cx, findObjectById(cx, objId));
if (!obj)
return fail(cx, rs);
JSAutoCompartment ac(cx, obj);
MOZ_RELEASE_ASSERT(JS_ObjectIsRegExp(cx, obj));
RootedString sourceJSStr(cx, JS_GetRegExpSource(cx, obj));
if (!sourceJSStr)
return fail(cx, rs);
nsAutoJSString sourceStr;
if (!sourceStr.init(cx, sourceJSStr))
return fail(cx, rs);
source->Assign(sourceStr);
*flags = JS_GetRegExpFlags(cx, obj);
return ok(rs);
}
bool
WrapperAnswer::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names)

View File

@ -52,6 +52,7 @@ class WrapperAnswer : public virtual JavaScriptShared
bool AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
bool *result);
bool AnswerClassName(const ObjectId &objId, nsString *result);
bool AnswerRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source, uint32_t *flags);
bool AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names);

View File

@ -91,6 +91,7 @@ class CPOWProxyHandler : public BaseProxyHandler
virtual bool objectClassIs(HandleObject obj, js::ESClassValue classValue,
JSContext *cx) const MOZ_OVERRIDE;
virtual const char* className(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) const MOZ_OVERRIDE;
virtual void objectMoved(JSObject *proxy, const JSObject *old) const MOZ_OVERRIDE;
virtual bool isCallable(JSObject *obj) const MOZ_OVERRIDE;
@ -651,6 +652,37 @@ WrapperOwner::className(JSContext *cx, HandleObject proxy)
return ToNewCString(name);
}
bool
CPOWProxyHandler::regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) const
{
FORWARD(regexp_toShared, (cx, proxy, g));
}
bool
WrapperOwner::regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g)
{
ObjectId objId = idOf(proxy);
ReturnStatus status;
nsString source;
unsigned flags = 0;
if (!CallRegExpToShared(objId, &status, &source, &flags))
return ipcfail(cx);
LOG_STACK();
if (!ok(cx, status))
return false;
RootedObject regexp(cx);
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
regexp = JS_NewUCRegExpObject(cx, global, source.get(), source.Length(), flags);
if (!regexp)
return false;
return js::RegExpToSharedNonInline(cx, regexp, g);
}
void
CPOWProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy) const
{

View File

@ -11,6 +11,7 @@
#include "JavaScriptShared.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "js/Class.h"
#include "jsproxy.h"
#ifdef XP_WIN
#undef GetClassName
@ -55,6 +56,7 @@ class WrapperOwner : public virtual JavaScriptShared
// SpiderMonkey Extensions.
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool regexp_toShared(JSContext *cx, JS::HandleObject proxy, js::RegExpGuard *g);
bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args,
bool construct);
bool hasInstance(JSContext *cx, JS::HandleObject proxy, JS::MutableHandleValue v, bool *bp);
@ -140,6 +142,8 @@ class WrapperOwner : public virtual JavaScriptShared
virtual bool CallObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
bool *result) = 0;
virtual bool CallClassName(const ObjectId &objId, nsString *result) = 0;
virtual bool CallRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source,
uint32_t *flags) = 0;
virtual bool CallGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names) = 0;

View File

@ -1157,6 +1157,10 @@ extern JS_FRIEND_API(unsigned)
GetEnterCompartmentDepth(JSContext* cx);
#endif
class RegExpGuard;
extern JS_FRIEND_API(bool)
RegExpToSharedNonInline(JSContext *cx, JS::HandleObject regexp, RegExpGuard *shared);
/* Implemented in jswrapper.cpp. */
typedef enum NukeReferencesToWindow {
NukeWindowReferences,

View File

@ -973,3 +973,9 @@ js::CloneScriptRegExpObject(JSContext *cx, RegExpObject &reobj)
RootedAtom source(cx, reobj.getSource());
return RegExpObject::createNoStatics(cx, source, reobj.getFlags(), nullptr, cx->tempLifoAlloc());
}
JS_FRIEND_API(bool)
js::RegExpToSharedNonInline(JSContext *cx, HandleObject obj, js::RegExpGuard *g)
{
return RegExpToShared(cx, obj, g);
}