Turn on GC all the time. Fix rooting errors during parsing and storing timers. Fix borrow errors during tracing.

This commit is contained in:
Josh Matthews 2014-03-28 10:17:56 -04:00
parent 4051a8096d
commit ffdc3f5b32
109 changed files with 1567 additions and 996 deletions

View file

@ -281,6 +281,7 @@ class CGMethodCall(CGThing):
isDefinitelyObject=True),
{
"declName" : "arg%d" % distinguishingIndex,
"simpleDeclName" : "arg%d" % distinguishingIndex,
"holderName" : ("arg%d" % distinguishingIndex) + "_holder",
"val" : distinguishingArg
})
@ -551,12 +552,21 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
templateBody += (
"} else {\n" +
CGIndenter(onFailureNotAnObject(failureCode)).define() +
"}")
"}\n")
if type.nullable():
templateBody = handleDefaultNull(templateBody, "None")
else:
assert(defaultValue is None)
#if type.isGeckoInterface() and not type.unroll().inner.isCallback():
# if type.nullable() or isOptional:
#
# else:
#
# templateBody = CGList([CGGeneric(templateBody),
# CGGeneric("\n"),
# CGGeneric(rootBody)]).define()
return templateBody
assert not (isEnforceRange and isClamp) # These are mutually exclusive
@ -888,6 +898,18 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
# Add an empty CGGeneric to get an extra newline after the argument
# conversion.
result.append(CGGeneric(""))
type = declType.define() if declType else None
if type and 'JS<' in type:
if dealWithOptional or 'Option<' in type:
rootBody = """let ${simpleDeclName} = ${declName}.as_ref().map(|inner| {
inner.root(&roots) //second root code
});"""
else:
rootBody = "let ${simpleDeclName} = ${declName}.root(&roots); //third root code"
result.append(CGGeneric(string.Template(rootBody).substitute(replacements)))
result.append(CGGeneric(""))
return result;
def convertConstIDLValueToJSVal(value):
@ -929,6 +951,7 @@ class CGArgumentConverter(CGThing):
}
self.replacementVariables = {
"declName" : "arg%d" % index,
"simpleDeclName" : "arg%d" % index,
"holderName" : ("arg%d" % index) + "_holder"
}
self.replacementVariables["val"] = string.Template(
@ -1691,6 +1714,8 @@ class Argument():
A class for outputting the type and name of an argument
"""
def __init__(self, argType, name, default=None, mutable=False):
if argType and 'JS<' in argType:
argType = argType.replace('JS<', 'JSRef<')
self.argType = argType
self.name = name
self.default = default
@ -1763,7 +1788,7 @@ class CGAbstractMethod(CGThing):
def _returnType(self):
return (" -> %s" % self.returnType) if self.returnType != "void" else ""
def _unsafe_open(self):
return "\n unsafe {" if self.unsafe else ""
return "\n unsafe {\n let roots = RootCollection::new();\n" if self.unsafe else ""
def _unsafe_close(self):
return "\n }\n" if self.unsafe else ""
@ -1809,7 +1834,7 @@ class CGWrapMethod(CGAbstractMethod):
def __init__(self, descriptor):
assert descriptor.interface.hasInterfacePrototypeObject()
if not descriptor.createGlobal:
args = [Argument('*JSContext', 'aCx'), Argument('&JS<Window>', 'aScope'),
args = [Argument('*JSContext', 'aCx'), Argument('&JSRef<Window>', 'aScope'),
Argument("~" + descriptor.concreteType, 'aObject', mutable=True)]
else:
args = [Argument('*JSContext', 'aCx'),
@ -2277,7 +2302,12 @@ class CGPerSignatureCall(CGThing):
def getArgc(self):
return "argc"
def getArguments(self):
return [(a, "arg" + str(i)) for (i, a) in enumerate(self.arguments)]
def process(arg, i):
argVal = "arg" + str(i)
if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback():
argVal += ".root_ref()"
return argVal
return [(a, process(a, i)) for (i, a) in enumerate(self.arguments)]
def isFallible(self):
return not 'infallible' in self.extendedAttributes
@ -2452,8 +2482,10 @@ class CGSpecializedMethod(CGAbstractExternMethod):
argsPre = []
if name in self.descriptor.needsAbstract:
abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType)
extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName
argsPre = ['&mut abstract_this']
extraPre = """ let mut abstract_this = %s::from_raw(this);
let abstract_this = abstract_this.root(&roots);
""" % abstractName
argsPre = ['&mut abstract_this.root_ref()']
return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(),
self.descriptor, self.method),
pre=extraPre +
@ -2480,10 +2512,8 @@ class CGGenericGetter(CGAbstractBindingMethod):
def generate_code(self):
return CGIndenter(CGGeneric(
"return with_gc_disabled(cx, || {\n"
" let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n"
" CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, &*vp)\n"
"});\n"))
"let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n"
"return CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, &*vp);\n"))
class CGSpecializedGetter(CGAbstractExternMethod):
"""
@ -2509,8 +2539,10 @@ class CGSpecializedGetter(CGAbstractExternMethod):
getter=True))
if name in self.descriptor.needsAbstract:
abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType)
extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName
argsPre = ['&mut abstract_this']
extraPre = """ let mut abstract_this = %s::from_raw(this);
let abstract_this = abstract_this.root(&roots);
""" % abstractName
argsPre = ['&mut abstract_this.root_ref()']
if self.attr.type.nullable() or not infallible:
nativeName = "Get" + nativeName
return CGWrapper(CGIndenter(CGGetterCall(argsPre, self.attr.type, nativeName,
@ -2541,10 +2573,7 @@ class CGGenericSetter(CGAbstractBindingMethod):
"let undef = UndefinedValue();\n"
"let argv: *JSVal = if argc != 0 { JS_ARGV(cx, vp as *JSVal) } else { &undef as *JSVal };\n"
"let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp as *JSVal));\n"
"let ok = with_gc_disabled(cx, || {\n"
" CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, argv)\n"
"});\n"
"if ok == 0 {\n"
"if CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, argv) == 0 {\n"
" return 0;\n"
"}\n"
"*vp = UndefinedValue();\n"
@ -2571,8 +2600,10 @@ class CGSpecializedSetter(CGAbstractExternMethod):
extraPre = ''
if name in self.descriptor.needsAbstract:
abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType)
extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName
argsPre = ['&mut abstract_this']
extraPre = """ let mut abstract_this = %s::from_raw(this);
let abstract_this = abstract_this.root(&roots);
""" % abstractName
argsPre = ['&mut abstract_this.root_ref()']
return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName,
self.descriptor, self.attr)),
pre=extraPre +
@ -3402,6 +3433,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
treatNullAs=argument.treatNullAs)
templateValues = {
"declName": argument.identifier.name,
"simpleDeclName": argument.identifier.name,
"holderName": argument.identifier.name + "_holder",
"val": "(*desc).value",
"valPtr": "&(*desc).value"
@ -3411,7 +3443,12 @@ class CGProxySpecialOperation(CGPerSignatureCall):
self.cgRoot.prepend(CGGeneric("let mut found = false;"))
def getArguments(self):
args = [(a, a.identifier.name) for a in self.arguments]
def process(arg):
argVal = arg.identifier.name
if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback():
argVal += ".root_ref()"
return argVal
args = [(a, process(a)) for a in self.arguments]
if self.idlNode.isGetter():
args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean],
self.idlNode),
@ -3825,11 +3862,13 @@ class CGClassConstructHook(CGAbstractExternMethod):
def generate_code(self):
preamble = """
let roots = RootCollection::new();
let global = global_object_for_js_object(JS_CALLEE(cx, &*vp).to_object());
let global = global.root(&roots);
let obj = global.reflector().get_jsobject();
"""
nativeName = MakeNativeName(self._ctor.identifier.name)
callGenerator = CGMethodCall(["&global"], nativeName, True,
callGenerator = CGMethodCall(["&global.root_ref()"], nativeName, True,
self.descriptor, self._ctor)
return preamble + callGenerator.define();
@ -4067,6 +4106,7 @@ class CGDictionary(CGThing):
return string.Template(
"impl ${selfName} {\n"
" pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n"
" let roots = RootCollection::new();\n" # XXXjdm need to root dict members outside of Init
" let object = if val.is_null_or_undefined() {\n"
" ptr::null()\n"
" } else if val.is_object() {\n"
@ -4266,7 +4306,7 @@ class CGBindingRoot(CGThing):
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
'dom::types::*',
'dom::bindings',
'dom::bindings::js::JS',
'dom::bindings::js::{JS, JSRef, RootCollection, RootedReference}',
'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}',
'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
@ -4279,8 +4319,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{Reflectable}',
'dom::bindings::utils::{squirrel_away_unique}',
'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}',
'dom::bindings::utils::{VoidVal, with_gc_disabled}',
'dom::bindings::utils::{with_gc_enabled}',
'dom::bindings::utils::VoidVal',
'dom::bindings::utils::get_dictionary_property',
'dom::bindings::trace::JSTraceable',
'dom::bindings::callback::{CallbackContainer,CallbackInterface}',
@ -5057,11 +5096,8 @@ class CallbackMethod(CallbackMember):
replacements["argc"] = "0"
return string.Template("${getCallable}"
"let ok = unsafe {\n"
" //JS_AllowGC(cx); // It's unsafe to enable GC at arbitrary points during Rust execution; leave it disabled\n"
" let ok = JS_CallFunctionValue(cx, ${thisObj}, callable,\n"
" ${argc}, ${argv}, &rval);\n"
" //JS_InhibitGC(cx);\n"
" ok\n"
" JS_CallFunctionValue(cx, ${thisObj}, callable,\n"
" ${argc}, ${argv}, &rval)\n"
"};\n"
"if ok == 0 {\n"
" return${errorReturn};\n"
@ -5209,7 +5245,7 @@ class GlobalGenRoots():
# TODO - Generate the methods we want
return CGImports(CGRegisterProtos(config), [
'dom::bindings::codegen',
'dom::bindings::js::JS',
'dom::bindings::js::{JS, JSRef}',
'dom::window::Window',
'script_task::JSPageInfo',
])
@ -5241,7 +5277,7 @@ class GlobalGenRoots():
descriptors = config.getDescriptors(register=True, hasInterfaceObject=True)
allprotos = [CGGeneric("#![allow(unused_imports)]\n"),
CGGeneric("use dom::types::*;\n"),
CGGeneric("use dom::bindings::js::JS;\n"),
CGGeneric("use dom::bindings::js::{JS, JSRef};\n"),
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
CGGeneric("use serialize::{Encodable, Encoder};\n"),
CGGeneric("use js::jsapi::JSTracer;\n\n")]
@ -5286,6 +5322,14 @@ class GlobalGenRoots():
assert!(base.get().${checkFn}());
base.clone().transmute()
}
fn from_ref<'a, 'b, T: ${fromBound}>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, Self> {
unsafe { derived.transmute() }
}
fn from_mut_ref<'a, 'b, T: ${fromBound}>(derived: &'a mut JSRef<'b, T>) -> &'a mut JSRef<'b, Self> {
unsafe { derived.transmute_mut() }
}
}
''').substitute({'checkFn': 'is_' + name.lower(),
'castTraitName': name + 'Cast',

View file

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::js::JS;
use dom::bindings::js::{JS, JSRef};
use dom::bindings::str::ByteString;
use dom::bindings::utils::Reflectable;
use dom::bindings::utils::{Reflectable, Reflector};
use dom::bindings::utils::jsstring_to_str;
use dom::bindings::utils::unwrap_jsmanaged;
use servo_util::str::DOMString;
@ -293,9 +293,9 @@ impl FromJSValConvertible<()> for ByteString {
}
}
impl<T: Reflectable> ToJSValConvertible for JS<T> {
impl ToJSValConvertible for Reflector {
fn to_jsval(&self, cx: *JSContext) -> JSVal {
let obj = self.reflector().get_jsobject();
let obj = self.get_jsobject();
assert!(obj.is_not_null());
let mut value = ObjectValue(unsafe { &*obj });
if unsafe { JS_WrapValue(cx, &mut value as *mut JSVal as *JSVal) } == 0 {
@ -316,6 +316,18 @@ impl<T: Reflectable+IDLInterface> FromJSValConvertible<()> for JS<T> {
}
}
impl<T: Reflectable> ToJSValConvertible for JS<T> {
fn to_jsval(&self, cx: *JSContext) -> JSVal {
self.reflector().to_jsval(cx)
}
}
impl<'a, T: Reflectable> ToJSValConvertible for JSRef<'a, T> {
fn to_jsval(&self, cx: *JSContext) -> JSVal {
self.reflector().to_jsval(cx)
}
}
impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> {
fn to_jsval(&self, cx: *JSContext) -> JSVal {
match self {

View file

@ -4,11 +4,13 @@
use dom::bindings::utils::{Reflector, Reflectable};
use dom::window::Window;
use js::jsapi::JSContext;
use js::jsapi::{JSObject, JSContext};
use layout_interface::TrustedNodeAddress;
use std::cast;
use std::cell::RefCell;
use std::cell::{Cell, RefCell};
use std::ptr;
//use std::ops::{Deref, DerefMut};
pub struct JS<T> {
ptr: RefCell<*mut T>
@ -31,8 +33,8 @@ impl <T> Clone for JS<T> {
impl<T: Reflectable> JS<T> {
pub fn new(obj: ~T,
window: &JS<Window>,
wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> JS<T>) -> JS<T> {
window: &JSRef<Window>,
wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~T) -> JS<T>) -> JS<T> {
wrap_fn(window.get().get_cx(), window, obj)
}
@ -49,6 +51,10 @@ impl<T: Reflectable> JS<T> {
ptr: RefCell::new(addr as *mut T)
}
}
pub fn root<'a>(&self, collection: &'a RootCollection) -> Root<'a, T> {
collection.new_root(self)
}
}
impl<T: Reflectable> Reflectable for JS<T> {
@ -94,3 +100,213 @@ impl<From, To> JS<From> {
cast::transmute_copy(self)
}
}
pub trait RootedReference<T> {
fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>>;
}
impl<'a, T: Reflectable> RootedReference<T> for Option<Root<'a, T>> {
fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>> {
self.as_ref().map(|root| root.root_ref())
}
}
#[deriving(Eq, Clone)]
struct RootReference(*JSObject);
impl RootReference {
fn new<'a, T: Reflectable>(unrooted: &Root<'a, T>) -> RootReference {
RootReference(unrooted.rooted())
}
fn null() -> RootReference {
RootReference(ptr::null())
}
}
static MAX_STACK_ROOTS: uint = 10;
pub struct RootCollection {
roots: [Cell<RootReference>, ..MAX_STACK_ROOTS],
current: Cell<uint>,
}
impl RootCollection {
pub fn new() -> RootCollection {
RootCollection {
roots: [Cell::new(RootReference::null()), ..MAX_STACK_ROOTS],
current: Cell::new(0),
}
}
fn new_root<'a, T: Reflectable>(&'a self, unrooted: &JS<T>) -> Root<'a, T> {
Root::new(self, unrooted)
}
fn root_impl(&self, unrooted: RootReference) {
let current = self.current.get();
assert!(current < MAX_STACK_ROOTS);
self.roots[current].set(unrooted);
self.current.set(current + 1);
}
fn root<'a, T: Reflectable>(&self, unrooted: &Root<'a, T>) {
self.root_impl(RootReference::new(unrooted));
}
pub fn root_raw(&self, unrooted: *JSObject) {
self.root_impl(RootReference(unrooted));
}
fn unroot_impl(&self, rooted: RootReference) {
let mut current = self.current.get();
assert!(current != 0);
current -= 1;
assert!(self.roots[current].get() == rooted);
self.roots[current].set(RootReference::null());
self.current.set(current);
}
fn unroot<'a, T: Reflectable>(&self, rooted: &Root<'a, T>) {
self.unroot_impl(RootReference::new(rooted));
}
pub fn unroot_raw(&self, rooted: *JSObject) {
self.unroot_impl(RootReference(rooted));
}
}
pub struct Root<'a, T> {
root_list: &'a RootCollection,
ptr: RefCell<*mut T>,
}
impl<'a, T: Reflectable> Root<'a, T> {
fn new(roots: &'a RootCollection, unrooted: &JS<T>) -> Root<'a, T> {
let root = Root {
root_list: roots,
ptr: unrooted.ptr.clone()
};
roots.root(&root);
root
}
pub fn get<'a>(&'a self) -> &'a T {
unsafe {
let borrow = self.ptr.borrow();
&**borrow
}
}
pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
unsafe {
let mut borrow = self.ptr.borrow_mut();
&mut **borrow
}
}
fn rooted(&self) -> *JSObject {
self.reflector().get_jsobject()
}
pub fn root_ref<'b>(&'b self) -> JSRef<'b,T> {
unsafe {
JSRef {
ptr: self.ptr.clone(),
chain: ::std::cast::transmute_region(&()),
}
}
}
}
#[unsafe_destructor]
impl<'a, T: Reflectable> Drop for Root<'a, T> {
fn drop(&mut self) {
self.root_list.unroot(self);
}
}
impl<'a, T: Reflectable> Reflectable for Root<'a, T> {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.get().reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.get_mut().mut_reflector()
}
}
/*impl<'a, T> Deref for Root<'a, T> {
fn deref<'a>(&'a self) -> &'a T {
self.get()
}
}
impl<'a, T> DerefMut for Root<'a, T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
self.get_mut()
}
}*/
/// Encapsulates a reference to something that is guaranteed to be alive. This is freely copyable.
pub struct JSRef<'a, T> {
ptr: RefCell<*mut T>,
chain: &'a (),
}
impl<'a, T> Clone for JSRef<'a, T> {
fn clone(&self) -> JSRef<'a, T> {
JSRef {
ptr: self.ptr.clone(),
chain: self.chain
}
}
}
impl<'a, T> Eq for JSRef<'a, T> {
fn eq(&self, other: &JSRef<T>) -> bool {
self.ptr == other.ptr
}
}
impl<'a,T> JSRef<'a,T> {
pub fn get<'a>(&'a self) -> &'a T {
unsafe {
let borrow = self.ptr.borrow();
&**borrow
}
}
pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
let mut borrowed = self.ptr.borrow_mut();
unsafe {
&mut **borrowed
}
}
//XXXjdm It would be lovely if this could be private.
pub unsafe fn transmute<'b, To>(&'b self) -> &'b JSRef<'a, To> {
cast::transmute(self)
}
//XXXjdm It would be lovely if this could be private.
pub unsafe fn transmute_mut<'b, To>(&'b mut self) -> &'b mut JSRef<'a, To> {
cast::transmute(self)
}
pub fn unrooted(&self) -> JS<T> {
JS {
ptr: self.ptr.clone()
}
}
}
impl<'a, T: Reflectable> Reflectable for JSRef<'a, T> {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.get().reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.get_mut().mut_reflector()
}
}

View file

@ -6,6 +6,7 @@ use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector};
use js::jsapi::{JSObject, JSTracer, JS_CallTracer, JSTRACE_OBJECT};
use js::jsval::JSVal;
use libc;
use std::cast;
@ -42,6 +43,22 @@ pub trait JSTraceable {
fn trace(&self, trc: *mut JSTracer);
}
pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) {
if !val.is_gcthing() {
return;
}
unsafe {
description.to_c_str().with_ref(|name| {
(*tracer).debugPrinter = ptr::null();
(*tracer).debugPrintIndex = -1;
(*tracer).debugPrintArg = name as *libc::c_void;
debug!("tracing value {:s}", description);
JS_CallTracer(tracer as *JSTracer, val.to_gcthing(), val.trace_kind());
});
}
}
pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) {
trace_object(tracer, description, reflector.get_jsobject())
}
@ -132,3 +149,10 @@ impl<S: Encoder<E>, E> Encodable<S, E> for Traceable<*JSObject> {
Ok(())
}
}
impl<S: Encoder<E>, E> Encodable<S, E> for Traceable<JSVal> {
fn encode(&self, s: &mut S) -> Result<(), E> {
trace_jsval(get_jstracer(s), "val", **self);
Ok(())
}
}

View file

@ -5,7 +5,7 @@
use dom::bindings::codegen::PrototypeList;
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
use dom::bindings::conversions::{FromJSValConvertible, IDLInterface};
use dom::bindings::js::JS;
use dom::bindings::js::{JS, JSRef};
use dom::bindings::trace::Untraceable;
use dom::browsercontext;
use dom::window;
@ -37,7 +37,6 @@ use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative};
use js::jsapi::{JSFunctionSpec, JSPropertySpec};
use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses};
use js::jsapi::{JSString};
use js::jsapi::{JS_AllowGC, JS_InhibitGC};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
use js::jsval::JSVal;
use js::jsval::{PrivateValue, ObjectValue, NullValue, ObjectOrNullValue};
@ -390,8 +389,8 @@ pub trait Reflectable {
pub fn reflect_dom_object<T: Reflectable>
(obj: ~T,
window: &JS<window::Window>,
wrap_fn: extern "Rust" fn(*JSContext, &JS<window::Window>, ~T) -> JS<T>)
window: &JSRef<window::Window>,
wrap_fn: extern "Rust" fn(*JSContext, &JSRef<window::Window>, ~T) -> JS<T>)
-> JS<T> {
JS::new(obj, window, wrap_fn)
}
@ -637,26 +636,6 @@ pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *JSContext {
cx_for_dom_reflector(obj.reflector().get_jsobject())
}
/// Execute arbitrary code with the JS GC enabled, then disable it afterwards.
pub fn with_gc_enabled<R>(cx: *JSContext, f: || -> R) -> R {
unsafe {
JS_AllowGC(cx);
let rv = f();
JS_InhibitGC(cx);
rv
}
}
/// Execute arbitrary code with the JS GC disabled, then enable it afterwards.
pub fn with_gc_disabled<R>(cx: *JSContext, f: || -> R) -> R {
unsafe {
JS_InhibitGC(cx);
let rv = f();
JS_AllowGC(cx);
rv
}
}
/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name
/// for details.
#[deriving(Eq)]