Auto merge of #13030 - nox:global, r=Ms2ger

Improve prototypes of global objects

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13030)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-08-25 07:45:39 -05:00 committed by GitHub
commit 8b84566097
12 changed files with 206 additions and 1030 deletions

View file

@ -2375,9 +2375,9 @@ class CGConstructorEnabled(CGAbstractMethod):
def CreateBindingJSObject(descriptor, parent=None):
assert not descriptor.isGlobal()
create = "let raw = Box::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n"
if descriptor.proxy:
assert not descriptor.isGlobal()
create += """
let handler = RegisterBindings::proxy_handlers[PrototypeList::Proxies::%s as usize];
rooted!(in(cx) let private = PrivateValue(raw as *const libc::c_void));
@ -2388,15 +2388,6 @@ let obj = NewProxyObject(cx, handler,
assert!(!obj.is_null());
rooted!(in(cx) let obj = obj);\
""" % (descriptor.name, parent)
elif descriptor.isGlobal():
create += ("rooted!(in(cx) let obj =\n"
" create_dom_global(\n"
" cx,\n"
" &Class.base as *const js::jsapi::Class as *const JSClass,\n"
" raw as *const libc::c_void,\n"
" Some(%s))\n"
");\n"
"assert!(!obj.is_null());" % TRACE_HOOK_NAME)
else:
create += ("rooted!(in(cx) let obj = JS_NewObjectWithGivenProto(\n"
" cx, &Class.base as *const js::jsapi::Class as *const JSClass, proto.handle()));\n"
@ -2475,21 +2466,17 @@ class CGWrapMethod(CGAbstractMethod):
"""
def __init__(self, descriptor):
assert not descriptor.interface.isCallback()
if not descriptor.isGlobal():
args = [Argument('*mut JSContext', 'cx'), Argument('GlobalRef', 'scope'),
Argument("Box<%s>" % descriptor.concreteType, 'object')]
else:
args = [Argument('*mut JSContext', 'cx'),
Argument("Box<%s>" % descriptor.concreteType, 'object')]
assert not descriptor.isGlobal()
args = [Argument('*mut JSContext', 'cx'), Argument('GlobalRef', 'scope'),
Argument("Box<%s>" % descriptor.concreteType, 'object')]
retval = 'Root<%s>' % descriptor.concreteType
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
pub=True, unsafe=True)
def definition_body(self):
unforgeable = CopyUnforgeablePropertiesToInstance(self.descriptor)
if not self.descriptor.isGlobal():
create = CreateBindingJSObject(self.descriptor, "scope")
return CGGeneric("""\
create = CreateBindingJSObject(self.descriptor, "scope")
return CGGeneric("""\
let scope = scope.reflector().get_jsobject();
assert!(!scope.get().is_null());
assert!(((*JS_GetClass(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0);
@ -2505,21 +2492,65 @@ assert!(!proto.is_null());
(*raw).init_reflector(obj.get());
Root::from_ref(&*raw)""" % {'copyUnforgeable': unforgeable, 'createObject': create})
else:
create = CreateBindingJSObject(self.descriptor)
return CGGeneric("""\
%(createObject)s
class CGWrapGlobalMethod(CGAbstractMethod):
"""
Class that generates the FooBinding::Wrap function for global interfaces.
"""
def __init__(self, descriptor, properties):
assert not descriptor.interface.isCallback()
assert descriptor.isGlobal()
args = [Argument('*mut JSContext', 'cx'),
Argument("Box<%s>" % descriptor.concreteType, 'object')]
retval = 'Root<%s>' % descriptor.concreteType
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
pub=True, unsafe=True)
self.properties = properties
def definition_body(self):
values = {
"unforgeable": CopyUnforgeablePropertiesToInstance(self.descriptor)
}
pairs = [
("define_guarded_properties", self.properties.attrs),
("define_guarded_methods", self.properties.methods),
("define_guarded_constants", self.properties.consts)
]
members = ["%s(cx, obj.handle(), %s);" % (function, array.variableName())
for (function, array) in pairs if array.length() > 0]
values["members"] = "\n".join(members)
return CGGeneric("""\
let raw = Box::into_raw(object);
let _rt = RootedTraceable::new(&*raw);
rooted!(in(cx) let mut obj = ptr::null_mut());
create_global_object(
cx,
&*(&Class.base as *const js::jsapi::Class as *const _),
raw as *const libc::c_void,
_trace,
obj.handle_mut());
assert!(!obj.is_null());
(*raw).init_reflector(obj.get());
let _ac = JSAutoCompartment::new(cx, obj.get());
rooted!(in(cx) let mut proto = ptr::null_mut());
GetProtoObject(cx, obj.handle(), proto.handle_mut());
JS_SplicePrototype(cx, obj.handle(), proto.handle());
assert!(JS_SplicePrototype(cx, obj.handle(), proto.handle()));
let mut immutable = false;
assert!(JS_SetImmutablePrototype(cx, obj.handle(), &mut immutable));
assert!(immutable);
%(copyUnforgeable)s
%(members)s
%(unforgeable)s
Root::from_ref(&*raw)\
""" % {'copyUnforgeable': unforgeable, 'createObject': create})
""" % values)
class CGIDLInterface(CGThing):
@ -2663,6 +2694,18 @@ assert!(!prototype_proto.is_null());""" % getPrototypeProto)]
else:
properties[arrayName] = "&[]"
if self.descriptor.isGlobal():
assert not self.haveUnscopables
proto_properties = {
"attrs": "&[]",
"consts": "&[]",
"id": name,
"methods": "&[]",
"unscopables": "&[]",
}
else:
proto_properties = properties
code.append(CGGeneric("""
rooted!(in(cx) let mut prototype = ptr::null_mut());
create_interface_prototype_object(cx,
@ -2679,7 +2722,7 @@ assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null());
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::ID::%(id)s as isize),
ptr::null_mut(),
prototype.get());
""" % properties))
""" % proto_properties))
if self.descriptor.interface.hasInterfaceObject():
properties["name"] = str_to_const_array(name)
@ -5249,26 +5292,26 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'js::{JS_CALLEE, JSCLASS_GLOBAL_SLOT_COUNT}',
'js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_MASK}',
'js::error::throw_type_error',
'js::jsapi::{JSJitInfo_AliasSet, JSJitInfo_ArgType, AutoIdVector, CallArgs, FreeOp}',
'js::jsapi::{JSITER_SYMBOLS, JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_SHARED}',
'js::jsapi::{JSCLASS_RESERVED_SLOTS_SHIFT, JSITER_HIDDEN, JSITER_OWNONLY}',
'js::jsapi::{GetPropertyKeys, Handle, Call, GetWellKnownSymbol}',
'js::jsapi::{HandleId, HandleObject, HandleValue, HandleValueArray}',
'js::jsapi::{INTERNED_STRING_TO_JSID, IsCallable, JS_CallFunctionValue}',
'js::jsapi::{JS_CopyPropertiesFrom, JS_ForwardGetPropertyTo}',
'js::jsapi::{JS_GetClass, JS_GetErrorPrototype, JS_GetFunctionPrototype}',
'js::jsapi::{JS_GetGlobalForObject, JS_GetObjectPrototype, JS_GetProperty}',
'js::jsapi::{JS_GetPropertyById, JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_InitializePropertiesFromCompatibleNativeObject}',
'js::jsapi::{JS_AtomizeAndPinString, JS_NewObject, JS_NewObjectWithGivenProto}',
'js::jsapi::{JS_NewObjectWithoutMetadata, JS_SetProperty, JS_DefinePropertyById2}',
'js::jsapi::{JS_SplicePrototype, JS_SetReservedSlot, JSAutoCompartment}',
'js::jsapi::{JSContext, JSClass, JSFreeOp, JSFunctionSpec, JS_GetIteratorPrototype}',
'js::jsapi::{JSJitGetterCallArgs, JSJitInfo, JSJitMethodCallArgs, JSJitSetterCallArgs}',
'js::jsapi::{JSNative, JSObject, JSNativeWrapper, JSPropertySpec}',
'js::jsapi::{JSString, JSTracer, JSType, JSTypedMethodJitInfo, JSValueType}',
'js::jsapi::{ObjectOpResult, JSJitInfo_OpType, MutableHandle, MutableHandleObject}',
'js::jsapi::{MutableHandleValue, PropertyDescriptor, RootedObject}',
'js::jsapi::{AutoIdVector, Call, CallArgs, FreeOp, GetPropertyKeys, GetWellKnownSymbol}',
'js::jsapi::{Handle, HandleId, HandleObject, HandleValue, HandleValueArray}',
'js::jsapi::{INTERNED_STRING_TO_JSID, IsCallable, JS_AtomizeAndPinString}',
'js::jsapi::{JS_CallFunctionValue, JS_CopyPropertiesFrom, JS_DefinePropertyById2}',
'js::jsapi::{JS_ForwardGetPropertyTo, JS_GetClass, JS_GetErrorPrototype}',
'js::jsapi::{JS_GetFunctionPrototype, JS_GetGlobalForObject, JS_GetIteratorPrototype}',
'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}',
'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot, JS_HasProperty}',
'js::jsapi::{JS_HasPropertyById, JS_InitializePropertiesFromCompatibleNativeObject}',
'js::jsapi::{JS_NewObject, JS_NewObjectWithGivenProto, JS_NewObjectWithoutMetadata}',
'js::jsapi::{JS_SetImmutablePrototype, JS_SetProperty, JS_SetReservedSlot}',
'js::jsapi::{JS_SplicePrototype, JSAutoCompartment, JSCLASS_RESERVED_SLOTS_SHIFT}',
'js::jsapi::{JSClass, JSContext, JSFreeOp, JSFunctionSpec, JSITER_HIDDEN}',
'js::jsapi::{JSITER_OWNONLY, JSITER_SYMBOLS, JSJitGetterCallArgs, JSJitInfo}',
'js::jsapi::{JSJitInfo_AliasSet, JSJitInfo_ArgType, JSJitInfo_OpType}',
'js::jsapi::{JSJitMethodCallArgs, JSJitSetterCallArgs, JSNative, JSNativeWrapper}',
'js::jsapi::{JSObject, JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY}',
'js::jsapi::{JSPROP_SHARED, JSPropertySpec, JSString, JSTracer, JSType}',
'js::jsapi::{JSTypedMethodJitInfo, JSValueType, MutableHandle, MutableHandleObject}',
'js::jsapi::{MutableHandleValue, ObjectOpResult, PropertyDescriptor, RootedObject}',
'js::jsapi::{SymbolCode, jsid}',
'js::jsval::JSVal',
'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}',
@ -5282,26 +5325,26 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'dom::bindings',
'dom::bindings::codegen::InterfaceObjectMap',
'dom::bindings::global::{GlobalRef, global_root_from_object, global_root_from_reflector}',
'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}',
'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}',
'dom::bindings::interface::{create_named_constructors, create_noncallback_interface_object}',
'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}',
'dom::bindings::interface::{ConstantSpec, NonNullJSNative}',
'dom::bindings::interface::{ConstantSpec, InterfaceConstructorBehavior}',
'dom::bindings::interface::{NonCallbackInterfaceObjectClass, NonNullJSNative}',
'dom::bindings::interface::{create_callback_interface_object, create_global_object}',
'dom::bindings::interface::{create_interface_prototype_object, create_named_constructors}',
'dom::bindings::interface::{create_noncallback_interface_object, define_guarded_constants}',
'dom::bindings::interface::{define_guarded_methods, define_guarded_properties, is_exposed_in}',
'dom::bindings::interface::ConstantVal::{IntVal, UintVal}',
'dom::bindings::interface::is_exposed_in',
'dom::bindings::iterable::{IteratorType, Iterable}',
'dom::bindings::js::{JS, Root, RootedReference}',
'dom::bindings::js::{OptionalRootedReference}',
'dom::bindings::reflector::{Reflectable}',
'dom::bindings::utils::{DOMClass, DOMJSClass}',
'dom::bindings::utils::{DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, JSCLASS_DOM_GLOBAL}',
'dom::bindings::utils::{ProtoOrIfaceArray, create_dom_global}',
'dom::bindings::utils::{enumerate_global, finalize_global, find_enum_string_index}',
'dom::bindings::utils::{generic_getter, generic_lenient_getter, generic_lenient_setter}',
'dom::bindings::utils::{generic_method, generic_setter, get_array_index_from_id}',
'dom::bindings::utils::{get_dictionary_property, get_property_on_prototype}',
'dom::bindings::utils::{get_proto_or_iface_array, has_property_on_prototype}',
'dom::bindings::utils::{is_platform_object, resolve_global, set_dictionary_property, trace_global}',
'dom::bindings::utils::{ProtoOrIfaceArray, enumerate_global, finalize_global}',
'dom::bindings::utils::{find_enum_string_index, generic_getter, generic_lenient_getter}',
'dom::bindings::utils::{generic_lenient_setter, generic_method, generic_setter}',
'dom::bindings::utils::{get_array_index_from_id, get_dictionary_property}',
'dom::bindings::utils::{get_property_on_prototype, get_proto_or_iface_array}',
'dom::bindings::utils::{has_property_on_prototype, is_platform_object}',
'dom::bindings::utils::{resolve_global, set_dictionary_property, trace_global}',
'dom::bindings::trace::{JSTraceable, RootedTraceable}',
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
'dom::bindings::callback::{CallSetup,ExceptionHandling}',
@ -5437,6 +5480,8 @@ class CGDescriptor(CGThing):
if descriptor.proxy:
cgThings.append(CGDefineProxyHandler(descriptor))
properties = PropertyArrays(descriptor)
if descriptor.concrete:
if descriptor.proxy:
# cgThings.append(CGProxyIsProxy(descriptor))
@ -5466,7 +5511,10 @@ class CGDescriptor(CGThing):
cgThings.append(CGDOMJSClass(descriptor))
pass
cgThings.append(CGWrapMethod(descriptor))
if descriptor.isGlobal():
cgThings.append(CGWrapGlobalMethod(descriptor, properties))
else:
cgThings.append(CGWrapMethod(descriptor))
reexports.append('Wrap')
haveUnscopables = False
@ -5489,7 +5537,6 @@ class CGDescriptor(CGThing):
if descriptor.weakReferenceable:
cgThings.append(CGWeakReferenceableTrait(descriptor))
properties = PropertyArrays(descriptor)
cgThings.append(CGGeneric(str(properties)))
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables))

