diff options
author | Igor Matuszewski <Xanewok@gmail.com> | 2018-03-04 20:32:08 +0100 |
---|---|---|
committer | Igor Matuszewski <Xanewok@gmail.com> | 2018-03-14 18:43:26 +0100 |
commit | e025bbb07964eb64317d9a6d63d4a55ba79cd8ae (patch) | |
tree | d37ea7e941df3071d62497ce110223a8e108f0b0 /components/script | |
parent | a0f2d618ee7ccb3e8e821738d0cdfc9bb74aa003 (diff) | |
download | servo-e025bbb07964eb64317d9a6d63d4a55ba79cd8ae.tar.gz servo-e025bbb07964eb64317d9a6d63d4a55ba79cd8ae.zip |
WIP: Accept typed array arguments in codegen
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 58 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 8 | ||||
-rw-r--r-- | components/script/dom/testbinding.rs | 5 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 7 | ||||
-rw-r--r-- | components/script/dom/webidls/TestBinding.webidl | 4 |
5 files changed, 76 insertions, 6 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 55e72086f12..3e39bc231d4 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -870,8 +870,50 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, return handleOptional(templateBody, declType, handleDefaultNull("None")) - if type.isSpiderMonkeyInterface(): - raise TypeError("Can't handle SpiderMonkey interface arguments yet") + if type.isTypedArray() or type.isArrayBuffer() or type.isArrayBufferView() or type.isSharedArrayBuffer(): + if failureCode is None: + substitutions = { + "sourceDescription": sourceDescription, + "exceptionCode": exceptionCode, + } + unwrapFailureCode = string.Template( + 'throw_type_error(cx, "${sourceDescription} is not a typed array.");\n' + '${exceptionCode}').substitute(substitutions) + else: + unwrapFailureCode = failureCode + + typeName = type.name + if isMember == "Union": + typeName = "Heap" + typeName + + templateBody = fill( + """ + match typedarray::${ty}::from($${val}.get().to_object()) { + Ok(val) => val, + Err(()) => { + $*{failureCode} + } + } + """, + ty=typeName, + failureCode=unwrapFailureCode + "\n", + ) + + if isMember == "Union": + templateBody = "RootedTraceableBox::new(%s)" % templateBody + + declType = CGGeneric("typedarray::%s" % type.name) + 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")) + + elif type.isSpiderMonkeyInterface(): + raise TypeError("Can't handle SpiderMonkey interface arguments other than typed arrays yet") if type.isDOMString(): nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs) @@ -2287,6 +2329,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config): 'js::jsapi::JSObject', 'js::jsapi::MutableHandleValue', 'js::jsval::JSVal', + 'js::typedarray' ] # Now find all the things we'll need as arguments and return values because @@ -4138,6 +4181,9 @@ def getUnionTypeTemplateVars(type, descriptorProvider): elif type.isObject(): name = type.name typeName = "Heap<*mut JSObject>" + elif type.isTypedArray() or type.isArrayBuffer() or type.isArrayBufferView() or type.isSharedArrayBuffer(): + name = type.name + typeName = "typedarray::Heap" + name else: raise TypeError("Can't handle %s in unions yet" % type) @@ -5688,6 +5734,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', @@ -5719,6 +5766,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', @@ -6419,6 +6467,9 @@ def type_needs_tracing(t): if t.isUnion(): return any(type_needs_tracing(member) for member in t.flatMemberTypes) + if t.isTypedArray() or t.isArrayBuffer() or t.isArrayBufferView() or t.isSharedArrayBuffer(): + return True + return False if t.isDictionary(): @@ -6449,6 +6500,9 @@ def type_needs_auto_root(t): if t.isType(): if t.isSequence() and (t.inner.isAny() or t.inner.isObject()): return True + # SpiderMonkey interfaces + if t.isTypedArray() or t.isArrayBuffer() or t.isArrayBufferView() or t.isSharedArrayBuffer(): + return True return False diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index f0c704b0b0a..423b053cbbf 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -62,6 +62,8 @@ use js::glue::{CallObjectTracer, CallValueTracer}; use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind}; use js::jsval::JSVal; use js::rust::Runtime; +use js::typedarray::TypedArray; +use js::typedarray::TypedArrayElement; use metrics::{InteractiveMetrics, InteractiveWindow}; use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId}; use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; @@ -658,6 +660,12 @@ unsafe impl JSTraceable for StyleLocked<MediaList> { } } +unsafe impl<T> JSTraceable for TypedArray<T, Box<Heap<*mut JSObject>>> where T: TypedArrayElement { + unsafe fn trace(&self, trc: *mut JSTracer) { + self.underlying_object().trace(trc); + } +} + unsafe impl<S> JSTraceable for DocumentStylesheetSet<S> where S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static, diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 11bcbfc5bd7..2f6d578b0c9 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -38,6 +38,7 @@ use js::jsapi::{HandleObject, HandleValue, Heap, JSContext, JSObject}; use js::jsapi::{JS_NewPlainObject, JS_NewUint8ClampedArray}; use js::jsval::{JSVal, NullValue}; use js::rust::CustomAutoRooterGuard; +use js::typedarray; use script_traits::MsDuration; use servo_config::prefs::PREFS; use std::borrow::ToOwned; @@ -436,6 +437,9 @@ impl TestBindingMethods for TestBinding { fn PassByteString(&self, _: ByteString) {} fn PassEnum(&self, _: TestEnum) {} fn PassInterface(&self, _: &Blob) {} + fn PassTypedArray(&self, _: CustomAutoRooterGuard<typedarray::Int8Array>) {} + fn PassTypedArray2(&self, _: CustomAutoRooterGuard<typedarray::ArrayBuffer>) {} + fn PassTypedArray3(&self, _: CustomAutoRooterGuard<typedarray::ArrayBufferView>) {} fn PassUnion(&self, _: HTMLElementOrLong) {} fn PassUnion2(&self, _: EventOrString) {} fn PassUnion3(&self, _: BlobOrString) {} @@ -447,6 +451,7 @@ impl TestBindingMethods for TestBinding { fn PassUnion9(&self, _: UnionTypes::TestDictionaryOrLong) {} #[allow(unsafe_code)] unsafe fn PassUnion10(&self, _: *mut JSContext, _: UnionTypes::StringOrObject) {} + fn PassUnion11(&self, _: UnionTypes::ArrayBufferOrArrayBufferView) {} fn PassUnionWithTypedef(&self, _: DocumentOrTestTypedef) {} fn PassUnionWithTypedef2(&self, _: LongSequenceOrTestTypedef) {} #[allow(unsafe_code)] diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 0aabf2e319a..0145d84ffd8 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -46,7 +46,7 @@ use euclid::Size2D; use fnv::FnvHashMap; use half::f16; use js::conversions::ConversionBehavior; -use js::jsapi::{JSContext, JSObject, Type, Rooted}; +use js::jsapi::{JSContext, JSObject, Type}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use js::typedarray::{TypedArray, TypedArrayElement, Float32, Int32}; use net_traits::image::base::PixelFormat; @@ -1182,9 +1182,8 @@ unsafe fn typed_array_or_sequence_to_vec<T>(cx: *mut JSContext, <T::Element as FromJSValConvertible>::Config: Clone, { // TODO(servo/rust-mozjs#330): replace this with a macro that supports generic types. - let mut typed_array_root = Rooted::new_unrooted(); - let typed_array: Option<TypedArray<T>> = - TypedArray::from(cx, &mut typed_array_root, sequence_or_abv).ok(); + let typed_array: Option<TypedArray<T, *mut JSObject>> = + TypedArray::from(sequence_or_abv).ok(); if let Some(mut typed_array) = typed_array { return Ok(typed_array.as_slice().to_vec()); } diff --git a/components/script/dom/webidls/TestBinding.webidl b/components/script/dom/webidls/TestBinding.webidl index 22c22f43dae..7021d7d7635 100644 --- a/components/script/dom/webidls/TestBinding.webidl +++ b/components/script/dom/webidls/TestBinding.webidl @@ -248,6 +248,9 @@ interface TestBinding { void passByteString(ByteString arg); void passEnum(TestEnum arg); void passInterface(Blob arg); + void passTypedArray(Int8Array arg); + void passTypedArray2(ArrayBuffer arg); + void passTypedArray3(ArrayBufferView arg); void passUnion((HTMLElement or long) arg); void passUnion2((Event or DOMString) data); void passUnion3((Blob or DOMString) data); @@ -258,6 +261,7 @@ interface TestBinding { void passUnion8((sequence<ByteString> or long) arg); void passUnion9((TestDictionary or long) arg); void passUnion10((DOMString or object) arg); + void passUnion11((ArrayBuffer or ArrayBufferView) arg); void passUnionWithTypedef((Document or TestTypedef) arg); void passUnionWithTypedef2((sequence<long> or TestTypedef) arg); void passAny(any arg); |