mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
Compare commits
1 Commits
f9cfd05af8
...
typed-arra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c160aacecc |
@@ -435,6 +435,7 @@ class CGMethodCall(CGThing):
|
||||
# large enough that we can examine this argument.
|
||||
info = getJSToNativeConversionInfo(
|
||||
type, descriptor, failureCode="break;", isDefinitelyObject=True)
|
||||
assert not info.needsRooting
|
||||
template = info.template
|
||||
declType = info.declType
|
||||
|
||||
@@ -558,28 +559,44 @@ def union_native_type(t):
|
||||
return 'UnionTypes::%s' % name
|
||||
|
||||
|
||||
def typed_array_native_type(t):
|
||||
"""
|
||||
Returns the name of the native type for `t`.
|
||||
"""
|
||||
assert t.isSpiderMonkeyInterface()
|
||||
assert t.isArrayBuffer() or t.isArrayBufferView() or t.isTypedArray()
|
||||
name = t.unroll().name
|
||||
return 'typedarray::%s' % name
|
||||
|
||||
|
||||
class JSToNativeConversionInfo():
|
||||
"""
|
||||
An object representing information about a JS-to-native conversion.
|
||||
"""
|
||||
def __init__(self, template, default=None, declType=None):
|
||||
def __init__(self, template, default=None, declType=None,
|
||||
needsRooting=False):
|
||||
"""
|
||||
template: A string representing the conversion code. This will have
|
||||
template substitution performed on it as follows:
|
||||
|
||||
${val} is a handle to the JS::Value in question
|
||||
${root} is the name of a `Rooted` on the stack, if `needsRooting` is true.
|
||||
|
||||
default: A string or None representing rust code for default value(if any).
|
||||
|
||||
declType: A CGThing representing the native C++ type we're converting
|
||||
to. This is allowed to be None if the conversion code is
|
||||
supposed to be used as-is.
|
||||
|
||||
needsRooting: A boolean indicating whether the caller needs to provide
|
||||
a `Rooted` on the stack.
|
||||
"""
|
||||
assert isinstance(template, str)
|
||||
assert declType is None or isinstance(declType, CGThing)
|
||||
self.template = template
|
||||
self.default = default
|
||||
self.declType = declType
|
||||
self.needsRooting = needsRooting
|
||||
|
||||
|
||||
def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
@@ -660,9 +677,9 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
else:
|
||||
failOrPropagate = failureCode
|
||||
|
||||
def handleOptional(template, declType, default):
|
||||
def handleOptional(template, declType, default, needsRooting=False):
|
||||
assert (defaultValue is None) == (default is None)
|
||||
return JSToNativeConversionInfo(template, default, declType)
|
||||
return JSToNativeConversionInfo(template, default, declType, needsRooting=needsRooting)
|
||||
|
||||
# Unfortunately, .capitalize() on a string will lowercase things inside the
|
||||
# string, which we do not want.
|
||||
@@ -729,6 +746,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
innerInfo = getJSToNativeConversionInfo(innerContainerType(type),
|
||||
descriptorProvider,
|
||||
isMember=isMember)
|
||||
assert not innerInfo.needsRooting
|
||||
declType = wrapInNativeContainerType(type, innerInfo.declType)
|
||||
config = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
|
||||
|
||||
@@ -862,7 +880,34 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||
return handleOptional(templateBody, declType, handleDefaultNull("None"))
|
||||
|
||||
if type.isSpiderMonkeyInterface():
|
||||
raise TypeError("Can't handle SpiderMonkey interface arguments yet")
|
||||
assert not isEnforceRange
|
||||
assert not isClamp
|
||||
ty = typed_array_native_type(type)
|
||||
templateBody = fill(
|
||||
"""
|
||||
{
|
||||
let array = ${ty}::from(cx, &mut $${root}, $${val}.get().to_object());
|
||||
match array {
|
||||
Ok(array) => array,
|
||||
Err(()) => {
|
||||
let error = "Object was not a typed array";
|
||||
$*{failure}
|
||||
}
|
||||
}
|
||||
}
|
||||
""",
|
||||
ty=ty,
|
||||
failure=failOrPropagate)
|
||||
|
||||
declType = CGGeneric(ty)
|
||||
if type.nullable():
|
||||
templateBody = "Some(%s)" % templateBody
|
||||
declType = CGWrapper(declType, pre="Option<", post=">")
|
||||
|
||||
templateBody = wrapObjectTemplate(templateBody, "None", isDefinitelyObject, type,
|
||||
failureCode)
|
||||
return handleOptional(templateBody, declType, handleDefaultNull("None"),
|
||||
needsRooting=True)
|
||||
|
||||
if type.isDOMString():
|
||||
nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
|
||||
@@ -1246,10 +1291,19 @@ class CGArgumentConverter(CGThing):
|
||||
else:
|
||||
assert not default
|
||||
|
||||
self.converter = instantiateJSToNativeConversionTemplate(
|
||||
template, replacementVariables, declType, "arg%d" % index)
|
||||
self.converter = CGList([], "\n")
|
||||
|
||||
if info.needsRooting:
|
||||
name = "__root%d" % index
|
||||
root = "let mut {root} = Rooted::new_unrooted();".format(root=name)
|
||||
replacementVariables["root"] = name
|
||||
self.converter.append(CGGeneric(root))
|
||||
|
||||
self.converter.append(instantiateJSToNativeConversionTemplate(
|
||||
template, replacementVariables, declType, "arg%d" % index))
|
||||
else:
|
||||
assert argument.optional
|
||||
assert not info.needsRooting
|
||||
variadicConversion = {
|
||||
"val": string.Template("${args}.get(variadicArg)").substitute(replacer),
|
||||
}
|
||||
@@ -4054,6 +4108,7 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
|
||||
type, descriptorProvider, failureCode="return Ok(None);",
|
||||
exceptionCode='return Err(());',
|
||||
isDefinitelyObject=True)
|
||||
assert not info.needsRooting
|
||||
template = info.template
|
||||
|
||||
jsConversion = string.Template(template).substitute({
|
||||
@@ -4641,6 +4696,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
||||
info = getJSToNativeConversionInfo(
|
||||
argument.type, descriptor, treatNullAs=argument.treatNullAs,
|
||||
exceptionCode="return false;")
|
||||
assert not info.needsRooting
|
||||
template = info.template
|
||||
declType = info.declType
|
||||
|
||||
@@ -5477,6 +5533,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
|
||||
'js::jsapi::MutableHandleValue',
|
||||
'js::jsapi::ObjectOpResult',
|
||||
'js::jsapi::PropertyDescriptor',
|
||||
'js::jsapi::Rooted',
|
||||
'js::jsapi::RootedId',
|
||||
'js::jsapi::RootedObject',
|
||||
'js::jsapi::RootedString',
|
||||
@@ -5505,6 +5562,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
|
||||
'js::rust::define_methods',
|
||||
'js::rust::define_properties',
|
||||
'js::rust::get_object_class',
|
||||
'js::typedarray',
|
||||
'dom',
|
||||
'dom::bindings',
|
||||
'dom::bindings::codegen::InterfaceObjectMap',
|
||||
@@ -5842,6 +5900,7 @@ class CGDictionary(CGThing):
|
||||
defaultValue=member.defaultValue,
|
||||
exceptionCode="return Err(());"))
|
||||
for member in dictionary.members]
|
||||
assert not any(i.needsRooting for (_, i) in self.memberInfo)
|
||||
|
||||
def define(self):
|
||||
if not self.generatable:
|
||||
@@ -6461,6 +6520,7 @@ class CallbackMember(CGNativeMember):
|
||||
isCallbackReturnValue="Callback",
|
||||
# XXXbz we should try to do better here
|
||||
sourceDescription="return value")
|
||||
assert not info.needsRooting
|
||||
template = info.template
|
||||
declType = info.declType
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ use dom::url::URL;
|
||||
use js::jsapi::{HandleObject, HandleValue, JSContext, JSObject, JSAutoCompartment};
|
||||
use js::jsapi::{JS_NewPlainObject, JS_NewUint8ClampedArray};
|
||||
use js::jsval::{JSVal, NullValue};
|
||||
use js::typedarray;
|
||||
use script_traits::MsDuration;
|
||||
use servo_config::prefs::PREFS;
|
||||
use std::borrow::ToOwned;
|
||||
@@ -626,6 +627,23 @@ impl TestBindingMethods for TestBinding {
|
||||
unsafe fn PassVariadicAny(&self, _: *mut JSContext, _: Vec<HandleValue>) {}
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn PassVariadicObject(&self, _: *mut JSContext, _: Vec<*mut JSObject>) {}
|
||||
|
||||
fn PassArrayBuffer(&self, _: typedarray::ArrayBuffer) {}
|
||||
fn PassNullableArrayBuffer(&self, _: Option<typedarray::ArrayBuffer>) {}
|
||||
fn PassOptionalArrayBuffer(&self, _: Option<typedarray::ArrayBuffer>) {}
|
||||
fn PassOptionalNullableArrayBuffer(&self, _: Option<Option<typedarray::ArrayBuffer>>) {}
|
||||
fn PassOptionalNullableArrayBufferWithDefaultValue(&self, _: Option<typedarray::ArrayBuffer>) {}
|
||||
fn PassArrayBufferView(&self, _: typedarray::ArrayBufferView) {}
|
||||
fn PassInt8Array(&self, _: typedarray::Int8Array) {}
|
||||
fn PassInt16Array(&self, _: typedarray::Int16Array) {}
|
||||
fn PassInt32Array(&self, _: typedarray::Int32Array) {}
|
||||
fn PassUint8Array(&self, _: typedarray::Uint8Array) {}
|
||||
fn PassUint8ClampedArray(&self, _: typedarray::Uint8ClampedArray) {}
|
||||
fn PassUint16Array(&self, _: typedarray::Uint16Array) {}
|
||||
fn PassUint32Array(&self, _: typedarray::Uint32Array) {}
|
||||
fn PassFloat32Array(&self, _: typedarray::Float32Array) {}
|
||||
fn PassFloat64Array(&self, _: typedarray::Float64Array) {}
|
||||
|
||||
fn BooleanMozPreference(&self, pref_name: DOMString) -> bool {
|
||||
PREFS.get(pref_name.as_ref()).as_boolean().unwrap_or(false)
|
||||
}
|
||||
|
||||
@@ -425,6 +425,22 @@ interface TestBinding {
|
||||
void passVariadicAny(any... args);
|
||||
void passVariadicObject(object... args);
|
||||
|
||||
void passArrayBuffer(ArrayBuffer arg);
|
||||
void passNullableArrayBuffer(ArrayBuffer? arg);
|
||||
void passOptionalArrayBuffer(optional ArrayBuffer arg);
|
||||
void passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
|
||||
void passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg = null);
|
||||
void passArrayBufferView(ArrayBufferView arg);
|
||||
void passInt8Array(Int8Array arg);
|
||||
void passInt16Array(Int16Array arg);
|
||||
void passInt32Array(Int32Array arg);
|
||||
void passUint8Array(Uint8Array arg);
|
||||
void passUint8ClampedArray(Uint8ClampedArray arg);
|
||||
void passUint16Array(Uint16Array arg);
|
||||
void passUint32Array(Uint32Array arg);
|
||||
void passFloat32Array(Float32Array arg);
|
||||
void passFloat64Array(Float64Array arg);
|
||||
|
||||
void passSequenceSequence(sequence<sequence<long>> seq);
|
||||
sequence<sequence<long>> returnSequenceSequence();
|
||||
void passUnionSequenceSequence((long or sequence<sequence<long>>) seq);
|
||||
|
||||
Reference in New Issue
Block a user