View file

@ -6,23 +6,26 @@
use dom::bindings::codegen::InterfaceObjectMap::Globals;
use dom::bindings::codegen::PrototypeList;
use dom::bindings::conversions::get_dom_class;
use dom::bindings::conversions::{DOM_OBJECT_SLOT, get_dom_class};
use dom::bindings::guard::Guard;
use dom::bindings::utils::get_proto_or_iface_array;
use dom::bindings::utils::{DOM_PROTOTYPE_SLOT, ProtoOrIfaceArray, get_proto_or_iface_array};
use js::error::throw_type_error;
use js::glue::{RUST_SYMBOL_TO_JSID, UncheckedUnwrapObject};
use js::jsapi::{Class, ClassOps, GetGlobalForObjectCrossCompartment};
use js::jsapi::{GetWellKnownSymbol, HandleObject, HandleValue, JSClass, JSContext};
use js::jsapi::{JSFunctionSpec, JSNative, JSFUN_CONSTRUCTOR, JSPROP_ENUMERATE};
use js::jsapi::{JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_RESOLVING, JSPropertySpec};
use js::jsapi::{JSString, JS_AtomizeAndPinString, JS_DefineProperty, JS_DefineProperty1};
use js::jsapi::{JS_DefineProperty2, JS_DefineProperty4, JS_DefinePropertyById3};
use js::jsapi::{JS_GetClass, JS_GetFunctionObject, JS_GetPrototype, JS_LinkConstructorAndPrototype};
use js::jsapi::{JS_NewFunction, JS_NewObject, JS_NewObjectWithUniqueType};
use js::jsapi::{JS_NewPlainObject, JS_NewStringCopyN, MutableHandleObject};
use js::jsapi::{MutableHandleValue, ObjectOps};
use js::jsapi::{SymbolCode, TrueHandleValue, Value};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
use js::jsapi::{Class, ClassOps, CompartmentOptions, GetGlobalForObjectCrossCompartment};
use js::jsapi::{GetWellKnownSymbol, HandleObject, HandleValue, JSAutoCompartment};
use js::jsapi::{JSClass, JSContext, JSFUN_CONSTRUCTOR, JSFunctionSpec, JSNative, JSObject};
use js::jsapi::{JSPROP_ENUMERATE, JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_RESOLVING};
use js::jsapi::{JSPropertySpec, JSString, JSTracer, JSVersion, JS_AtomizeAndPinString};
use js::jsapi::{JS_DefineProperty, JS_DefineProperty1, JS_DefineProperty2};
use js::jsapi::{JS_DefineProperty4, JS_DefinePropertyById3, JS_FireOnNewGlobalObject};
use js::jsapi::{JS_GetClass, JS_GetFunctionObject, JS_GetPrototype};
use js::jsapi::{JS_LinkConstructorAndPrototype, JS_NewFunction, JS_NewGlobalObject};
use js::jsapi::{JS_NewObject, JS_NewObjectWithUniqueType, JS_NewPlainObject};
use js::jsapi::{JS_NewStringCopyN, JS_SetReservedSlot, MutableHandleObject};
use js::jsapi::{MutableHandleValue, ObjectOps, OnNewGlobalHookOption, SymbolCode};
use js::jsapi::{TrueHandleValue, Value};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue};
use js::jsval::{PrivateValue, UInt32Value};
use js::rust::{define_methods, define_properties};
use libc;
use std::ptr;
@ -70,21 +73,19 @@ pub type NonNullJSNative =
/// Defines constants on `obj`.
/// Fails on JSAPI failure.
fn define_constants(
unsafe fn define_constants(
cx: *mut JSContext,
obj: HandleObject,
constants: &[ConstantSpec]) {
for spec in constants {
rooted!(in(cx) let value = spec.get_value());
unsafe {
assert!(JS_DefineProperty(cx,
obj,
spec.name.as_ptr() as *const libc::c_char,
value.handle(),
JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT,
None,
None));
}
assert!(JS_DefineProperty(cx,
obj,
spec.name.as_ptr() as *const libc::c_char,
value.handle(),
JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT,
None,
None));
}
}
@ -208,6 +209,44 @@ impl InterfaceConstructorBehavior {
}
}
/// A trace hook.
pub type TraceHook =
unsafe extern "C" fn(trc: *mut JSTracer, obj: *mut JSObject);
/// Create a global object with the given class.
pub unsafe fn create_global_object(
cx: *mut JSContext,
class: &'static JSClass,
private: *const libc::c_void,
trace: TraceHook,
rval: MutableHandleObject) {
assert!(rval.is_null());
let mut options = CompartmentOptions::default();
options.behaviors_.version_ = JSVersion::JSVERSION_ECMA_5;
options.creationOptions_.traceGlobal_ = Some(trace);
options.creationOptions_.sharedMemoryAndAtomics_ = true;
rval.set(JS_NewGlobalObject(cx,
class,
ptr::null_mut(),
OnNewGlobalHookOption::DontFireOnNewGlobalHook,
&options));
assert!(!rval.is_null());
// Initialize the reserved slots before doing anything that can GC, to
// avoid getting trace hooks called on a partially initialized object.
JS_SetReservedSlot(rval.get(), DOM_OBJECT_SLOT, PrivateValue(private));
let proto_array: Box<ProtoOrIfaceArray> =
box [0 as *mut JSObject; PrototypeList::PROTO_OR_IFACE_LENGTH];
JS_SetReservedSlot(rval.get(),
DOM_PROTOTYPE_SLOT,
PrivateValue(Box::into_raw(proto_array) as *const libc::c_void));
let _ac = JSAutoCompartment::new(cx, rval.get());
JS_FireOnNewGlobalObject(cx, rval.handle());
}
/// Create and define the interface object of a callback interface.
pub unsafe fn create_callback_interface_object(
cx: *mut JSContext,
@ -218,11 +257,7 @@ pub unsafe fn create_callback_interface_object(
assert!(!constants.is_empty());
rval.set(JS_NewObject(cx, ptr::null()));
assert!(!rval.ptr.is_null());
for guard in constants {
if let Some(specs) = guard.expose(cx, rval.handle()) {
define_constants(cx, rval.handle(), specs);
}
}
define_guarded_constants(cx, rval.handle(), constants);
define_name(cx, rval.handle(), name);
define_on_global_object(cx, global, name, rval.handle());
}
@ -382,11 +417,7 @@ unsafe fn create_object(
assert!(!rval.ptr.is_null());
define_guarded_methods(cx, rval.handle(), methods);
define_guarded_properties(cx, rval.handle(), properties);
for guard in constants {
if let Some(specs) = guard.expose(cx, rval.handle()) {
define_constants(cx, rval.handle(), specs);
}
}
define_guarded_constants(cx, rval.handle(), constants);
}
unsafe fn create_unscopable_object(
@ -405,6 +436,18 @@ unsafe fn create_unscopable_object(
}
}
/// Conditionally define constants on an object.
pub unsafe fn define_guarded_constants(
cx: *mut JSContext,
obj: HandleObject,
constants: &[Guard<&[ConstantSpec]>]) {
for guard in constants {
if let Some(specs) = guard.expose(cx, obj) {
define_constants(cx, obj, specs);
}
}
}
/// Conditionally define methods on an object.
pub unsafe fn define_guarded_methods(
cx: *mut JSContext,

View file

@ -7,8 +7,7 @@
use dom::bindings::codegen::InterfaceObjectMap;
use dom::bindings::codegen::PrototypeList;
use dom::bindings::codegen::PrototypeList::{MAX_PROTO_CHAIN_LENGTH, PROTO_OR_IFACE_LENGTH};
use dom::bindings::conversions::{DOM_OBJECT_SLOT, is_dom_class};
use dom::bindings::conversions::{jsstring_to_str, private_from_proto_check};
use dom::bindings::conversions::{is_dom_class, jsstring_to_str, private_from_proto_check};
use dom::bindings::error::throw_invalid_this;
use dom::bindings::inheritance::TopTypeId;
use dom::bindings::str::DOMString;
@ -21,20 +20,18 @@ use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper};
use js::glue::{GetCrossCompartmentWrapper, WrapperNew};
use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT, RUST_JSID_IS_STRING};
use js::glue::{RUST_JSID_TO_INT, RUST_JSID_TO_STRING, UnwrapObject};
use js::jsapi::{CallArgs, CompartmentOptions, DOMCallbacks, GetGlobalForObjectCrossCompartment};
use js::jsapi::{HandleId, HandleObject, HandleValue, Heap, JSAutoCompartment, JSClass, JSContext};
use js::jsapi::{JSJitInfo, JSObject, JSTraceOp, JSTracer, JSVersion, JSWrapObjectCallbacks};
use js::jsapi::{JS_DeletePropertyById, JS_EnumerateStandardClasses, JS_FireOnNewGlobalObject};
use js::jsapi::{CallArgs, DOMCallbacks, GetGlobalForObjectCrossCompartment};
use js::jsapi::{HandleId, HandleObject, HandleValue, Heap, JSAutoCompartment, JSContext};
use js::jsapi::{JSJitInfo, JSObject, JSTracer, JSWrapObjectCallbacks};
use js::jsapi::{JS_DeletePropertyById, JS_EnumerateStandardClasses};
use js::jsapi::{JS_ForwardGetPropertyTo, JS_GetClass, JS_GetLatin1StringCharsAndLength};
use js::jsapi::{JS_GetProperty, JS_GetPrototype, JS_GetReservedSlot, JS_HasProperty};
use js::jsapi::{JS_HasPropertyById, JS_IsExceptionPending, JS_IsGlobalObject, JS_NewGlobalObject};
use js::jsapi::{JS_HasPropertyById, JS_IsExceptionPending, JS_IsGlobalObject};
use js::jsapi::{JS_ResolveStandardClass, JS_SetProperty, ToWindowProxyIfWindow};
use js::jsapi::{JS_SetReservedSlot, JS_StringHasLatin1Chars, MutableHandleValue};
use js::jsapi::{ObjectOpResult, OnNewGlobalHookOption};
use js::jsval::{JSVal, ObjectValue, PrivateValue, UndefinedValue};
use js::jsapi::{JS_StringHasLatin1Chars, MutableHandleValue, ObjectOpResult};
use js::jsval::{JSVal, ObjectValue, UndefinedValue};
use js::rust::{GCMethods, ToString};
use libc;
use std::default::Default;
use std::ffi::CString;
use std::os::raw::c_void;
use std::ptr;
@ -296,43 +293,6 @@ pub fn has_property_on_prototype(cx: *mut JSContext, proxy: HandleObject, id: Ha
}) || found
}
/// Create a DOM global object with the given class.
pub fn create_dom_global(cx: *mut JSContext,
class: *const JSClass,
private: *const libc::c_void,
trace: JSTraceOp)
-> *mut JSObject {
unsafe {
let mut options = CompartmentOptions::default();
options.behaviors_.version_ = JSVersion::JSVERSION_ECMA_5;
options.creationOptions_.traceGlobal_ = trace;
options.creationOptions_.sharedMemoryAndAtomics_ = true;
rooted!(in(cx) let obj =
JS_NewGlobalObject(cx,
class,
ptr::null_mut(),
OnNewGlobalHookOption::DontFireOnNewGlobalHook,
&options));
if obj.is_null() {
return ptr::null_mut();
}
// Initialize the reserved slots before doing amything that can GC, to
// avoid getting trace hooks called on a partially initialized object.
JS_SetReservedSlot(obj.get(), DOM_OBJECT_SLOT, PrivateValue(private));
let proto_array: Box<ProtoOrIfaceArray> =
box [0 as *mut JSObject; PROTO_OR_IFACE_LENGTH];
JS_SetReservedSlot(obj.get(),
DOM_PROTOTYPE_SLOT,
PrivateValue(Box::into_raw(proto_array) as *const libc::c_void));
let _ac = JSAutoCompartment::new(cx, obj.get());
JS_FireOnNewGlobalObject(cx, obj.handle());
obj.get()
}
}
/// Drop the resources held by reserved slots of a global object
pub unsafe fn finalize_global(obj: *mut JSObject) {
let protolist = get_proto_or_iface_array(obj);