diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 6 | ||||
-rw-r--r-- | src/components/script/dom/bindings/conversions.rs | 94 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 109 | ||||
-rw-r--r-- | src/test/html/content/test_union.html | 2 |
4 files changed, 52 insertions, 159 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 6000e2abcba..bc5ac31feaf 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1246,7 +1246,7 @@ for (uint32_t i = 0; i < length; ++i) { "if (%s) {\n" " ${declName} = None;\n" "} else {\n" - " match JSValConvertible::from_jsval(${val}) {\n" + " match JSValConvertible::from_jsval(cx, ${val}) {\n" " Some(val_) => ${declName} = Some(%s),\n" " None => %s\n" " }\n" @@ -1261,7 +1261,7 @@ for (uint32_t i = 0; i < length; ++i) { if preSuccess or postSuccess: successVal = preSuccess + successVal + postSuccess template = ( - "match JSValConvertible::from_jsval(${val}) {\n" + "match JSValConvertible::from_jsval(cx, ${val}) {\n" " None => %s,\n" " Some(v) => %s = %s\n" "}" % (failureCode, dataLoc, successVal)) @@ -2792,7 +2792,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): return "ptr::to_unsafe_ptr(&%s[0])" % val call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, - %s, ptr::null(), %s, %d, + %s, %s, %d, %s, %s, %s, diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index decb047ab9f..116b74e8efa 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -2,15 +2,27 @@ * 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 js::jsapi::JSVal; +use js::jsapi::{JSVal, JSBool, JSContext}; +use js::jsapi::{JS_ValueToInt64, JS_ValueToECMAInt32, JS_ValueToECMAUint32}; +use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean}; use js::{JSVAL_FALSE, JSVAL_TRUE}; -use js::glue::{RUST_UINT_TO_JSVAL, RUST_JSVAL_TO_INT, RUST_DOUBLE_TO_JSVAL}; -use js::glue::{RUST_JSVAL_TO_DOUBLE, RUST_JSVAL_IS_INT, RUST_JSVAL_IS_DOUBLE}; -use js::glue::{RUST_JSVAL_IS_BOOLEAN, RUST_JSVAL_TO_BOOLEAN}; +use js::glue::{RUST_UINT_TO_JSVAL, RUST_DOUBLE_TO_JSVAL}; pub trait JSValConvertible { fn to_jsval(&self) -> JSVal; - fn from_jsval(val: JSVal) -> Option<Self>; + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<Self>; +} + + +unsafe fn convert_from_jsval<T: Default>( + cx: *JSContext, value: JSVal, + convert_fn: extern "C" unsafe fn(*JSContext, JSVal, *T) -> JSBool) -> Option<T> { + let mut ret = Default::default(); + if convert_fn(cx, value, &mut ret as *mut T as *T) == 0 { + None + } else { + Some(ret) + } } @@ -21,14 +33,8 @@ impl JSValConvertible for i64 { } } - fn from_jsval(val: JSVal) -> Option<i64> { - unsafe { - if RUST_JSVAL_IS_INT(val) != 0 { - Some(RUST_JSVAL_TO_DOUBLE(val) as i64) - } else { - None - } - } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i64> { + unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) } } } @@ -39,14 +45,8 @@ impl JSValConvertible for u32 { } } - fn from_jsval(val: JSVal) -> Option<u32> { - unsafe { - if RUST_JSVAL_IS_INT(val) != 0 { - Some(RUST_JSVAL_TO_INT(val) as u32) - } else { - None - } - } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u32> { + unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) } } } @@ -57,14 +57,8 @@ impl JSValConvertible for i32 { } } - fn from_jsval(val: JSVal) -> Option<i32> { - unsafe { - if RUST_JSVAL_IS_INT(val) != 0 { - Some(RUST_JSVAL_TO_INT(val) as i32) - } else { - None - } - } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<i32> { + unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) } } } @@ -75,14 +69,8 @@ impl JSValConvertible for u16 { } } - fn from_jsval(val: JSVal) -> Option<u16> { - unsafe { - if RUST_JSVAL_IS_INT(val) != 0 { - Some(RUST_JSVAL_TO_INT(val) as u16) - } else { - None - } - } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<u16> { + unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) } } } @@ -95,14 +83,9 @@ impl JSValConvertible for bool { } } - fn from_jsval(val: JSVal) -> Option<bool> { - unsafe { - if RUST_JSVAL_IS_BOOLEAN(val) != 0 { - Some(RUST_JSVAL_TO_BOOLEAN(val) != 0) - } else { - None - } - } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<bool> { + let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) }; + result.map(|b| b != 0) } } @@ -113,14 +96,9 @@ impl JSValConvertible for f32 { } } - fn from_jsval(val: JSVal) -> Option<f32> { - unsafe { - if RUST_JSVAL_IS_DOUBLE(val) != 0 { - Some(RUST_JSVAL_TO_DOUBLE(val) as f32) - } else { - None - } - } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f32> { + let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }; + result.map(|f| f as f32) } } @@ -131,13 +109,7 @@ impl JSValConvertible for f64 { } } - fn from_jsval(val: JSVal) -> Option<f64> { - unsafe { - if RUST_JSVAL_IS_DOUBLE(val) != 0 { - Some(RUST_JSVAL_TO_DOUBLE(val) as f64) - } else { - None - } - } + fn from_jsval(cx: *JSContext, val: JSVal) -> Option<f64> { + unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) } } } diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 7c0c7a9a1e7..22f10b65c47 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -19,13 +19,13 @@ use std::str; use std::vec; use std::unstable::raw::Box; use js::glue::*; -use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL}; +use js::glue::{RUST_OBJECT_TO_JSVAL}; use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily}; -use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction}; +use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction}; use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo}; use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype, JS_GetStringCharsAndLength}; use js::jsapi::{JS_ObjectIsRegExp, JS_ObjectIsDate}; -use js::jsapi::{JS_GetFunctionPrototype, JS_InternString, JS_GetFunctionObject}; +use js::jsapi::{JS_InternString, JS_GetFunctionObject}; use js::jsapi::{JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject}; use js::jsapi::{JS_NewUCStringCopyN, JS_DefineFunctions, JS_DefineProperty}; use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot}; @@ -38,16 +38,12 @@ use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::{JSPROP_ENUMERATE, JSVAL_NULL, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS}; use js::{JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER}; use js::{JSPROP_SETTER, JSVAL_VOID, JSVAL_TRUE, JSVAL_FALSE}; -use js::{JS_THIS_OBJECT, JSFUN_CONSTRUCTOR, JS_CALLEE, JSPROP_READONLY}; +use js::{JSFUN_CONSTRUCTOR, JSPROP_READONLY}; use js; -static TOSTRING_CLASS_RESERVED_SLOT: libc::size_t = 0; -static TOSTRING_NAME_RESERVED_SLOT: libc::size_t = 1; - mod jsval { use js::glue::{RUST_JSVAL_IS_NULL, RUST_JSVAL_IS_VOID}; - use js::glue::{RUST_JSVAL_IS_STRING, RUST_JSVAL_TO_STRING}; - use js::jsapi::{JSVal, JSString}; + use js::jsapi::JSVal; pub fn is_null(v: JSVal) -> bool { unsafe { RUST_JSVAL_IS_NULL(v) == 1 } @@ -56,14 +52,6 @@ mod jsval { pub fn is_undefined(v: JSVal) -> bool { unsafe { RUST_JSVAL_IS_VOID(v) == 1 } } - - pub fn is_string(v: JSVal) -> bool { - unsafe { RUST_JSVAL_IS_STRING(v) == 1 } - } - - pub unsafe fn to_string(v: JSVal) -> *JSString { - RUST_JSVAL_TO_STRING(v) - } } pub struct GlobalStaticData { @@ -82,40 +70,6 @@ pub fn GlobalStaticData() -> GlobalStaticData { } } -extern fn InterfaceObjectToString(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool { - unsafe { - let callee = RUST_JSVAL_TO_OBJECT(*JS_CALLEE(cx, cast::transmute(&vp))); - let obj = JS_THIS_OBJECT(cx, cast::transmute(&vp)); - if obj.is_null() { - //XXXjdm figure out JSMSG madness - /*JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO, - "null", "object");*/ - return 0; - } - - let v = GetFunctionNativeReserved(callee, TOSTRING_CLASS_RESERVED_SLOT); - let clasp: *JSClass = cast::transmute(RUST_JSVAL_TO_PRIVATE(*v)); - - if GetObjectJSClass(obj) != clasp { - /*let jsname: *JSString = RUST_JSVAL_TO_STRING(*v); - let length = 0; - let name = JS_GetInternedStringCharsAndLength(jsname, &length);*/ - //XXXjdm figure out JSMSG madness - /*JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, - NS_ConvertUTF16toUTF8(name).get(), "toString", - "object");*/ - return 0; - } - - let v = *GetFunctionNativeReserved(callee, TOSTRING_NAME_RESERVED_SLOT); - assert!(jsval::is_string(v)); - let name = jsstring_to_str(cx, jsval::to_string(v)); - let retval = ~"function " + name + "() {\n [native code]\n}"; - *vp = str_to_jsval(cx, retval); - return 1; - } -} - fn is_dom_class(clasp: *JSClass) -> bool { unsafe { ((*clasp).flags & js::JSCLASS_IS_DOMJSCLASS) != 0 @@ -362,7 +316,7 @@ pub fn GetProtoOrIfaceArray(global: *JSObject) -> **JSObject { pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSObject, protoProto: *JSObject, protoClass: *JSClass, - constructorClass: *JSClass, constructor: Option<JSNative>, + constructor: Option<JSNative>, ctorNargs: u32, domClass: *DOMClass, methods: *JSFunctionSpec, @@ -386,9 +340,9 @@ pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSO } let mut interface = ptr::null(); - if constructorClass.is_not_null() || constructor.is_some() { + if constructor.is_some() { interface = name.to_c_str().with_ref(|s| { - CreateInterfaceObject(cx, global, receiver, constructorClass, + CreateInterfaceObject(cx, global, receiver, constructor, ctorNargs, proto, staticMethods, constants, s) }); @@ -405,59 +359,26 @@ pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSO } fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject, - constructorClass: *JSClass, constructorNative: Option<JSNative>, + constructorNative: Option<JSNative>, ctorNargs: u32, proto: *JSObject, staticMethods: *JSFunctionSpec, constants: *ConstantSpec, name: *libc::c_char) -> *JSObject { unsafe { - let constructor = if constructorClass.is_not_null() { - let functionProto = JS_GetFunctionPrototype(cx, global); - if functionProto.is_null() { - ptr::null() - } else { - JS_NewObject(cx, constructorClass, functionProto, global) - } - } else { - let fun = JS_NewFunction(cx, constructorNative, ctorNargs, - JSFUN_CONSTRUCTOR, global, name); - if fun.is_null() { - ptr::null() - } else { - JS_GetFunctionObject(fun) - } - }; - - if constructor.is_null() { + let fun = JS_NewFunction(cx, constructorNative, ctorNargs, + JSFUN_CONSTRUCTOR, global, name); + if fun.is_null() { return ptr::null(); } + let constructor = JS_GetFunctionObject(fun); + assert!(constructor.is_not_null()); + if staticMethods.is_not_null() && !DefineMethods(cx, constructor, staticMethods) { return ptr::null(); } - if constructorClass.is_not_null() { - let toString = "toString".to_c_str().with_ref(|s| { - DefineFunctionWithReserved(cx, constructor, s, - InterfaceObjectToString, - 0, 0) - }); - if toString.is_null() { - return ptr::null(); - } - - let toStringObj = JS_GetFunctionObject(toString); - SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT, - &RUST_PRIVATE_TO_JSVAL(constructorClass as *libc::c_void)); - let s = JS_InternString(cx, name); - if s.is_null() { - return ptr::null(); - } - SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT, - &RUST_STRING_TO_JSVAL(s)); - } - if constants.is_not_null() && !DefineConstants(cx, constructor, constants) { return ptr::null(); diff --git a/src/test/html/content/test_union.html b/src/test/html/content/test_union.html index d5483ad8a3a..fd2bf84f96b 100644 --- a/src/test/html/content/test_union.html +++ b/src/test/html/content/test_union.html @@ -18,7 +18,7 @@ }); should_throw(function() { sel.add(div) }); - should_throw(function() { sel.add(optgroup, function() {}) }); + should_not_throw(function() { sel.add(optgroup, function() {}) }); finish(); </script> |