зеркало из https://github.com/mozilla/gecko-dev.git
Bug 792215 part 1. Convert quickstubs to using JSNative getters and setters. r=peterv
This commit is contained in:
Родитель
ba16ebc540
Коммит
9b67eb7d78
|
@ -63,26 +63,26 @@ XPCOMUtils.defineLazyGetter(window, "gFindBar", function() {
|
||||||
return findbar;
|
return findbar;
|
||||||
});
|
});
|
||||||
|
|
||||||
__defineGetter__("gPrefService", function() {
|
this.__defineGetter__("gPrefService", function() {
|
||||||
delete this.gPrefService;
|
delete this.gPrefService;
|
||||||
return this.gPrefService = Services.prefs;
|
return this.gPrefService = Services.prefs;
|
||||||
});
|
});
|
||||||
|
|
||||||
__defineGetter__("AddonManager", function() {
|
this.__defineGetter__("AddonManager", function() {
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
Cu.import("resource://gre/modules/AddonManager.jsm", tmp);
|
Cu.import("resource://gre/modules/AddonManager.jsm", tmp);
|
||||||
return this.AddonManager = tmp.AddonManager;
|
return this.AddonManager = tmp.AddonManager;
|
||||||
});
|
});
|
||||||
__defineSetter__("AddonManager", function (val) {
|
this.__defineSetter__("AddonManager", function (val) {
|
||||||
delete this.AddonManager;
|
delete this.AddonManager;
|
||||||
return this.AddonManager = val;
|
return this.AddonManager = val;
|
||||||
});
|
});
|
||||||
|
|
||||||
__defineGetter__("PluralForm", function() {
|
this.__defineGetter__("PluralForm", function() {
|
||||||
Cu.import("resource://gre/modules/PluralForm.jsm");
|
Cu.import("resource://gre/modules/PluralForm.jsm");
|
||||||
return this.PluralForm;
|
return this.PluralForm;
|
||||||
});
|
});
|
||||||
__defineSetter__("PluralForm", function (val) {
|
this.__defineSetter__("PluralForm", function (val) {
|
||||||
delete this.PluralForm;
|
delete this.PluralForm;
|
||||||
return this.PluralForm = val;
|
return this.PluralForm = val;
|
||||||
});
|
});
|
||||||
|
@ -1539,7 +1539,7 @@ var gBrowserInit = {
|
||||||
if (!gStartupRan)
|
if (!gStartupRan)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!__lookupGetter__("InspectorUI"))
|
if (!window.__lookupGetter__("InspectorUI"))
|
||||||
InspectorUI.destroy();
|
InspectorUI.destroy();
|
||||||
|
|
||||||
// First clean up services initialized in gBrowserInit.onLoad (or those whose
|
// First clean up services initialized in gBrowserInit.onLoad (or those whose
|
||||||
|
@ -3614,7 +3614,7 @@ function BrowserToolboxCustomizeDone(aToolboxChanged) {
|
||||||
// Hacky: update the PopupNotifications' object's reference to the iconBox,
|
// Hacky: update the PopupNotifications' object's reference to the iconBox,
|
||||||
// if it already exists, since it may have changed if the URL bar was
|
// if it already exists, since it may have changed if the URL bar was
|
||||||
// added/removed.
|
// added/removed.
|
||||||
if (!__lookupGetter__("PopupNotifications"))
|
if (!window.__lookupGetter__("PopupNotifications"))
|
||||||
PopupNotifications.iconBox = document.getElementById("notification-popup-box");
|
PopupNotifications.iconBox = document.getElementById("notification-popup-box");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4073,7 +4073,7 @@ var XULBrowserWindow = {
|
||||||
// Only need to call locationChange if the PopupNotifications object
|
// Only need to call locationChange if the PopupNotifications object
|
||||||
// for this window has already been initialized (i.e. its getter no
|
// for this window has already been initialized (i.e. its getter no
|
||||||
// longer exists)
|
// longer exists)
|
||||||
if (!__lookupGetter__("PopupNotifications"))
|
if (!window.__lookupGetter__("PopupNotifications"))
|
||||||
PopupNotifications.locationChange();
|
PopupNotifications.locationChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,25 @@ typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleGetterType, nsIDOMCanvasRender
|
||||||
GetStrokeStyle_multi, (nsAString &, nsISupports **, int32_t *));
|
GetStrokeStyle_multi, (nsAString &, nsISupports **, int32_t *));
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleValue vp,
|
Canvas2D_SetStyleHelper(JSContext *cx, unsigned argc, JS::Value *vp,
|
||||||
CanvasStyleSetterType setfunc)
|
const char* propName, CanvasStyleSetterType setfunc)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
if (!obj)
|
||||||
|
return JS_FALSE;
|
||||||
nsIDOMCanvasRenderingContext2D *self;
|
nsIDOMCanvasRenderingContext2D *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
JS::AutoValueRooter tvr(cx);
|
if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, &vp[1], nullptr))
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, tvr.jsval_addr(), nullptr))
|
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
|
if (argc < 1)
|
||||||
|
return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||||
|
jsval *argv = JS_ARGV(cx, vp);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
if (JSVAL_IS_STRING(vp)) {
|
if (JSVAL_IS_STRING(argv[0])) {
|
||||||
xpc_qsDOMString arg0(cx, vp, vp.address(),
|
xpc_qsDOMString arg0(cx, argv[0], &argv[0],
|
||||||
xpc_qsDOMString::eDefaultNullBehavior,
|
xpc_qsDOMString::eDefaultNullBehavior,
|
||||||
xpc_qsDOMString::eDefaultUndefinedBehavior);
|
xpc_qsDOMString::eDefaultUndefinedBehavior);
|
||||||
if (!arg0.IsValid())
|
if (!arg0.IsValid())
|
||||||
|
@ -40,9 +46,9 @@ Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleVa
|
||||||
} else {
|
} else {
|
||||||
nsISupports *arg0;
|
nsISupports *arg0;
|
||||||
xpc_qsSelfRef arg0ref;
|
xpc_qsSelfRef arg0ref;
|
||||||
rv = xpc_qsUnwrapArg<nsISupports>(cx, vp, &arg0, &arg0ref.ptr, vp.address());
|
rv = xpc_qsUnwrapArg<nsISupports>(cx, argv[0], &arg0, &arg0ref.ptr, &argv[0]);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
|
xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(vp[1]), propName);
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,20 +56,24 @@ Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleVa
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);
|
return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(vp[1]),
|
||||||
|
propName);
|
||||||
|
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleValue vp,
|
Canvas2D_GetStyleHelper(JSContext *cx, unsigned argc, JS::Value *vp,
|
||||||
CanvasStyleGetterType getfunc)
|
const char* propName, CanvasStyleGetterType getfunc)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
if (!obj)
|
||||||
|
return JS_FALSE;
|
||||||
nsIDOMCanvasRenderingContext2D *self;
|
nsIDOMCanvasRenderingContext2D *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
XPCLazyCallContext lccx(JS_CALLER, cx, obj);
|
XPCLazyCallContext lccx(JS_CALLER, cx, obj);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, vp.address(), &lccx))
|
if (!xpc_qsUnwrapThis(cx, obj, &self, &selfref.ptr, &vp[1], &lccx))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
@ -72,11 +82,12 @@ Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleVa
|
||||||
int32_t resultType;
|
int32_t resultType;
|
||||||
rv = (self->*getfunc)(resultString, getter_AddRefs(resultInterface), &resultType);
|
rv = (self->*getfunc)(resultString, getter_AddRefs(resultInterface), &resultType);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(vp), id);
|
return xpc_qsThrowGetterSetterFailed(cx, rv, JSVAL_TO_OBJECT(vp[1]),
|
||||||
|
propName);
|
||||||
|
|
||||||
switch (resultType) {
|
switch (resultType) {
|
||||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_STRING:
|
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_STRING:
|
||||||
return xpc::StringToJsval(cx, resultString, vp.address());
|
return xpc::StringToJsval(cx, resultString, vp);
|
||||||
|
|
||||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_PATTERN:
|
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_PATTERN:
|
||||||
{
|
{
|
||||||
|
@ -84,7 +95,7 @@ Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleVa
|
||||||
xpc_qsGetWrapperCache(resultInterface));
|
xpc_qsGetWrapperCache(resultInterface));
|
||||||
return xpc_qsXPCOMObjectToJsval(lccx, helper,
|
return xpc_qsXPCOMObjectToJsval(lccx, helper,
|
||||||
&NS_GET_IID(nsIDOMCanvasPattern),
|
&NS_GET_IID(nsIDOMCanvasPattern),
|
||||||
&interfaces[k_nsIDOMCanvasPattern], vp.address());
|
&interfaces[k_nsIDOMCanvasPattern], vp);
|
||||||
}
|
}
|
||||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_GRADIENT:
|
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_GRADIENT:
|
||||||
{
|
{
|
||||||
|
@ -92,35 +103,40 @@ Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsid id, JSMutableHandleVa
|
||||||
xpc_qsGetWrapperCache(resultInterface));
|
xpc_qsGetWrapperCache(resultInterface));
|
||||||
return xpc_qsXPCOMObjectToJsval(lccx, helper,
|
return xpc_qsXPCOMObjectToJsval(lccx, helper,
|
||||||
&NS_GET_IID(nsIDOMCanvasGradient),
|
&NS_GET_IID(nsIDOMCanvasGradient),
|
||||||
&interfaces[k_nsIDOMCanvasGradient], vp.address());
|
&interfaces[k_nsIDOMCanvasGradient], vp);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(vp), id);
|
return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE,
|
||||||
|
JSVAL_TO_OBJECT(vp[1]), propName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp)
|
nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||||
{
|
{
|
||||||
return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
|
return Canvas2D_SetStyleHelper(cx, argc, vp, "strokeStyle",
|
||||||
|
&nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
|
nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||||
{
|
{
|
||||||
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
|
return Canvas2D_GetStyleHelper(cx, argc, vp, "strokeStyle",
|
||||||
|
&nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp)
|
nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||||
{
|
{
|
||||||
return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
|
return Canvas2D_SetStyleHelper(cx, argc, vp, "fillStyle",
|
||||||
|
&nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp)
|
nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||||
{
|
{
|
||||||
return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
|
return Canvas2D_GetStyleHelper(cx, argc, vp, "fillStyle",
|
||||||
|
&nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
|
extern const char* xpc_qsStringTable;
|
||||||
|
|
||||||
static inline QITableEntry *
|
static inline QITableEntry *
|
||||||
GetOffsets(nsISupports *identity, XPCWrappedNativeProto* proto)
|
GetOffsets(nsISupports *identity, XPCWrappedNativeProto* proto)
|
||||||
{
|
{
|
||||||
|
@ -97,182 +99,6 @@ PointerHolderClass = {
|
||||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, PointerFinalize
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, PointerFinalize
|
||||||
};
|
};
|
||||||
|
|
||||||
static JSBool
|
|
||||||
ReifyPropertyOps(JSContext *cx, JSObject *obj, jsid id, unsigned orig_attrs,
|
|
||||||
JSPropertyOp getter, JSStrictPropertyOp setter,
|
|
||||||
JSObject **getterobjp, JSObject **setterobjp)
|
|
||||||
{
|
|
||||||
// Generate both getter and setter and stash them in the prototype.
|
|
||||||
jsval roots[2] = { JSVAL_NULL, JSVAL_NULL };
|
|
||||||
JS::AutoArrayRooter tvr(cx, ArrayLength(roots), roots);
|
|
||||||
|
|
||||||
unsigned attrs = JSPROP_SHARED | (orig_attrs & JSPROP_ENUMERATE);
|
|
||||||
JSObject *getterobj;
|
|
||||||
if (getter) {
|
|
||||||
getterobj = GeneratePropertyOp(cx, obj, id, 0, getter);
|
|
||||||
if (!getterobj)
|
|
||||||
return false;
|
|
||||||
roots[0] = OBJECT_TO_JSVAL(getterobj);
|
|
||||||
attrs |= JSPROP_GETTER;
|
|
||||||
} else
|
|
||||||
getterobj = nullptr;
|
|
||||||
|
|
||||||
JSObject *setterobj;
|
|
||||||
if (setter) {
|
|
||||||
setterobj = GeneratePropertyOp(cx, obj, id, 1, setter);
|
|
||||||
if (!setterobj)
|
|
||||||
return false;
|
|
||||||
roots[1] = OBJECT_TO_JSVAL(setterobj);
|
|
||||||
attrs |= JSPROP_SETTER;
|
|
||||||
} else
|
|
||||||
setterobj = nullptr;
|
|
||||||
|
|
||||||
if (getterobjp)
|
|
||||||
*getterobjp = getterobj;
|
|
||||||
if (setterobjp)
|
|
||||||
*setterobjp = setterobj;
|
|
||||||
return JS_DefinePropertyById(cx, obj, id, JSVAL_VOID,
|
|
||||||
JS_DATA_TO_FUNC_PTR(JSPropertyOp, getterobj),
|
|
||||||
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setterobj),
|
|
||||||
attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
LookupGetterOrSetter(JSContext *cx, JSBool wantGetter, unsigned argc, jsval *vp)
|
|
||||||
{
|
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
|
||||||
|
|
||||||
if (argc == 0) {
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
|
||||||
if (!obj)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
jsval idval = JS_ARGV(cx, vp)[0];
|
|
||||||
jsid id;
|
|
||||||
JSPropertyDescriptor desc;
|
|
||||||
if (!JS_ValueToId(cx, idval, &id) ||
|
|
||||||
!JS_GetPropertyDescriptorById(cx, obj, id, JSRESOLVE_QUALIFIED, &desc))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// No property at all means no getters or setters possible.
|
|
||||||
if (!desc.obj) {
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inline obj_lookup[GS]etter here.
|
|
||||||
if (wantGetter) {
|
|
||||||
if (desc.attrs & JSPROP_GETTER) {
|
|
||||||
JS_SET_RVAL(cx, vp,
|
|
||||||
OBJECT_TO_JSVAL(JS_FUNC_TO_DATA_PTR(JSObject *, desc.getter)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (desc.attrs & JSPROP_SETTER) {
|
|
||||||
JS_SET_RVAL(cx, vp,
|
|
||||||
OBJECT_TO_JSVAL(JS_FUNC_TO_DATA_PTR(JSObject *, desc.setter)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since XPConnect doesn't use JSPropertyOps in any other contexts,
|
|
||||||
// ensuring that we have an XPConnect prototype object ensures that
|
|
||||||
// we are only going to expose quickstubbed properties to script.
|
|
||||||
// Also be careful not to overwrite existing properties!
|
|
||||||
|
|
||||||
if (!JSID_IS_STRING(id) ||
|
|
||||||
!IS_PROTO_CLASS(js::GetObjectClass(desc.obj)) ||
|
|
||||||
(desc.attrs & (JSPROP_GETTER | JSPROP_SETTER)) ||
|
|
||||||
!(desc.getter || desc.setter) ||
|
|
||||||
desc.setter == js::GetObjectJSClass(desc.obj)->setProperty) {
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject *getterobj, *setterobj;
|
|
||||||
if (!ReifyPropertyOps(cx, desc.obj, id, desc.attrs, desc.getter, desc.setter,
|
|
||||||
&getterobj, &setterobj)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject *wantedobj = wantGetter ? getterobj : setterobj;
|
|
||||||
jsval v = wantedobj ? OBJECT_TO_JSVAL(wantedobj) : JSVAL_VOID;
|
|
||||||
JS_SET_RVAL(cx, vp, v);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
SharedLookupGetter(JSContext *cx, unsigned argc, jsval *vp)
|
|
||||||
{
|
|
||||||
return LookupGetterOrSetter(cx, true, argc, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
SharedLookupSetter(JSContext *cx, unsigned argc, jsval *vp)
|
|
||||||
{
|
|
||||||
return LookupGetterOrSetter(cx, false, argc, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
DefineGetterOrSetter(JSContext *cx, unsigned argc, JSBool wantGetter, jsval *vp)
|
|
||||||
{
|
|
||||||
unsigned attrs;
|
|
||||||
JSBool found;
|
|
||||||
JSPropertyOp getter;
|
|
||||||
JSStrictPropertyOp setter;
|
|
||||||
JSObject *obj2;
|
|
||||||
jsval v;
|
|
||||||
jsid id;
|
|
||||||
|
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
|
||||||
if (!obj)
|
|
||||||
return false;
|
|
||||||
JSNative forward = wantGetter ? js::obj_defineGetter : js::obj_defineSetter;
|
|
||||||
jsval idval = (argc >= 1) ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
|
|
||||||
if (!JSVAL_IS_STRING(idval))
|
|
||||||
return forward(cx, argc, vp);
|
|
||||||
|
|
||||||
if (!JS_ValueToId(cx, idval, &id) ||
|
|
||||||
!JS_LookupPropertyWithFlagsById(cx, obj, id,
|
|
||||||
JSRESOLVE_QUALIFIED, &obj2, &v) ||
|
|
||||||
(obj2 &&
|
|
||||||
!JS_GetPropertyAttrsGetterAndSetterById(cx, obj2, id, &attrs,
|
|
||||||
&found, &getter, &setter)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// The property didn't exist, already has a getter or setter, or is not
|
|
||||||
// our property, then just forward now.
|
|
||||||
if (!obj2 ||
|
|
||||||
(attrs & (JSPROP_GETTER | JSPROP_SETTER)) ||
|
|
||||||
!(getter || setter) ||
|
|
||||||
!IS_PROTO_CLASS(js::GetObjectClass(obj2)))
|
|
||||||
return forward(cx, argc, vp);
|
|
||||||
|
|
||||||
// Reify the getter and setter...
|
|
||||||
if (!ReifyPropertyOps(cx, obj2, id, attrs, getter, setter, nullptr, nullptr))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return forward(cx, argc, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
SharedDefineGetter(JSContext *cx, unsigned argc, jsval *vp)
|
|
||||||
{
|
|
||||||
return DefineGetterOrSetter(cx, argc, true, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSBool
|
|
||||||
SharedDefineSetter(JSContext *cx, unsigned argc, jsval *vp)
|
|
||||||
{
|
|
||||||
return DefineGetterOrSetter(cx, argc, false, vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, unsigned flags,
|
xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, unsigned flags,
|
||||||
uint32_t ifacec, const nsIID **interfaces,
|
uint32_t ifacec, const nsIID **interfaces,
|
||||||
|
@ -304,8 +130,10 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, unsigned flags,
|
||||||
definedProperty = true;
|
definedProperty = true;
|
||||||
if (!JS_DefineProperty(cx, proto,
|
if (!JS_DefineProperty(cx, proto,
|
||||||
stringTable + ps->name_index,
|
stringTable + ps->name_index,
|
||||||
JSVAL_VOID, ps->getter, ps->setter,
|
JSVAL_VOID,
|
||||||
flags | JSPROP_SHARED))
|
(JSPropertyOp)ps->getter,
|
||||||
|
(JSStrictPropertyOp)ps->setter,
|
||||||
|
flags | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,17 +157,6 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, unsigned flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSFunctionSpec getterfns[] = {
|
|
||||||
JS_FN("__lookupGetter__", SharedLookupGetter, 1, 0),
|
|
||||||
JS_FN("__lookupSetter__", SharedLookupSetter, 1, 0),
|
|
||||||
JS_FN("__defineGetter__", SharedDefineGetter, 2, 0),
|
|
||||||
JS_FN("__defineSetter__", SharedDefineSetter, 2, 0),
|
|
||||||
JS_FS_END
|
|
||||||
};
|
|
||||||
|
|
||||||
if (definedProperty && !JS_DefineFunctions(cx, proto, getterfns))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,6 +280,26 @@ xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv, JSObject *obj,
|
||||||
return ThrowCallFailed(cx, rv, ifaceName, memberId, NULL);
|
return ThrowCallFailed(cx, rv, ifaceName, memberId, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSBool
|
||||||
|
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv, JSObject *obj,
|
||||||
|
const char* memberName)
|
||||||
|
{
|
||||||
|
JSString *str = JS_InternString(cx, memberName);
|
||||||
|
if (!str) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return xpc_qsThrowGetterSetterFailed(cx, rv, obj,
|
||||||
|
INTERNED_STRING_TO_JSID(cx, str));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSBool
|
||||||
|
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv, JSObject *obj,
|
||||||
|
uint16_t memberIndex)
|
||||||
|
{
|
||||||
|
return xpc_qsThrowGetterSetterFailed(cx, rv, obj,
|
||||||
|
xpc_qsStringTable + memberIndex);
|
||||||
|
}
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
xpc_qsThrowMethodFailed(JSContext *cx, nsresult rv, jsval *vp)
|
xpc_qsThrowMethodFailed(JSContext *cx, nsresult rv, jsval *vp)
|
||||||
{
|
{
|
||||||
|
@ -547,6 +384,24 @@ xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv,
|
||||||
ThrowBadArg(cx, rv, ifaceName, propId, NULL, 0);
|
ThrowBadArg(cx, rv, ifaceName, propId, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv,
|
||||||
|
JSObject *obj, const char* propName)
|
||||||
|
{
|
||||||
|
JSString *str = JS_InternString(cx, propName);
|
||||||
|
if (!str) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xpc_qsThrowBadSetterValue(cx, rv, obj, INTERNED_STRING_TO_JSID(cx, str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv, JSObject *obj,
|
||||||
|
uint16_t name_index)
|
||||||
|
{
|
||||||
|
xpc_qsThrowBadSetterValue(cx, rv, obj, xpc_qsStringTable + name_index);
|
||||||
|
}
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict,
|
xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict,
|
||||||
JSMutableHandleValue vp)
|
JSMutableHandleValue vp)
|
||||||
|
@ -558,6 +413,16 @@ xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, J
|
||||||
JSMSG_GETTER_ONLY);
|
JSMSG_GETTER_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSBool
|
||||||
|
xpc_qsGetterOnlyNativeStub(JSContext *cx, unsigned argc, jsval *vp)
|
||||||
|
{
|
||||||
|
return JS_ReportErrorFlagsAndNumber(cx,
|
||||||
|
JSREPORT_WARNING | JSREPORT_STRICT |
|
||||||
|
JSREPORT_STRICT_MODE_ERROR,
|
||||||
|
js_GetErrorMessage, NULL,
|
||||||
|
JSMSG_GETTER_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval,
|
xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval,
|
||||||
StringificationBehavior nullBehavior,
|
StringificationBehavior nullBehavior,
|
||||||
StringificationBehavior undefinedBehavior)
|
StringificationBehavior undefinedBehavior)
|
||||||
|
|
|
@ -19,8 +19,8 @@ class XPCCallContext;
|
||||||
|
|
||||||
struct xpc_qsPropertySpec {
|
struct xpc_qsPropertySpec {
|
||||||
uint16_t name_index;
|
uint16_t name_index;
|
||||||
JSPropertyOp getter;
|
JSNative getter;
|
||||||
JSStrictPropertyOp setter;
|
JSNative setter;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xpc_qsFunctionSpec {
|
struct xpc_qsFunctionSpec {
|
||||||
|
@ -70,6 +70,13 @@ xpc_qsThrow(JSContext *cx, nsresult rv);
|
||||||
JSBool
|
JSBool
|
||||||
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv,
|
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv,
|
||||||
JSObject *obj, jsid memberId);
|
JSObject *obj, jsid memberId);
|
||||||
|
// And variants using strings and string tables
|
||||||
|
JSBool
|
||||||
|
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv,
|
||||||
|
JSObject *obj, const char* memberName);
|
||||||
|
JSBool
|
||||||
|
xpc_qsThrowGetterSetterFailed(JSContext *cx, nsresult rv,
|
||||||
|
JSObject *obj, uint16_t memberIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fail after an XPCOM method returned rv.
|
* Fail after an XPCOM method returned rv.
|
||||||
|
@ -110,11 +117,21 @@ xpc_qsThrowBadArgWithDetails(JSContext *cx, nsresult rv, unsigned paramnum,
|
||||||
void
|
void
|
||||||
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv, JSObject *obj,
|
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv, JSObject *obj,
|
||||||
jsid propId);
|
jsid propId);
|
||||||
|
// And variants using strings and string tables
|
||||||
|
void
|
||||||
|
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv, JSObject *obj,
|
||||||
|
const char* propName);
|
||||||
|
void
|
||||||
|
xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv, JSObject *obj,
|
||||||
|
uint16_t name_index);
|
||||||
|
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp);
|
xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp);
|
||||||
|
|
||||||
|
JSBool
|
||||||
|
xpc_qsGetterOnlyNativeStub(JSContext *cx, unsigned argc, jsval *vp);
|
||||||
|
|
||||||
/* Functions for converting values between COM and JS. */
|
/* Functions for converting values between COM and JS. */
|
||||||
|
|
||||||
inline JSBool
|
inline JSBool
|
||||||
|
|
|
@ -385,6 +385,7 @@ class StringTable:
|
||||||
% (offset, explodeToCharArray(string)))
|
% (offset, explodeToCharArray(string)))
|
||||||
f.write(" /* %5d */ %s, '\\0' };\n\n"
|
f.write(" /* %5d */ %s, '\\0' };\n\n"
|
||||||
% (entries[-1][1], explodeToCharArray(entries[-1][0])))
|
% (entries[-1][1], explodeToCharArray(entries[-1][0])))
|
||||||
|
f.write("const char* xpc_qsStringTable = %s;\n\n" % name);
|
||||||
|
|
||||||
def substitute(template, vals):
|
def substitute(template, vals):
|
||||||
""" Simple replacement for string.Template, which isn't in Python 2.3. """
|
""" Simple replacement for string.Template, which isn't in Python 2.3. """
|
||||||
|
@ -491,10 +492,11 @@ argumentUnboxingTemplates = {
|
||||||
# however, defaults to 'undefined'.
|
# however, defaults to 'undefined'.
|
||||||
#
|
#
|
||||||
def writeArgumentUnboxing(f, i, name, type, optional, rvdeclared,
|
def writeArgumentUnboxing(f, i, name, type, optional, rvdeclared,
|
||||||
nullBehavior, undefinedBehavior):
|
nullBehavior, undefinedBehavior,
|
||||||
|
propIndex=None):
|
||||||
# f - file to write to
|
# f - file to write to
|
||||||
# i - int or None - Indicates the source jsval. If i is an int, the source
|
# i - int or None - Indicates the source jsval. If i is an int, the source
|
||||||
# jsval is argv[i]; otherwise it is *vp. But if Python i >= C++ argc,
|
# jsval is argv[i]; otherwise it is argv[0]. But if Python i >= C++ argc,
|
||||||
# which can only happen if optional is True, the argument is missing;
|
# which can only happen if optional is True, the argument is missing;
|
||||||
# use JSVAL_NULL as the source jsval instead.
|
# use JSVAL_NULL as the source jsval instead.
|
||||||
# name - str - name of the native C++ variable to create.
|
# name - str - name of the native C++ variable to create.
|
||||||
|
@ -507,8 +509,8 @@ def writeArgumentUnboxing(f, i, name, type, optional, rvdeclared,
|
||||||
isSetter = (i is None)
|
isSetter = (i is None)
|
||||||
|
|
||||||
if isSetter:
|
if isSetter:
|
||||||
argPtr = "vp"
|
argPtr = "argv"
|
||||||
argVal = "*vp"
|
argVal = "argv[0]"
|
||||||
elif optional:
|
elif optional:
|
||||||
if typeName == "[jsval]":
|
if typeName == "[jsval]":
|
||||||
val = "JSVAL_VOID"
|
val = "JSVAL_VOID"
|
||||||
|
@ -559,8 +561,9 @@ def writeArgumentUnboxing(f, i, name, type, optional, rvdeclared,
|
||||||
% (type.name, argVal, name, name, argPtr))
|
% (type.name, argVal, name, name, argPtr))
|
||||||
f.write(" if (NS_FAILED(rv)) {\n")
|
f.write(" if (NS_FAILED(rv)) {\n")
|
||||||
if isSetter:
|
if isSetter:
|
||||||
f.write(" xpc_qsThrowBadSetterValue("
|
assert(propIndex is not None)
|
||||||
"cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);\n")
|
f.write(" xpc_qsThrowBadSetterValue(cx, rv, JSVAL_TO_OBJECT(vp[1]), (uint16_t)%s);\n" %
|
||||||
|
propIndex)
|
||||||
else:
|
else:
|
||||||
f.write(" xpc_qsThrowBadArg(cx, rv, vp, %d);\n" % i)
|
f.write(" xpc_qsThrowBadArg(cx, rv, vp, %d);\n" % i)
|
||||||
f.write(" return JS_FALSE;\n"
|
f.write(" return JS_FALSE;\n"
|
||||||
|
@ -569,7 +572,7 @@ def writeArgumentUnboxing(f, i, name, type, optional, rvdeclared,
|
||||||
|
|
||||||
warn("Unable to unbox argument of type %s (native type %s)" % (type.name, typeName))
|
warn("Unable to unbox argument of type %s (native type %s)" % (type.name, typeName))
|
||||||
if i is None:
|
if i is None:
|
||||||
src = '*vp'
|
src = 'argv[0]'
|
||||||
else:
|
else:
|
||||||
src = 'argv[%d]' % i
|
src = 'argv[%d]' % i
|
||||||
f.write(" !; // TODO - Unbox argument %s = %s\n" % (name, src))
|
f.write(" !; // TODO - Unbox argument %s = %s\n" % (name, src))
|
||||||
|
@ -741,7 +744,8 @@ def validateParam(member, param):
|
||||||
if param.const or param.array or param.shared:
|
if param.const or param.array or param.shared:
|
||||||
pfail("I am a simple caveman.")
|
pfail("I am a simple caveman.")
|
||||||
|
|
||||||
def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
def writeQuickStub(f, customMethodCalls, stringtable, member, stubName,
|
||||||
|
isSetter=False):
|
||||||
""" Write a single quick stub (a custom SpiderMonkey getter/setter/method)
|
""" Write a single quick stub (a custom SpiderMonkey getter/setter/method)
|
||||||
for the specified XPCOM interface-member.
|
for the specified XPCOM interface-member.
|
||||||
"""
|
"""
|
||||||
|
@ -750,16 +754,8 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||||
assert isAttr or isMethod
|
assert isAttr or isMethod
|
||||||
isGetter = isAttr and not isSetter
|
isGetter = isAttr and not isSetter
|
||||||
|
|
||||||
signature = "static JSBool\n"
|
signature = ("static JSBool\n" +
|
||||||
if isAttr:
|
"%s(JSContext *cx, unsigned argc,%s jsval *vp)\n")
|
||||||
# JSPropertyOp signature.
|
|
||||||
if isSetter:
|
|
||||||
signature += "%s(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict,%s JSMutableHandleValue vp_)\n"
|
|
||||||
else:
|
|
||||||
signature += "%s(JSContext *cx, JSHandleObject obj, JSHandleId id,%s JSMutableHandleValue vp_)\n"
|
|
||||||
else:
|
|
||||||
# JSFastNative.
|
|
||||||
signature += "%s(JSContext *cx, unsigned argc,%s jsval *vp)\n"
|
|
||||||
|
|
||||||
customMethodCall = customMethodCalls.get(stubName, None)
|
customMethodCall = customMethodCalls.get(stubName, None)
|
||||||
|
|
||||||
|
@ -792,12 +788,8 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||||
or header.firstCap(member.name))
|
or header.firstCap(member.name))
|
||||||
argumentValues = (customMethodCall['additionalArgumentValues']
|
argumentValues = (customMethodCall['additionalArgumentValues']
|
||||||
% nativeName)
|
% nativeName)
|
||||||
if isAttr:
|
callTemplate += (" return %s(cx, argc, %s, vp);\n"
|
||||||
callTemplate += (" return %s(cx, obj, id%s, %s, vp_);\n"
|
% (templateName, argumentValues))
|
||||||
% (templateName, ", strict" if isSetter else "", argumentValues))
|
|
||||||
else:
|
|
||||||
callTemplate += (" return %s(cx, argc, %s, vp);\n"
|
|
||||||
% (templateName, argumentValues))
|
|
||||||
callTemplate += "}\n\n"
|
callTemplate += "}\n\n"
|
||||||
|
|
||||||
# Fall through and create the template function stub called from the
|
# Fall through and create the template function stub called from the
|
||||||
|
@ -833,15 +825,10 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||||
f.write("{\n")
|
f.write("{\n")
|
||||||
f.write(" XPC_QS_ASSERT_CONTEXT_OK(cx);\n")
|
f.write(" XPC_QS_ASSERT_CONTEXT_OK(cx);\n")
|
||||||
|
|
||||||
# Convert JSMutableHandleValue to jsval*
|
# Compute "this".
|
||||||
if isAttr:
|
f.write(" JSObject *obj = JS_THIS_OBJECT(cx, vp);\n"
|
||||||
f.write(" jsval *vp = vp_.address();\n")
|
" if (!obj)\n"
|
||||||
|
" return JS_FALSE;\n")
|
||||||
# For methods, compute "this".
|
|
||||||
if isMethod:
|
|
||||||
f.write(" JSObject *obj = JS_THIS_OBJECT(cx, vp);\n"
|
|
||||||
" if (!obj)\n"
|
|
||||||
" return JS_FALSE;\n")
|
|
||||||
|
|
||||||
# Get the 'self' pointer.
|
# Get the 'self' pointer.
|
||||||
if customMethodCall is None or not 'thisType' in customMethodCall:
|
if customMethodCall is None or not 'thisType' in customMethodCall:
|
||||||
|
@ -849,13 +836,7 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||||
else:
|
else:
|
||||||
f.write(" %s *self;\n" % customMethodCall['thisType'])
|
f.write(" %s *self;\n" % customMethodCall['thisType'])
|
||||||
f.write(" xpc_qsSelfRef selfref;\n")
|
f.write(" xpc_qsSelfRef selfref;\n")
|
||||||
if isGetter:
|
pthisval = '&vp[1]' # as above, ok to overwrite vp[1]
|
||||||
pthisval = 'vp'
|
|
||||||
elif isSetter:
|
|
||||||
f.write(" JS::AutoValueRooter tvr(cx);\n")
|
|
||||||
pthisval = 'tvr.jsval_addr()'
|
|
||||||
else:
|
|
||||||
pthisval = '&vp[1]' # as above, ok to overwrite vp[1]
|
|
||||||
|
|
||||||
if unwrapThisFailureFatal:
|
if unwrapThisFailureFatal:
|
||||||
unwrapFatalArg = "true"
|
unwrapFatalArg = "true"
|
||||||
|
@ -883,10 +864,14 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||||
requiredArgs = len(member.params)
|
requiredArgs = len(member.params)
|
||||||
while requiredArgs and member.params[requiredArgs-1].optional:
|
while requiredArgs and member.params[requiredArgs-1].optional:
|
||||||
requiredArgs -= 1
|
requiredArgs -= 1
|
||||||
if requiredArgs:
|
elif isSetter:
|
||||||
f.write(" if (argc < %d)\n" % requiredArgs)
|
requiredArgs = 1
|
||||||
f.write(" return xpc_qsThrow(cx, "
|
else:
|
||||||
"NS_ERROR_XPC_NOT_ENOUGH_ARGS);\n")
|
requiredArgs = 0
|
||||||
|
if requiredArgs:
|
||||||
|
f.write(" if (argc < %d)\n" % requiredArgs)
|
||||||
|
f.write(" return xpc_qsThrow(cx, "
|
||||||
|
"NS_ERROR_XPC_NOT_ENOUGH_ARGS);\n")
|
||||||
|
|
||||||
# Convert in-parameters.
|
# Convert in-parameters.
|
||||||
rvdeclared = False
|
rvdeclared = False
|
||||||
|
@ -910,11 +895,13 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||||
nullBehavior=param.null,
|
nullBehavior=param.null,
|
||||||
undefinedBehavior=param.undefined)
|
undefinedBehavior=param.undefined)
|
||||||
elif isSetter:
|
elif isSetter:
|
||||||
|
f.write(" jsval *argv = JS_ARGV(cx, vp);\n")
|
||||||
rvdeclared = writeArgumentUnboxing(f, None, 'arg0', member.realtype,
|
rvdeclared = writeArgumentUnboxing(f, None, 'arg0', member.realtype,
|
||||||
optional=False,
|
optional=False,
|
||||||
rvdeclared=rvdeclared,
|
rvdeclared=rvdeclared,
|
||||||
nullBehavior=member.null,
|
nullBehavior=member.null,
|
||||||
undefinedBehavior=member.undefined)
|
undefinedBehavior=member.undefined,
|
||||||
|
propIndex=stringtable.stringIndex(member.name))
|
||||||
|
|
||||||
canFail = customMethodCall is None or customMethodCall.get('canFail', True)
|
canFail = customMethodCall is None or customMethodCall.get('canFail', True)
|
||||||
if canFail and not rvdeclared:
|
if canFail and not rvdeclared:
|
||||||
|
@ -987,12 +974,9 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
|
||||||
f.write(" return xpc_qsThrowMethodFailed("
|
f.write(" return xpc_qsThrowMethodFailed("
|
||||||
"cx, rv, vp);\n")
|
"cx, rv, vp);\n")
|
||||||
else:
|
else:
|
||||||
if isGetter:
|
|
||||||
thisval = '*vp'
|
|
||||||
else:
|
|
||||||
thisval = '*tvr.jsval_addr()'
|
|
||||||
f.write(" return xpc_qsThrowGetterSetterFailed(cx, rv, " +
|
f.write(" return xpc_qsThrowGetterSetterFailed(cx, rv, " +
|
||||||
"JSVAL_TO_OBJECT(%s), id);\n" % thisval)
|
"JSVAL_TO_OBJECT(vp[1]), (uint16_t)%d);\n" %
|
||||||
|
stringtable.stringIndex(member.name))
|
||||||
|
|
||||||
# Convert the return value.
|
# Convert the return value.
|
||||||
if isMethod or isGetter:
|
if isMethod or isGetter:
|
||||||
|
@ -1014,14 +998,15 @@ def writeAttrStubs(f, customMethodCalls, stringtable, attr):
|
||||||
getterName = (attr.iface.name + '_'
|
getterName = (attr.iface.name + '_'
|
||||||
+ header.attributeNativeName(attr, True))
|
+ header.attributeNativeName(attr, True))
|
||||||
if not custom:
|
if not custom:
|
||||||
writeQuickStub(f, customMethodCalls, attr, getterName)
|
writeQuickStub(f, customMethodCalls, stringtable, attr, getterName)
|
||||||
if attr.readonly:
|
if attr.readonly:
|
||||||
setterName = 'xpc_qsGetterOnlyPropertyStub'
|
setterName = 'xpc_qsGetterOnlyNativeStub'
|
||||||
else:
|
else:
|
||||||
setterName = (attr.iface.name + '_'
|
setterName = (attr.iface.name + '_'
|
||||||
+ header.attributeNativeName(attr, False))
|
+ header.attributeNativeName(attr, False))
|
||||||
if not custom:
|
if not custom:
|
||||||
writeQuickStub(f, customMethodCalls, attr, setterName, isSetter=True)
|
writeQuickStub(f, customMethodCalls, stringtable, attr, setterName,
|
||||||
|
isSetter=True)
|
||||||
|
|
||||||
ps = ('{%d, %s, %s}'
|
ps = ('{%d, %s, %s}'
|
||||||
% (stringtable.stringIndex(attr.name), getterName, setterName))
|
% (stringtable.stringIndex(attr.name), getterName, setterName))
|
||||||
|
@ -1035,7 +1020,7 @@ def writeMethodStub(f, customMethodCalls, stringtable, method):
|
||||||
|
|
||||||
stubName = method.iface.name + '_' + header.methodNativeName(method)
|
stubName = method.iface.name + '_' + header.methodNativeName(method)
|
||||||
if not custom:
|
if not custom:
|
||||||
writeQuickStub(f, customMethodCalls, method, stubName)
|
writeQuickStub(f, customMethodCalls, stringtable, method, stubName)
|
||||||
fs = '{%d, %d, %s}' % (stringtable.stringIndex(method.name),
|
fs = '{%d, %d, %s}' % (stringtable.stringIndex(method.name),
|
||||||
len(method.params), stubName)
|
len(method.params), stubName)
|
||||||
return fs
|
return fs
|
||||||
|
|
Загрузка…
Ссылка в новой задаче