diff options
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 29 | ||||
-rw-r--r-- | components/script/dom/bindings/utils.rs | 24 |
2 files changed, 50 insertions, 3 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index d44db4078b4..9f965a9c7e8 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1165,6 +1165,15 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): return CGGeneric("*mut JSObject") if returnType.isSequence(): raise TypeError("We don't support sequence return values") + if returnType.isDictionary(): + nullable = returnType.nullable() + dictName = returnType.inner.name if nullable else returnType.name + result = CGGeneric(dictName) + if typeNeedsRooting(returnType, descriptorProvider): + raise TypeError("We don't support rootable dictionaries return values") + if nullable: + result = CGWrapper(result, pre="Option<", post=">") + return result raise TypeError("Don't know how to declare return value for %s" % returnType) @@ -4517,7 +4526,14 @@ class CGDictionary(CGThing): conversion = self.getMemberConversion(memberInfo) return CGGeneric("%s: %s,\n" % (name, conversion.define())) + def memberInsert(memberInfo): + member, _ = memberInfo + name = self.makeMemberName(member.identifier.name) + insertion = ("set_dictionary_property(cx, obj, \"%s\", &mut self.%s.to_jsval(cx)).unwrap();" % (name, name)) + return CGGeneric("%s\n" % insertion) + memberInits = CGList([memberInit(m) for m in self.memberInfo]) + memberInserts = CGList([memberInsert(m) for m in self.memberInfo]) return string.Template( "impl ${selfName} {\n" @@ -4538,10 +4554,19 @@ class CGDictionary(CGThing): "${initMembers}" " })\n" " }\n" - "}").substitute({ + "}\n" + "\n" + "impl ToJSValConvertible for ${selfName} {\n" + " fn to_jsval(&self, cx: *mut JSContext) -> JSVal {\n" + " let obj = unsafe { JS_NewObject(cx, 0 as *const JSClass, 0 as *const JSObject, 0 as *const JSObject) };\n" + "${insertMembers}" + " ObjectOrNullValue(obj)\n" + " }\n" + "}\n").substitute({ "selfName": self.makeClassName(d), "initParent": CGIndenter(CGGeneric(initParent), indentLevel=12).define(), "initMembers": CGIndenter(memberInits, indentLevel=12).define(), + "insertMembers": CGIndenter(memberInserts, indentLevel=8).define(), }) @staticmethod @@ -4590,6 +4615,7 @@ class CGDictionary(CGThing): return CGGeneric(conversion) + @staticmethod def makeIdName(name): return name + "_id" @@ -4750,6 +4776,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{Reflectable}', 'dom::bindings::utils::throwing_constructor', 'dom::bindings::utils::get_dictionary_property', + 'dom::bindings::utils::set_dictionary_property', 'dom::bindings::utils::{NativeProperties, NativePropertyHooks}', 'dom::bindings::utils::ConstantVal::{IntVal, UintVal}', 'dom::bindings::utils::NonNullJSNative', diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 612cba46f35..f53451352cc 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -29,7 +29,7 @@ use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype, JS_GetStringCharsAn use js::jsapi::JSHandleObject; use js::jsapi::JS_GetFunctionObject; use js::jsapi::{JS_HasPropertyById, JS_GetPrototype}; -use js::jsapi::{JS_GetProperty, JS_HasProperty}; +use js::jsapi::{JS_GetProperty, JS_HasProperty, JS_SetProperty}; use js::jsapi::{JS_DefineFunctions, JS_DefineProperty}; use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot}; use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass}; @@ -510,7 +510,6 @@ pub fn is_platform_object(obj: *mut JSObject) -> bool { pub fn get_dictionary_property(cx: *mut JSContext, object: *mut JSObject, property: &str) -> Result<Option<JSVal>, ()> { - use std::ffi::CString; fn has_property(cx: *mut JSContext, object: *mut JSObject, property: &CString, found: &mut JSBool) -> bool { unsafe { @@ -546,6 +545,27 @@ pub fn get_dictionary_property(cx: *mut JSContext, Ok(Some(value)) } +/// Set the property with name `property` from `object`. +/// Returns `Err(())` on JSAPI failure, or null object, +/// and Ok(()) otherwise +pub fn set_dictionary_property(cx: *mut JSContext, + object: *mut JSObject, + property: &str, + value: &mut JSVal) -> Result<(), ()> { + if object.is_null() { + return Err(()); + } + + let property = CString::new(property).unwrap(); + unsafe { + if JS_SetProperty(cx, object, property.as_ptr(), value) == 0 { + return Err(()); + } + } + + Ok(()) +} + /// Returns whether `proxy` has a property `id` on its prototype. pub fn has_property_on_prototype(cx: *mut JSContext, proxy: *mut JSObject, id: jsid) -> bool { |