diff options
Diffstat (limited to 'components/script/dom/bindings/interface.rs')
-rw-r--r-- | components/script/dom/bindings/interface.rs | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index 47a549602b6..bcc619579dc 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -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; @@ -206,6 +209,46 @@ 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: *const JSClass, + private: *const libc::c_void, + trace: TraceHook) + -> *mut JSObject { + let mut options = CompartmentOptions::default(); + options.behaviors_.version_ = JSVersion::JSVERSION_ECMA_5; + options.creationOptions_.traceGlobal_ = Some(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 anything 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; PrototypeList::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() +} + /// Create and define the interface object of a callback interface. pub unsafe fn create_callback_interface_object( cx: *mut JSContext, |