mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 747287 - Part 1: Generate JSJitInfos and specialized accessors for Paris bindings. (r=peterv)
This commit is contained in:
parent
028d3cc41a
commit
b5fcc44a40
@ -458,8 +458,8 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
|
|||||||
if (id == attributeIds[i]) {
|
if (id == attributeIds[i]) {
|
||||||
desc->attrs = attributeSpecs[i].flags;
|
desc->attrs = attributeSpecs[i].flags;
|
||||||
desc->obj = wrapper;
|
desc->obj = wrapper;
|
||||||
desc->setter = attributeSpecs[i].setter;
|
desc->setter = attributeSpecs[i].setter.op;
|
||||||
desc->getter = attributeSpecs[i].getter;
|
desc->getter = attributeSpecs[i].getter.op;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -961,12 +961,14 @@ class AttrDefiner(PropertyDefiner):
|
|||||||
return flags
|
return flags
|
||||||
|
|
||||||
def getter(attr):
|
def getter(attr):
|
||||||
return "get_" + attr.identifier.name
|
return ("{(JSPropertyOp)get_%(name)s, &%(name)s_getterinfo}"
|
||||||
|
% {"name" : attr.identifier.name})
|
||||||
|
|
||||||
def setter(attr):
|
def setter(attr):
|
||||||
if attr.readonly:
|
if attr.readonly:
|
||||||
return "NULL"
|
return "JSOP_NULLWRAPPER"
|
||||||
return "set_" + attr.identifier.name
|
return ("{(JSStrictPropertyOp)set_%(name)s, &%(name)s_setterinfo}"
|
||||||
|
% {"name" : attr.identifier.name})
|
||||||
|
|
||||||
def specData(attr):
|
def specData(attr):
|
||||||
return (attr.identifier.name, flags(attr), getter(attr),
|
return (attr.identifier.name, flags(attr), getter(attr),
|
||||||
@ -974,8 +976,8 @@ class AttrDefiner(PropertyDefiner):
|
|||||||
|
|
||||||
return self.generatePrefableArray(
|
return self.generatePrefableArray(
|
||||||
array, name,
|
array, name,
|
||||||
' { "%s", 0, %s, (JSPropertyOp)%s, (JSStrictPropertyOp)%s }',
|
' { "%s", 0, %s, %s, %s}',
|
||||||
' { 0, 0, 0, 0, 0 }',
|
' { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }',
|
||||||
'JSPropertySpec',
|
'JSPropertySpec',
|
||||||
PropertyDefiner.getControllingPref, specData, doIdArrays)
|
PropertyDefiner.getControllingPref, specData, doIdArrays)
|
||||||
|
|
||||||
@ -3180,23 +3182,12 @@ class CGSetterCall(CGGetterSetterCall):
|
|||||||
nativeMethodName, descriptor, attr,
|
nativeMethodName, descriptor, attr,
|
||||||
setter=True)
|
setter=True)
|
||||||
def wrap_return_value(self):
|
def wrap_return_value(self):
|
||||||
if generateNativeAccessors:
|
|
||||||
return CGGetterSetterCall.wrap_return_value(self)
|
|
||||||
# We have no return value
|
# We have no return value
|
||||||
return "\nreturn true;"
|
return "\nreturn true;"
|
||||||
def getArgc(self):
|
def getArgc(self):
|
||||||
if generateNativeAccessors:
|
|
||||||
return CGGetterSetterCall.getArgc(self)
|
|
||||||
return "1"
|
return "1"
|
||||||
def getArgvDecl(self):
|
def getArgvDecl(self):
|
||||||
if generateNativeAccessors:
|
# We just get our stuff from our last arg no matter what
|
||||||
return (CGPerSignatureCall.getArgvDecl(self) +
|
|
||||||
"jsval undef = JS::UndefinedValue();\n"
|
|
||||||
"if (argc == 0) {\n"
|
|
||||||
" argv = &undef;\n"
|
|
||||||
" argc = 1;\n"
|
|
||||||
"}")
|
|
||||||
# We just get our stuff from vp
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
class FakeCastableDescriptor():
|
class FakeCastableDescriptor():
|
||||||
@ -3231,7 +3222,7 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
|||||||
|
|
||||||
def getThis(self):
|
def getThis(self):
|
||||||
return CGIndenter(
|
return CGIndenter(
|
||||||
CGGeneric("JSObject* obj = JS_THIS_OBJECT(cx, vp);\n"
|
CGGeneric("JS::RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));\n"
|
||||||
"if (!obj) {\n"
|
"if (!obj) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
@ -3282,10 +3273,29 @@ class CGNativeGetter(CGAbstractBindingMethod):
|
|||||||
CGGeneric("%s* self;" % self.descriptor.nativeType))
|
CGGeneric("%s* self;" % self.descriptor.nativeType))
|
||||||
|
|
||||||
def generate_code(self):
|
def generate_code(self):
|
||||||
|
return CGIndenter(CGGeneric(
|
||||||
|
"return specialized_get_%s(cx, obj, self, vp);" %
|
||||||
|
self.attr.identifier.name))
|
||||||
|
|
||||||
|
class CGSpecializedGetter(CGAbstractStaticMethod):
|
||||||
|
"""
|
||||||
|
A class for generating the code for a specialized attribute getter
|
||||||
|
that the JIT can call with lower overhead.
|
||||||
|
"""
|
||||||
|
def __init__(self, descriptor, attr):
|
||||||
|
self.attr = attr
|
||||||
|
name = 'specialized_get_' + attr.identifier.name
|
||||||
|
args = [ Argument('JSContext*', 'cx'),
|
||||||
|
Argument('JSHandleObject', 'obj'),
|
||||||
|
Argument('%s*' % descriptor.nativeType, 'self'),
|
||||||
|
Argument('JS::Value*', 'vp') ]
|
||||||
|
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
|
||||||
|
|
||||||
|
def definition_body(self):
|
||||||
name = self.attr.identifier.name
|
name = self.attr.identifier.name
|
||||||
nativeName = "Get" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
|
nativeName = "Get" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
|
||||||
return CGIndenter(CGGetterCall(self.attr.type, nativeName, self.descriptor,
|
return CGIndenter(CGGetterCall(self.attr.type, nativeName,
|
||||||
self.attr))
|
self.descriptor, self.attr)).define()
|
||||||
|
|
||||||
class CGNativeSetter(CGAbstractBindingMethod):
|
class CGNativeSetter(CGAbstractBindingMethod):
|
||||||
"""
|
"""
|
||||||
@ -3311,10 +3321,89 @@ class CGNativeSetter(CGAbstractBindingMethod):
|
|||||||
CGGeneric("%s* self;" % self.descriptor.nativeType))
|
CGGeneric("%s* self;" % self.descriptor.nativeType))
|
||||||
|
|
||||||
def generate_code(self):
|
def generate_code(self):
|
||||||
|
if generateNativeAccessors:
|
||||||
|
argv = ("JS::Value* argv = JS_ARGV(cx, vp);\n"
|
||||||
|
"jsval undef = JS::UndefinedValue();\n"
|
||||||
|
"if (argc == 0) {\n"
|
||||||
|
" argv = &undef;\n"
|
||||||
|
"}\n")
|
||||||
|
retval = "*vp = JSVAL_VOID;\n"
|
||||||
|
else:
|
||||||
|
argv = "JS::Value* argv = vp;\n"
|
||||||
|
retval = ""
|
||||||
|
|
||||||
|
return CGIndenter(CGGeneric(
|
||||||
|
argv +
|
||||||
|
("if (!specialized_set_%s(cx, obj, self, argv)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n" % self.attr.identifier.name) +
|
||||||
|
retval +
|
||||||
|
"return true;"))
|
||||||
|
|
||||||
|
class CGSpecializedSetter(CGAbstractStaticMethod):
|
||||||
|
"""
|
||||||
|
A class for generating the code for a specialized attribute setter
|
||||||
|
that the JIT can call with lower overhead.
|
||||||
|
"""
|
||||||
|
def __init__(self, descriptor, attr):
|
||||||
|
self.attr = attr
|
||||||
|
name = 'specialized_set_' + attr.identifier.name
|
||||||
|
args = [ Argument('JSContext*', 'cx'),
|
||||||
|
Argument('JSHandleObject', 'obj'),
|
||||||
|
Argument('%s*' % descriptor.nativeType, 'self') ]
|
||||||
|
# Our last argument is named differently depending on whether we're
|
||||||
|
# in the native accessors case or not
|
||||||
|
if generateNativeAccessors:
|
||||||
|
args.append(Argument('JS::Value*', 'argv'))
|
||||||
|
else:
|
||||||
|
args.append(Argument('JS::Value*', 'vp'))
|
||||||
|
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
|
||||||
|
|
||||||
|
def definition_body(self):
|
||||||
name = self.attr.identifier.name
|
name = self.attr.identifier.name
|
||||||
nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
|
nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
|
||||||
return CGIndenter(CGSetterCall(self.attr.type, nativeName, self.descriptor,
|
return CGIndenter(CGSetterCall(self.attr.type, nativeName,
|
||||||
self.attr))
|
self.descriptor, self.attr)).define()
|
||||||
|
|
||||||
|
class CGPropertyJITInfo(CGThing):
|
||||||
|
"""
|
||||||
|
A class for generating the JITInfo for a property that points to
|
||||||
|
our specialized getter and setter.
|
||||||
|
"""
|
||||||
|
def __init__(self, descriptor, attr):
|
||||||
|
self.attr = attr
|
||||||
|
self.descriptor = descriptor
|
||||||
|
|
||||||
|
def declare(self):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def defineJitInfo(self, infoName, opName, infallible):
|
||||||
|
protoID = "prototypes::id::%s" % self.descriptor.interface.identifier.name
|
||||||
|
depth = "PrototypeTraits<%s>::Depth" % protoID
|
||||||
|
failstr = "true" if infallible else "false"
|
||||||
|
return ("\n"
|
||||||
|
"const JSJitInfo %s = {\n"
|
||||||
|
" %s,\n"
|
||||||
|
" %s,\n"
|
||||||
|
" %s,\n"
|
||||||
|
" %s, /* isInfallible. False for setters. */\n"
|
||||||
|
" false /* isConstant. False for setters. */\n"
|
||||||
|
"};\n" % (infoName, opName, protoID, depth, failstr))
|
||||||
|
|
||||||
|
def define(self):
|
||||||
|
getterinfo = ("%s_getterinfo" % self.attr.identifier.name)
|
||||||
|
getter = ("(JSJitPropertyOp)specialized_get_%s" %
|
||||||
|
self.attr.identifier.name)
|
||||||
|
# For now, mark all getters fallible, until argument wrapping has been
|
||||||
|
# handled.
|
||||||
|
result = self.defineJitInfo(getterinfo, getter, False)
|
||||||
|
if not self.attr.readonly:
|
||||||
|
setterinfo = ("%s_setterinfo" % self.attr.identifier.name)
|
||||||
|
setter = ("(JSJitPropertyOp)specialized_set_%s" %
|
||||||
|
self.attr.identifier.name)
|
||||||
|
# Setters are always fallible, since they have to do a typed unwrap.
|
||||||
|
result += self.defineJitInfo(setterinfo, setter, False)
|
||||||
|
return result
|
||||||
|
|
||||||
def getEnumValueName(value):
|
def getEnumValueName(value):
|
||||||
# Some enum values can be empty strings. Others might have weird
|
# Some enum values can be empty strings. Others might have weird
|
||||||
@ -4052,14 +4141,16 @@ class CGDescriptor(CGThing):
|
|||||||
|
|
||||||
cgThings = []
|
cgThings = []
|
||||||
if descriptor.interface.hasInterfacePrototypeObject():
|
if descriptor.interface.hasInterfacePrototypeObject():
|
||||||
cgThings.extend([CGNativeMethod(descriptor, m) for m in
|
for m in descriptor.interface.members:
|
||||||
descriptor.interface.members if
|
if m.isMethod() and not m.isStatic():
|
||||||
m.isMethod() and not m.isStatic()])
|
cgThings.append(CGNativeMethod(descriptor, m))
|
||||||
cgThings.extend([CGNativeGetter(descriptor, a) for a in
|
elif m.isAttr():
|
||||||
descriptor.interface.members if a.isAttr()])
|
cgThings.append(CGSpecializedGetter(descriptor, m))
|
||||||
cgThings.extend([CGNativeSetter(descriptor, a) for a in
|
cgThings.append(CGNativeGetter(descriptor, m))
|
||||||
descriptor.interface.members if
|
if not m.readonly:
|
||||||
a.isAttr() and not a.readonly])
|
cgThings.append(CGSpecializedSetter(descriptor, m))
|
||||||
|
cgThings.append(CGNativeSetter(descriptor, m))
|
||||||
|
cgThings.append(CGPropertyJITInfo(descriptor, m))
|
||||||
|
|
||||||
if descriptor.concrete:
|
if descriptor.concrete:
|
||||||
if not descriptor.workers and descriptor.wrapperCache:
|
if not descriptor.workers and descriptor.wrapperCache:
|
||||||
|
@ -1292,11 +1292,23 @@ JS_GetDataViewByteLength(JSObject *obj, JSContext *cx);
|
|||||||
JS_FRIEND_API(void *)
|
JS_FRIEND_API(void *)
|
||||||
JS_GetDataViewData(JSObject *obj, JSContext *cx);
|
JS_GetDataViewData(JSObject *obj, JSContext *cx);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
/*
|
/*
|
||||||
* This struct contains metadata passed from the DOM to the JS Engine for JIT
|
* This struct contains metadata passed from the DOM to the JS Engine for JIT
|
||||||
* optimizations on DOM property accessors. Eventually, this should be made
|
* optimizations on DOM property accessors. Eventually, this should be made
|
||||||
* available to general JSAPI users, but we are not currently ready to do so.
|
* available to general JSAPI users, but we are not currently ready to do so.
|
||||||
*/
|
*/
|
||||||
struct JSJitInfo;
|
typedef bool
|
||||||
|
(* JSJitPropertyOp)(JSContext *cx, JSObject *thisObj,
|
||||||
|
void *specializedThis, JS::Value *vp);
|
||||||
|
|
||||||
|
struct JSJitInfo {
|
||||||
|
JSJitPropertyOp op;
|
||||||
|
uint32_t protoID;
|
||||||
|
uint32_t depth;
|
||||||
|
bool isInfallible; /* Is op fallible? Getters only */
|
||||||
|
bool isConstant; /* Getting a construction-time constant? */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* jsfriendapi_h___ */
|
#endif /* jsfriendapi_h___ */
|
||||||
|
Loading…
Reference in New Issue
Block a user