diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 98 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 91 |
2 files changed, 97 insertions, 92 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 2efe1af1359..9f333ca6e75 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -443,7 +443,6 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, invalidEnumValueFatal=True, defaultValue=None, treatNullAs="Default", - treatUndefinedAs="Default", isEnforceRange=False, isClamp=False, exceptionCode=None, @@ -1058,37 +1057,31 @@ for (uint32_t i = 0; i < length; ++i) { assert not isEnforceRange and not isClamp treatAs = { - "Default": "eStringify", - "EmptyString": "eEmpty", - "Null": "eNull" + "Default": "Default", + "EmptyString": "Empty", } - if type.nullable(): - # For nullable strings null becomes a null string. - treatNullAs = "Null" - # For nullable strings undefined becomes a null string unless - # specified otherwise. - if treatUndefinedAs == "Default": - treatUndefinedAs = "Null" + if treatNullAs not in treatAs: + raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs) nullBehavior = treatAs[treatNullAs] - if treatUndefinedAs == "Missing": - raise TypeError("We don't support [TreatUndefinedAs=Missing]") - undefinedBehavior = treatAs[treatUndefinedAs] def getConversionCode(varName, isOptional=False): - #XXXjdm support nullBehavior and undefinedBehavior - #conversionCode = ( - # "if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, %s)) {\n" - # " return false;\n" - # "}" % (nullBehavior, undefinedBehavior, varName)) - strval = "Some(strval.unwrap())" + strval = "strval" + if not type.nullable(): + # XXX #1207 Actually pass non-nullable strings to callees. + strval = "Some(%s)" % strval if isOptional: strval = "Some(%s)" % strval + if type.nullable(): + call = "jsval_to_domstring(cx, ${val})" + else: + call = "jsval_to_str(cx, ${val}, %s)" % nullBehavior conversionCode = ( - "let strval = jsval_to_str(cx, ${val});\n" + "let strval = %s;\n" "if strval.is_err() {\n" " return 0;\n" "}\n" - "%s = %s;" % (varName, strval)) + "let strval = strval.unwrap();\n" + "%s = %s;" % (call, varName, strval)) if defaultValue is None: return conversionCode @@ -1456,7 +1449,6 @@ class CGArgumentConverter(CGThing): invalidEnumValueFatal=self.invalidEnumValueFatal, defaultValue=self.argument.defaultValue, treatNullAs=self.argument.treatNullAs, - treatUndefinedAs=self.argument.treatUndefinedAs, isEnforceRange=self.argument.enforceRange, isClamp=self.argument.clamp), self.replacementVariables, @@ -3189,7 +3181,6 @@ class FakeArgument(): self.variadic = False self.defaultValue = None self.treatNullAs = interfaceMember.treatNullAs - self.treatUndefinedAs = interfaceMember.treatUndefinedAs self.enforceRange = False self.clamp = False @@ -4089,8 +4080,7 @@ class CGProxySpecialOperation(CGPerSignatureCall): # arguments[0] is the index or name of the item that we're setting. argument = arguments[1] template = getJSToNativeConversionTemplate(argument.type, descriptor, - treatNullAs=argument.treatNullAs, - treatUndefinedAs=argument.treatUndefinedAs) + treatNullAs=argument.treatNullAs) templateValues = { "declName": argument.identifier.name, "holderName": argument.identifier.name + "_holder", @@ -4231,16 +4221,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): # properties that shadow prototype properties. namedGet = ("\n" + "if set == 0 && RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" + - " let nameVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" + - " //FakeDependentString name;\n" - " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" + - " // eStringify, eStringify, name)) {\n" + - " let strval = jsval_to_str(cx, nameVal);\n" + - " if strval.is_err() {\n" + - " return 0;\n" + - " }\n" + - " let name = Some(strval.unwrap());\n" + - "\n" + + " let name = Some(jsid_to_str(cx, id));\n" + " let this: *%s = UnwrapProxy(proxy);\n" + CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" + "}\n") % (self.descriptor.concreteType) @@ -4298,33 +4279,14 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): if namedSetter: if not self.descriptor.operations['NamedCreator'] is namedSetter: raise TypeError("Can't handle creator that's different from the setter") - #XXXjdm need to properly support eStringify set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" + - " let nameVal: JSVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" + - " let strval = jsval_to_str(cx, nameVal);\n" + - " //FakeDependentString name;\n" + - " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" + - " // eStringify, eStringify, name)) {\n" + - " if strval.is_err() {\n" + - " return 0;\n" + - " }\n" + - " let name = Some(strval.unwrap());\n" + - "\n" + + " let name = Some(jsid_to_str(cx, id));\n" + " let this: *%s = UnwrapProxy(proxy);\n" + CGIndenter(CGProxyNamedSetter(self.descriptor)).define() + "\n" + "}\n") % (self.descriptor.concreteType) elif self.descriptor.operations['NamedGetter']: set += ("if RUST_JSID_IS_STRING(id) {\n" + - " let nameVal: JSVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" + - " let strval = jsval_to_str(cx, nameVal);\n" + - " //FakeDependentString name;\n" - " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" + - " // eStringify, eStringify, name)) {\n" + - " let strval = jsval_to_str(cx, nameVal);\n" + - " if strval.is_err() {\n" + - " return 0;\n" + - " }\n" + - " let name = Some(strval.unwrap());\n" + + " let name = Some(jsid_to_str(cx, id));\n" + " let this: %%s = UnwrapProxy(proxy);\n" + CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + " if (found) {\n" @@ -4360,18 +4322,8 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): namedGetter = self.descriptor.operations['NamedGetter'] if namedGetter: - #XXXjdm support eStringify named = ("if RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" + - " let nameVal: JSVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" + - " let strval = jsval_to_str(cx, nameVal);\n" + - " //FakeDependentString name;\n" - " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" + - " // eStringify, eStringify, name)) {\n" + - " if strval.is_err() {\n" + - " return 0;\n" + - " }\n" + - " let name = Some(strval.unwrap());\n" + - "\n" + + " let name = Some(jsid_to_str(cx, id));\n" + " let this: *%s = UnwrapProxy(proxy);\n" + CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" + " *bp = found as JSBool;\n" @@ -4439,13 +4391,7 @@ if expando.is_not_null() { namedGetter = self.descriptor.operations['NamedGetter'] if namedGetter and False: #XXXjdm unfinished getNamed = ("if (JSID_IS_STRING(id)) {\n" + - " JS::Value nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" + - " FakeDependentString name;\n" - " if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" + - " eStringify, eStringify, name)) {\n" + - " return false;\n" + - " }\n" + - "\n" + + " let name = Some(jsid_to_str(cx, id));\n" + " let this = UnwrapProxy(proxy);\n" + CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "}\n") % (self.descriptor.concreteType) @@ -5736,7 +5682,7 @@ class CGCallbackInterface(CGCallback): class FakeMember(): def __init__(self): - self.treatUndefinedAs = self.treatNullAs = "Default" + self.treatNullAs = "Default" def isStatic(self): return False def isAttr(self): diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index e75e9d5198f..716f16459d5 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -29,6 +29,7 @@ use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot}; use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative, JSTracer}; use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor}; use js::jsapi::{JSPropertyOp, JSStrictPropertyOp, JS_NewGlobalObject, JS_InitStandardClasses}; +use js::jsapi::{JSString}; 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}; @@ -39,6 +40,32 @@ 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}; + + #[fixed_stack_segment] + pub fn is_null(v: JSVal) -> bool { + unsafe { RUST_JSVAL_IS_NULL(v) == 1 } + } + + #[fixed_stack_segment] + pub fn is_undefined(v: JSVal) -> bool { + unsafe { RUST_JSVAL_IS_VOID(v) == 1 } + } + + #[fixed_stack_segment] + pub fn is_string(v: JSVal) -> bool { + unsafe { RUST_JSVAL_IS_STRING(v) == 1 } + } + + #[fixed_stack_segment] + pub unsafe fn to_string(v: JSVal) -> *JSString { + RUST_JSVAL_TO_STRING(v) + } +} + pub struct GlobalStaticData { proxy_handlers: HashMap<uint, *libc::c_void>, attribute_ids: HashMap<uint, ~[jsid]>, @@ -69,8 +96,6 @@ extern fn InterfaceObjectToString(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) let v = GetFunctionNativeReserved(callee, TOSTRING_CLASS_RESERVED_SLOT); let clasp: *JSClass = cast::transmute(RUST_JSVAL_TO_PRIVATE(*v)); - let v = GetFunctionNativeReserved(callee, TOSTRING_NAME_RESERVED_SLOT); - if GetObjectJSClass(obj) != clasp { /*let jsname: *JSString = RUST_JSVAL_TO_STRING(*v); let length = 0; @@ -82,7 +107,9 @@ extern fn InterfaceObjectToString(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) return 0; } - let name = jsval_to_str(cx, *v).unwrap(); + 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 = Some(~"function " + name + "() {\n [native code]\n}"); *vp = domstring_to_jsval(cx, &retval); return 1; @@ -191,24 +218,56 @@ pub unsafe fn squirrel_away<T>(x: @mut T) -> *Box<T> { y } -//XXX very incomplete #[fixed_stack_segment] -pub fn jsval_to_str(cx: *JSContext, v: JSVal) -> Result<~str, ()> { +pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> ~str { + unsafe { + let length = 0; + let chars = JS_GetStringCharsAndLength(cx, s, &length); + do vec::raw::buf_as_slice(chars, length as uint) |char_vec| { + str::from_utf16(char_vec) + } + } +} + +#[fixed_stack_segment] +pub fn jsid_to_str(cx: *JSContext, id: jsid) -> ~str { unsafe { - let jsstr; - if RUST_JSVAL_IS_STRING(v) == 1 { - jsstr = RUST_JSVAL_TO_STRING(v) + assert!(RUST_JSID_IS_STRING(id) != 0); + jsstring_to_str(cx, RUST_JSID_TO_STRING(id)) + } +} + +#[deriving(Eq)] +pub enum StringificationBehavior { + Default, + Empty, +} + +#[fixed_stack_segment] +pub fn jsval_to_str(cx: *JSContext, v: JSVal, + nullBehavior: StringificationBehavior) -> Result<~str, ()> { + if jsval::is_null(v) && nullBehavior == Empty { + Ok(~"") + } else { + let jsstr = unsafe { JS_ValueToString(cx, v) }; + if jsstr.is_null() { + Err(()) } else { - jsstr = JS_ValueToString(cx, v); - if jsstr.is_null() { - return Err(()); - } + Ok(jsstring_to_str(cx, jsstr)) } + } +} - let length = 0; - let chars = JS_GetStringCharsAndLength(cx, jsstr, &length); - do vec::raw::buf_as_slice(chars, length as uint) |char_vec| { - Ok(str::from_utf16(char_vec)) +#[fixed_stack_segment] +pub fn jsval_to_domstring(cx: *JSContext, v: JSVal) -> Result<DOMString, ()> { + if jsval::is_null(v) || jsval::is_undefined(v) { + Ok(None) + } else { + let jsstr = unsafe { JS_ValueToString(cx, v) }; + if jsstr.is_null() { + Err(()) + } else { + Ok(Some(jsstring_to_str(cx, jsstr))) } } } |