mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:25:44 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Ensure input events account for APZ transforms on Windows. (bug 1143567 part 4, r=jmathies) (e9df7b3cb) - Fix mouse event handling regression from bug 1143567. (bug 1142866, r=jmathies) (91b195614) - Fix regression from bug 1143567 that broke context menus. (bug 1144827, r=jmathies, a=kwierso) (c852a6554) - fix typo in applying bug 1143567 part 3 (b246c45a8) - fix typo in applying bug 1143567 part 3 (6f1e6084f) - Bug 1130089 - Use constexpr for JitStackValueAlignment. r=bbouvier (59793733b) - pointer style (b3a4de187) - Bug 1121613 - Move MacroAssemblerSpecific::Push to the generic MacroAssembler. r=jandem (54d0c7e82) - Bug 1151382 - Fix Alignment mismatch for none jit. r=luke (05cce8627) - fix typo (66dd065dd) - pointer style (2fe56af71) - remove MOZ_HAVE_CXX11_OVERRIDE and MOZ_HAVE_CXX11_FINAL - may break some older compilers, let's hope not anything currently used (a883df8d7) - Bug 1135428 - OdinMonkey: remove compileAndGo restriction (r=bbouvier) Bug 1135428 - OdinMonkey: return nullptr, not false (r=warnings-as-errors CLOSED TREE) (378f1047e) - Bug 1135428: Fix test to run with --no-asmjs as well (76b45cc55) - pointer style (e85078674) - Bug 1142784, part 1 - In NativeObject.cpp, move some Lookup functions out of the way and make a big swath of this file the [[DefineOwnProperty]] section. r=Waldo. (5452ceb3a) - Bug 1142784, part 2 - Change ProxyHandler::defineProperty() to make the desc argument a non-mutable handle. r=Waldo. (26afaeb1e) - Bug 1142784, part 3 - Change js::DefinePropertyOp and a few property-defining functions to use PropertyDescriptor rather than separate (value, attrs, getter, setter) arguments. r=Waldo. (0cf9f0f6d) - more pointer style.... soon to be changed again, boring (88956061f) - Bug 1146165 - Stop calling Proxy::set directly from Ion IC stub. EmitObjectOpResultCheck is retained because GenerateCallSetter still uses it in the JSSetterOp case. r=efaust. (28d368865) - Bug 1138157 - Change ScriptedDirectProxyHandler to inherit from BaseProxyHandler. r=efaust (1ecb895cc) - missing bit of Bug 1113369, part 4 - [[Set]] ObjectOpResult support. (ac03ea66d) - pointer style (b966f0173) - pointer style (883527058)
This commit is contained in:
@@ -163,7 +163,7 @@ bool
|
||||
WindowNamedPropertiesHandler::defineProperty(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc,
|
||||
JS::Handle<JSPropertyDescriptor> aDesc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
ErrorResult rv;
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
virtual bool
|
||||
defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc,
|
||||
JS::Handle<JSPropertyDescriptor> aDesc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool
|
||||
ownPropNames(JSContext* aCx, JS::Handle<JSObject*> aProxy, unsigned flags,
|
||||
|
||||
@@ -623,7 +623,7 @@ public:
|
||||
virtual bool defineProperty(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
@@ -784,7 +784,7 @@ bool
|
||||
nsOuterWindowProxy::defineProperty(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
int32_t index = GetArrayIndexFromId(cx, id);
|
||||
|
||||
@@ -1565,7 +1565,7 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
bool
|
||||
XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
if (!js::IsProxy(obj))
|
||||
|
||||
@@ -2475,7 +2475,7 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
bool
|
||||
XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result,
|
||||
bool *defined);
|
||||
|
||||
|
||||
@@ -10261,7 +10261,7 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'proxy'),
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc'),
|
||||
Argument('JS::Handle<JSPropertyDescriptor>', 'desc'),
|
||||
Argument('JS::ObjectOpResult&', 'opresult'),
|
||||
Argument('bool*', 'defined')]
|
||||
ClassMethod.__init__(self, "defineProperty", "bool", args, virtual=True, override=True, const=True)
|
||||
|
||||
@@ -199,7 +199,7 @@ BaseDOMProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
|
||||
|
||||
bool
|
||||
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined) const
|
||||
{
|
||||
if (desc.hasGetterObject() && desc.setter() == JS_StrictPropertyStub) {
|
||||
@@ -256,7 +256,7 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
|
||||
}
|
||||
}
|
||||
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &desc, result);
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -105,14 +105,14 @@ public:
|
||||
{}
|
||||
|
||||
bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override
|
||||
{
|
||||
bool unused;
|
||||
return defineProperty(cx, proxy, id, desc, result, &unused);
|
||||
}
|
||||
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined) const;
|
||||
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
|
||||
+12
-12
@@ -66,19 +66,19 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
||||
ReturnStatus* rs, bool* bp) {
|
||||
return Answer::RecvHasOwn(ObjectId::deserialize(objId), id, rs, bp);
|
||||
}
|
||||
bool RecvGet(const uint64_t& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id,
|
||||
ReturnStatus* rs, JSVariant* result) {
|
||||
bool RecvGet(const uint64_t &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result) {
|
||||
return Answer::RecvGet(ObjectId::deserialize(objId), receiverVar, id, rs, result);
|
||||
}
|
||||
bool RecvSet(const uint64_t& objId, const ObjectVariant& receiverVar,
|
||||
bool RecvSet(const uint64_t &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *result) {
|
||||
return Answer::RecvSet(ObjectId::deserialize(objId), receiverVar, id, value, rs, result);
|
||||
}
|
||||
|
||||
bool RecvIsExtensible(const uint64_t& objId, ReturnStatus* rs,
|
||||
bool* result) {
|
||||
bool RecvIsExtensible(const uint64_t &objId, ReturnStatus *rs,
|
||||
bool *result) {
|
||||
return Answer::RecvIsExtensible(ObjectId::deserialize(objId), rs, result);
|
||||
}
|
||||
bool RecvCallOrConstruct(const uint64_t& objId, InfallibleTArray<JSParam>&& argv,
|
||||
@@ -156,19 +156,19 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
||||
ReturnStatus* rs, bool* bp) {
|
||||
return Base::SendHasOwn(objId.serialize(), id, rs, bp);
|
||||
}
|
||||
bool SendGet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id,
|
||||
ReturnStatus* rs, JSVariant* result) {
|
||||
bool SendGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result) {
|
||||
return Base::SendGet(objId.serialize(), receiverVar, id, rs, result);
|
||||
}
|
||||
bool SendSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *result) {
|
||||
return Base::SendSet(objId.serialize(), receiverVar, id, value, rs, result);
|
||||
}
|
||||
|
||||
bool SendIsExtensible(const ObjectId& objId, ReturnStatus* rs,
|
||||
bool* result) {
|
||||
bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result) {
|
||||
return Base::SendIsExtensible(objId.serialize(), rs, result);
|
||||
}
|
||||
bool SendCallOrConstruct(const ObjectId& objId, const nsTArray<JSParam>& argv,
|
||||
|
||||
@@ -308,13 +308,13 @@ WrapperAnswer::RecvGet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::RecvSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
WrapperAnswer::RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &idVar, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *resultValue)
|
||||
{
|
||||
// We may run scripted setters.
|
||||
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()));
|
||||
JSContext* cx = aes.cx();
|
||||
JSContext *cx = aes.cx();
|
||||
|
||||
// The outparam will be written to the buffer, so it must be set even if
|
||||
// the parent won't read it.
|
||||
|
||||
@@ -34,15 +34,15 @@ class WrapperAnswer : public virtual JavaScriptShared
|
||||
ReturnStatus* rs, bool* bp);
|
||||
bool RecvHasOwn(const ObjectId& objId, const JSIDVariant& id,
|
||||
ReturnStatus* rs, bool* bp);
|
||||
bool RecvGet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id,
|
||||
ReturnStatus* rs, JSVariant* result);
|
||||
bool RecvSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
bool RecvGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result);
|
||||
bool RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *result);
|
||||
|
||||
bool RecvIsExtensible(const ObjectId& objId, ReturnStatus* rs,
|
||||
bool* result);
|
||||
bool RecvIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result);
|
||||
bool RecvCallOrConstruct(const ObjectId& objId, InfallibleTArray<JSParam>&& argv,
|
||||
const bool& construct, ReturnStatus* rs, JSVariant* result,
|
||||
nsTArray<JSParam>* outparams);
|
||||
|
||||
+11
-11
@@ -94,10 +94,10 @@ class CPOWProxyHandler : public BaseProxyHandler
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const override;
|
||||
@@ -110,11 +110,11 @@ class CPOWProxyHandler : public BaseProxyHandler
|
||||
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override;
|
||||
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
@@ -212,8 +212,8 @@ WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, Handle
|
||||
}
|
||||
|
||||
bool
|
||||
CPOWProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
CPOWProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
FORWARD(defineProperty, (cx, proxy, id, desc, result));
|
||||
@@ -221,7 +221,7 @@ CPOWProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
|
||||
bool
|
||||
WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
ObjectId objId = idOf(proxy);
|
||||
@@ -517,14 +517,14 @@ WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
}
|
||||
|
||||
bool
|
||||
CPOWProxyHandler::set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result) const
|
||||
{
|
||||
FORWARD(set, (cx, proxy, receiver, id, vp, result));
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperOwner::set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result)
|
||||
{
|
||||
ObjectId objId = idOf(proxy);
|
||||
|
||||
+12
-12
@@ -29,10 +29,10 @@ class WrapperOwner : public virtual JavaScriptShared
|
||||
|
||||
// Standard internal methods.
|
||||
// (The traps should be in the same order like js/Proxy.h)
|
||||
bool getOwnPropertyDescriptor(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
bool getOwnPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result);
|
||||
bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
|
||||
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
@@ -42,9 +42,9 @@ class WrapperOwner : public virtual JavaScriptShared
|
||||
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
|
||||
bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp);
|
||||
bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
bool callOrConstruct(JSContext* cx, JS::HandleObject proxy, const JS::CallArgs& args,
|
||||
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args,
|
||||
bool construct);
|
||||
|
||||
// SpiderMonkey extensions.
|
||||
@@ -125,15 +125,15 @@ class WrapperOwner : public virtual JavaScriptShared
|
||||
ReturnStatus* rs, bool* bp) = 0;
|
||||
virtual bool SendHasOwn(const ObjectId& objId, const JSIDVariant& id,
|
||||
ReturnStatus* rs, bool* bp) = 0;
|
||||
virtual bool SendGet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id,
|
||||
ReturnStatus* rs, JSVariant* result) = 0;
|
||||
virtual bool SendSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
virtual bool SendGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id,
|
||||
ReturnStatus *rs, JSVariant *result) = 0;
|
||||
virtual bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const JSVariant &value,
|
||||
ReturnStatus *rs, JSVariant *result) = 0;
|
||||
|
||||
virtual bool SendIsExtensible(const ObjectId& objId, ReturnStatus* rs,
|
||||
bool* result) = 0;
|
||||
virtual bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result) = 0;
|
||||
virtual bool SendCallOrConstruct(const ObjectId& objId, const nsTArray<JSParam>& argv,
|
||||
const bool& construct, ReturnStatus* rs, JSVariant* result,
|
||||
nsTArray<JSParam>* outparams) = 0;
|
||||
|
||||
+4
-4
@@ -333,16 +333,16 @@ typedef bool
|
||||
(* LookupPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
|
||||
typedef bool
|
||||
(* DefinePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
(* DefinePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result);
|
||||
typedef bool
|
||||
(* HasPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
|
||||
typedef bool
|
||||
(* GetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
(* GetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue vp);
|
||||
typedef bool
|
||||
(* SetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
(* SetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
typedef bool
|
||||
(* GetOwnPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
|
||||
+17
-16
@@ -18,6 +18,7 @@ namespace js {
|
||||
|
||||
using JS::AutoIdVector;
|
||||
using JS::CallArgs;
|
||||
using JS::Handle;
|
||||
using JS::HandleId;
|
||||
using JS::HandleObject;
|
||||
using JS::HandleValue;
|
||||
@@ -249,13 +250,13 @@ class JS_FRIEND_API(BaseProxyHandler)
|
||||
bool* bp) const;
|
||||
|
||||
/* Standard internal methods. */
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const = 0;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const = 0;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const = 0;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const = 0;
|
||||
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
ObjectOpResult &result) const = 0;
|
||||
/*
|
||||
@@ -290,10 +291,10 @@ class JS_FRIEND_API(BaseProxyHandler)
|
||||
* The base-class implementations work by calling getPropertyDescriptor().
|
||||
* They do not follow any standard. When in doubt, override them.
|
||||
*/
|
||||
virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const;
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const;
|
||||
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp) const;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const;
|
||||
|
||||
/*
|
||||
@@ -370,13 +371,13 @@ class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler
|
||||
{ }
|
||||
|
||||
/* Standard internal methods. */
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const override;
|
||||
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool enumerate(JSContext *cx, HandleObject proxy,
|
||||
@@ -394,11 +395,11 @@ class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler
|
||||
bool *bp) const override;
|
||||
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
|
||||
/* SpiderMonkey extensions. */
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
|
||||
@@ -9407,9 +9407,6 @@ EstablishPreconditions(ExclusiveContext* cx, AsmJSParser& parser)
|
||||
if (!parser.options().asmJSOption)
|
||||
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by javascript.options.asmjs in about:config");
|
||||
|
||||
if (!parser.options().compileAndGo)
|
||||
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Temporarily disabled for event-handler and other cloneable scripts");
|
||||
|
||||
if (cx->compartment()->debuggerObservesAsmJS())
|
||||
return Warn(parser, JSMSG_USE_ASM_TYPE_FAIL, "Disabled by debugger");
|
||||
|
||||
|
||||
@@ -1751,8 +1751,8 @@ ReportPropertyError(JSContext* cx,
|
||||
}
|
||||
|
||||
bool
|
||||
TypedObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
TypedObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<TypedObject *> typedObj(cx, &obj->as<TypedObject>());
|
||||
@@ -1904,10 +1904,10 @@ TypedObject::obj_getArrayElement(JSContext* cx,
|
||||
}
|
||||
|
||||
bool
|
||||
TypedObject::obj_setProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
|
||||
Rooted<TypedObject *> typedObj(cx, &obj->as<TypedObject>());
|
||||
|
||||
switch (typedObj->typeDescr().kind()) {
|
||||
case type::Scalar:
|
||||
|
||||
@@ -528,8 +528,8 @@ class TypedObject : public JSObject
|
||||
static bool obj_lookupElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext *cx, HandleObject obj, HandleId id, bool *foundp);
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// |jit-test| error:Error
|
||||
|
||||
if (!isAsmJSCompilationAvailable()) {
|
||||
throw new Error('this test expects an error to be thrown, here it is');
|
||||
quit();
|
||||
}
|
||||
|
||||
var g = newGlobal();
|
||||
evaluate("function h() { function f() { 'use asm'; function g() { return 42 } return g } return f }", { compileAndGo:false, global:g});
|
||||
var h = clone(g.h);
|
||||
|
||||
@@ -798,7 +798,7 @@ BaselineCompiler::emitDebugTrap()
|
||||
bool
|
||||
BaselineCompiler::emitTraceLoggerEnter()
|
||||
{
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime());
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
Register loggerReg = regs.takeGeneral();
|
||||
Register scriptReg = regs.takeGeneral();
|
||||
@@ -832,7 +832,7 @@ BaselineCompiler::emitTraceLoggerEnter()
|
||||
bool
|
||||
BaselineCompiler::emitTraceLoggerExit()
|
||||
{
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
TraceLoggerThread *logger = TraceLoggerForMainThread(cx->runtime());
|
||||
Register loggerReg = RegisterSet::Volatile().takeGeneral();
|
||||
|
||||
Label noTraceLogger;
|
||||
|
||||
+30
-30
@@ -734,7 +734,7 @@ ICStubCompiler::leaveStubFrame(MacroAssembler& masm, bool calledIntoIon)
|
||||
}
|
||||
|
||||
inline bool
|
||||
ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler& masm, Register obj, ValueOperand val,
|
||||
ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val,
|
||||
Register scratch, GeneralRegisterSet saveRegs)
|
||||
{
|
||||
Label skipBarrier;
|
||||
@@ -3187,13 +3187,13 @@ GetDOMProxyProto(JSObject* obj)
|
||||
// Callers are expected to have already guarded on the shape of the
|
||||
// object, which guarantees the object is a DOM proxy.
|
||||
static void
|
||||
CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, Register object,
|
||||
const Address& checkExpandoShapeAddr,
|
||||
Address* expandoAndGenerationAddr,
|
||||
Address* generationAddr,
|
||||
CheckDOMProxyExpandoDoesNotShadow(JSContext *cx, MacroAssembler &masm, Register object,
|
||||
const Address &checkExpandoShapeAddr,
|
||||
Address *expandoAndGenerationAddr,
|
||||
Address *generationAddr,
|
||||
Register scratch,
|
||||
GeneralRegisterSet& domProxyRegSet,
|
||||
Label* checkFailed)
|
||||
GeneralRegisterSet &domProxyRegSet,
|
||||
Label *checkFailed)
|
||||
{
|
||||
// Guard that the object does not have expando properties, or has an expando
|
||||
// which is known to not have the desired property.
|
||||
@@ -4146,7 +4146,7 @@ typedef bool (*DoAtomizeStringFn)(JSContext*, HandleString, MutableHandleValue);
|
||||
static const VMFunction DoAtomizeStringInfo = FunctionInfo<DoAtomizeStringFn>(DoAtomizeString);
|
||||
|
||||
bool
|
||||
ICGetElemNativeCompiler::emitCallNative(MacroAssembler& masm, Register objReg)
|
||||
ICGetElemNativeCompiler::emitCallNative(MacroAssembler &masm, Register objReg)
|
||||
{
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
regs.takeUnchecked(objReg);
|
||||
@@ -4173,7 +4173,7 @@ ICGetElemNativeCompiler::emitCallNative(MacroAssembler& masm, Register objReg)
|
||||
}
|
||||
|
||||
bool
|
||||
ICGetElemNativeCompiler::emitCallScripted(MacroAssembler& masm, Register objReg)
|
||||
ICGetElemNativeCompiler::emitCallScripted(MacroAssembler &masm, Register objReg)
|
||||
{
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
regs.takeUnchecked(objReg);
|
||||
@@ -4240,7 +4240,7 @@ ICGetElemNativeCompiler::emitCallScripted(MacroAssembler& masm, Register objReg)
|
||||
}
|
||||
|
||||
bool
|
||||
ICGetElemNativeCompiler::generateStubCode(MacroAssembler& masm)
|
||||
ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
Label failurePopR1;
|
||||
@@ -7926,7 +7926,7 @@ typedef bool (*DoGetPropGenericFn)(JSContext*, BaselineFrame*, ICGetProp_Generic
|
||||
static const VMFunction DoGetPropGenericInfo = FunctionInfo<DoGetPropGenericFn>(DoGetPropGeneric);
|
||||
|
||||
bool
|
||||
ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
GeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
|
||||
@@ -7953,7 +7953,7 @@ ICGetProp_Generic::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
@@ -7986,7 +7986,7 @@ ICGetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICGetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICGetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
@@ -8858,7 +8858,7 @@ ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
|
||||
@@ -8980,7 +8980,7 @@ ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICSetProp_CallScripted::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
Label failureUnstow;
|
||||
@@ -9100,7 +9100,7 @@ static const VMFunction DoCallNativeSetterInfo =
|
||||
FunctionInfo<DoCallNativeSetterFn>(DoCallNativeSetter);
|
||||
|
||||
bool
|
||||
ICSetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICSetProp_CallNative::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
Label failureUnstow;
|
||||
@@ -9830,7 +9830,7 @@ DoSpreadCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_
|
||||
}
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushCallArguments(MacroAssembler& masm, GeneralRegisterSet regs,
|
||||
ICCallStubCompiler::pushCallArguments(MacroAssembler &masm, GeneralRegisterSet regs,
|
||||
Register argcReg, bool isJitCall)
|
||||
{
|
||||
MOZ_ASSERT(!regs.has(argcReg));
|
||||
@@ -9883,7 +9883,7 @@ ICCallStubCompiler::guardSpreadCall(MacroAssembler& masm, Register argcReg, Labe
|
||||
}
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler& masm, GeneralRegisterSet regs,
|
||||
ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, GeneralRegisterSet regs,
|
||||
Register argcReg, bool isJitCall)
|
||||
{
|
||||
// Push arguments
|
||||
@@ -9920,8 +9920,8 @@ ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler& masm, GeneralRegiste
|
||||
}
|
||||
|
||||
Register
|
||||
ICCallStubCompiler::guardFunApply(MacroAssembler& masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool checkNative, FunApplyThing applyThing, Label* failure)
|
||||
ICCallStubCompiler::guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool checkNative, FunApplyThing applyThing, Label *failure)
|
||||
{
|
||||
// Ensure argc == 2
|
||||
masm.branch32(Assembler::NotEqual, argcReg, Imm32(2), failure);
|
||||
@@ -10040,7 +10040,7 @@ ICCallStubCompiler::guardFunApply(MacroAssembler& masm, GeneralRegisterSet regs,
|
||||
}
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushCallerArguments(MacroAssembler& masm, GeneralRegisterSet regs)
|
||||
ICCallStubCompiler::pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet regs)
|
||||
{
|
||||
// Initialize copyReg to point to start caller arguments vector.
|
||||
// Initialize argcReg to poitn to the end of it.
|
||||
@@ -10065,7 +10065,7 @@ ICCallStubCompiler::pushCallerArguments(MacroAssembler& masm, GeneralRegisterSet
|
||||
}
|
||||
|
||||
void
|
||||
ICCallStubCompiler::pushArrayArguments(MacroAssembler& masm, Address arrayVal,
|
||||
ICCallStubCompiler::pushArrayArguments(MacroAssembler &masm, Address arrayVal,
|
||||
GeneralRegisterSet regs)
|
||||
{
|
||||
// Load start and end address of values to copy.
|
||||
@@ -10101,7 +10101,7 @@ static const VMFunction DoSpreadCallFallbackInfo =
|
||||
FunctionInfo<DoSpreadCallFallbackFn>(DoSpreadCallFallback);
|
||||
|
||||
bool
|
||||
ICCall_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCall_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
MOZ_ASSERT(R0 == JSReturnOperand);
|
||||
|
||||
@@ -10215,7 +10215,7 @@ typedef bool (*CreateThisFn)(JSContext* cx, HandleObject callee, MutableHandleVa
|
||||
static const VMFunction CreateThisInfoBaseline = FunctionInfo<CreateThisFn>(CreateThis);
|
||||
|
||||
bool
|
||||
ICCallScriptedCompiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
@@ -10480,7 +10480,7 @@ typedef bool (*CopyArrayFn)(JSContext*, HandleArrayObject, MutableHandleValue);
|
||||
static const VMFunction CopyArrayInfo = FunctionInfo<CopyArrayFn>(CopyArray);
|
||||
|
||||
bool
|
||||
ICCall_StringSplit::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCall_StringSplit::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
// Stack Layout: [ ..., CalleeVal, ThisVal, Arg0Val, +ICStackValueOffset+ ]
|
||||
GeneralRegisterSet regs = availableGeneralRegs(0);
|
||||
@@ -10571,7 +10571,7 @@ ICCall_StringSplit::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
// The IsSuspendedStarGenerator intrinsic is only called in self-hosted
|
||||
// code, so it's safe to assume we have a single argument and the callee
|
||||
@@ -10613,7 +10613,7 @@ ICCall_IsSuspendedStarGenerator::Compiler::generateStubCode(MacroAssembler& masm
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCall_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
@@ -10717,7 +10717,7 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
@@ -10804,7 +10804,7 @@ ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
@@ -10906,7 +10906,7 @@ ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_ScriptedApplyArguments::Compiler::generateStubCode(MacroAssembler& masm)
|
||||
ICCall_ScriptedApplyArguments::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
+10
-10
@@ -1125,7 +1125,7 @@ class ICStubCompiler
|
||||
// Some stubs need to emit SPS profiler updates. This emits the guarding
|
||||
// jitcode for those stubs. If profiling is not enabled, jumps to the
|
||||
// given label.
|
||||
void guardProfilingEnabled(MacroAssembler& masm, Register scratch, Label* skip);
|
||||
void guardProfilingEnabled(MacroAssembler &masm, Register scratch, Label *skip);
|
||||
|
||||
inline GeneralRegisterSet availableGeneralRegs(size_t numInputs) const {
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
@@ -1161,11 +1161,11 @@ class ICStubCompiler
|
||||
return regs;
|
||||
}
|
||||
|
||||
inline bool emitPostWriteBarrierSlot(MacroAssembler& masm, Register obj, ValueOperand val,
|
||||
inline bool emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, ValueOperand val,
|
||||
Register scratch, GeneralRegisterSet saveRegs);
|
||||
|
||||
public:
|
||||
virtual ICStub* getStub(ICStubSpace* space) = 0;
|
||||
virtual ICStub *getStub(ICStubSpace *space) = 0;
|
||||
|
||||
static ICStubSpace* StubSpaceForKind(ICStub::Kind kind, JSScript* script) {
|
||||
if (ICStub::CanMakeCalls(kind))
|
||||
@@ -5259,15 +5259,15 @@ class ICCallStubCompiler : public ICStubCompiler
|
||||
FunApply_Array
|
||||
};
|
||||
|
||||
void pushCallArguments(MacroAssembler& masm, GeneralRegisterSet regs, Register argcReg,
|
||||
void pushCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool isJitCall);
|
||||
void pushSpreadCallArguments(MacroAssembler& masm, GeneralRegisterSet regs, Register argcReg,
|
||||
void pushSpreadCallArguments(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool isJitCall);
|
||||
void guardSpreadCall(MacroAssembler& masm, Register argcReg, Label* failure);
|
||||
Register guardFunApply(MacroAssembler& masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool checkNative, FunApplyThing applyThing, Label* failure);
|
||||
void pushCallerArguments(MacroAssembler& masm, GeneralRegisterSet regs);
|
||||
void pushArrayArguments(MacroAssembler& masm, Address arrayVal, GeneralRegisterSet regs);
|
||||
void guardSpreadCall(MacroAssembler &masm, Register argcReg, Label *failure);
|
||||
Register guardFunApply(MacroAssembler &masm, GeneralRegisterSet regs, Register argcReg,
|
||||
bool checkNative, FunApplyThing applyThing, Label *failure);
|
||||
void pushCallerArguments(MacroAssembler &masm, GeneralRegisterSet regs);
|
||||
void pushArrayArguments(MacroAssembler &masm, Address arrayVal, GeneralRegisterSet regs);
|
||||
};
|
||||
|
||||
class ICCall_Fallback : public ICMonitoredFallbackStub
|
||||
|
||||
@@ -3135,11 +3135,10 @@ CodeGenerator::emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSp
|
||||
masm.movePtr(argcreg, extraStackSpace);
|
||||
|
||||
// Align the JitFrameLayout on the JitStackAlignment.
|
||||
const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
if (alignment > 1) {
|
||||
if (JitStackValueAlignment > 1) {
|
||||
MOZ_ASSERT(frameSize() % JitStackAlignment == 0,
|
||||
"Stack padding assumes that the frameSize is correct");
|
||||
MOZ_ASSERT(alignment == 2);
|
||||
MOZ_ASSERT(JitStackValueAlignment == 2);
|
||||
Label noPaddingNeeded;
|
||||
// if the number of arguments is odd, then we do not need any padding.
|
||||
masm.branchTestPtr(Assembler::NonZero, argcreg, Imm32(1), &noPaddingNeeded);
|
||||
@@ -3156,8 +3155,8 @@ CodeGenerator::emitPushArguments(LApplyArgsGeneric* apply, Register extraStackSp
|
||||
// Put a magic value in the space reserved for padding. Note, this code
|
||||
// cannot be merged with the previous test, as not all architectures can
|
||||
// write below their stack pointers.
|
||||
if (alignment > 1) {
|
||||
MOZ_ASSERT(alignment == 2);
|
||||
if (JitStackValueAlignment > 1) {
|
||||
MOZ_ASSERT(JitStackValueAlignment == 2);
|
||||
Label noPaddingNeeded;
|
||||
// if the number of arguments is odd, then we do not need any padding.
|
||||
masm.branchTestPtr(Assembler::NonZero, argcreg, Imm32(1), &noPaddingNeeded);
|
||||
@@ -6061,7 +6060,7 @@ JitRuntime::generateMallocStub(JSContext* cx)
|
||||
masm.movePtr(ImmPtr(cx->runtime()), regRuntime);
|
||||
masm.passABIArg(regRuntime);
|
||||
masm.passABIArg(regNBytes);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, MallocWrapper));
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, MallocWrapper));
|
||||
masm.storeCallResult(regReturn);
|
||||
|
||||
masm.PopRegsInMask(regs);
|
||||
@@ -6097,7 +6096,7 @@ JitRuntime::generateFreeStub(JSContext* cx)
|
||||
|
||||
masm.setupUnalignedABICall(1, regTemp);
|
||||
masm.passABIArg(regSlots);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js_free));
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js_free));
|
||||
|
||||
masm.PopRegsInMask(regs);
|
||||
|
||||
@@ -6778,7 +6777,7 @@ CodeGenerator::emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, R
|
||||
saveVolatile(temps);
|
||||
masm.setupUnalignedABICall(1, lengthTemp);
|
||||
masm.passABIArg(obj);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, js::ArrayShiftMoveElements));
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ArrayShiftMoveElements));
|
||||
restoreVolatile(temps);
|
||||
}
|
||||
|
||||
@@ -7848,7 +7847,7 @@ CodeGenerator::visitStoreFixedSlotT(LStoreFixedSlotT* ins)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGetNameCache(LGetNameCache* ins)
|
||||
CodeGenerator::visitGetNameCache(LGetNameCache *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register scopeChain = ToRegister(ins->scopeObj());
|
||||
@@ -7880,9 +7879,9 @@ CodeGenerator::visitNameIC(OutOfLineUpdateCache* ool, DataPtr<NameIC>& ic)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::addGetPropertyCache(LInstruction* ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName* name, TypedOrValueRegister output,
|
||||
bool monitoredResult, jsbytecode* profilerLeavePc)
|
||||
CodeGenerator::addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool monitoredResult, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
GetPropertyIC cache(liveRegs, objReg, name, output, monitoredResult);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
@@ -7890,9 +7889,9 @@ CodeGenerator::addGetPropertyCache(LInstruction* ins, RegisterSet liveRegs, Regi
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::addSetPropertyCache(LInstruction* ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName* name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier, jsbytecode* profilerLeavePc)
|
||||
CodeGenerator::addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier, jsbytecode *profilerLeavePc)
|
||||
{
|
||||
SetPropertyIC cache(liveRegs, objReg, name, value, strict, needsTypeBarrier);
|
||||
cache.setProfilerLeavePC(profilerLeavePc);
|
||||
@@ -7913,7 +7912,7 @@ CodeGenerator::addSetElementCache(LInstruction* ins, Register obj, Register unbo
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV* ins)
|
||||
CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
@@ -7926,7 +7925,7 @@ CodeGenerator::visitGetPropertyCacheV(LGetPropertyCacheV* ins)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGetPropertyCacheT(LGetPropertyCacheT* ins)
|
||||
CodeGenerator::visitGetPropertyCacheT(LGetPropertyCacheT *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
@@ -8170,7 +8169,7 @@ CodeGenerator::visitCallDeleteElement(LCallDeleteElement* lir)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV* ins)
|
||||
CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
@@ -8182,7 +8181,7 @@ CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV* ins)
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT* ins)
|
||||
CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins)
|
||||
{
|
||||
RegisterSet liveRegs = ins->safepoint()->liveRegs();
|
||||
Register objReg = ToRegister(ins->getOperand(0));
|
||||
|
||||
@@ -370,19 +370,19 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
}
|
||||
|
||||
private:
|
||||
void addGetPropertyCache(LInstruction* ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName* name, TypedOrValueRegister output,
|
||||
bool monitoredResult, jsbytecode* profilerLeavePc);
|
||||
void addGetElementCache(LInstruction* ins, Register obj, ConstantOrRegister index,
|
||||
void addGetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, TypedOrValueRegister output,
|
||||
bool monitoredResult, jsbytecode *profilerLeavePc);
|
||||
void addGetElementCache(LInstruction *ins, Register obj, ConstantOrRegister index,
|
||||
TypedOrValueRegister output, bool monitoredResult,
|
||||
bool allowDoubleResult, jsbytecode* profilerLeavePc);
|
||||
void addSetPropertyCache(LInstruction* ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName* name, ConstantOrRegister value, bool strict,
|
||||
bool allowDoubleResult, jsbytecode *profilerLeavePc);
|
||||
void addSetPropertyCache(LInstruction *ins, RegisterSet liveRegs, Register objReg,
|
||||
PropertyName *name, ConstantOrRegister value, bool strict,
|
||||
bool needsTypeBarrier, jsbytecode* profilerLeavePc);
|
||||
void addSetElementCache(LInstruction* ins, Register obj, Register unboxIndex, Register temp,
|
||||
void addSetElementCache(LInstruction *ins, Register obj, Register unboxIndex, Register temp,
|
||||
FloatRegister tempDouble, FloatRegister tempFloat32,
|
||||
ValueOperand index, ConstantOrRegister value,
|
||||
bool strict, bool guardHoles, jsbytecode* profilerLeavePc);
|
||||
bool strict, bool guardHoles, jsbytecode *profilerLeavePc);
|
||||
|
||||
bool generateBranchV(const ValueOperand& value, Label* ifTrue, Label* ifFalse, FloatRegister fr);
|
||||
|
||||
|
||||
+43
-43
@@ -960,12 +960,12 @@ GenerateReadUnboxed(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitGetterCall(JSContext* cx, MacroAssembler& masm,
|
||||
IonCache::StubAttacher& attacher, JSObject* obj,
|
||||
JSObject* holder, HandleShape shape,
|
||||
EmitGetterCall(JSContext *cx, MacroAssembler &masm,
|
||||
IonCache::StubAttacher &attacher, JSObject *obj,
|
||||
JSObject *holder, HandleShape shape,
|
||||
RegisterSet liveRegs, Register object,
|
||||
TypedOrValueRegister output,
|
||||
void* returnAddr)
|
||||
void *returnAddr)
|
||||
{
|
||||
MOZ_ASSERT(output.hasValue());
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
@@ -987,7 +987,7 @@ EmitGetterCall(JSContext* cx, MacroAssembler& masm,
|
||||
Register argUintNReg = regSet.takeGeneral();
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
|
||||
JSFunction* target = &shape->getterValue().toObject().as<JSFunction>();
|
||||
JSFunction *target = &shape->getterValue().toObject().as<JSFunction>();
|
||||
MOZ_ASSERT(target);
|
||||
MOZ_ASSERT(target->isNative());
|
||||
|
||||
@@ -1525,9 +1525,9 @@ PushObjectOpResult(MacroAssembler &masm)
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitCallProxyGet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher,
|
||||
PropertyName* name, RegisterSet liveRegs, Register object,
|
||||
TypedOrValueRegister output, jsbytecode* pc, void* returnAddr)
|
||||
EmitCallProxyGet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
|
||||
PropertyName *name, RegisterSet liveRegs, Register object,
|
||||
TypedOrValueRegister output, jsbytecode *pc, void *returnAddr)
|
||||
{
|
||||
MOZ_ASSERT(output.hasValue());
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
@@ -1537,7 +1537,7 @@ EmitCallProxyGet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
|
||||
// Proxy::get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// MutableHandleValue vp)
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argProxyReg = regSet.takeGeneral();
|
||||
@@ -1546,9 +1546,9 @@ EmitCallProxyGet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
|
||||
Register scratch = regSet.takeGeneral();
|
||||
|
||||
void* getFunction = JSOp(*pc) == JSOP_CALLPROP ?
|
||||
JS_FUNC_TO_DATA_PTR(void*, Proxy::callProp) :
|
||||
JS_FUNC_TO_DATA_PTR(void*, Proxy::get);
|
||||
void *getFunction = JSOp(*pc) == JSOP_CALLPROP ?
|
||||
JS_FUNC_TO_DATA_PTR(void *, Proxy::callProp) :
|
||||
JS_FUNC_TO_DATA_PTR(void *, Proxy::get);
|
||||
|
||||
// Push stubCode for marking.
|
||||
attacher.pushStubCodePointer(masm);
|
||||
@@ -1567,9 +1567,6 @@ EmitCallProxyGet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
masm.Push(object);
|
||||
masm.movePtr(StackPointer, argProxyReg);
|
||||
|
||||
// Unused space, to keep the same stack layout as Proxy::set frames.
|
||||
PushObjectOpResult(masm);
|
||||
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
@@ -2235,9 +2232,18 @@ EmitObjectOpResultCheck(MacroAssembler &masm, Label *failure, bool strict,
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher,
|
||||
ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
|
||||
bool strict)
|
||||
{
|
||||
ObjectOpResult result;
|
||||
return Proxy::set(cx, proxy, proxy, id, vp, result)
|
||||
&& result.checkStrictErrorOrWarning(cx, proxy, id, strict);
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &attacher,
|
||||
HandleId propId, RegisterSet liveRegs, Register object,
|
||||
ConstantOrRegister value, void* returnAddr, bool strict)
|
||||
ConstantOrRegister value, void *returnAddr, bool strict)
|
||||
{
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
|
||||
@@ -2251,23 +2257,26 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
|
||||
// Proxy::set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// MutableHandleValue vp, ObjectOpResult &result)
|
||||
// ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
|
||||
// bool strict);
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argProxyReg = regSet.takeGeneral();
|
||||
Register argIdReg = regSet.takeGeneral();
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
Register argResultReg = regSet.takeGeneral();
|
||||
Register argStrictReg = regSet.takeGeneral();
|
||||
|
||||
Register scratch = regSet.takeGeneral();
|
||||
|
||||
// Push stubCode for marking.
|
||||
attacher.pushStubCodePointer(masm);
|
||||
|
||||
// Push args on stack first so we can take pointers to make handles.
|
||||
// Push args on stack so we can take pointers to make handles.
|
||||
// Push value before touching any other registers (see WARNING above).
|
||||
masm.Push(value);
|
||||
masm.movePtr(StackPointer, argVpReg);
|
||||
|
||||
masm.move32(Imm32(strict), argStrictReg);
|
||||
|
||||
masm.Push(propId, scratch);
|
||||
masm.movePtr(StackPointer, argIdReg);
|
||||
|
||||
@@ -2277,10 +2286,6 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
masm.Push(object);
|
||||
masm.movePtr(StackPointer, argProxyReg);
|
||||
|
||||
// Allocate result out-param.
|
||||
PushObjectOpResult(masm);
|
||||
masm.movePtr(StackPointer, argResultReg);
|
||||
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
@@ -2288,24 +2293,17 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
masm.enterFakeExitFrame(IonOOLProxyExitFrameLayout::Token());
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(6, scratch);
|
||||
masm.setupUnalignedABICall(5, scratch);
|
||||
masm.passABIArg(argJSContextReg);
|
||||
masm.passABIArg(argProxyReg);
|
||||
masm.passABIArg(argProxyReg);
|
||||
masm.passABIArg(argIdReg);
|
||||
masm.passABIArg(argVpReg);
|
||||
masm.passABIArg(argResultReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Proxy::set));
|
||||
masm.passABIArg(argStrictReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ProxySetProperty));
|
||||
|
||||
// Test for error.
|
||||
masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
|
||||
|
||||
// Test for strict failure. We emit the check even in non-strict mode in
|
||||
// order to pick up the warning if extraWarnings is enabled.
|
||||
EmitObjectOpResultCheck<IonOOLProxyExitFrameLayout>(masm, masm.exceptionLabel(), strict,
|
||||
scratch, argJSContextReg, argProxyReg,
|
||||
argIdReg, argVpReg, argResultReg);
|
||||
|
||||
// masm.leaveExitFrame & pop locals
|
||||
masm.adjustStack(IonOOLProxyExitFrameLayout::Size());
|
||||
|
||||
@@ -2406,11 +2404,11 @@ SetPropertyIC::attachDOMProxyShadowed(JSContext* cx, HandleScript outerScript, I
|
||||
}
|
||||
|
||||
static bool
|
||||
GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
||||
IonCache::StubAttacher& attacher, HandleObject obj,
|
||||
GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler& masm,
|
||||
IonCache::StubAttacher &attacher, HandleObject obj,
|
||||
HandleObject holder, HandleShape shape, bool strict, Register object,
|
||||
ConstantOrRegister value, Label* failure, RegisterSet liveRegs,
|
||||
void* returnAddr)
|
||||
ConstantOrRegister value, Label *failure, RegisterSet liveRegs,
|
||||
void *returnAddr)
|
||||
{
|
||||
// Generate prototype guards if needed.
|
||||
// Take a scratch register for use, save on stack.
|
||||
@@ -2522,8 +2520,9 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
||||
|
||||
SetterOp target = shape->setterOp();
|
||||
MOZ_ASSERT(target);
|
||||
|
||||
// JSSetterOp: bool fn(JSContext *cx, HandleObject obj,
|
||||
// HandleId id, bool strict, MutableHandleValue vp);
|
||||
// HandleId id, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
// First, allocate an ObjectOpResult on the stack. We push this before
|
||||
// the stubCode pointer in order to match the layout of
|
||||
@@ -2570,12 +2569,13 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
||||
masm.passABIArg(argIdReg);
|
||||
masm.passABIArg(argVpReg);
|
||||
masm.passABIArg(argResultReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, target));
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target));
|
||||
|
||||
// Test for error.
|
||||
masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
|
||||
|
||||
// Test for failure.
|
||||
// Test for strict failure. We emit the check even in non-strict mode
|
||||
// in order to pick up the warning if extraWarnings is enabled.
|
||||
EmitObjectOpResultCheck<IonOOLSetterOpExitFrameLayout>(masm, masm.exceptionLabel(),
|
||||
strict, scratchReg,
|
||||
argJSContextReg, argObjReg,
|
||||
@@ -3758,7 +3758,7 @@ GenerateGetTypedArrayElement(JSContext* cx, MacroAssembler& masm, IonCache::Stub
|
||||
|
||||
masm.setupUnalignedABICall(1, temp);
|
||||
masm.passABIArg(str);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, GetIndexFromString));
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, GetIndexFromString));
|
||||
masm.mov(ReturnReg, indexReg);
|
||||
|
||||
RegisterSet ignore = RegisterSet();
|
||||
|
||||
@@ -547,7 +547,7 @@ class GetPropertyIC : public RepatchIonCache
|
||||
RegisterSet liveRegs_;
|
||||
|
||||
Register object_;
|
||||
PropertyName* name_;
|
||||
PropertyName *name_;
|
||||
TypedOrValueRegister output_;
|
||||
|
||||
// Only valid if idempotent
|
||||
@@ -563,7 +563,7 @@ class GetPropertyIC : public RepatchIonCache
|
||||
|
||||
public:
|
||||
GetPropertyIC(RegisterSet liveRegs,
|
||||
Register object, PropertyName* name,
|
||||
Register object, PropertyName *name,
|
||||
TypedOrValueRegister output,
|
||||
bool monitoredResult)
|
||||
: liveRegs_(liveRegs),
|
||||
@@ -692,7 +692,7 @@ class SetPropertyIC : public RepatchIonCache
|
||||
RegisterSet liveRegs_;
|
||||
|
||||
Register object_;
|
||||
PropertyName* name_;
|
||||
PropertyName *name_;
|
||||
ConstantOrRegister value_;
|
||||
bool strict_;
|
||||
bool needsTypeBarrier_;
|
||||
@@ -700,7 +700,7 @@ class SetPropertyIC : public RepatchIonCache
|
||||
bool hasGenericProxyStub_;
|
||||
|
||||
public:
|
||||
SetPropertyIC(RegisterSet liveRegs, Register object, PropertyName* name,
|
||||
SetPropertyIC(RegisterSet liveRegs, Register object, PropertyName *name,
|
||||
ConstantOrRegister value, bool strict, bool needsTypeBarrier)
|
||||
: liveRegs_(liveRegs),
|
||||
object_(object),
|
||||
@@ -1012,12 +1012,12 @@ class NameIC : public RepatchIonCache
|
||||
|
||||
bool typeOf_;
|
||||
Register scopeChain_;
|
||||
PropertyName* name_;
|
||||
PropertyName *name_;
|
||||
TypedOrValueRegister output_;
|
||||
|
||||
public:
|
||||
NameIC(RegisterSet liveRegs, bool typeOf,
|
||||
Register scopeChain, PropertyName* name,
|
||||
Register scopeChain, PropertyName *name,
|
||||
TypedOrValueRegister output)
|
||||
: liveRegs_(liveRegs),
|
||||
typeOf_(typeOf),
|
||||
|
||||
@@ -344,9 +344,9 @@ JitFrameIterator::machineState() const
|
||||
for (GeneralRegisterBackwardIterator iter(reader.allGprSpills()); iter.more(); iter++)
|
||||
machine.setRegisterLocation(*iter, --spill);
|
||||
|
||||
uint8_t* spillAlign = alignDoubleSpillWithOffset(reinterpret_cast<uint8_t*>(spill), 0);
|
||||
uint8_t *spillAlign = alignDoubleSpillWithOffset(reinterpret_cast<uint8_t *>(spill), 0);
|
||||
|
||||
char* floatSpill = reinterpret_cast<char*>(spillAlign);
|
||||
char *floatSpill = reinterpret_cast<char *>(spillAlign);
|
||||
FloatRegisterSet fregs = reader.allFloatSpills();
|
||||
fregs = fregs.reduceSetForPush();
|
||||
for (FloatRegisterBackwardIterator iter(fregs); iter.more(); iter++) {
|
||||
@@ -1079,7 +1079,7 @@ MarkIonJSFrame(JSTracer* trc, const JitFrameIterator& frame)
|
||||
gc::MarkValueRoot(trc, v, "ion-gc-slot");
|
||||
}
|
||||
|
||||
uintptr_t* spill = frame.spillBase();
|
||||
uintptr_t *spill = frame.spillBase();
|
||||
GeneralRegisterSet gcRegs = safepoint.gcSpills();
|
||||
GeneralRegisterSet valueRegs = safepoint.valueSpills();
|
||||
for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) {
|
||||
@@ -1164,11 +1164,11 @@ UpdateIonJSFrameForMinorGC(JSTracer* trc, const JitFrameIterator& frame)
|
||||
|
||||
Nursery& nursery = trc->runtime()->gc.nursery;
|
||||
|
||||
const SafepointIndex* si = ionScript->getSafepointIndex(frame.returnAddressToFp());
|
||||
const SafepointIndex *si = ionScript->getSafepointIndex(frame.returnAddressToFp());
|
||||
SafepointReader safepoint(ionScript, si);
|
||||
|
||||
GeneralRegisterSet slotsRegs = safepoint.slotsOrElementsSpills();
|
||||
uintptr_t* spill = frame.spillBase();
|
||||
uintptr_t *spill = frame.spillBase();
|
||||
for (GeneralRegisterBackwardIterator iter(safepoint.allGprSpills()); iter.more(); iter++) {
|
||||
--spill;
|
||||
if (slotsRegs.has(*iter))
|
||||
|
||||
+3
-18
@@ -697,19 +697,16 @@ class IonOOLSetterOpExitFrameLayout : public IonOOLPropertyOpExitFrameLayout
|
||||
}
|
||||
};
|
||||
|
||||
// Proxy::get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// Proxy::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// MutableHandleValue vp)
|
||||
// Proxy::set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// MutableHandleValue vp, ObjectOpResult &result)
|
||||
// ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
|
||||
// bool strict)
|
||||
class IonOOLProxyExitFrameLayout
|
||||
{
|
||||
protected: // only to silence a clang warning about unused private fields
|
||||
ExitFooterFrame footer_;
|
||||
ExitFrameLayout exit_;
|
||||
|
||||
// result out-parameter (unused for Proxy::get)
|
||||
JS::ObjectOpResult result_;
|
||||
|
||||
// The proxy object.
|
||||
JSObject* proxy_;
|
||||
|
||||
@@ -734,22 +731,10 @@ class IonOOLProxyExitFrameLayout
|
||||
return sizeof(IonOOLProxyExitFrameLayout);
|
||||
}
|
||||
|
||||
static size_t offsetOfObject() {
|
||||
return offsetof(IonOOLProxyExitFrameLayout, proxy_);
|
||||
}
|
||||
|
||||
static size_t offsetOfResult() {
|
||||
return offsetof(IonOOLProxyExitFrameLayout, vp0_);
|
||||
}
|
||||
|
||||
static size_t offsetOfId() {
|
||||
return offsetof(IonOOLProxyExitFrameLayout, id_);
|
||||
}
|
||||
|
||||
static size_t offsetOfObjectOpResult() {
|
||||
return offsetof(IonOOLProxyExitFrameLayout, result_);
|
||||
}
|
||||
|
||||
inline JitCode** stubCode() {
|
||||
return &stubCode_;
|
||||
}
|
||||
|
||||
@@ -1538,9 +1538,8 @@ class LJSCallInstructionHelper : public LCallInstructionHelper<Defs, Operands, T
|
||||
{
|
||||
public:
|
||||
uint32_t argslot() const {
|
||||
static const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
if (alignment > 1)
|
||||
return AlignBytes(mir()->numStackArgs(), alignment);
|
||||
if (JitStackValueAlignment > 1)
|
||||
return AlignBytes(mir()->numStackArgs(), JitStackValueAlignment);
|
||||
return mir()->numStackArgs();
|
||||
}
|
||||
MCall* mir() const {
|
||||
|
||||
+10
-9
@@ -1386,7 +1386,7 @@ class LSafepoint : public TempObject
|
||||
liveRegs_.addUnchecked(reg);
|
||||
assertInvariants();
|
||||
}
|
||||
const RegisterSet& liveRegs() const {
|
||||
const RegisterSet &liveRegs() const {
|
||||
return liveRegs_;
|
||||
}
|
||||
#ifdef CHECK_OSIPOINT_REGISTERS
|
||||
@@ -1394,7 +1394,7 @@ class LSafepoint : public TempObject
|
||||
clobberedRegs_.addUnchecked(reg);
|
||||
assertInvariants();
|
||||
}
|
||||
const RegisterSet& clobberedRegs() const {
|
||||
const RegisterSet &clobberedRegs() const {
|
||||
return clobberedRegs_;
|
||||
}
|
||||
#endif
|
||||
@@ -1411,11 +1411,11 @@ class LSafepoint : public TempObject
|
||||
assertInvariants();
|
||||
return result;
|
||||
}
|
||||
SlotList& gcSlots() {
|
||||
SlotList &gcSlots() {
|
||||
return gcSlots_;
|
||||
}
|
||||
|
||||
SlotList& slotsOrElementsSlots() {
|
||||
SlotList &slotsOrElementsSlots() {
|
||||
return slotsOrElementsSlots_;
|
||||
}
|
||||
GeneralRegisterSet slotsOrElementsRegs() const {
|
||||
@@ -1760,11 +1760,12 @@ class LIRGraph
|
||||
// platform stack alignment requirement, and so that it's a multiple of
|
||||
// the number of slots per Value.
|
||||
uint32_t paddedLocalSlotCount() const {
|
||||
// Round to ABIStackAlignment, but also round to at least sizeof(Value)
|
||||
// in case that's greater, because StackOffsetOfPassedArg rounds
|
||||
// argument slots to 8-byte boundaries.
|
||||
size_t Alignment = Max(size_t(JitStackAlignment), sizeof(Value));
|
||||
return AlignBytes(localSlotCount(), Alignment);
|
||||
// Round to JitStackAlignment, and implicitly to sizeof(Value) as
|
||||
// JitStackAlignment is a multiple of sizeof(Value). These alignments
|
||||
// are needed for spilling SIMD registers properly, and for
|
||||
// StackOffsetOfPassedArg which rounds argument slots to 8-byte
|
||||
// boundaries.
|
||||
return AlignBytes(localSlotCount(), JitStackAlignment);
|
||||
}
|
||||
size_t paddedLocalSlotsSize() const {
|
||||
return paddedLocalSlotCount();
|
||||
|
||||
@@ -393,9 +393,8 @@ LIRGenerator::lowerCallArguments(MCall* call)
|
||||
// Align the arguments of a call such that the callee would keep the same
|
||||
// alignment as the caller.
|
||||
uint32_t baseSlot = 0;
|
||||
static const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
if (alignment > 1)
|
||||
baseSlot = AlignBytes(argc, alignment);
|
||||
if (JitStackValueAlignment > 1)
|
||||
baseSlot = AlignBytes(argc, JitStackValueAlignment);
|
||||
else
|
||||
baseSlot = argc;
|
||||
|
||||
|
||||
+185
-58
@@ -1657,7 +1657,7 @@ MacroAssembler::handleFailure()
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
AssumeUnreachable_(const char* output) {
|
||||
AssumeUnreachable_(const char *output) {
|
||||
MOZ_ReportAssertionFailure(output, __FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
@@ -1674,7 +1674,7 @@ MacroAssembler::assumeUnreachable(const char* output)
|
||||
setupUnalignedABICall(1, temp);
|
||||
movePtr(ImmPtr(output), temp);
|
||||
passABIArg(temp);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void*, AssumeUnreachable_));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
@@ -1706,7 +1706,7 @@ Printf0_(const char* output) {
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::printf(const char* output)
|
||||
MacroAssembler::printf(const char *output)
|
||||
{
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
@@ -1716,7 +1716,7 @@ MacroAssembler::printf(const char* output)
|
||||
setupUnalignedABICall(1, temp);
|
||||
movePtr(ImmPtr(output), temp);
|
||||
passABIArg(temp);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void*, Printf0_));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, Printf0_));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
@@ -1729,7 +1729,7 @@ Printf1_(const char* output, uintptr_t value) {
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::printf(const char* output, Register value)
|
||||
MacroAssembler::printf(const char *output, Register value)
|
||||
{
|
||||
RegisterSet regs = RegisterSet::Volatile();
|
||||
PushRegsInMask(regs);
|
||||
@@ -1765,7 +1765,7 @@ MacroAssembler::tracelogStartId(Register logger, uint32_t textId, bool force)
|
||||
passABIArg(logger);
|
||||
move32(Imm32(textId), temp);
|
||||
passABIArg(temp);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void*, TraceLogStartEventPrivate));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
@@ -1784,7 +1784,7 @@ MacroAssembler::tracelogStartId(Register logger, Register textId)
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
passABIArg(textId);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void*, TraceLogStartEventPrivate));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStartEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
@@ -1792,7 +1792,7 @@ MacroAssembler::tracelogStartId(Register logger, Register textId)
|
||||
void
|
||||
MacroAssembler::tracelogStartEvent(Register logger, Register event)
|
||||
{
|
||||
void (&TraceLogFunc)(TraceLoggerThread*, const TraceLoggerEvent&) = TraceLogStartEvent;
|
||||
void (&TraceLogFunc)(TraceLoggerThread *, const TraceLoggerEvent &) = TraceLogStartEvent;
|
||||
|
||||
PushRegsInMask(RegisterSet::Volatile());
|
||||
|
||||
@@ -1805,7 +1805,7 @@ MacroAssembler::tracelogStartEvent(Register logger, Register event)
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
passABIArg(event);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void*, TraceLogFunc));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogFunc));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
@@ -1828,7 +1828,7 @@ MacroAssembler::tracelogStopId(Register logger, uint32_t textId, bool force)
|
||||
move32(Imm32(textId), temp);
|
||||
passABIArg(temp);
|
||||
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void*, TraceLogStopEventPrivate));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
@@ -1847,7 +1847,7 @@ MacroAssembler::tracelogStopId(Register logger, Register textId)
|
||||
setupUnalignedABICall(2, temp);
|
||||
passABIArg(logger);
|
||||
passABIArg(textId);
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void*, TraceLogStopEventPrivate));
|
||||
callWithABI(JS_FUNC_TO_DATA_PTR(void *, TraceLogStopEventPrivate));
|
||||
|
||||
PopRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
@@ -1942,48 +1942,9 @@ MacroAssembler::convertValueToFloatingPoint(JSContext* cx, const Value& v, Float
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PushEmptyRooted(VMFunction::RootType rootType)
|
||||
{
|
||||
switch (rootType) {
|
||||
case VMFunction::RootNone:
|
||||
MOZ_CRASH("Handle must have root type");
|
||||
case VMFunction::RootObject:
|
||||
case VMFunction::RootString:
|
||||
case VMFunction::RootPropertyName:
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunction::RootCell:
|
||||
Push(ImmPtr(nullptr));
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
Push(UndefinedValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::popRooted(VMFunction::RootType rootType, Register cellReg,
|
||||
const ValueOperand& valueReg)
|
||||
{
|
||||
switch (rootType) {
|
||||
case VMFunction::RootNone:
|
||||
MOZ_CRASH("Handle must have root type");
|
||||
case VMFunction::RootObject:
|
||||
case VMFunction::RootString:
|
||||
case VMFunction::RootPropertyName:
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunction::RootCell:
|
||||
Pop(cellReg);
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
Pop(valueReg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MacroAssembler::convertConstantOrRegisterToFloatingPoint(JSContext* cx, ConstantOrRegister src,
|
||||
FloatRegister output, Label* fail,
|
||||
MacroAssembler::convertConstantOrRegisterToFloatingPoint(JSContext *cx, ConstantOrRegister src,
|
||||
FloatRegister output, Label *fail,
|
||||
MIRType outputType)
|
||||
{
|
||||
if (src.constant())
|
||||
@@ -2394,8 +2355,7 @@ MacroAssembler::profilerPreCallImpl(Register reg, Register reg2)
|
||||
void
|
||||
MacroAssembler::alignJitStackBasedOnNArgs(Register nargs)
|
||||
{
|
||||
const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
if (alignment == 1)
|
||||
if (JitStackValueAlignment == 1)
|
||||
return;
|
||||
|
||||
// A JitFrameLayout is composed of the following:
|
||||
@@ -2408,7 +2368,7 @@ MacroAssembler::alignJitStackBasedOnNArgs(Register nargs)
|
||||
|
||||
// Which implies that |argN| is aligned if |nargs| is even, and offset by
|
||||
// |sizeof(Value)| if |nargs| is odd.
|
||||
MOZ_ASSERT(alignment == 2);
|
||||
MOZ_ASSERT(JitStackValueAlignment == 2);
|
||||
|
||||
// Thus the |padding| is offset by |sizeof(Value)| if |nargs| is even, and
|
||||
// aligned if |nargs| is odd.
|
||||
@@ -2443,8 +2403,7 @@ MacroAssembler::alignJitStackBasedOnNArgs(Register nargs)
|
||||
void
|
||||
MacroAssembler::alignJitStackBasedOnNArgs(uint32_t nargs)
|
||||
{
|
||||
const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
if (alignment == 1)
|
||||
if (JitStackValueAlignment == 1)
|
||||
return;
|
||||
|
||||
// A JitFrameLayout is composed of the following:
|
||||
@@ -2457,7 +2416,7 @@ MacroAssembler::alignJitStackBasedOnNArgs(uint32_t nargs)
|
||||
|
||||
// Which implies that |argN| is aligned if |nargs| is even, and offset by
|
||||
// |sizeof(Value)| if |nargs| is odd.
|
||||
MOZ_ASSERT(alignment == 2);
|
||||
MOZ_ASSERT(JitStackValueAlignment == 2);
|
||||
|
||||
// Thus the |padding| is offset by |sizeof(Value)| if |nargs| is even, and
|
||||
// aligned if |nargs| is odd.
|
||||
@@ -2473,3 +2432,171 @@ MacroAssembler::alignJitStackBasedOnNArgs(uint32_t nargs)
|
||||
andPtr(Imm32(~(JitStackAlignment - 1)), StackPointer);
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set)
|
||||
{
|
||||
PushRegsInMask(set, FloatRegisterSet());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(GeneralRegisterSet set)
|
||||
{
|
||||
PushRegsInMask(RegisterSet(set, FloatRegisterSet()));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMask(RegisterSet set)
|
||||
{
|
||||
PopRegsInMaskIgnore(set, RegisterSet());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
{
|
||||
PopRegsInMaskIgnore(set, RegisterSet(), simdSet);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMask(GeneralRegisterSet set)
|
||||
{
|
||||
PopRegsInMask(RegisterSet(set, FloatRegisterSet()));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
|
||||
{
|
||||
PopRegsInMaskIgnore(set, ignore, FloatRegisterSet());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(jsid id, Register scratchReg)
|
||||
{
|
||||
if (JSID_IS_GCTHING(id)) {
|
||||
// If we're pushing a gcthing, then we can't just push the tagged jsid
|
||||
// value since the GC won't have any idea that the push instruction
|
||||
// carries a reference to a gcthing. Need to unpack the pointer,
|
||||
// push it using ImmGCPtr, and then rematerialize the id at runtime.
|
||||
|
||||
if (JSID_IS_STRING(id)) {
|
||||
JSString *str = JSID_TO_STRING(id);
|
||||
MOZ_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
|
||||
MOZ_ASSERT(JSID_TYPE_STRING == 0x0);
|
||||
Push(ImmGCPtr(str));
|
||||
} else {
|
||||
MOZ_ASSERT(JSID_IS_SYMBOL(id));
|
||||
JS::Symbol *sym = JSID_TO_SYMBOL(id);
|
||||
movePtr(ImmGCPtr(sym), scratchReg);
|
||||
orPtr(Imm32(JSID_TYPE_SYMBOL), scratchReg);
|
||||
Push(scratchReg);
|
||||
}
|
||||
} else {
|
||||
Push(ImmWord(JSID_BITS(id)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(TypedOrValueRegister v)
|
||||
{
|
||||
if (v.hasValue()) {
|
||||
Push(v.valueReg());
|
||||
} else if (IsFloatingPointType(v.type())) {
|
||||
FloatRegister reg = v.typedReg().fpu();
|
||||
if (v.type() == MIRType_Float32) {
|
||||
convertFloat32ToDouble(reg, ScratchDoubleReg);
|
||||
reg = ScratchDoubleReg;
|
||||
}
|
||||
Push(reg);
|
||||
} else {
|
||||
Push(ValueTypeFromMIRType(v.type()), v.typedReg().gpr());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(ConstantOrRegister v)
|
||||
{
|
||||
if (v.constant())
|
||||
Push(v.value());
|
||||
else
|
||||
Push(v.reg());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const ValueOperand &val)
|
||||
{
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const Value &val)
|
||||
{
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(JSValueType type, Register reg)
|
||||
{
|
||||
pushValue(type, reg);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PushValue(const Address &addr)
|
||||
{
|
||||
MOZ_ASSERT(addr.base != StackPointer);
|
||||
pushValue(addr);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PushEmptyRooted(VMFunction::RootType rootType)
|
||||
{
|
||||
switch (rootType) {
|
||||
case VMFunction::RootNone:
|
||||
MOZ_CRASH("Handle must have root type");
|
||||
case VMFunction::RootObject:
|
||||
case VMFunction::RootString:
|
||||
case VMFunction::RootPropertyName:
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunction::RootCell:
|
||||
Push(ImmPtr(nullptr));
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
Push(UndefinedValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::popRooted(VMFunction::RootType rootType, Register cellReg,
|
||||
const ValueOperand &valueReg)
|
||||
{
|
||||
switch (rootType) {
|
||||
case VMFunction::RootNone:
|
||||
MOZ_CRASH("Handle must have root type");
|
||||
case VMFunction::RootObject:
|
||||
case VMFunction::RootString:
|
||||
case VMFunction::RootPropertyName:
|
||||
case VMFunction::RootFunction:
|
||||
case VMFunction::RootCell:
|
||||
Pop(cellReg);
|
||||
break;
|
||||
case VMFunction::RootValue:
|
||||
Pop(valueReg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::adjustStack(int amount)
|
||||
{
|
||||
if (amount > 0)
|
||||
freeStack(amount);
|
||||
else if (amount < 0)
|
||||
reserveStack(-amount);
|
||||
}
|
||||
|
||||
+69
-109
@@ -32,6 +32,26 @@
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/UnboxedObject.h"
|
||||
|
||||
// This Macro is only a hint for code readers that the function is defined in a
|
||||
// specific macro assembler, and not in the generic macro assembler. Thus, when
|
||||
// looking for the implementation one might find if the function is implemented
|
||||
// and where it is supposed to be implemented.
|
||||
# define PER_ARCH
|
||||
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
# define ONLY_X86_X64
|
||||
#elif defined(JS_CODEGEN_X64)
|
||||
# define ONLY_X86_X64
|
||||
#elif defined(JS_CODEGEN_ARM)
|
||||
# define ONLY_X86_X64 = delete
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
# define ONLY_X86_X64 = delete
|
||||
#elif defined(JS_CODEGEN_NONE)
|
||||
# define ONLY_X86_X64 = delete
|
||||
#else
|
||||
# error "Unknown architecture!"
|
||||
#endif
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
#define IMM32_16ADJ(X) X << 16
|
||||
#else
|
||||
@@ -272,6 +292,47 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
return size();
|
||||
}
|
||||
|
||||
public:
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) PER_ARCH;
|
||||
void PushRegsInMask(RegisterSet set);
|
||||
void PushRegsInMask(GeneralRegisterSet set);
|
||||
|
||||
void PopRegsInMask(RegisterSet set);
|
||||
void PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet);
|
||||
void PopRegsInMask(GeneralRegisterSet set);
|
||||
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore,
|
||||
FloatRegisterSet simdSet) PER_ARCH;
|
||||
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore);
|
||||
|
||||
void Push(const Operand op) PER_ARCH ONLY_X86_X64;
|
||||
void Push(Register reg) PER_ARCH;
|
||||
void Push(const Imm32 imm) PER_ARCH;
|
||||
void Push(const ImmWord imm) PER_ARCH;
|
||||
void Push(const ImmPtr imm) PER_ARCH;
|
||||
void Push(const ImmGCPtr ptr) PER_ARCH;
|
||||
void Push(FloatRegister reg) PER_ARCH;
|
||||
void Push(jsid id, Register scratchReg);
|
||||
void Push(TypedOrValueRegister v);
|
||||
void Push(ConstantOrRegister v);
|
||||
void Push(const ValueOperand &val);
|
||||
void Push(const Value &val);
|
||||
void Push(JSValueType type, Register reg);
|
||||
void PushValue(const Address &addr);
|
||||
void PushEmptyRooted(VMFunction::RootType rootType);
|
||||
|
||||
void Pop(const Operand op) PER_ARCH ONLY_X86_X64;
|
||||
void Pop(Register reg) PER_ARCH;
|
||||
void Pop(FloatRegister t) PER_ARCH ONLY_X86_X64;
|
||||
void Pop(const ValueOperand &val) PER_ARCH;
|
||||
void popRooted(VMFunction::RootType rootType, Register cellReg, const ValueOperand &valueReg);
|
||||
|
||||
void adjustStack(int amount);
|
||||
|
||||
public:
|
||||
|
||||
// Emits a test of a value against all types in a TypeSet. A scratch
|
||||
// register is required.
|
||||
template <typename Source, typename TypeSet>
|
||||
@@ -515,28 +576,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
return extractObject(source, scratch);
|
||||
}
|
||||
|
||||
void PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet);
|
||||
void PushRegsInMask(RegisterSet set) {
|
||||
PushRegsInMask(set, FloatRegisterSet());
|
||||
}
|
||||
void PushRegsInMask(GeneralRegisterSet set) {
|
||||
PushRegsInMask(RegisterSet(set, FloatRegisterSet()));
|
||||
}
|
||||
void PopRegsInMask(RegisterSet set) {
|
||||
PopRegsInMaskIgnore(set, RegisterSet());
|
||||
}
|
||||
void PopRegsInMask(RegisterSet set, FloatRegisterSet simdSet) {
|
||||
PopRegsInMaskIgnore(set, RegisterSet(), simdSet);
|
||||
}
|
||||
void PopRegsInMask(GeneralRegisterSet set) {
|
||||
PopRegsInMask(RegisterSet(set, FloatRegisterSet()));
|
||||
}
|
||||
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet);
|
||||
void PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore) {
|
||||
PopRegsInMaskIgnore(set, ignore, FloatRegisterSet());
|
||||
}
|
||||
|
||||
void branchIfFunctionHasNoScript(Register fun, Label* label) {
|
||||
void branchIfFunctionHasNoScript(Register fun, Label *label) {
|
||||
// 16-bit loads are slow and unaligned 32-bit loads may be too so
|
||||
// perform an aligned 32-bit load and adjust the bitmask accordingly.
|
||||
MOZ_ASSERT(JSFunction::offsetOfNargs() % sizeof(uint32_t) == 0);
|
||||
@@ -555,89 +595,9 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
branchTest32(Assembler::NonZero, address, Imm32(bit), label);
|
||||
}
|
||||
|
||||
void branchIfNotInterpretedConstructor(Register fun, Register scratch, Label* label);
|
||||
void branchIfNotInterpretedConstructor(Register fun, Register scratch, Label *label);
|
||||
|
||||
using MacroAssemblerSpecific::Push;
|
||||
using MacroAssemblerSpecific::Pop;
|
||||
|
||||
void Push(jsid id, Register scratchReg) {
|
||||
if (JSID_IS_GCTHING(id)) {
|
||||
// If we're pushing a gcthing, then we can't just push the tagged jsid
|
||||
// value since the GC won't have any idea that the push instruction
|
||||
// carries a reference to a gcthing. Need to unpack the pointer,
|
||||
// push it using ImmGCPtr, and then rematerialize the id at runtime.
|
||||
|
||||
if (JSID_IS_STRING(id)) {
|
||||
JSString* str = JSID_TO_STRING(id);
|
||||
MOZ_ASSERT(((size_t)str & JSID_TYPE_MASK) == 0);
|
||||
MOZ_ASSERT(JSID_TYPE_STRING == 0x0);
|
||||
Push(ImmGCPtr(str));
|
||||
} else {
|
||||
MOZ_ASSERT(JSID_IS_SYMBOL(id));
|
||||
JS::Symbol* sym = JSID_TO_SYMBOL(id);
|
||||
movePtr(ImmGCPtr(sym), scratchReg);
|
||||
orPtr(Imm32(JSID_TYPE_SYMBOL), scratchReg);
|
||||
Push(scratchReg);
|
||||
}
|
||||
} else {
|
||||
Push(ImmWord(JSID_BITS(id)));
|
||||
}
|
||||
}
|
||||
|
||||
void Push(TypedOrValueRegister v) {
|
||||
if (v.hasValue()) {
|
||||
Push(v.valueReg());
|
||||
} else if (IsFloatingPointType(v.type())) {
|
||||
FloatRegister reg = v.typedReg().fpu();
|
||||
if (v.type() == MIRType_Float32) {
|
||||
convertFloat32ToDouble(reg, ScratchDoubleReg);
|
||||
reg = ScratchDoubleReg;
|
||||
}
|
||||
Push(reg);
|
||||
} else {
|
||||
Push(ValueTypeFromMIRType(v.type()), v.typedReg().gpr());
|
||||
}
|
||||
}
|
||||
|
||||
void Push(ConstantOrRegister v) {
|
||||
if (v.constant())
|
||||
Push(v.value());
|
||||
else
|
||||
Push(v.reg());
|
||||
}
|
||||
|
||||
void Push(const ValueOperand& val) {
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void Push(const Value& val) {
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void Push(JSValueType type, Register reg) {
|
||||
pushValue(type, reg);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void PushValue(const Address& addr) {
|
||||
MOZ_ASSERT(addr.base != StackPointer);
|
||||
pushValue(addr);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
|
||||
void PushEmptyRooted(VMFunction::RootType rootType);
|
||||
void popRooted(VMFunction::RootType rootType, Register cellReg, const ValueOperand& valueReg);
|
||||
|
||||
void adjustStack(int amount) {
|
||||
if (amount > 0)
|
||||
freeStack(amount);
|
||||
else if (amount < 0)
|
||||
reserveStack(-amount);
|
||||
}
|
||||
|
||||
void bumpKey(Int32Key* key, int diff) {
|
||||
void bumpKey(Int32Key *key, int diff) {
|
||||
if (key->isRegister())
|
||||
add32(Imm32(diff), key->reg());
|
||||
else
|
||||
@@ -1263,21 +1223,21 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
uint32_t alignmentPadding;
|
||||
};
|
||||
|
||||
void alignFrameForICArguments(AfterICSaveLive& aic);
|
||||
void restoreFrameAlignmentForICArguments(AfterICSaveLive& aic);
|
||||
void alignFrameForICArguments(AfterICSaveLive &aic);
|
||||
void restoreFrameAlignmentForICArguments(AfterICSaveLive &aic);
|
||||
|
||||
AfterICSaveLive icSaveLive(RegisterSet& liveRegs) {
|
||||
AfterICSaveLive icSaveLive(RegisterSet &liveRegs) {
|
||||
PushRegsInMask(liveRegs);
|
||||
AfterICSaveLive aic(framePushed());
|
||||
alignFrameForICArguments(aic);
|
||||
return aic;
|
||||
}
|
||||
|
||||
bool icBuildOOLFakeExitFrame(void* fakeReturnAddr, AfterICSaveLive& aic) {
|
||||
bool icBuildOOLFakeExitFrame(void *fakeReturnAddr, AfterICSaveLive &aic) {
|
||||
return buildOOLFakeExitFrame(fakeReturnAddr);
|
||||
}
|
||||
|
||||
void icRestoreLive(RegisterSet& liveRegs, AfterICSaveLive& aic) {
|
||||
void icRestoreLive(RegisterSet &liveRegs, AfterICSaveLive &aic) {
|
||||
restoreFrameAlignmentForICArguments(aic);
|
||||
MOZ_ASSERT(framePushed() == aic.initialStack);
|
||||
PopRegsInMask(liveRegs);
|
||||
|
||||
@@ -408,7 +408,7 @@ class TypedRegisterSet
|
||||
// Determine if some register are still allocated. This function should
|
||||
// be used with the set of allocatable registers used for the initialization
|
||||
// of the current set.
|
||||
bool someAllocated(const TypedRegisterSet& allocatable) const {
|
||||
bool someAllocated(const TypedRegisterSet &allocatable) const {
|
||||
return allocatable.bits_ & ~bits_;
|
||||
}
|
||||
bool empty() const {
|
||||
@@ -641,7 +641,7 @@ class RegisterSet {
|
||||
else
|
||||
addUnchecked(any.gpr());
|
||||
}
|
||||
void addAllAliasedUnchecked(const AnyRegister& reg) {
|
||||
void addAllAliasedUnchecked(const AnyRegister ®) {
|
||||
if (reg.isFloat())
|
||||
fpu_.addAllAliasedUnchecked(reg.fpu());
|
||||
else
|
||||
@@ -701,7 +701,7 @@ class RegisterSet {
|
||||
MOZ_CONSTEXPR FloatRegisterSet fpus() const {
|
||||
return fpu_;
|
||||
}
|
||||
bool operator ==(const RegisterSet& other) const {
|
||||
bool operator ==(const RegisterSet &other) const {
|
||||
return other.gpr_ == gpr_ && other.fpu_ == fpu_;
|
||||
}
|
||||
|
||||
@@ -739,7 +739,7 @@ class TypedRegisterIterator
|
||||
public:
|
||||
explicit TypedRegisterIterator(TypedRegisterSet<T> regset) : regset_(regset)
|
||||
{ }
|
||||
TypedRegisterIterator(const TypedRegisterIterator& other) : regset_(other.regset_)
|
||||
TypedRegisterIterator(const TypedRegisterIterator &other) : regset_(other.regset_)
|
||||
{ }
|
||||
|
||||
bool more() const {
|
||||
@@ -768,7 +768,7 @@ class TypedRegisterBackwardIterator
|
||||
public:
|
||||
explicit TypedRegisterBackwardIterator(TypedRegisterSet<T> regset) : regset_(regset)
|
||||
{ }
|
||||
TypedRegisterBackwardIterator(const TypedRegisterBackwardIterator& other)
|
||||
TypedRegisterBackwardIterator(const TypedRegisterBackwardIterator &other)
|
||||
: regset_(other.regset_)
|
||||
{ }
|
||||
|
||||
@@ -798,7 +798,7 @@ class TypedRegisterForwardIterator
|
||||
public:
|
||||
explicit TypedRegisterForwardIterator(TypedRegisterSet<T> regset) : regset_(regset)
|
||||
{ }
|
||||
TypedRegisterForwardIterator(const TypedRegisterForwardIterator& other) : regset_(other.regset_)
|
||||
TypedRegisterForwardIterator(const TypedRegisterForwardIterator &other) : regset_(other.regset_)
|
||||
{ }
|
||||
|
||||
bool more() const {
|
||||
@@ -837,10 +837,10 @@ class AnyRegisterIterator
|
||||
AnyRegisterIterator(GeneralRegisterSet genset, FloatRegisterSet floatset)
|
||||
: geniter_(genset), floatiter_(floatset)
|
||||
{ }
|
||||
explicit AnyRegisterIterator(const RegisterSet& set)
|
||||
explicit AnyRegisterIterator(const RegisterSet &set)
|
||||
: geniter_(set.gpr_), floatiter_(set.fpu_)
|
||||
{ }
|
||||
AnyRegisterIterator(const AnyRegisterIterator& other)
|
||||
AnyRegisterIterator(const AnyRegisterIterator &other)
|
||||
: geniter_(other.geniter_), floatiter_(other.floatiter_)
|
||||
{ }
|
||||
bool more() const {
|
||||
|
||||
@@ -146,16 +146,20 @@ static MOZ_CONSTEXPR_VAR FloatRegister d15 = {FloatRegisters::d15, VFPRegister::
|
||||
// load/store) operate in a single cycle when the address they are dealing with
|
||||
// is 8 byte aligned. Also, the ARM abi wants the stack to be 8 byte aligned at
|
||||
// function boundaries. I'm trying to make sure this is always true.
|
||||
static const uint32_t ABIStackAlignment = 8;
|
||||
static const uint32_t CodeAlignment = 8;
|
||||
static const uint32_t JitStackAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t ABIStackAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t CodeAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackAlignment = 8;
|
||||
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackValueAlignment = JitStackAlignment / sizeof(Value);
|
||||
static_assert(JitStackAlignment % sizeof(Value) == 0 && JitStackValueAlignment >= 1,
|
||||
"Stack alignment should be a non-zero multiple of sizeof(Value)");
|
||||
|
||||
// This boolean indicates whether we support SIMD instructions flavoured for
|
||||
// this architecture or not. Rather than a method in the LIRGenerator, it is
|
||||
// here such that it is accessible from the entire codebase. Once full support
|
||||
// for SIMD is reached on all tier-1 platforms, this constant can be deleted.
|
||||
static const bool SupportsSimd = false;
|
||||
static const uint32_t SimdMemoryAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR bool SupportsSimd = false;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t SimdMemoryAlignment = 8;
|
||||
|
||||
static_assert(CodeAlignment % SimdMemoryAlignment == 0,
|
||||
"Code alignment should be larger than any of the alignments which are used for "
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "jit/Bailouts.h"
|
||||
#include "jit/BaselineFrame.h"
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/MacroAssembler.h"
|
||||
#include "jit/MoveEmitter.h"
|
||||
|
||||
using namespace js;
|
||||
@@ -1792,11 +1793,11 @@ MacroAssemblerARMCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
|
||||
DebugOnly<uint32_t> initialDepth = framePushed();
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
|
||||
Push(Imm32(descriptor)); // descriptor_
|
||||
asMasm().Push(Imm32(descriptor)); // descriptor_
|
||||
|
||||
enterNoPool(2);
|
||||
DebugOnly<uint32_t> offsetBeforePush = currentOffset();
|
||||
Push(pc); // actually pushes $pc + 8.
|
||||
asMasm().Push(pc); // actually pushes $pc + 8.
|
||||
|
||||
// Consume an additional 4 bytes. The start of the next instruction will
|
||||
// then be 8 bytes after the instruction for Push(pc); this offset can
|
||||
@@ -1817,8 +1818,8 @@ MacroAssemblerARMCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
|
||||
DebugOnly<uint32_t> initialDepth = framePushed();
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
|
||||
Push(Imm32(descriptor)); // descriptor_
|
||||
Push(ImmPtr(fakeReturnAddr));
|
||||
asMasm().Push(Imm32(descriptor)); // descriptor_
|
||||
asMasm().Push(ImmPtr(fakeReturnAddr));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1827,7 +1828,7 @@ void
|
||||
MacroAssemblerARMCompat::callWithExitFrame(Label* target)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor)); // descriptor
|
||||
asMasm().Push(Imm32(descriptor)); // descriptor
|
||||
|
||||
ma_callJitHalfPush(target);
|
||||
}
|
||||
@@ -1836,7 +1837,7 @@ void
|
||||
MacroAssemblerARMCompat::callWithExitFrame(JitCode* target)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor)); // descriptor
|
||||
asMasm().Push(Imm32(descriptor)); // descriptor
|
||||
|
||||
addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
|
||||
RelocStyle rs;
|
||||
@@ -1854,7 +1855,7 @@ MacroAssemblerARMCompat::callWithExitFrame(JitCode* target, Register dynStack)
|
||||
{
|
||||
ma_add(Imm32(framePushed()), dynStack);
|
||||
makeFrameDescriptor(dynStack, JitFrame_IonJS);
|
||||
Push(dynStack); // descriptor
|
||||
asMasm().Push(dynStack); // descriptor
|
||||
|
||||
addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
|
||||
RelocStyle rs;
|
||||
@@ -1912,80 +1913,6 @@ MacroAssemblerARMCompat::freeStack(Register amount)
|
||||
ma_add(amount, sp);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
|
||||
if (set.gprs().size() > 1) {
|
||||
adjustFrame(diffG);
|
||||
startDataTransferM(IsStore, StackPointer, DB, WriteBack);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
transferReg(*iter);
|
||||
}
|
||||
finishDataTransfer();
|
||||
} else {
|
||||
reserveStack(diffG);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
storePtr(*iter, Address(StackPointer, diffG));
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
|
||||
adjustFrame(diffF);
|
||||
diffF += transferMultipleByRuns(set.fpus(), IsStore, StackPointer, DB);
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
const int32_t reservedG = diffG;
|
||||
const int32_t reservedF = diffF;
|
||||
|
||||
// ARM can load multiple registers at once, but only if we want back all
|
||||
// the registers we previously saved to the stack.
|
||||
if (ignore.empty(true)) {
|
||||
diffF -= transferMultipleByRuns(set.fpus(), IsLoad, StackPointer, IA);
|
||||
adjustFrame(-reservedF);
|
||||
} else {
|
||||
TypedRegisterSet<VFPRegister> fpset = set.fpus().reduceSetForPush();
|
||||
TypedRegisterSet<VFPRegister> fpignore = ignore.fpus().reduceSetForPush();
|
||||
for (FloatRegisterBackwardIterator iter(fpset); iter.more(); iter++) {
|
||||
diffF -= (*iter).size();
|
||||
if (!fpignore.has(*iter))
|
||||
loadDouble(Address(StackPointer, diffF), *iter);
|
||||
}
|
||||
freeStack(reservedF);
|
||||
}
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
|
||||
if (set.gprs().size() > 1 && ignore.empty(false)) {
|
||||
startDataTransferM(IsLoad, StackPointer, IA, WriteBack);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
transferReg(*iter);
|
||||
}
|
||||
finishDataTransfer();
|
||||
adjustFrame(-reservedG);
|
||||
} else {
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
if (!ignore.has(*iter))
|
||||
loadPtr(Address(StackPointer, diffG), *iter);
|
||||
}
|
||||
freeStack(reservedG);
|
||||
}
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::add32(Register src, Register dest)
|
||||
{
|
||||
@@ -4077,7 +4004,7 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t* stackAdjust, bool callFromAsmJ
|
||||
if (!enoughMemory_)
|
||||
return;
|
||||
|
||||
MoveEmitter emitter(*this);
|
||||
MoveEmitter emitter(asMasm());
|
||||
emitter.emit(moveResolver_);
|
||||
emitter.finish();
|
||||
}
|
||||
@@ -5073,3 +5000,148 @@ MacroAssemblerARMCompat::profilerExitFrame()
|
||||
{
|
||||
branch(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
|
||||
}
|
||||
|
||||
MacroAssembler &
|
||||
MacroAssemblerARMCompat::asMasm()
|
||||
{
|
||||
return *static_cast<MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
const MacroAssembler &
|
||||
MacroAssemblerARMCompat::asMasm() const
|
||||
{
|
||||
return *static_cast<const MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
|
||||
if (set.gprs().size() > 1) {
|
||||
adjustFrame(diffG);
|
||||
startDataTransferM(IsStore, StackPointer, DB, WriteBack);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
transferReg(*iter);
|
||||
}
|
||||
finishDataTransfer();
|
||||
} else {
|
||||
reserveStack(diffG);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
storePtr(*iter, Address(StackPointer, diffG));
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
|
||||
adjustFrame(diffF);
|
||||
diffF += transferMultipleByRuns(set.fpus(), IsStore, StackPointer, DB);
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
const int32_t reservedG = diffG;
|
||||
const int32_t reservedF = diffF;
|
||||
|
||||
// ARM can load multiple registers at once, but only if we want back all
|
||||
// the registers we previously saved to the stack.
|
||||
if (ignore.empty(true)) {
|
||||
diffF -= transferMultipleByRuns(set.fpus(), IsLoad, StackPointer, IA);
|
||||
adjustFrame(-reservedF);
|
||||
} else {
|
||||
TypedRegisterSet<VFPRegister> fpset = set.fpus().reduceSetForPush();
|
||||
TypedRegisterSet<VFPRegister> fpignore = ignore.fpus().reduceSetForPush();
|
||||
for (FloatRegisterBackwardIterator iter(fpset); iter.more(); iter++) {
|
||||
diffF -= (*iter).size();
|
||||
if (!fpignore.has(*iter))
|
||||
loadDouble(Address(StackPointer, diffF), *iter);
|
||||
}
|
||||
freeStack(reservedF);
|
||||
}
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
|
||||
if (set.gprs().size() > 1 && ignore.empty(false)) {
|
||||
startDataTransferM(IsLoad, StackPointer, IA, WriteBack);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
transferReg(*iter);
|
||||
}
|
||||
finishDataTransfer();
|
||||
adjustFrame(-reservedG);
|
||||
} else {
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
if (!ignore.has(*iter))
|
||||
loadPtr(Address(StackPointer, diffG), *iter);
|
||||
}
|
||||
freeStack(reservedG);
|
||||
}
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(Register reg)
|
||||
{
|
||||
ma_push(reg);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const Imm32 imm)
|
||||
{
|
||||
push(imm);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const ImmWord imm)
|
||||
{
|
||||
push(imm);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const ImmPtr imm)
|
||||
{
|
||||
Push(ImmWord(uintptr_t(imm.value)));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const ImmGCPtr ptr)
|
||||
{
|
||||
push(ptr);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(FloatRegister reg)
|
||||
{
|
||||
VFPRegister r = VFPRegister(reg);
|
||||
ma_vpush(VFPRegister(reg));
|
||||
adjustFrame(r.size());
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(Register reg)
|
||||
{
|
||||
ma_pop(reg);
|
||||
adjustFrame(-sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(const ValueOperand &val)
|
||||
{
|
||||
popValue(val);
|
||||
framePushed_ -= sizeof(Value);
|
||||
}
|
||||
|
||||
@@ -475,8 +475,16 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class MacroAssembler;
|
||||
|
||||
class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
{
|
||||
private:
|
||||
// Perform a downcast. Should be removed by Bug 996602.
|
||||
MacroAssembler &asMasm();
|
||||
const MacroAssembler &asMasm() const;
|
||||
|
||||
private:
|
||||
bool inCall_;
|
||||
// Number of bytes the stack is adjusted inside a call to C. Calls to C may
|
||||
// not be nested.
|
||||
@@ -1227,18 +1235,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
push(ImmTag(JSVAL_TYPE_TO_TAG(type)));
|
||||
ma_push(reg);
|
||||
}
|
||||
void pushValue(const Address& addr);
|
||||
void Push(const ValueOperand& val) {
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
void Pop(const ValueOperand& val) {
|
||||
popValue(val);
|
||||
framePushed_ -= sizeof(Value);
|
||||
}
|
||||
void storePayload(const Value& val, Operand dest);
|
||||
void pushValue(const Address &addr);
|
||||
|
||||
void storePayload(const Value &val, Operand dest);
|
||||
void storePayload(Register src, Operand dest);
|
||||
void storePayload(const Value& val, const BaseIndex& dest);
|
||||
void storePayload(const Value &val, const BaseIndex &dest);
|
||||
void storePayload(Register src, const BaseIndex& dest);
|
||||
void storeTypeTag(ImmTag tag, Operand dest);
|
||||
void storeTypeTag(ImmTag tag, const BaseIndex& dest);
|
||||
@@ -1255,30 +1256,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
/////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
// The following functions are exposed for use in platform-shared code.
|
||||
void Push(Register reg) {
|
||||
ma_push(reg);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(const Imm32 imm) {
|
||||
push(imm);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(const ImmWord imm) {
|
||||
push(imm);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(const ImmPtr imm) {
|
||||
Push(ImmWord(uintptr_t(imm.value)));
|
||||
}
|
||||
void Push(const ImmGCPtr ptr) {
|
||||
push(ptr);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(FloatRegister t) {
|
||||
VFPRegister r = VFPRegister(t);
|
||||
ma_vpush(VFPRegister(t));
|
||||
adjustFrame(r.size());
|
||||
}
|
||||
|
||||
CodeOffsetLabel PushWithPatch(ImmWord word) {
|
||||
framePushed_ += sizeof(word.value);
|
||||
@@ -1297,10 +1274,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
adjustFrame(sizeof(intptr_t) + extraSpace.value);
|
||||
}
|
||||
|
||||
void Pop(Register reg) {
|
||||
ma_pop(reg);
|
||||
adjustFrame(-sizeof(intptr_t));
|
||||
}
|
||||
void implicitPop(uint32_t args) {
|
||||
MOZ_ASSERT(args % sizeof(intptr_t) == 0);
|
||||
adjustFrame(-args);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
MoveEmitterARM::MoveEmitterARM(MacroAssemblerARMCompat& masm)
|
||||
MoveEmitterARM::MoveEmitterARM(MacroAssembler &masm)
|
||||
: inCycle_(0),
|
||||
masm(masm),
|
||||
pushedAtCycle_(-1),
|
||||
|
||||
@@ -18,7 +18,7 @@ class CodeGenerator;
|
||||
class MoveEmitterARM
|
||||
{
|
||||
uint32_t inCycle_;
|
||||
MacroAssemblerARMCompat& masm;
|
||||
MacroAssembler &masm;
|
||||
|
||||
// Original stack push value.
|
||||
uint32_t pushedAtStart_;
|
||||
@@ -49,12 +49,12 @@ class MoveEmitterARM
|
||||
MoveOp::Type type, uint32_t slot);
|
||||
void completeCycle(const MoveOperand& from, const MoveOperand& to,
|
||||
MoveOp::Type type, uint32_t slot);
|
||||
void emit(const MoveOp& move);
|
||||
void emit(const MoveOp &move);
|
||||
|
||||
public:
|
||||
MoveEmitterARM(MacroAssemblerARMCompat& masm);
|
||||
MoveEmitterARM(MacroAssembler &masm);
|
||||
~MoveEmitterARM();
|
||||
void emit(const MoveResolver& moves);
|
||||
void emit(const MoveResolver &moves);
|
||||
void finish();
|
||||
|
||||
void setScratchRegister(Register reg) {}
|
||||
|
||||
@@ -161,23 +161,27 @@ static MOZ_CONSTEXPR_VAR FloatRegister f30 = { FloatRegisters::f30, FloatRegiste
|
||||
|
||||
// MIPS CPUs can only load multibyte data that is "naturally"
|
||||
// four-byte-aligned, sp register should be eight-byte-aligned.
|
||||
static const uint32_t ABIStackAlignment = 8;
|
||||
static const uint32_t CodeAlignment = 4;
|
||||
static const uint32_t JitStackAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t ABIStackAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t CodeAlignment = 4;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackAlignment = 8;
|
||||
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackValueAlignment = JitStackAlignment / sizeof(Value);
|
||||
static_assert(JitStackAlignment % sizeof(Value) == 0 && JitStackValueAlignment >= 1,
|
||||
"Stack alignment should be a non-zero multiple of sizeof(Value)");
|
||||
|
||||
// This boolean indicates whether we support SIMD instructions flavoured for
|
||||
// this architecture or not. Rather than a method in the LIRGenerator, it is
|
||||
// here such that it is accessible from the entire codebase. Once full support
|
||||
// for SIMD is reached on all tier-1 platforms, this constant can be deleted.
|
||||
static const bool SupportsSimd = false;
|
||||
static MOZ_CONSTEXPR_VAR bool SupportsSimd = false;
|
||||
// TODO this is just a filler to prevent a build failure. The MIPS SIMD
|
||||
// alignment requirements still need to be explored.
|
||||
// TODO Copy the static_asserts from x64/x86 assembler files.
|
||||
static const uint32_t SimdMemoryAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t SimdMemoryAlignment = 8;
|
||||
|
||||
static const uint32_t AsmJSStackAlignment = SimdMemoryAlignment;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t AsmJSStackAlignment = SimdMemoryAlignment;
|
||||
|
||||
static const Scale ScalePointer = TimesFour;
|
||||
static MOZ_CONSTEXPR_VAR Scale ScalePointer = TimesFour;
|
||||
|
||||
// MIPS instruction types
|
||||
// +---------------------------------------------------------------+
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "jit/BaselineFrame.h"
|
||||
#include "jit/BaselineRegisters.h"
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/MacroAssembler.h"
|
||||
#include "jit/mips/Simulator-mips.h"
|
||||
#include "jit/MoveEmitter.h"
|
||||
|
||||
@@ -1497,8 +1498,8 @@ MacroAssemblerMIPSCompat::buildFakeExitFrame(Register scratch, uint32_t* offset)
|
||||
ma_li(scratch, cl.dest());
|
||||
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor));
|
||||
Push(scratch);
|
||||
asMasm().Push(Imm32(descriptor));
|
||||
asMasm().Push(scratch);
|
||||
|
||||
bind(cl.src());
|
||||
*offset = currentOffset();
|
||||
@@ -1512,8 +1513,8 @@ MacroAssemblerMIPSCompat::buildOOLFakeExitFrame(void* fakeReturnAddr)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
|
||||
Push(Imm32(descriptor)); // descriptor_
|
||||
Push(ImmPtr(fakeReturnAddr));
|
||||
asMasm().Push(Imm32(descriptor)); // descriptor_
|
||||
asMasm().Push(ImmPtr(fakeReturnAddr));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1522,7 +1523,7 @@ void
|
||||
MacroAssemblerMIPSCompat::callWithExitFrame(Label* target)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor)); // descriptor
|
||||
asMasm().Push(Imm32(descriptor)); // descriptor
|
||||
|
||||
ma_callJitHalfPush(target);
|
||||
}
|
||||
@@ -1531,7 +1532,7 @@ void
|
||||
MacroAssemblerMIPSCompat::callWithExitFrame(JitCode* target)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor)); // descriptor
|
||||
asMasm().Push(Imm32(descriptor)); // descriptor
|
||||
|
||||
addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
|
||||
ma_liPatchable(ScratchRegister, ImmPtr(target->raw()));
|
||||
@@ -1543,7 +1544,7 @@ MacroAssemblerMIPSCompat::callWithExitFrame(JitCode* target, Register dynStack)
|
||||
{
|
||||
ma_addu(dynStack, dynStack, Imm32(framePushed()));
|
||||
makeFrameDescriptor(dynStack, JitFrame_IonJS);
|
||||
Push(dynStack); // descriptor
|
||||
asMasm().Push(dynStack); // descriptor
|
||||
|
||||
addPendingJump(m_buffer.nextOffset(), ImmPtr(target->raw()), Relocation::JITCODE);
|
||||
ma_liPatchable(ScratchRegister, ImmPtr(target->raw()));
|
||||
@@ -1585,65 +1586,6 @@ MacroAssemblerMIPSCompat::freeStack(Register amount)
|
||||
as_addu(StackPointer, StackPointer, amount);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
|
||||
reserveStack(diffG);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
storePtr(*iter, Address(StackPointer, diffG));
|
||||
}
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
|
||||
// Double values have to be aligned. We reserve extra space so that we can
|
||||
// start writing from the first aligned location.
|
||||
// We reserve a whole extra double so that the buffer has even size.
|
||||
ma_and(SecondScratchReg, sp, Imm32(~(ABIStackAlignment - 1)));
|
||||
reserveStack(diffF + sizeof(double));
|
||||
|
||||
for (FloatRegisterForwardIterator iter(set.fpus().reduceSetForPush()); iter.more(); iter++) {
|
||||
if ((*iter).code() % 2 == 0)
|
||||
as_sd(*iter, SecondScratchReg, -diffF);
|
||||
diffF -= sizeof(double);
|
||||
}
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
const int32_t reservedG = diffG;
|
||||
const int32_t reservedF = diffF;
|
||||
|
||||
// Read the buffer form the first aligned location.
|
||||
ma_addu(SecondScratchReg, sp, Imm32(reservedF + sizeof(double)));
|
||||
ma_and(SecondScratchReg, SecondScratchReg, Imm32(~(ABIStackAlignment - 1)));
|
||||
|
||||
for (FloatRegisterForwardIterator iter(set.fpus().reduceSetForPush()); iter.more(); iter++) {
|
||||
if (!ignore.has(*iter) && ((*iter).code() % 2 == 0))
|
||||
// Use assembly l.d because we have alligned the stack.
|
||||
as_ld(*iter, SecondScratchReg, -diffF);
|
||||
diffF -= sizeof(double);
|
||||
}
|
||||
freeStack(reservedF + sizeof(double));
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
if (!ignore.has(*iter))
|
||||
loadPtr(Address(StackPointer, diffG), *iter);
|
||||
}
|
||||
freeStack(reservedG);
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::add32(Register src, Register dest)
|
||||
{
|
||||
@@ -3427,7 +3369,7 @@ MacroAssemblerMIPSCompat::callWithABIPre(uint32_t* stackAdjust, bool callFromAsm
|
||||
if (!enoughMemory_)
|
||||
return;
|
||||
|
||||
MoveEmitter emitter(*this);
|
||||
MoveEmitter emitter(asMasm());
|
||||
emitter.emit(moveResolver_);
|
||||
emitter.finish();
|
||||
}
|
||||
@@ -3709,3 +3651,135 @@ MacroAssemblerMIPSCompat::profilerExitFrame()
|
||||
{
|
||||
branch(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
|
||||
}
|
||||
|
||||
MacroAssembler &
|
||||
MacroAssemblerMIPSCompat::asMasm()
|
||||
{
|
||||
return *static_cast<MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
const MacroAssembler &
|
||||
MacroAssemblerMIPSCompat::asMasm() const
|
||||
{
|
||||
return *static_cast<const MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
|
||||
reserveStack(diffG);
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
storePtr(*iter, Address(StackPointer, diffG));
|
||||
}
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
|
||||
// Double values have to be aligned. We reserve extra space so that we can
|
||||
// start writing from the first aligned location.
|
||||
// We reserve a whole extra double so that the buffer has even size.
|
||||
ma_and(SecondScratchReg, sp, Imm32(~(ABIStackAlignment - 1)));
|
||||
reserveStack(diffF + sizeof(double));
|
||||
|
||||
for (FloatRegisterForwardIterator iter(set.fpus().reduceSetForPush()); iter.more(); iter++) {
|
||||
if ((*iter).code() % 2 == 0)
|
||||
as_sd(*iter, SecondScratchReg, -diffF);
|
||||
diffF -= sizeof(double);
|
||||
}
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_ASSERT(!SupportsSimd() && simdSet.size() == 0);
|
||||
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||
int32_t diffF = set.fpus().getPushSizeInBytes();
|
||||
const int32_t reservedG = diffG;
|
||||
const int32_t reservedF = diffF;
|
||||
|
||||
// Read the buffer form the first aligned location.
|
||||
ma_addu(SecondScratchReg, sp, Imm32(reservedF + sizeof(double)));
|
||||
ma_and(SecondScratchReg, SecondScratchReg, Imm32(~(ABIStackAlignment - 1)));
|
||||
|
||||
for (FloatRegisterForwardIterator iter(set.fpus().reduceSetForPush()); iter.more(); iter++) {
|
||||
if (!ignore.has(*iter) && ((*iter).code() % 2 == 0))
|
||||
// Use assembly l.d because we have alligned the stack.
|
||||
as_ld(*iter, SecondScratchReg, -diffF);
|
||||
diffF -= sizeof(double);
|
||||
}
|
||||
freeStack(reservedF + sizeof(double));
|
||||
MOZ_ASSERT(diffF == 0);
|
||||
|
||||
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||
diffG -= sizeof(intptr_t);
|
||||
if (!ignore.has(*iter))
|
||||
loadPtr(Address(StackPointer, diffG), *iter);
|
||||
}
|
||||
freeStack(reservedG);
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(Register reg)
|
||||
{
|
||||
ma_push(reg);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const Imm32 imm)
|
||||
{
|
||||
ma_li(ScratchRegister, imm);
|
||||
ma_push(ScratchRegister);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const ImmWord imm)
|
||||
{
|
||||
ma_li(ScratchRegister, Imm32(imm.value));
|
||||
ma_push(ScratchRegister);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const ImmPtr imm)
|
||||
{
|
||||
Push(ImmWord(uintptr_t(imm.value)));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(const ImmGCPtr ptr)
|
||||
{
|
||||
ma_li(ScratchRegister, ptr);
|
||||
ma_push(ScratchRegister);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Push(FloatRegister f)
|
||||
{
|
||||
ma_push(f);
|
||||
adjustFrame(sizeof(double));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(Register reg)
|
||||
{
|
||||
ma_pop(reg);
|
||||
adjustFrame(-sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(const ValueOperand &val)
|
||||
{
|
||||
popValue(val);
|
||||
framePushed_ -= sizeof(Value);
|
||||
}
|
||||
|
||||
@@ -333,8 +333,16 @@ class MacroAssemblerMIPS : public Assembler
|
||||
void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c);
|
||||
};
|
||||
|
||||
class MacroAssembler;
|
||||
|
||||
class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
{
|
||||
private:
|
||||
// Perform a downcast. Should be removed by Bug 996602.
|
||||
MacroAssembler &asMasm();
|
||||
const MacroAssembler &asMasm() const;
|
||||
|
||||
private:
|
||||
// Number of bytes the stack is adjusted inside a call to C. Calls to C may
|
||||
// not be nested.
|
||||
bool inCall_;
|
||||
@@ -942,18 +950,11 @@ public:
|
||||
push(ImmTag(JSVAL_TYPE_TO_TAG(type)));
|
||||
ma_push(reg);
|
||||
}
|
||||
void pushValue(const Address& addr);
|
||||
void Push(const ValueOperand& val) {
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
void Pop(const ValueOperand& val) {
|
||||
popValue(val);
|
||||
framePushed_ -= sizeof(Value);
|
||||
}
|
||||
void storePayload(const Value& val, Address dest);
|
||||
void pushValue(const Address &addr);
|
||||
|
||||
void storePayload(const Value &val, Address dest);
|
||||
void storePayload(Register src, Address dest);
|
||||
void storePayload(const Value& val, const BaseIndex& dest);
|
||||
void storePayload(const Value &val, const BaseIndex& dest);
|
||||
void storePayload(Register src, const BaseIndex& dest);
|
||||
void storeTypeTag(ImmTag tag, Address dest);
|
||||
void storeTypeTag(ImmTag tag, const BaseIndex& dest);
|
||||
@@ -1102,33 +1103,6 @@ public:
|
||||
MOZ_CRASH("NYI");
|
||||
}
|
||||
|
||||
void Push(Register reg) {
|
||||
ma_push(reg);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(const Imm32 imm) {
|
||||
ma_li(ScratchRegister, imm);
|
||||
ma_push(ScratchRegister);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(const ImmWord imm) {
|
||||
ma_li(ScratchRegister, Imm32(imm.value));
|
||||
ma_push(ScratchRegister);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(const ImmPtr imm) {
|
||||
Push(ImmWord(uintptr_t(imm.value)));
|
||||
}
|
||||
void Push(const ImmGCPtr ptr) {
|
||||
ma_li(ScratchRegister, ptr);
|
||||
ma_push(ScratchRegister);
|
||||
adjustFrame(sizeof(intptr_t));
|
||||
}
|
||||
void Push(FloatRegister f) {
|
||||
ma_push(f);
|
||||
adjustFrame(sizeof(double));
|
||||
}
|
||||
|
||||
CodeOffsetLabel PushWithPatch(ImmWord word) {
|
||||
framePushed_ += sizeof(word.value);
|
||||
return pushWithPatch(word);
|
||||
@@ -1137,10 +1111,6 @@ public:
|
||||
return PushWithPatch(ImmWord(uintptr_t(imm.value)));
|
||||
}
|
||||
|
||||
void Pop(Register reg) {
|
||||
ma_pop(reg);
|
||||
adjustFrame(-sizeof(intptr_t));
|
||||
}
|
||||
void implicitPop(uint32_t args) {
|
||||
MOZ_ASSERT(args % sizeof(intptr_t) == 0);
|
||||
adjustFrame(-args);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
MoveEmitterMIPS::MoveEmitterMIPS(MacroAssemblerMIPSCompat& masm)
|
||||
MoveEmitterMIPS::MoveEmitterMIPS(MacroAssembler &masm)
|
||||
: inCycle_(0),
|
||||
masm(masm),
|
||||
pushedAtCycle_(-1),
|
||||
|
||||
@@ -18,7 +18,7 @@ class CodeGenerator;
|
||||
class MoveEmitterMIPS
|
||||
{
|
||||
uint32_t inCycle_;
|
||||
MacroAssemblerMIPSCompat& masm;
|
||||
MacroAssembler &masm;
|
||||
|
||||
// Original stack push value.
|
||||
uint32_t pushedAtStart_;
|
||||
@@ -49,12 +49,12 @@ class MoveEmitterMIPS
|
||||
MoveOp::Type type, uint32_t slot);
|
||||
void completeCycle(const MoveOperand& from, const MoveOperand& to,
|
||||
MoveOp::Type type, uint32_t slot);
|
||||
void emit(const MoveOp& move);
|
||||
void emit(const MoveOp &move);
|
||||
|
||||
public:
|
||||
MoveEmitterMIPS(MacroAssemblerMIPSCompat& masm);
|
||||
MoveEmitterMIPS(MacroAssembler &masm);
|
||||
~MoveEmitterMIPS();
|
||||
void emit(const MoveResolver& moves);
|
||||
void emit(const MoveResolver &moves);
|
||||
void finish();
|
||||
|
||||
void setScratchRegister(Register reg) {}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace jit {
|
||||
|
||||
static const bool SupportsSimd = false;
|
||||
static const uint32_t SimdMemoryAlignment = 4; // Make it 4 to avoid a bunch of div-by-zero warnings
|
||||
static const uint32_t AsmJSStackAlignment = 4;
|
||||
static const uint32_t AsmJSStackAlignment = 8;
|
||||
|
||||
class Registers
|
||||
{
|
||||
@@ -121,7 +121,7 @@ struct FloatRegister
|
||||
bool equiv(FloatRegister) const { MOZ_CRASH(); }
|
||||
uint32_t size() const { MOZ_CRASH(); }
|
||||
uint32_t numAlignedAliased() const { MOZ_CRASH(); }
|
||||
void alignedAliased(uint32_t, FloatRegister*) { MOZ_CRASH(); }
|
||||
void alignedAliased(uint32_t, FloatRegister *) { MOZ_CRASH(); }
|
||||
template <typename T> static T ReduceSetForPush(T) { MOZ_CRASH(); }
|
||||
uint32_t getRegisterDumpOffsetInBytes() { MOZ_CRASH(); }
|
||||
static uint32_t SetSize(SetType x) { MOZ_CRASH(); }
|
||||
|
||||
@@ -71,9 +71,10 @@ static MOZ_CONSTEXPR_VAR ValueOperand JSReturnOperand(InvalidReg);
|
||||
#error "Bad architecture"
|
||||
#endif
|
||||
|
||||
static const uint32_t ABIStackAlignment = 4;
|
||||
static const uint32_t CodeAlignment = 4;
|
||||
static const uint32_t JitStackAlignment = 4;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t ABIStackAlignment = 4;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t CodeAlignment = 4;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackAlignment = 8;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackValueAlignment = JitStackAlignment / sizeof(Value);
|
||||
|
||||
static const Scale ScalePointer = TimesOne;
|
||||
|
||||
|
||||
@@ -32,13 +32,7 @@ FrameSizeClass FrameSizeClass::FromDepth(uint32_t) { MOZ_CRASH(); }
|
||||
FrameSizeClass FrameSizeClass::ClassLimit() { MOZ_CRASH(); }
|
||||
uint32_t FrameSizeClass::frameSize() const { MOZ_CRASH(); }
|
||||
|
||||
void DispatchIonCache::initializeAddCacheState(LInstruction*, AddCacheState*) { MOZ_CRASH(); }
|
||||
|
||||
void MacroAssembler::PushRegsInMask(RegisterSet, FloatRegisterSet) { MOZ_CRASH(); }
|
||||
void MacroAssembler::clampDoubleToUint8(FloatRegister, Register) { MOZ_CRASH(); }
|
||||
void MacroAssembler::PopRegsInMaskIgnore(RegisterSet, RegisterSet, FloatRegisterSet) { MOZ_CRASH(); }
|
||||
void MacroAssembler::alignFrameForICArguments(AfterICSaveLive&) { MOZ_CRASH(); }
|
||||
void MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive&) { MOZ_CRASH(); }
|
||||
void DispatchIonCache::initializeAddCacheState(LInstruction *, AddCacheState *) { MOZ_CRASH(); }
|
||||
|
||||
const Register ABIArgGenerator::NonArgReturnReg0 = { Registers::invalid_reg };
|
||||
const Register ABIArgGenerator::NonArgReturnReg1 = { Registers::invalid_reg };
|
||||
@@ -56,8 +50,28 @@ BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& iter, Invalidati
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
bool ICCompare_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
|
||||
bool ICCompare_Double::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
|
||||
bool ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
|
||||
bool ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler&) { MOZ_CRASH(); }
|
||||
JitCode* JitRuntime::generateProfilerExitFrameTailStub(JSContext*) { MOZ_CRASH(); }
|
||||
bool ICCompare_Int32::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
|
||||
bool ICCompare_Double::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
|
||||
bool ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
|
||||
bool ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler &) { MOZ_CRASH(); }
|
||||
JitCode *JitRuntime::generateProfilerExitFrameTailStub(JSContext *) { MOZ_CRASH(); }
|
||||
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet) { MOZ_CRASH(); }
|
||||
void MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore,
|
||||
FloatRegisterSet simdSet)
|
||||
{
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
void MacroAssembler::Push(Register reg) { MOZ_CRASH(); }
|
||||
void MacroAssembler::Push(const Imm32 imm) { MOZ_CRASH(); }
|
||||
void MacroAssembler::Push(const ImmWord imm) { MOZ_CRASH(); }
|
||||
void MacroAssembler::Push(const ImmPtr imm) { MOZ_CRASH(); }
|
||||
void MacroAssembler::Push(const ImmGCPtr ptr) { MOZ_CRASH(); }
|
||||
void MacroAssembler::Push(FloatRegister reg) { MOZ_CRASH(); }
|
||||
|
||||
void MacroAssembler::Pop(Register reg) { MOZ_CRASH(); }
|
||||
void MacroAssembler::Pop(const ValueOperand &val) { MOZ_CRASH(); }
|
||||
|
||||
@@ -154,32 +154,32 @@ void
|
||||
CodeGeneratorShared::restoreLive(LInstruction* ins)
|
||||
{
|
||||
MOZ_ASSERT(!ins->isCall());
|
||||
LSafepoint* safepoint = ins->safepoint();
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
masm.PopRegsInMask(safepoint->liveRegs());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorShared::restoreLiveIgnore(LInstruction* ins, RegisterSet ignore)
|
||||
CodeGeneratorShared::restoreLiveIgnore(LInstruction *ins, RegisterSet ignore)
|
||||
{
|
||||
MOZ_ASSERT(!ins->isCall());
|
||||
LSafepoint* safepoint = ins->safepoint();
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
masm.PopRegsInMaskIgnore(safepoint->liveRegs(), ignore);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorShared::saveLiveVolatile(LInstruction* ins)
|
||||
CodeGeneratorShared::saveLiveVolatile(LInstruction *ins)
|
||||
{
|
||||
MOZ_ASSERT(!ins->isCall());
|
||||
LSafepoint* safepoint = ins->safepoint();
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
RegisterSet regs = RegisterSet::Intersect(safepoint->liveRegs(), RegisterSet::Volatile());
|
||||
masm.PushRegsInMask(regs);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorShared::restoreLiveVolatile(LInstruction* ins)
|
||||
CodeGeneratorShared::restoreLiveVolatile(LInstruction *ins)
|
||||
{
|
||||
MOZ_ASSERT(!ins->isCall());
|
||||
LSafepoint* safepoint = ins->safepoint();
|
||||
LSafepoint *safepoint = ins->safepoint();
|
||||
RegisterSet regs = RegisterSet::Intersect(safepoint->liveRegs(), RegisterSet::Volatile());
|
||||
masm.PopRegsInMask(regs);
|
||||
}
|
||||
|
||||
@@ -1029,7 +1029,7 @@ CodeGeneratorShared::markOsiPoint(LOsiPoint* ins)
|
||||
#ifdef CHECK_OSIPOINT_REGISTERS
|
||||
template <class Op>
|
||||
static void
|
||||
HandleRegisterDump(Op op, MacroAssembler& masm, RegisterSet liveRegs, Register activation,
|
||||
HandleRegisterDump(Op op, MacroAssembler &masm, RegisterSet liveRegs, Register activation,
|
||||
Register scratch)
|
||||
{
|
||||
const size_t baseOffset = JitActivation::offsetOfRegs();
|
||||
@@ -1088,7 +1088,7 @@ class StoreOp
|
||||
};
|
||||
|
||||
static void
|
||||
StoreAllLiveRegs(MacroAssembler& masm, RegisterSet liveRegs)
|
||||
StoreAllLiveRegs(MacroAssembler &masm, RegisterSet liveRegs)
|
||||
{
|
||||
// Store a copy of all live registers before performing the call.
|
||||
// When we reach the OsiPoint, we can use this to check nothing
|
||||
|
||||
@@ -442,13 +442,13 @@ class CodeGeneratorShared : public LElementVisitor
|
||||
// any modifications of the stack. Modification of the stack made after
|
||||
// these calls should update the framePushed variable, needed by the exit
|
||||
// frame produced by callVM.
|
||||
inline void saveLive(LInstruction* ins);
|
||||
inline void restoreLive(LInstruction* ins);
|
||||
inline void restoreLiveIgnore(LInstruction* ins, RegisterSet reg);
|
||||
inline void saveLive(LInstruction *ins);
|
||||
inline void restoreLive(LInstruction *ins);
|
||||
inline void restoreLiveIgnore(LInstruction *ins, RegisterSet reg);
|
||||
|
||||
// Save/restore all registers that are both live and volatile.
|
||||
inline void saveLiveVolatile(LInstruction* ins);
|
||||
inline void restoreLiveVolatile(LInstruction* ins);
|
||||
inline void saveLiveVolatile(LInstruction *ins);
|
||||
inline void restoreLiveVolatile(LInstruction *ins);
|
||||
|
||||
template <typename T>
|
||||
void pushArg(const T& t) {
|
||||
@@ -643,7 +643,7 @@ class ArgSeq : public SeqType
|
||||
return ArgSeq<ThisType, NextType>(*this, last);
|
||||
}
|
||||
|
||||
inline void generate(CodeGeneratorShared* codegen) const {
|
||||
inline void generate(CodeGeneratorShared *codegen) const {
|
||||
codegen->pushArg(last_);
|
||||
this->SeqType::generate(codegen);
|
||||
}
|
||||
@@ -666,7 +666,7 @@ class ArgSeq<void, void>
|
||||
return ArgSeq<ThisType, NextType>(*this, last);
|
||||
}
|
||||
|
||||
inline void generate(CodeGeneratorShared* codegen) const {
|
||||
inline void generate(CodeGeneratorShared *codegen) const {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,172 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
// Note: this function clobbers the input register.
|
||||
void
|
||||
MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
|
||||
{
|
||||
MOZ_ASSERT(input != ScratchDoubleReg);
|
||||
Label positive, done;
|
||||
|
||||
// <= 0 or NaN --> 0
|
||||
zeroDouble(ScratchDoubleReg);
|
||||
branchDouble(DoubleGreaterThan, input, ScratchDoubleReg, &positive);
|
||||
{
|
||||
move32(Imm32(0), output);
|
||||
jump(&done);
|
||||
}
|
||||
|
||||
bind(&positive);
|
||||
|
||||
// Add 0.5 and truncate.
|
||||
loadConstantDouble(0.5, ScratchDoubleReg);
|
||||
addDouble(ScratchDoubleReg, input);
|
||||
|
||||
Label outOfRange;
|
||||
|
||||
// Truncate to int32 and ensure the result <= 255. This relies on the
|
||||
// processor setting output to a value > 255 for doubles outside the int32
|
||||
// range (for instance 0x80000000).
|
||||
vcvttsd2si(input, output);
|
||||
branch32(Assembler::Above, output, Imm32(255), &outOfRange);
|
||||
{
|
||||
// Check if we had a tie.
|
||||
convertInt32ToDouble(output, ScratchDoubleReg);
|
||||
branchDouble(DoubleNotEqual, input, ScratchDoubleReg, &done);
|
||||
|
||||
// It was a tie. Mask out the ones bit to get an even value.
|
||||
// See also js_TypedArray_uint8_clamp_double.
|
||||
and32(Imm32(~1), output);
|
||||
jump(&done);
|
||||
}
|
||||
|
||||
// > 255 --> 255
|
||||
bind(&outOfRange);
|
||||
{
|
||||
move32(Imm32(255), output);
|
||||
}
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
// Builds an exit frame on the stack, with a return address to an internal
|
||||
// non-function. Returns offset to be passed to markSafepointAt().
|
||||
void
|
||||
MacroAssemblerX86Shared::buildFakeExitFrame(Register scratch, uint32_t *offset)
|
||||
{
|
||||
mozilla::DebugOnly<uint32_t> initialDepth = framePushed();
|
||||
|
||||
CodeLabel cl;
|
||||
mov(cl.dest(), scratch);
|
||||
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
asMasm().Push(Imm32(descriptor));
|
||||
asMasm().Push(scratch);
|
||||
|
||||
bind(cl.src());
|
||||
*offset = currentOffset();
|
||||
|
||||
MOZ_ASSERT(framePushed() == initialDepth + ExitFrameLayout::Size());
|
||||
addCodeLabel(cl);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::callWithExitFrame(Label *target)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
asMasm().Push(Imm32(descriptor));
|
||||
call(target);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::callWithExitFrame(JitCode *target)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
asMasm().Push(Imm32(descriptor));
|
||||
call(target);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::alignFrameForICArguments(AfterICSaveLive &aic)
|
||||
{
|
||||
// Exists for MIPS compatibility.
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive &aic)
|
||||
{
|
||||
// Exists for MIPS compatibility.
|
||||
}
|
||||
|
||||
bool
|
||||
MacroAssemblerX86Shared::buildOOLFakeExitFrame(void *fakeReturnAddr)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
asMasm().Push(Imm32(descriptor));
|
||||
asMasm().Push(ImmPtr(fakeReturnAddr));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::branchNegativeZero(FloatRegister reg,
|
||||
Register scratch,
|
||||
Label *label,
|
||||
bool maybeNonZero)
|
||||
{
|
||||
// Determines whether the low double contained in the XMM register reg
|
||||
// is equal to -0.0.
|
||||
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
Label nonZero;
|
||||
|
||||
// if not already compared to zero
|
||||
if (maybeNonZero) {
|
||||
// Compare to zero. Lets through {0, -0}.
|
||||
zeroDouble(ScratchDoubleReg);
|
||||
|
||||
// If reg is non-zero, jump to nonZero.
|
||||
branchDouble(DoubleNotEqual, reg, ScratchDoubleReg, &nonZero);
|
||||
}
|
||||
// Input register is either zero or negative zero. Retrieve sign of input.
|
||||
vmovmskpd(reg, scratch);
|
||||
|
||||
// If reg is 1 or 3, input is negative zero.
|
||||
// If reg is 0 or 2, input is a normal zero.
|
||||
branchTest32(NonZero, scratch, Imm32(1), label);
|
||||
|
||||
bind(&nonZero);
|
||||
#elif defined(JS_CODEGEN_X64)
|
||||
vmovq(reg, scratch);
|
||||
cmpq(Imm32(1), scratch);
|
||||
j(Overflow, label);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::branchNegativeZeroFloat32(FloatRegister reg,
|
||||
Register scratch,
|
||||
Label *label)
|
||||
{
|
||||
vmovd(reg, scratch);
|
||||
cmp32(scratch, Imm32(1));
|
||||
j(Overflow, label);
|
||||
}
|
||||
|
||||
MacroAssembler &
|
||||
MacroAssemblerX86Shared::asMasm()
|
||||
{
|
||||
return *static_cast<MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
const MacroAssembler &
|
||||
MacroAssemblerX86Shared::asMasm() const
|
||||
{
|
||||
return *static_cast<const MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
||||
void
|
||||
MacroAssembler::PushRegsInMask(RegisterSet set, FloatRegisterSet simdSet)
|
||||
{
|
||||
@@ -128,153 +294,78 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore, FloatRe
|
||||
MOZ_ASSERT(diffG == 0);
|
||||
}
|
||||
|
||||
// Note: this function clobbers the input register.
|
||||
void
|
||||
MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output)
|
||||
MacroAssembler::Push(const Operand op)
|
||||
{
|
||||
MOZ_ASSERT(input != ScratchDoubleReg);
|
||||
Label positive, done;
|
||||
|
||||
// <= 0 or NaN --> 0
|
||||
zeroDouble(ScratchDoubleReg);
|
||||
branchDouble(DoubleGreaterThan, input, ScratchDoubleReg, &positive);
|
||||
{
|
||||
move32(Imm32(0), output);
|
||||
jump(&done);
|
||||
}
|
||||
|
||||
bind(&positive);
|
||||
|
||||
// Add 0.5 and truncate.
|
||||
loadConstantDouble(0.5, ScratchDoubleReg);
|
||||
addDouble(ScratchDoubleReg, input);
|
||||
|
||||
Label outOfRange;
|
||||
|
||||
// Truncate to int32 and ensure the result <= 255. This relies on the
|
||||
// processor setting output to a value > 255 for doubles outside the int32
|
||||
// range (for instance 0x80000000).
|
||||
vcvttsd2si(input, output);
|
||||
branch32(Assembler::Above, output, Imm32(255), &outOfRange);
|
||||
{
|
||||
// Check if we had a tie.
|
||||
convertInt32ToDouble(output, ScratchDoubleReg);
|
||||
branchDouble(DoubleNotEqual, input, ScratchDoubleReg, &done);
|
||||
|
||||
// It was a tie. Mask out the ones bit to get an even value.
|
||||
// See also js_TypedArray_uint8_clamp_double.
|
||||
and32(Imm32(~1), output);
|
||||
jump(&done);
|
||||
}
|
||||
|
||||
// > 255 --> 255
|
||||
bind(&outOfRange);
|
||||
{
|
||||
move32(Imm32(255), output);
|
||||
}
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
// Builds an exit frame on the stack, with a return address to an internal
|
||||
// non-function. Returns offset to be passed to markSafepointAt().
|
||||
void
|
||||
MacroAssemblerX86Shared::buildFakeExitFrame(Register scratch, uint32_t* offset)
|
||||
{
|
||||
mozilla::DebugOnly<uint32_t> initialDepth = framePushed();
|
||||
|
||||
CodeLabel cl;
|
||||
mov(cl.dest(), scratch);
|
||||
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor));
|
||||
Push(scratch);
|
||||
|
||||
bind(cl.src());
|
||||
*offset = currentOffset();
|
||||
|
||||
MOZ_ASSERT(framePushed() == initialDepth + ExitFrameLayout::Size());
|
||||
addCodeLabel(cl);
|
||||
push(op);
|
||||
framePushed_ += sizeof(intptr_t);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::callWithExitFrame(Label* target)
|
||||
MacroAssembler::Push(Register reg)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor));
|
||||
call(target);
|
||||
push(reg);
|
||||
framePushed_ += sizeof(intptr_t);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::callWithExitFrame(JitCode* target)
|
||||
MacroAssembler::Push(const Imm32 imm)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor));
|
||||
call(target);
|
||||
push(imm);
|
||||
framePushed_ += sizeof(intptr_t);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::alignFrameForICArguments(AfterICSaveLive& aic)
|
||||
MacroAssembler::Push(const ImmWord imm)
|
||||
{
|
||||
// Exists for MIPS compatibility.
|
||||
push(imm);
|
||||
framePushed_ += sizeof(intptr_t);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic)
|
||||
MacroAssembler::Push(const ImmPtr imm)
|
||||
{
|
||||
// Exists for MIPS compatibility.
|
||||
}
|
||||
|
||||
bool
|
||||
MacroAssemblerX86Shared::buildOOLFakeExitFrame(void* fakeReturnAddr)
|
||||
{
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS);
|
||||
Push(Imm32(descriptor));
|
||||
Push(ImmPtr(fakeReturnAddr));
|
||||
return true;
|
||||
Push(ImmWord(uintptr_t(imm.value)));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::branchNegativeZero(FloatRegister reg,
|
||||
Register scratch,
|
||||
Label* label,
|
||||
bool maybeNonZero)
|
||||
MacroAssembler::Push(const ImmGCPtr ptr)
|
||||
{
|
||||
// Determines whether the low double contained in the XMM register reg
|
||||
// is equal to -0.0.
|
||||
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
Label nonZero;
|
||||
|
||||
// if not already compared to zero
|
||||
if (maybeNonZero) {
|
||||
// Compare to zero. Lets through {0, -0}.
|
||||
zeroDouble(ScratchDoubleReg);
|
||||
|
||||
// If reg is non-zero, jump to nonZero.
|
||||
branchDouble(DoubleNotEqual, reg, ScratchDoubleReg, &nonZero);
|
||||
}
|
||||
// Input register is either zero or negative zero. Retrieve sign of input.
|
||||
vmovmskpd(reg, scratch);
|
||||
|
||||
// If reg is 1 or 3, input is negative zero.
|
||||
// If reg is 0 or 2, input is a normal zero.
|
||||
branchTest32(NonZero, scratch, Imm32(1), label);
|
||||
|
||||
bind(&nonZero);
|
||||
#elif defined(JS_CODEGEN_X64)
|
||||
vmovq(reg, scratch);
|
||||
cmpq(Imm32(1), scratch);
|
||||
j(Overflow, label);
|
||||
#endif
|
||||
push(ptr);
|
||||
framePushed_ += sizeof(intptr_t);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86Shared::branchNegativeZeroFloat32(FloatRegister reg,
|
||||
Register scratch,
|
||||
Label* label)
|
||||
MacroAssembler::Push(FloatRegister t)
|
||||
{
|
||||
vmovd(reg, scratch);
|
||||
cmp32(scratch, Imm32(1));
|
||||
j(Overflow, label);
|
||||
push(t);
|
||||
framePushed_ += sizeof(double);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(const Operand op)
|
||||
{
|
||||
pop(op);
|
||||
framePushed_ -= sizeof(intptr_t);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(Register reg)
|
||||
{
|
||||
pop(reg);
|
||||
framePushed_ -= sizeof(intptr_t);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(FloatRegister reg)
|
||||
{
|
||||
pop(reg);
|
||||
framePushed_ -= sizeof(double);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::Pop(const ValueOperand &val)
|
||||
{
|
||||
popValue(val);
|
||||
framePushed_ -= sizeof(Value);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,15 @@
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class MacroAssembler;
|
||||
|
||||
class MacroAssemblerX86Shared : public Assembler
|
||||
{
|
||||
private:
|
||||
// Perform a downcast. Should be removed by Bug 996602.
|
||||
MacroAssembler &asMasm();
|
||||
const MacroAssembler &asMasm() const;
|
||||
|
||||
protected:
|
||||
// Bytes pushed onto the frame by the callee; includes frameDepth_. This is
|
||||
// needed to compute offsets to stack slots while temporary space has been
|
||||
@@ -565,15 +572,6 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
}
|
||||
|
||||
// The following functions are exposed for use in platform-shared code.
|
||||
template <typename T>
|
||||
void Push(const T& t) {
|
||||
push(t);
|
||||
framePushed_ += sizeof(intptr_t);
|
||||
}
|
||||
void Push(FloatRegister t) {
|
||||
push(t);
|
||||
framePushed_ += sizeof(double);
|
||||
}
|
||||
CodeOffsetLabel PushWithPatch(ImmWord word) {
|
||||
framePushed_ += sizeof(word.value);
|
||||
return pushWithPatch(word);
|
||||
@@ -582,15 +580,6 @@ class MacroAssemblerX86Shared : public Assembler
|
||||
return PushWithPatch(ImmWord(uintptr_t(imm.value)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Pop(const T& t) {
|
||||
pop(t);
|
||||
framePushed_ -= sizeof(intptr_t);
|
||||
}
|
||||
void Pop(FloatRegister t) {
|
||||
pop(t);
|
||||
framePushed_ -= sizeof(double);
|
||||
}
|
||||
void implicitPop(uint32_t args) {
|
||||
MOZ_ASSERT(args % sizeof(intptr_t) == 0);
|
||||
framePushed_ -= args;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
||||
MoveEmitterX86::MoveEmitterX86(MacroAssemblerSpecific& masm)
|
||||
MoveEmitterX86::MoveEmitterX86(MacroAssembler &masm)
|
||||
: inCycle_(false),
|
||||
masm(masm),
|
||||
pushedAtCycle_(-1)
|
||||
|
||||
@@ -7,13 +7,7 @@
|
||||
#ifndef jit_MoveEmitter_x86_shared_h
|
||||
#define jit_MoveEmitter_x86_shared_h
|
||||
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
# include "jit/x86/MacroAssembler-x86.h"
|
||||
#elif defined(JS_CODEGEN_X64)
|
||||
# include "jit/x64/MacroAssembler-x64.h"
|
||||
#else
|
||||
# error "Wrong architecture. Only x86 and x64 should build this file!"
|
||||
#endif
|
||||
#include "jit/MacroAssembler.h"
|
||||
#include "jit/MoveResolver.h"
|
||||
|
||||
namespace js {
|
||||
@@ -24,7 +18,7 @@ class CodeGenerator;
|
||||
class MoveEmitterX86
|
||||
{
|
||||
bool inCycle_;
|
||||
MacroAssemblerSpecific& masm;
|
||||
MacroAssembler &masm;
|
||||
|
||||
// Original stack push value.
|
||||
uint32_t pushedAtStart_;
|
||||
@@ -58,9 +52,9 @@ class MoveEmitterX86
|
||||
void completeCycle(const MoveOperand& to, MoveOp::Type type);
|
||||
|
||||
public:
|
||||
explicit MoveEmitterX86(MacroAssemblerSpecific& masm);
|
||||
explicit MoveEmitterX86(MacroAssembler &masm);
|
||||
~MoveEmitterX86();
|
||||
void emit(const MoveResolver& moves);
|
||||
void emit(const MoveResolver &moves);
|
||||
void finish();
|
||||
|
||||
void setScratchRegister(Register reg) {
|
||||
|
||||
@@ -178,16 +178,20 @@ static MOZ_CONSTEXPR_VAR Register OsrFrameReg = IntArgReg3;
|
||||
|
||||
static MOZ_CONSTEXPR_VAR Register PreBarrierReg = rdx;
|
||||
|
||||
static const uint32_t ABIStackAlignment = 16;
|
||||
static const uint32_t CodeAlignment = 16;
|
||||
static const uint32_t JitStackAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t ABIStackAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t CodeAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackAlignment = 16;
|
||||
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackValueAlignment = JitStackAlignment / sizeof(Value);
|
||||
static_assert(JitStackAlignment % sizeof(Value) == 0 && JitStackValueAlignment >= 1,
|
||||
"Stack alignment should be a non-zero multiple of sizeof(Value)");
|
||||
|
||||
// This boolean indicates whether we support SIMD instructions flavoured for
|
||||
// this architecture or not. Rather than a method in the LIRGenerator, it is
|
||||
// here such that it is accessible from the entire codebase. Once full support
|
||||
// for SIMD is reached on all tier-1 platforms, this constant can be deleted.
|
||||
static const bool SupportsSimd = true;
|
||||
static const uint32_t SimdMemoryAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR bool SupportsSimd = true;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t SimdMemoryAlignment = 16;
|
||||
|
||||
static_assert(CodeAlignment % SimdMemoryAlignment == 0,
|
||||
"Code alignment should be larger than any of the alignments which are used for "
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "jit/BaselineFrame.h"
|
||||
#include "jit/JitCompartment.h"
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/MacroAssembler.h"
|
||||
#include "jit/MoveEmitter.h"
|
||||
|
||||
using namespace js;
|
||||
@@ -288,7 +289,7 @@ MacroAssemblerX64::callWithABIPre(uint32_t* stackAdjust)
|
||||
if (!enoughMemory_)
|
||||
return;
|
||||
|
||||
MoveEmitter emitter(*this);
|
||||
MoveEmitter emitter(asMasm());
|
||||
emitter.emit(moveResolver_);
|
||||
emitter.finish();
|
||||
}
|
||||
@@ -504,6 +505,15 @@ template void
|
||||
MacroAssemblerX64::storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const BaseIndex& dest,
|
||||
MIRType slotType);
|
||||
|
||||
void
|
||||
MacroAssemblerX64::callWithExitFrame(JitCode *target, Register dynStack)
|
||||
{
|
||||
addPtr(Imm32(framePushed()), dynStack);
|
||||
makeFrameDescriptor(dynStack, JitFrame_IonJS);
|
||||
asMasm().Push(dynStack);
|
||||
call(target);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label)
|
||||
{
|
||||
@@ -548,3 +558,15 @@ MacroAssemblerX64::profilerExitFrame()
|
||||
{
|
||||
jmp(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
|
||||
}
|
||||
|
||||
MacroAssembler &
|
||||
MacroAssemblerX64::asMasm()
|
||||
{
|
||||
return *static_cast<MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
const MacroAssembler &
|
||||
MacroAssemblerX64::asMasm() const
|
||||
{
|
||||
return *static_cast<const MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,12 @@ struct ImmTag : public Imm32
|
||||
|
||||
class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
{
|
||||
private:
|
||||
// Perform a downcast. Should be removed by Bug 996602.
|
||||
MacroAssembler &asMasm();
|
||||
const MacroAssembler &asMasm() const;
|
||||
|
||||
private:
|
||||
// Number of bytes the stack is adjusted inside a call to C. Calls to C may
|
||||
// not be nested.
|
||||
bool inCall_;
|
||||
@@ -84,8 +90,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
|
||||
public:
|
||||
using MacroAssemblerX86Shared::call;
|
||||
using MacroAssemblerX86Shared::Push;
|
||||
using MacroAssemblerX86Shared::Pop;
|
||||
using MacroAssemblerX86Shared::callWithExitFrame;
|
||||
using MacroAssemblerX86Shared::branch32;
|
||||
using MacroAssemblerX86Shared::branchTest32;
|
||||
@@ -215,14 +219,10 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
void pushValue(ValueOperand val) {
|
||||
push(val.valueReg());
|
||||
}
|
||||
void Push(const ValueOperand& val) {
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
void popValue(ValueOperand val) {
|
||||
pop(val.valueReg());
|
||||
}
|
||||
void pushValue(const Value& val) {
|
||||
void pushValue(const Value &val) {
|
||||
jsval_layout jv = JSVAL_TO_IMPL(val);
|
||||
if (val.isMarkable()) {
|
||||
movWithPatch(ImmWord(jv.asBits), ScratchReg);
|
||||
@@ -236,15 +236,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
boxValue(type, reg, ScratchReg);
|
||||
push(ScratchReg);
|
||||
}
|
||||
void pushValue(const Address& addr) {
|
||||
void pushValue(const Address &addr) {
|
||||
push(Operand(addr));
|
||||
}
|
||||
void Pop(const ValueOperand& val) {
|
||||
popValue(val);
|
||||
framePushed_ -= sizeof(Value);
|
||||
}
|
||||
|
||||
void moveValue(const Value& val, Register dest) {
|
||||
void moveValue(const Value &val, Register dest) {
|
||||
jsval_layout jv = JSVAL_TO_IMPL(val);
|
||||
movWithPatch(ImmWord(jv.asBits), dest);
|
||||
writeDataRelocation(val);
|
||||
@@ -1449,15 +1445,10 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
orq(Imm32(type), frameSizeReg);
|
||||
}
|
||||
|
||||
void callWithExitFrame(JitCode* target, Register dynStack) {
|
||||
addPtr(Imm32(framePushed()), dynStack);
|
||||
makeFrameDescriptor(dynStack, JitFrame_IonJS);
|
||||
Push(dynStack);
|
||||
call(target);
|
||||
}
|
||||
void callWithExitFrame(JitCode *target, Register dynStack);
|
||||
|
||||
// See CodeGeneratorX64 calls to noteAsmJSGlobalAccess.
|
||||
void patchAsmJSGlobalAccess(CodeOffsetLabel patchAt, uint8_t* code, uint8_t* globalData,
|
||||
void patchAsmJSGlobalAccess(CodeOffsetLabel patchAt, uint8_t *code, uint8_t *globalData,
|
||||
unsigned globalDataOffset)
|
||||
{
|
||||
uint8_t* nextInsn = code + patchAt.offset();
|
||||
|
||||
@@ -405,10 +405,9 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
|
||||
static_assert(JitStackAlignment % sizeof(Value) == 0,
|
||||
"Ensure that we can pad the stack by pushing extra UndefinedValue");
|
||||
|
||||
const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
MOZ_ASSERT(IsPowerOfTwo(alignment));
|
||||
masm.addl(Imm32(alignment - 1 /* for padding */ + 1 /* for |this| */), rcx);
|
||||
masm.andl(Imm32(~(alignment - 1)), rcx);
|
||||
MOZ_ASSERT(IsPowerOfTwo(JitStackValueAlignment));
|
||||
masm.addl(Imm32(JitStackValueAlignment - 1 /* for padding */ + 1 /* for |this| */), rcx);
|
||||
masm.andl(Imm32(~(JitStackValueAlignment - 1)), rcx);
|
||||
|
||||
// Load the number of |undefined|s to push into %rcx.
|
||||
masm.subq(r8, rcx);
|
||||
|
||||
@@ -105,19 +105,23 @@ static MOZ_CONSTEXPR_VAR Register AsmJSIonExitRegD2 = esi;
|
||||
// GCC stack is aligned on 16 bytes. Ion does not maintain this for internal
|
||||
// calls. asm.js code does.
|
||||
#if defined(__GNUC__)
|
||||
static const uint32_t ABIStackAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t ABIStackAlignment = 16;
|
||||
#else
|
||||
static const uint32_t ABIStackAlignment = 4;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t ABIStackAlignment = 4;
|
||||
#endif
|
||||
static const uint32_t CodeAlignment = 16;
|
||||
static const uint32_t JitStackAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t CodeAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackAlignment = 16;
|
||||
|
||||
static MOZ_CONSTEXPR_VAR uint32_t JitStackValueAlignment = JitStackAlignment / sizeof(Value);
|
||||
static_assert(JitStackAlignment % sizeof(Value) == 0 && JitStackValueAlignment >= 1,
|
||||
"Stack alignment should be a non-zero multiple of sizeof(Value)");
|
||||
|
||||
// This boolean indicates whether we support SIMD instructions flavoured for
|
||||
// this architecture or not. Rather than a method in the LIRGenerator, it is
|
||||
// here such that it is accessible from the entire codebase. Once full support
|
||||
// for SIMD is reached on all tier-1 platforms, this constant can be deleted.
|
||||
static const bool SupportsSimd = true;
|
||||
static const uint32_t SimdMemoryAlignment = 16;
|
||||
static MOZ_CONSTEXPR_VAR bool SupportsSimd = true;
|
||||
static MOZ_CONSTEXPR_VAR uint32_t SimdMemoryAlignment = 16;
|
||||
|
||||
static_assert(CodeAlignment % SimdMemoryAlignment == 0,
|
||||
"Code alignment should be larger than any of the alignments which are used for "
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "jit/Bailouts.h"
|
||||
#include "jit/BaselineFrame.h"
|
||||
#include "jit/JitFrames.h"
|
||||
#include "jit/MacroAssembler.h"
|
||||
#include "jit/MoveEmitter.h"
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
@@ -282,7 +283,7 @@ MacroAssemblerX86::callWithABIPre(uint32_t* stackAdjust)
|
||||
if (!enoughMemory_)
|
||||
return;
|
||||
|
||||
MoveEmitter emitter(*this);
|
||||
MoveEmitter emitter(asMasm());
|
||||
emitter.emit(moveResolver_);
|
||||
emitter.finish();
|
||||
}
|
||||
@@ -498,6 +499,15 @@ template void
|
||||
MacroAssemblerX86::storeUnboxedValue(ConstantOrRegister value, MIRType valueType, const BaseIndex& dest,
|
||||
MIRType slotType);
|
||||
|
||||
void
|
||||
MacroAssemblerX86::callWithExitFrame(JitCode *target, Register dynStack)
|
||||
{
|
||||
addPtr(ImmWord(framePushed()), dynStack);
|
||||
makeFrameDescriptor(dynStack, JitFrame_IonJS);
|
||||
asMasm().Push(dynStack);
|
||||
call(target);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::branchPtrInNurseryRange(Condition cond, Register ptr, Register temp,
|
||||
Label* label)
|
||||
@@ -541,3 +551,15 @@ MacroAssemblerX86::profilerExitFrame()
|
||||
{
|
||||
jmp(GetJitContext()->runtime->jitRuntime()->getProfilerExitFrameTail());
|
||||
}
|
||||
|
||||
MacroAssembler &
|
||||
MacroAssemblerX86::asMasm()
|
||||
{
|
||||
return *static_cast<MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
const MacroAssembler &
|
||||
MacroAssemblerX86::asMasm() const
|
||||
{
|
||||
return *static_cast<const MacroAssembler *>(this);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ namespace jit {
|
||||
|
||||
class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
{
|
||||
private:
|
||||
// Perform a downcast. Should be removed by Bug 996602.
|
||||
MacroAssembler &asMasm();
|
||||
const MacroAssembler &asMasm() const;
|
||||
|
||||
private:
|
||||
// Number of bytes the stack is adjusted inside a call to C. Calls to C may
|
||||
// not be nested.
|
||||
bool inCall_;
|
||||
@@ -77,8 +83,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
void setupABICall(uint32_t args);
|
||||
|
||||
public:
|
||||
using MacroAssemblerX86Shared::Push;
|
||||
using MacroAssemblerX86Shared::Pop;
|
||||
using MacroAssemblerX86Shared::callWithExitFrame;
|
||||
using MacroAssemblerX86Shared::branch32;
|
||||
using MacroAssemblerX86Shared::branchTest32;
|
||||
@@ -238,15 +242,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
push(tagOf(addr));
|
||||
push(payloadOf(addr));
|
||||
}
|
||||
void Push(const ValueOperand& val) {
|
||||
pushValue(val);
|
||||
framePushed_ += sizeof(Value);
|
||||
}
|
||||
void Pop(const ValueOperand& val) {
|
||||
popValue(val);
|
||||
framePushed_ -= sizeof(Value);
|
||||
}
|
||||
void storePayload(const Value& val, Operand dest) {
|
||||
void storePayload(const Value &val, Operand dest) {
|
||||
jsval_layout jv = JSVAL_TO_IMPL(val);
|
||||
if (val.isMarkable())
|
||||
movl(ImmGCPtr((gc::Cell*)jv.s.payload.ptr), ToPayload(dest));
|
||||
@@ -1211,15 +1207,10 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
orl(Imm32(type), frameSizeReg);
|
||||
}
|
||||
|
||||
void callWithExitFrame(JitCode* target, Register dynStack) {
|
||||
addPtr(ImmWord(framePushed()), dynStack);
|
||||
makeFrameDescriptor(dynStack, JitFrame_IonJS);
|
||||
Push(dynStack);
|
||||
call(target);
|
||||
}
|
||||
void callWithExitFrame(JitCode *target, Register dynStack);
|
||||
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label* label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label* label);
|
||||
void branchPtrInNurseryRange(Condition cond, Register ptr, Register temp, Label *label);
|
||||
void branchValueIsNurseryObject(Condition cond, ValueOperand value, Register temp, Label *label);
|
||||
|
||||
// Instrumentation for entering and leaving the profiler.
|
||||
void profilerEnterFrame(Register framePtr, Register scratch);
|
||||
|
||||
@@ -395,10 +395,9 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut)
|
||||
static_assert(JitStackAlignment % sizeof(Value) == 0,
|
||||
"Ensure that we can pad the stack by pushing extra UndefinedValue");
|
||||
|
||||
const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||
MOZ_ASSERT(IsPowerOfTwo(alignment));
|
||||
masm.addl(Imm32(alignment - 1 /* for padding */), ecx);
|
||||
masm.andl(Imm32(~(alignment - 1)), ecx);
|
||||
MOZ_ASSERT(IsPowerOfTwo(JitStackValueAlignment));
|
||||
masm.addl(Imm32(JitStackValueAlignment - 1 /* for padding */), ecx);
|
||||
masm.andl(Imm32(~(JitStackValueAlignment - 1)), ecx);
|
||||
masm.subl(esi, ecx);
|
||||
|
||||
// Copy the number of actual arguments.
|
||||
|
||||
@@ -27,13 +27,13 @@ class CustomProxyHandler : public DirectProxyHandler {
|
||||
return impl(cx, proxy, id, desc, true);
|
||||
}
|
||||
|
||||
bool set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const override
|
||||
{
|
||||
Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc))
|
||||
return false;
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &desc, result);
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, desc, result);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
+7
-7
@@ -2918,7 +2918,7 @@ JS_ForwardSetPropertyTo(JSContext *cx, HandleObject obj, HandleId id, HandleValu
|
||||
}
|
||||
|
||||
static bool
|
||||
SetElement(JSContext* cx, HandleObject obj, uint32_t index, MutableHandleValue vp)
|
||||
SetElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
@@ -2929,42 +2929,42 @@ SetElement(JSContext* cx, HandleObject obj, uint32_t index, MutableHandleValue v
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue v)
|
||||
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v)
|
||||
{
|
||||
RootedValue value(cx, v);
|
||||
return SetElement(cx, obj, index, &value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext* cx, HandleObject obj, uint32_t index, HandleObject v)
|
||||
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleObject v)
|
||||
{
|
||||
RootedValue value(cx, ObjectOrNullValue(v));
|
||||
return SetElement(cx, obj, index, &value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext* cx, HandleObject obj, uint32_t index, HandleString v)
|
||||
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleString v)
|
||||
{
|
||||
RootedValue value(cx, StringValue(v));
|
||||
return SetElement(cx, obj, index, &value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext* cx, HandleObject obj, uint32_t index, int32_t v)
|
||||
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, int32_t v)
|
||||
{
|
||||
RootedValue value(cx, NumberValue(v));
|
||||
return SetElement(cx, obj, index, &value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext* cx, HandleObject obj, uint32_t index, uint32_t v)
|
||||
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, uint32_t v)
|
||||
{
|
||||
RootedValue value(cx, NumberValue(v));
|
||||
return SetElement(cx, obj, index, &value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext* cx, HandleObject obj, uint32_t index, double v)
|
||||
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, double v)
|
||||
{
|
||||
RootedValue value(cx, NumberValue(v));
|
||||
return SetElement(cx, obj, index, &value);
|
||||
|
||||
+13
-1
@@ -2587,7 +2587,19 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<
|
||||
value().setUndefined();
|
||||
}
|
||||
|
||||
void assign(JSPropertyDescriptor& other) {
|
||||
void initFields(HandleObject obj, HandleValue v, unsigned attrs,
|
||||
JSGetterOp getterOp, JSSetterOp setterOp) {
|
||||
MOZ_ASSERT(getterOp != JS_PropertyStub);
|
||||
MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
|
||||
|
||||
object().set(obj);
|
||||
value().set(v);
|
||||
setAttributes(attrs);
|
||||
setGetter(getterOp);
|
||||
setSetter(setterOp);
|
||||
}
|
||||
|
||||
void assign(JSPropertyDescriptor &other) {
|
||||
object().set(other.obj);
|
||||
setAttributes(other.attrs);
|
||||
setGetter(other.getter);
|
||||
|
||||
@@ -334,8 +334,8 @@ extern JS_FRIEND_API(bool)
|
||||
proxy_LookupProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp,
|
||||
JS::MutableHandle<Shape*> propp);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_DefineProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
proxy_DefineProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_HasProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
|
||||
@@ -343,10 +343,10 @@ extern JS_FRIEND_API(bool)
|
||||
proxy_GetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue vp);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_SetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue bp, JS::ObjectOpResult &result);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
proxy_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_DeleteProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
@@ -2605,7 +2605,7 @@ ForwardToNative(JSContext* cx, JSNative native, const JS::CallArgs& args);
|
||||
JS_FRIEND_API(bool)
|
||||
SetPropertyIgnoringNamedGetter(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandleValue vp, JS::HandleObject receiver,
|
||||
JS::MutableHandle<JSPropertyDescriptor> ownDesc,
|
||||
JS::Handle<JSPropertyDescriptor> ownDesc,
|
||||
JS::ObjectOpResult &result);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
||||
+18
-11
@@ -690,7 +690,7 @@ js::StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
if (obj->is<ProxyObject>()) {
|
||||
Rooted<PropertyDescriptor> pd(cx, desc);
|
||||
pd.object().set(obj);
|
||||
return Proxy::defineProperty(cx, obj, id, &pd, result);
|
||||
return Proxy::defineProperty(cx, obj, id, pd, result);
|
||||
}
|
||||
return result.fail(JSMSG_OBJECT_NOT_EXTENSIBLE);
|
||||
}
|
||||
@@ -1577,11 +1577,11 @@ js::CreateThisForFunction(JSContext* cx, HandleObject callee, NewObjectKind newK
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetProperty(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (MOZ_UNLIKELY(obj->watched())) {
|
||||
WatchpointMap* wpmap = cx->compartment()->watchpointMap;
|
||||
WatchpointMap *wpmap = cx->compartment()->watchpointMap;
|
||||
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
|
||||
return false;
|
||||
}
|
||||
@@ -1589,7 +1589,7 @@ JSObject::nonNativeSetProperty(JSContext* cx, HandleObject obj, HandleObject rec
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetElement(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
uint32_t index, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
@@ -3175,23 +3175,30 @@ js::GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineProperty(JSContext *cx, HandleObject obj, HandleId id, Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (DefinePropertyOp op = obj->getOps()->defineProperty)
|
||||
return op(cx, obj, id, desc, result);
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
|
||||
|
||||
DefinePropertyOp op = obj->getOps()->defineProperty;
|
||||
if (op) {
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.initFields(obj, value, attrs, getter, setter);
|
||||
if (DefinePropertyOp op = obj->getOps()->defineProperty) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
return op(cx->asJSContext(), obj, id, value, getter, setter, attrs, result);
|
||||
return op(cx->asJSContext(), obj, id, desc, result);
|
||||
}
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, value, getter, setter, attrs,
|
||||
result);
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
+11
-7
@@ -471,17 +471,17 @@ class JSObject : public js::gc::Cell
|
||||
* callable a TypeError will be thrown. On success the value returned by
|
||||
* the call is stored in *vp.
|
||||
*/
|
||||
bool callMethod(JSContext* cx, js::HandleId id, unsigned argc, js::Value* argv,
|
||||
bool callMethod(JSContext *cx, js::HandleId id, unsigned argc, js::Value *argv,
|
||||
js::MutableHandleValue vp);
|
||||
|
||||
static bool nonNativeSetProperty(JSContext* cx, js::HandleObject obj,
|
||||
static bool nonNativeSetProperty(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleObject receiver, js::HandleId id,
|
||||
js::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
static bool nonNativeSetElement(JSContext* cx, js::HandleObject obj,
|
||||
static bool nonNativeSetElement(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleObject receiver, uint32_t index,
|
||||
js::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
|
||||
static bool swap(JSContext* cx, JS::HandleObject a, JS::HandleObject b);
|
||||
static bool swap(JSContext *cx, JS::HandleObject a, JS::HandleObject b);
|
||||
|
||||
private:
|
||||
void fixDictionaryShapeAfterSwap();
|
||||
@@ -764,6 +764,10 @@ extern bool
|
||||
StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc);
|
||||
|
||||
extern bool
|
||||
DefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp, unsigned attrs, ObjectOpResult &result);
|
||||
@@ -861,11 +865,11 @@ GetElementNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, uint32_t index,
|
||||
* argument instead, but this has to change. See bug 1113369.
|
||||
*/
|
||||
inline bool
|
||||
SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
inline bool
|
||||
SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, PropertyName* name,
|
||||
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, PropertyName *name,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
@@ -873,7 +877,7 @@ SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, PropertyName
|
||||
}
|
||||
|
||||
inline bool
|
||||
SetElement(JSContext* cx, HandleObject obj, HandleObject receiver, uint32_t index,
|
||||
SetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
inline bool
|
||||
|
||||
+5
-1
@@ -3012,7 +3012,11 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
|
||||
} else if (obj->is<JSFunction>()) {
|
||||
RootedFunction innerFun(cx, &obj->as<JSFunction>());
|
||||
if (innerFun->isNative()) {
|
||||
assertSameCompartment(cx, innerFun);
|
||||
if (cx->compartment() != innerFun->compartment()) {
|
||||
MOZ_ASSERT(innerFun->isAsmJSNative());
|
||||
JS_ReportError(cx, "AsmJS modules do not yet support cloning.");
|
||||
return nullptr;
|
||||
}
|
||||
clone = innerFun;
|
||||
} else {
|
||||
if (innerFun->isInterpretedLazy()) {
|
||||
|
||||
+2
-2
@@ -117,7 +117,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper,
|
||||
AutoIdVector& props) const override;
|
||||
@@ -185,7 +185,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
|
||||
bool* bp) const override;
|
||||
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const override;
|
||||
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper,
|
||||
|
||||
@@ -72,7 +72,7 @@ BaseProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
}
|
||||
|
||||
bool
|
||||
BaseProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
@@ -88,15 +88,17 @@ BaseProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
|
||||
// The rest is factored out into a separate function with a weird name.
|
||||
// This algorithm continues just below.
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &ownDesc, result);
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, ownDesc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, HandleObject receiver,
|
||||
MutableHandle<PropertyDescriptor> ownDesc,
|
||||
Handle<PropertyDescriptor> ownDesc_,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<PropertyDescriptor> ownDesc(cx, ownDesc_);
|
||||
|
||||
// Step 4.
|
||||
if (!ownDesc.object()) {
|
||||
// The spec calls this variable "parent", but that word has weird
|
||||
@@ -107,16 +109,13 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
|
||||
if (proto)
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
|
||||
// Change ownDesc to be a complete descriptor for a configurable,
|
||||
// writable, enumerable data property. Then fall through to step 5.
|
||||
ownDesc.clear();
|
||||
ownDesc.setAttributes(JSPROP_ENUMERATE);
|
||||
// Step 4.d.
|
||||
ownDesc.setDataDescriptor(UndefinedHandleValue, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (ownDesc.isDataDescriptor()) {
|
||||
// Steps 5.a-b, adapted to our nonstandard implementation of ES6
|
||||
// [[Set]] return values.
|
||||
// Steps 5.a-b.
|
||||
if (!ownDesc.writable())
|
||||
return result.fail(JSMSG_READ_ONLY);
|
||||
|
||||
@@ -140,7 +139,7 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
|
||||
|
||||
// A very old nonstandard SpiderMonkey extension: default to the Class
|
||||
// getter and setter ops.
|
||||
const Class* clasp = receiver->getClass();
|
||||
const Class *clasp = receiver->getClass();
|
||||
MOZ_ASSERT(clasp->getProperty != JS_PropertyStub);
|
||||
MOZ_ASSERT(clasp->setProperty != JS_StrictPropertyStub);
|
||||
return DefineProperty(cx, receiver, id, vp, clasp->getProperty, clasp->setProperty,
|
||||
|
||||
@@ -48,14 +48,14 @@ CrossCompartmentWrapper::getOwnPropertyDescriptor(JSContext* cx, HandleObject wr
|
||||
}
|
||||
|
||||
bool
|
||||
CrossCompartmentWrapper::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
CrossCompartmentWrapper::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
Rooted<PropertyDescriptor> desc2(cx, desc);
|
||||
PIERCE(cx, wrapper,
|
||||
cx->compartment()->wrap(cx, &desc2),
|
||||
Wrapper::defineProperty(cx, wrapper, id, &desc2, result),
|
||||
Wrapper::defineProperty(cx, wrapper, id, desc2, result),
|
||||
NOTHING);
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ CrossCompartmentWrapper::get(JSContext* cx, HandleObject wrapper, HandleObject r
|
||||
}
|
||||
|
||||
bool
|
||||
CrossCompartmentWrapper::set(JSContext* cx, HandleObject wrapper, HandleObject receiver,
|
||||
CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
RootedObject receiverCopy(cx, receiver);
|
||||
@@ -181,7 +181,7 @@ CrossCompartmentWrapper::set(JSContext* cx, HandleObject wrapper, HandleObject r
|
||||
}
|
||||
|
||||
bool
|
||||
CrossCompartmentWrapper::getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject wrapper,
|
||||
CrossCompartmentWrapper::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject wrapper,
|
||||
AutoIdVector& props) const
|
||||
{
|
||||
PIERCE(cx, wrapper,
|
||||
|
||||
@@ -15,7 +15,7 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
bool
|
||||
DeadObjectProxy::getPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
DeadObjectProxy::getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
{
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
|
||||
@@ -23,7 +23,7 @@ DeadObjectProxy::getPropertyDescriptor(JSContext* cx, HandleObject wrapper, Hand
|
||||
}
|
||||
|
||||
bool
|
||||
DeadObjectProxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
DeadObjectProxy::getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
{
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
|
||||
@@ -31,8 +31,8 @@ DeadObjectProxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, H
|
||||
}
|
||||
|
||||
bool
|
||||
DeadObjectProxy::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
DeadObjectProxy::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
|
||||
|
||||
@@ -19,12 +19,12 @@ class DeadObjectProxy : public BaseProxyHandler
|
||||
{ }
|
||||
|
||||
/* Standard internal methods. */
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper,
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
ObjectOpResult &result) const override;
|
||||
|
||||
@@ -33,8 +33,8 @@ DirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy,
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
DirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
@@ -103,12 +103,8 @@ DirectProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandle
|
||||
bool* bp) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
|
||||
bool b;
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
if (!HasInstance(cx, target, v, &b))
|
||||
return false;
|
||||
*bp = !!b;
|
||||
return true;
|
||||
return HasInstance(cx, target, v, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -198,12 +194,8 @@ DirectProxyHandler::has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
|
||||
bool found;
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
if (!JS_HasPropertyById(cx, target, id, &found))
|
||||
return false;
|
||||
*bp = !!found;
|
||||
return true;
|
||||
return HasProperty(cx, target, id, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -211,7 +203,7 @@ DirectProxyHandler::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool*
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, GET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return js::HasOwnProperty(cx, target, id, bp);
|
||||
return HasOwnProperty(cx, target, id, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -224,7 +216,7 @@ DirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
|
||||
+7
-13
@@ -133,11 +133,11 @@ Proxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc, ObjectOpResult &result)
|
||||
Proxy::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc, ObjectOpResult &result)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
|
||||
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||
if (!policy.allowed()) {
|
||||
if (!policy.returnValue())
|
||||
@@ -559,17 +559,11 @@ js::proxy_LookupProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
bool
|
||||
js::proxy_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
js::proxy_DefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.object().set(obj);
|
||||
desc.value().set(value);
|
||||
desc.setAttributes(attrs);
|
||||
desc.setGetter(getter);
|
||||
desc.setSetter(setter);
|
||||
return Proxy::defineProperty(cx, obj, id, &desc, result);
|
||||
return Proxy::defineProperty(cx, obj, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -586,7 +580,7 @@ js::proxy_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, Ha
|
||||
}
|
||||
|
||||
bool
|
||||
js::proxy_SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
js::proxy_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
return Proxy::set(cx, obj, receiver, id, vp, result);
|
||||
|
||||
@@ -26,11 +26,11 @@ class Proxy
|
||||
{
|
||||
public:
|
||||
/* Standard internal methods. */
|
||||
static bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc);
|
||||
static bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc, ObjectOpResult &result);
|
||||
static bool ownPropertyKeys(JSContext* cx, HandleObject proxy, AutoIdVector& props);
|
||||
static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc, ObjectOpResult &result);
|
||||
static bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props);
|
||||
static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, ObjectOpResult &result);
|
||||
static bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp);
|
||||
static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible);
|
||||
|
||||
@@ -274,7 +274,7 @@ ScriptedDirectProxyHandler::getPrototype(JSContext *cx, HandleObject proxy,
|
||||
return false;
|
||||
}
|
||||
|
||||
return DirectProxyHandler::getPrototype(cx, proxy, protop);
|
||||
return GetPrototype(cx, target, protop);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -287,7 +287,7 @@ ScriptedDirectProxyHandler::setPrototype(JSContext *cx, HandleObject proxy, Hand
|
||||
return false;
|
||||
}
|
||||
|
||||
return DirectProxyHandler::setPrototype(cx, proxy, proto, result);
|
||||
return SetPrototype(cx, target, proto, result);
|
||||
}
|
||||
|
||||
// Not yet part of ES6, but hopefully to be standards-tracked -- and needed to
|
||||
@@ -302,7 +302,7 @@ ScriptedDirectProxyHandler::setImmutablePrototype(JSContext *cx, HandleObject pr
|
||||
return false;
|
||||
}
|
||||
|
||||
return DirectProxyHandler::setImmutablePrototype(cx, proxy, succeeded);
|
||||
return SetImmutablePrototype(cx, target, succeeded);
|
||||
}
|
||||
|
||||
// ES6 draft rev 32 (2 Feb 2015) 9.5.4 Proxy.[[PreventExtensions]]()
|
||||
@@ -327,7 +327,7 @@ ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy,
|
||||
|
||||
// Step 7.
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::preventExtensions(cx, proxy, result);
|
||||
return PreventExtensions(cx, target, result);
|
||||
|
||||
// Steps 8-9.
|
||||
Value argv[] = {
|
||||
@@ -375,7 +375,7 @@ ScriptedDirectProxyHandler::isExtensible(JSContext* cx, HandleObject proxy, bool
|
||||
|
||||
// step 6
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::isExtensible(cx, proxy, extensible);
|
||||
return IsExtensible(cx, target, extensible);
|
||||
|
||||
// step 7, 9
|
||||
Value argv[] = {
|
||||
@@ -450,7 +450,7 @@ ScriptedDirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject
|
||||
|
||||
// step 7
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::getOwnPropertyDescriptor(cx, proxy, id, desc);
|
||||
return GetOwnPropertyDescriptor(cx, target, id, desc);
|
||||
|
||||
// step 8-9
|
||||
RootedValue propKey(cx);
|
||||
@@ -549,8 +549,8 @@ ScriptedDirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject
|
||||
|
||||
// ES6 draft rev 31 (15 Jan 2015) 9.5.6 Proxy.[[DefineOwnProperty]](P, Desc)
|
||||
bool
|
||||
ScriptedDirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ScriptedDirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
// step 2-4
|
||||
@@ -570,7 +570,7 @@ ScriptedDirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, Ha
|
||||
|
||||
// step 8
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::defineProperty(cx, proxy, id, desc, result);
|
||||
return StandardDefineProperty(cx, target, id, desc, result);
|
||||
|
||||
// step 9
|
||||
RootedValue descObj(cx);
|
||||
@@ -657,7 +657,7 @@ ScriptedDirectProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
|
||||
// step 6
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::ownPropertyKeys(cx, proxy, props);
|
||||
return GetPropertyKeys(cx, target, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &props);
|
||||
|
||||
// step 7-8
|
||||
Value argv[] = {
|
||||
@@ -704,7 +704,7 @@ ScriptedDirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId
|
||||
|
||||
// step 8
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::delete_(cx, proxy, id, result);
|
||||
return DeleteProperty(cx, target, id, result);
|
||||
|
||||
// steps 9-10
|
||||
RootedValue value(cx);
|
||||
@@ -763,7 +763,7 @@ ScriptedDirectProxyHandler::enumerate(JSContext* cx, HandleObject proxy,
|
||||
|
||||
// step 7
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::enumerate(cx, proxy, objp);
|
||||
return GetIterator(cx, target, 0, objp);
|
||||
|
||||
// step 8-9
|
||||
Value argv[] = {
|
||||
@@ -807,7 +807,7 @@ ScriptedDirectProxyHandler::has(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
|
||||
// step 7
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::has(cx, proxy, id, bp);
|
||||
return HasProperty(cx, target, id, bp);
|
||||
|
||||
// step 8,10
|
||||
RootedValue value(cx);
|
||||
@@ -875,7 +875,7 @@ ScriptedDirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject
|
||||
|
||||
// step 7
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::get(cx, proxy, receiver, id, vp);
|
||||
return GetProperty(cx, target, receiver, id, vp);
|
||||
|
||||
// step 8-9
|
||||
RootedValue value(cx);
|
||||
@@ -922,7 +922,7 @@ ScriptedDirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject
|
||||
|
||||
// ES6 draft rev 32 (2015 Feb 2) 9.5.9 Proxy.[[Set]](P, V, Receiver)
|
||||
bool
|
||||
ScriptedDirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
// step 2-3 (Steps 1 and 4 are irrelevant assertions.)
|
||||
@@ -940,7 +940,7 @@ ScriptedDirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject
|
||||
|
||||
// step 8
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::set(cx, proxy, receiver, id, vp, result);
|
||||
return SetProperty(cx, target, receiver, id, vp, result);
|
||||
|
||||
// step 9-10
|
||||
RootedValue value(cx);
|
||||
@@ -1015,8 +1015,10 @@ ScriptedDirectProxyHandler::call(JSContext* cx, HandleObject proxy, const CallAr
|
||||
return false;
|
||||
|
||||
// step 6
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::call(cx, proxy, args);
|
||||
if (trap.isUndefined()) {
|
||||
RootedValue targetv(cx, ObjectValue(*target));
|
||||
return Invoke(cx, args.thisv(), targetv, args.length(), args.array(), args.rval());
|
||||
}
|
||||
|
||||
// step 8
|
||||
Value argv[] = {
|
||||
@@ -1056,8 +1058,10 @@ ScriptedDirectProxyHandler::construct(JSContext* cx, HandleObject proxy, const C
|
||||
return false;
|
||||
|
||||
// step 6
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::construct(cx, proxy, args);
|
||||
if (trap.isUndefined()) {
|
||||
RootedValue targetv(cx, ObjectValue(*target));
|
||||
return InvokeConstructor(cx, targetv, args.length(), args.array(), args.rval());
|
||||
}
|
||||
|
||||
// step 8-9
|
||||
Value constructArgv[] = {
|
||||
@@ -1088,13 +1092,13 @@ bool
|
||||
ScriptedDirectProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
|
||||
bool* bp) const
|
||||
{
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
if (!handler) {
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
if (!target) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return DirectProxyHandler::hasInstance(cx, proxy, v, bp);
|
||||
return HasInstance(cx, target, v, bp);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1121,11 +1125,11 @@ const char*
|
||||
ScriptedDirectProxyHandler::className(JSContext* cx, HandleObject proxy) const
|
||||
{
|
||||
// Right now the caller is not prepared to handle failures.
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
if (!handler)
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
if (!target)
|
||||
return BaseProxyHandler::className(cx, proxy);
|
||||
|
||||
return DirectProxyHandler::className(cx, proxy);
|
||||
return GetObjectClassName(cx, target);
|
||||
}
|
||||
JSString*
|
||||
ScriptedDirectProxyHandler::fun_toString(JSContext* cx, HandleObject proxy,
|
||||
|
||||
@@ -12,20 +12,20 @@
|
||||
namespace js {
|
||||
|
||||
/* Derived class for all scripted direct proxy handlers. */
|
||||
class ScriptedDirectProxyHandler : public DirectProxyHandler {
|
||||
class ScriptedDirectProxyHandler : public BaseProxyHandler {
|
||||
public:
|
||||
MOZ_CONSTEXPR ScriptedDirectProxyHandler()
|
||||
: DirectProxyHandler(&family)
|
||||
: BaseProxyHandler(&family)
|
||||
{ }
|
||||
|
||||
/* Standard internal methods. */
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const override;
|
||||
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const override;
|
||||
@@ -46,10 +46,10 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
|
||||
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override;
|
||||
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const override;
|
||||
virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
|
||||
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
|
||||
/* SpiderMonkey extensions. */
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
|
||||
@@ -197,7 +197,7 @@ ScriptedIndirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObje
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
|
||||
@@ -304,7 +304,7 @@ ScriptedIndirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObjec
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
ScriptedIndirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
|
||||
@@ -393,7 +393,7 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext* cx, HandleObject proxy, Hand
|
||||
|
||||
if (descIsOwn) {
|
||||
MOZ_ASSERT(desc.object() == proxy);
|
||||
return this->defineProperty(cx, proxy, id, &desc, result);
|
||||
return this->defineProperty(cx, proxy, id, desc, result);
|
||||
}
|
||||
return DefineProperty(cx, receiver, id, desc.value(), desc.getter(), desc.setter(),
|
||||
desc.attributes(), result);
|
||||
|
||||
@@ -20,10 +20,10 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
||||
{ }
|
||||
|
||||
/* Standard internal methods. */
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
@@ -55,7 +55,7 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
||||
static const ScriptedIndirectProxyHandler singleton;
|
||||
|
||||
private:
|
||||
bool derivedSet(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
bool derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -103,8 +103,8 @@ SecurityWrapper<Base>::boxedValue_unbox(JSContext* cx, HandleObject obj, Mutable
|
||||
|
||||
template <class Base>
|
||||
bool
|
||||
SecurityWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id, MutableHandle<PropertyDescriptor> desc,
|
||||
SecurityWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
if (desc.getter() || desc.setter()) {
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
function createProxy(proxyTarget) {
|
||||
var {proxy, revoke} = Proxy.revocable(proxyTarget, new Proxy({}, {
|
||||
get(target, propertyKey, receiver) {
|
||||
print("trap get:", propertyKey);
|
||||
revoke();
|
||||
}
|
||||
}));
|
||||
return proxy;
|
||||
}
|
||||
|
||||
var obj;
|
||||
|
||||
// [[GetPrototypeOf]]
|
||||
assertEq(Object.getPrototypeOf(createProxy({})), Object.prototype);
|
||||
assertEq(Object.getPrototypeOf(createProxy([])), Array.prototype);
|
||||
|
||||
// [[SetPrototypeOf]]
|
||||
obj = {};
|
||||
Object.setPrototypeOf(createProxy(obj), Array.prototype);
|
||||
assertEq(Object.getPrototypeOf(obj), Array.prototype);
|
||||
|
||||
// [[IsExtensible]]
|
||||
assertEq(Object.isExtensible(createProxy({})), true);
|
||||
assertEq(Object.isExtensible(createProxy(Object.preventExtensions({}))), false);
|
||||
|
||||
// [[PreventExtensions]]
|
||||
obj = {};
|
||||
Object.preventExtensions(createProxy(obj));
|
||||
assertEq(Object.isExtensible(obj), false);
|
||||
|
||||
// [[GetOwnProperty]]
|
||||
assertEq(Object.getOwnPropertyDescriptor(createProxy({}), "a"), undefined);
|
||||
assertEq(Object.getOwnPropertyDescriptor(createProxy({a: 5}), "a").value, 5);
|
||||
|
||||
// [[DefineOwnProperty]]
|
||||
obj = {};
|
||||
Object.defineProperty(createProxy(obj), "a", {value: 5});
|
||||
assertEq(obj.a, 5);
|
||||
|
||||
// [[HasProperty]]
|
||||
assertEq("a" in createProxy({}), false);
|
||||
assertEq("a" in createProxy({a: 5}), true);
|
||||
|
||||
// [[Get]]
|
||||
assertEq(createProxy({}).a, undefined);
|
||||
assertEq(createProxy({a: 5}).a, 5);
|
||||
|
||||
// [[Set]]
|
||||
assertThrowsInstanceOf(() => createProxy({}).a = 0, TypeError);
|
||||
assertThrowsInstanceOf(() => createProxy({a: 5}).a = 0, TypeError);
|
||||
|
||||
// [[Delete]]
|
||||
assertEq(delete createProxy({}).a, true);
|
||||
assertEq(delete createProxy(Object.defineProperty({}, "a", {configurable: false})).a, false);
|
||||
|
||||
// [[Enumerate]]
|
||||
for (var k in createProxy({})) {
|
||||
// No properties in object.
|
||||
assertEq(true, false);
|
||||
}
|
||||
for (var k in createProxy({a: 5})) {
|
||||
// Properties in object.
|
||||
assertEq(k, "a");
|
||||
}
|
||||
|
||||
// [[OwnPropertyKeys]]
|
||||
assertEq(Object.getOwnPropertyNames(createProxy({})).length, 0);
|
||||
assertEq(Object.getOwnPropertyNames(createProxy({a: 5})).length, 1);
|
||||
|
||||
// [[Call]]
|
||||
assertEq(createProxy(function() { return "ok" })(), "ok");
|
||||
|
||||
// [[Construct]]
|
||||
// This should throw per bug 1141865.
|
||||
assertEq(new (createProxy(function(){ return obj; })), obj);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
@@ -317,7 +317,7 @@ GetNameOperation(JSContext *cx, InterpreterFrame *fp, jsbytecode *pc, MutableHan
|
||||
}
|
||||
|
||||
static bool
|
||||
SetObjectProperty(JSContext* cx, JSOp op, HandleValue lval, HandleId id, MutableHandleValue rref)
|
||||
SetObjectProperty(JSContext *cx, JSOp op, HandleValue lval, HandleId id, MutableHandleValue rref)
|
||||
{
|
||||
MOZ_ASSERT(lval.isObject());
|
||||
|
||||
@@ -339,7 +339,7 @@ SetObjectProperty(JSContext* cx, JSOp op, HandleValue lval, HandleId id, Mutable
|
||||
}
|
||||
|
||||
static bool
|
||||
SetPrimitiveProperty(JSContext* cx, JSOp op, HandleValue lval, HandleId id,
|
||||
SetPrimitiveProperty(JSContext *cx, JSOp op, HandleValue lval, HandleId id,
|
||||
MutableHandleValue rref)
|
||||
{
|
||||
MOZ_ASSERT(lval.isPrimitive());
|
||||
@@ -353,7 +353,7 @@ SetPrimitiveProperty(JSContext* cx, JSOp op, HandleValue lval, HandleId id,
|
||||
}
|
||||
|
||||
static bool
|
||||
SetPropertyOperation(JSContext* cx, JSOp op, HandleValue lval, HandleId id, HandleValue rval)
|
||||
SetPropertyOperation(JSContext *cx, JSOp op, HandleValue lval, HandleId id, HandleValue rval)
|
||||
{
|
||||
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
|
||||
|
||||
@@ -842,8 +842,8 @@ js::InvokeConstructor(JSContext* cx, Value fval, unsigned argc, const Value* arg
|
||||
}
|
||||
|
||||
bool
|
||||
js::InvokeGetterOrSetter(JSContext* cx, JSObject* obj, Value fval, unsigned argc,
|
||||
Value* argv, MutableHandleValue rval)
|
||||
js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc,
|
||||
Value *argv, MutableHandleValue rval)
|
||||
{
|
||||
/*
|
||||
* Invoke could result in another try to get or set the same id again, see
|
||||
|
||||
@@ -80,7 +80,7 @@ Invoke(JSContext* cx, const Value& thisv, const Value& fval, unsigned argc, cons
|
||||
* getter/setter calls.
|
||||
*/
|
||||
extern bool
|
||||
InvokeGetterOrSetter(JSContext* cx, JSObject* obj, Value fval, unsigned argc, Value* argv,
|
||||
InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc, Value *argv,
|
||||
MutableHandleValue rval);
|
||||
|
||||
/*
|
||||
|
||||
@@ -72,8 +72,8 @@ NativeObject::clearShouldConvertDoubleElements()
|
||||
}
|
||||
|
||||
inline void
|
||||
NativeObject::setDenseElementWithType(ExclusiveContext* cx, uint32_t index,
|
||||
const Value& val)
|
||||
NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index,
|
||||
const Value &val)
|
||||
{
|
||||
// Avoid a slow AddTypePropertyId call if the type is the same as the type
|
||||
// of the previous element.
|
||||
@@ -84,8 +84,8 @@ NativeObject::setDenseElementWithType(ExclusiveContext* cx, uint32_t index,
|
||||
}
|
||||
|
||||
inline void
|
||||
NativeObject::initDenseElementWithType(ExclusiveContext* cx, uint32_t index,
|
||||
const Value& val)
|
||||
NativeObject::initDenseElementWithType(ExclusiveContext *cx, uint32_t index,
|
||||
const Value &val)
|
||||
{
|
||||
MOZ_ASSERT(!shouldConvertDoubleElements());
|
||||
AddTypePropertyId(cx, this, JSID_VOID, val);
|
||||
|
||||
+73
-56
@@ -981,6 +981,59 @@ NativeObject::addDataProperty(ExclusiveContext* cx, HandlePropertyName name,
|
||||
return addProperty(cx, self, id, nullptr, nullptr, slot, attrs, 0);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeLookupOwnProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
bool done;
|
||||
return LookupOwnPropertyInline<allowGC>(cx, obj, id, propp, &done);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<CanGC>(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<NoGC>(ExclusiveContext *cx, NativeObject *obj, jsid id,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeLookupProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
return LookupPropertyInline<allowGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<CanGC>(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<NoGC>(ExclusiveContext *cx, NativeObject *obj, jsid id,
|
||||
FakeMutableHandle<JSObject*> objp,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
bool
|
||||
js::NativeLookupElement(JSContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
||||
return LookupPropertyInline<CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
|
||||
/*** [[DefineOwnProperty]] ***********************************************************************/
|
||||
|
||||
/*
|
||||
* Backward compatibility requires allowing addProperty hooks to mutate the
|
||||
* nominal initial value of a slotful property, while GC safety wants that
|
||||
@@ -1286,10 +1339,13 @@ CheckAccessorRedefinition(ExclusiveContext *cx, HandleObject obj, HandleShape sh
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
GetterOp getter = desc.getter();
|
||||
SetterOp setter = desc.setter();
|
||||
unsigned attrs = desc.attributes();
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
|
||||
@@ -1297,7 +1353,7 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
|
||||
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
||||
|
||||
RootedShape shape(cx);
|
||||
RootedValue updateValue(cx, value);
|
||||
RootedValue updateValue(cx, desc.value());
|
||||
bool shouldDefine = true;
|
||||
|
||||
/*
|
||||
@@ -1305,7 +1361,7 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
|
||||
* update the attributes and property ops. A getter or setter is really
|
||||
* only half of a property.
|
||||
*/
|
||||
if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
|
||||
if (desc.isAccessorDescriptor()) {
|
||||
if (!NativeLookupOwnProperty<CanGC>(cx, obj, id, &shape))
|
||||
return false;
|
||||
if (shape) {
|
||||
@@ -1339,7 +1395,7 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
|
||||
shouldDefine = false;
|
||||
}
|
||||
}
|
||||
} else if (!(attrs & JSPROP_IGNORE_VALUE)) {
|
||||
} else if (desc.hasValue()) {
|
||||
// If we did a normal lookup here, it would cause resolve hook recursion in
|
||||
// the following case. Suppose the first script we run in a lazy global is
|
||||
// |parseInt()|.
|
||||
@@ -1444,60 +1500,20 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeLookupOwnProperty(ExclusiveContext* cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
bool done;
|
||||
return LookupOwnPropertyInline<allowGC>(cx, obj, id, propp, &done);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<CanGC>(ExclusiveContext* cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<NoGC>(ExclusiveContext* cx, NativeObject* obj, jsid id,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeLookupProperty(ExclusiveContext* cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
return LookupPropertyInline<allowGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<CanGC>(ExclusiveContext* cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<NoGC>(ExclusiveContext* cx, NativeObject* obj, jsid id,
|
||||
FakeMutableHandle<JSObject*> objp,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
bool
|
||||
js::NativeLookupElement(JSContext* cx, HandleNativeObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
||||
return LookupPropertyInline<CanGC>(cx, obj, id, objp, propp);
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.initFields(obj, value, attrs, getter, setter);
|
||||
return NativeDefineProperty(cx, obj, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, GetterOp getter, SetterOp setter,
|
||||
unsigned attrs, ObjectOpResult &result)
|
||||
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
@@ -1505,8 +1521,8 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyN
|
||||
|
||||
bool
|
||||
js::NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
HandleValue value, GetterOp getter, SetterOp setter,
|
||||
unsigned attrs, ObjectOpResult &result)
|
||||
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (index <= JSID_INT_MAX) {
|
||||
@@ -1551,6 +1567,7 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyN
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
|
||||
/*** [[HasProperty]] *****************************************************************************/
|
||||
|
||||
// ES6 draft rev31 9.1.7.1 OrdinaryHasProperty
|
||||
@@ -2101,7 +2118,7 @@ SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t inde
|
||||
* conforms to no standard and there is a lot of legacy baggage here.
|
||||
*/
|
||||
static bool
|
||||
NativeSet(JSContext* cx, HandleNativeObject obj, HandleObject receiver,
|
||||
NativeSet(JSContext *cx, HandleNativeObject obj, HandleObject receiver,
|
||||
HandleShape shape, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(obj->isNative());
|
||||
|
||||
@@ -1256,6 +1256,11 @@ IsObjectValueInCompartment(Value v, JSCompartment* comp)
|
||||
* (9.4.2), Strings (9.4.3), and so on.
|
||||
*/
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
GetterOp getter, SetterOp, unsigned attrs,
|
||||
|
||||
@@ -501,12 +501,11 @@ with_LookupProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
static bool
|
||||
with_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
with_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return DefineProperty(cx, actual, id, value, getter, setter, attrs, result);
|
||||
return DefineProperty(cx, actual, id, desc, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -533,7 +532,7 @@ with_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleI
|
||||
}
|
||||
|
||||
static bool
|
||||
with_SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
with_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
@@ -999,7 +998,7 @@ uninitialized_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver
|
||||
}
|
||||
|
||||
static bool
|
||||
uninitialized_SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
uninitialized_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
ReportUninitializedLexicalId(cx, id);
|
||||
@@ -1685,8 +1684,8 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
}
|
||||
}
|
||||
|
||||
bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override
|
||||
{
|
||||
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
|
||||
|
||||
@@ -38,7 +38,7 @@ Shape::search(ExclusiveContext* cx, jsid id)
|
||||
}
|
||||
|
||||
inline bool
|
||||
Shape::set(JSContext *cx, HandleNativeObject obj, HandleObject receiver, MutableHandleValue vp,
|
||||
Shape::set(JSContext* cx, HandleNativeObject obj, HandleObject receiver, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT_IF(hasDefaultSetter(), hasGetterValue());
|
||||
|
||||
@@ -679,16 +679,16 @@ UnboxedPlainObject::obj_lookupProperty(JSContext *cx, HandleObject obj,
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
const UnboxedLayout &layout = obj->as<UnboxedPlainObject>().layout();
|
||||
|
||||
if (const UnboxedLayout::Property *property = layout.lookup(id)) {
|
||||
if (!getter && !setter && attrs == JSPROP_ENUMERATE) {
|
||||
if (!desc.getter() && !desc.setter() && desc.attributes() == JSPROP_ENUMERATE) {
|
||||
// This define is equivalent to setting an existing property.
|
||||
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, v))
|
||||
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, desc.value()))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -697,7 +697,8 @@ UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId
|
||||
if (!convertToNative(cx, obj))
|
||||
return false;
|
||||
|
||||
return DefineProperty(cx, obj, id, v, getter, setter, attrs);
|
||||
return DefineProperty(cx, obj, id, desc, result) &&
|
||||
result.checkStrict(cx, obj, id);
|
||||
}
|
||||
|
||||
// Define the property on the expando object.
|
||||
@@ -706,9 +707,9 @@ UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId
|
||||
return false;
|
||||
|
||||
// Update property types on the unboxed object as well.
|
||||
AddTypePropertyId(cx, obj, id, v);
|
||||
AddTypePropertyId(cx, obj, id, desc.value());
|
||||
|
||||
return DefineProperty(cx, expando, id, v, getter, setter, attrs, result);
|
||||
return DefineProperty(cx, expando, id, desc, result);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
@@ -760,7 +761,7 @@ UnboxedPlainObject::obj_getProperty(JSContext *cx, HandleObject obj, HandleObjec
|
||||
UnboxedPlainObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
const UnboxedLayout& layout = obj->as<UnboxedPlainObject>().layout();
|
||||
const UnboxedLayout &layout = obj->as<UnboxedPlainObject>().layout();
|
||||
|
||||
if (const UnboxedLayout::Property *property = layout.lookup(id)) {
|
||||
if (obj == receiver) {
|
||||
|
||||
@@ -192,8 +192,8 @@ class UnboxedPlainObject : public JSObject
|
||||
HandleId id, MutableHandleObject objp,
|
||||
MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext *cx, HandleObject obj, HandleId id, bool* foundp);
|
||||
|
||||
@@ -736,7 +736,7 @@ xpc::SandboxProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
}
|
||||
|
||||
bool
|
||||
xpc::SandboxProxyHandler::set(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
xpc::SandboxProxyHandler::set(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<Value> vp,
|
||||
|
||||
@@ -119,7 +119,7 @@ AddonWrapper<Base>::get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle
|
||||
|
||||
template<typename Base>
|
||||
bool
|
||||
AddonWrapper<Base>::set(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject receiver,
|
||||
AddonWrapper<Base>::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
@@ -146,9 +146,9 @@ AddonWrapper<Base>::set(JSContext* cx, JS::HandleObject wrapper, JS::HandleObjec
|
||||
|
||||
template<typename Base>
|
||||
bool
|
||||
AddonWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
AddonWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
Rooted<JSPropertyDescriptor> interpDesc(cx);
|
||||
if (!Interpose(cx, wrapper, nullptr, id, &interpDesc))
|
||||
|
||||
@@ -24,21 +24,21 @@ class AddonWrapper : public Base {
|
||||
public:
|
||||
explicit MOZ_CONSTEXPR AddonWrapper(unsigned flags) : Base(flags) { }
|
||||
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
virtual bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
|
||||
virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
|
||||
virtual bool set(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject receiver,
|
||||
virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ const ChromeObjectWrapper ChromeObjectWrapper::singleton;
|
||||
bool
|
||||
ChromeObjectWrapper::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, desc.value()))
|
||||
@@ -30,7 +30,7 @@ ChromeObjectWrapper::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeObjectWrapper::set(JSContext* cx, HandleObject wrapper,
|
||||
ChromeObjectWrapper::set(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
|
||||
@@ -29,9 +29,9 @@ class ChromeObjectWrapper : public ChromeObjectWrapperBase
|
||||
|
||||
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool set(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
virtual bool set(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> receiver, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
|
||||
@@ -234,7 +234,7 @@ CrossOriginXrayWrapper::ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wra
|
||||
bool
|
||||
CrossOriginXrayWrapper::defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
JS_ReportError(cx, "Permission denied to define property on cross-origin object");
|
||||
|
||||
@@ -73,7 +73,7 @@ class CrossOriginXrayWrapper : public SecurityXrayDOM {
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector& props) const override;
|
||||
|
||||
@@ -592,8 +592,8 @@ JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, ObjectOp
|
||||
}
|
||||
|
||||
bool
|
||||
JSXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JSXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
ObjectOpResult &result,
|
||||
bool *defined)
|
||||
@@ -637,9 +637,10 @@ JSXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<JSPropertyDescriptor> wrappedDesc(cx, desc);
|
||||
JSAutoCompartment ac(cx, target);
|
||||
if (!JS_WrapPropertyDescriptor(cx, desc) ||
|
||||
!JS_DefinePropertyById(cx, target, id, desc, result))
|
||||
if (!JS_WrapPropertyDescriptor(cx, &wrappedDesc) ||
|
||||
!JS_DefinePropertyById(cx, target, id, wrappedDesc, result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1423,8 +1424,8 @@ XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsW
|
||||
}
|
||||
|
||||
bool
|
||||
XPCWrappedNativeXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
XPCWrappedNativeXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
@@ -1584,8 +1585,8 @@ DOMXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper, Handl
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
DOMXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
@@ -1939,7 +1940,7 @@ XrayWrapper<Base, Traits>::getOwnPropertyDescriptor(JSContext* cx, HandleObject
|
||||
// to the content object. This is ok, because the the expando object is only
|
||||
// ever accessed by code across the compartment boundary.
|
||||
static bool
|
||||
RecreateLostWaivers(JSContext* cx, JSPropertyDescriptor* orig,
|
||||
RecreateLostWaivers(JSContext *cx, const JSPropertyDescriptor *orig,
|
||||
MutableHandle<JSPropertyDescriptor> wrapped)
|
||||
{
|
||||
// Compute whether the original objects were waived, and implicitly, whether
|
||||
@@ -1983,8 +1984,8 @@ RecreateLostWaivers(JSContext* cx, JSPropertyDescriptor* orig,
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id, MutableHandle<JSPropertyDescriptor> desc,
|
||||
XrayWrapper<Base, Traits>::defineProperty(JSContext *cx, HandleObject wrapper,
|
||||
HandleId id, Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET);
|
||||
@@ -2077,7 +2078,7 @@ XrayWrapper<Base, Traits>::delete_(JSContext* cx, HandleObject wrapper,
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::get(JSContext* cx, HandleObject wrapper,
|
||||
XrayWrapper<Base, Traits>::get(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp) const
|
||||
{
|
||||
@@ -2089,7 +2090,7 @@ XrayWrapper<Base, Traits>::get(JSContext* cx, HandleObject wrapper,
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::set(JSContext* cx, HandleObject wrapper,
|
||||
XrayWrapper<Base, Traits>::set(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user