aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/interface.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/interface.rs')
-rw-r--r--components/script/dom/bindings/interface.rs71
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,