summaryrefslogtreecommitdiff
path: root/ops
diff options
context:
space:
mode:
Diffstat (limited to 'ops')
-rw-r--r--ops/fast_call.rs5
-rw-r--r--ops/lib.rs37
-rw-r--r--ops/optimizer.rs32
-rw-r--r--ops/optimizer_tests/f64_slice.expected11
-rw-r--r--ops/optimizer_tests/f64_slice.out112
-rw-r--r--ops/optimizer_tests/f64_slice.rs3
6 files changed, 199 insertions, 1 deletions
diff --git a/ops/fast_call.rs b/ops/fast_call.rs
index 9093190b2..fe6455f37 100644
--- a/ops/fast_call.rs
+++ b/ops/fast_call.rs
@@ -426,7 +426,9 @@ fn q_fast_ty(v: &FastValue) -> Quote {
FastValue::F64 => q!({ f64 }),
FastValue::Bool => q!({ bool }),
FastValue::V8Value => q!({ v8::Local<v8::Value> }),
- FastValue::Uint8Array | FastValue::Uint32Array => unreachable!(),
+ FastValue::Uint8Array
+ | FastValue::Uint32Array
+ | FastValue::Float64Array => unreachable!(),
}
}
@@ -444,6 +446,7 @@ fn q_fast_ty_variant(v: &FastValue) -> Quote {
FastValue::V8Value => q!({ V8Value }),
FastValue::Uint8Array => q!({ TypedArray(CType::Uint8) }),
FastValue::Uint32Array => q!({ TypedArray(CType::Uint32) }),
+ FastValue::Float64Array => q!({ TypedArray(CType::Float64) }),
}
}
diff --git a/ops/lib.rs b/ops/lib.rs
index 35796d41a..d8f28dd37 100644
--- a/ops/lib.rs
+++ b/ops/lib.rs
@@ -452,6 +452,13 @@ fn codegen_arg(
let #ident = #blck;
};
}
+ Some(SliceType::F64Mut) => {
+ assert!(!asyncness, "Memory slices are not allowed in async ops");
+ let blck = codegen_f64_mut_slice(core, idx);
+ return quote! {
+ let #ident = #blck;
+ };
+ }
Some(_) => {
assert!(!asyncness, "Memory slices are not allowed in async ops");
let blck = codegen_u8_slice(core, idx);
@@ -576,6 +583,28 @@ fn codegen_u32_mut_slice(core: &TokenStream2, idx: usize) -> TokenStream2 {
}
}
+fn codegen_f64_mut_slice(core: &TokenStream2, idx: usize) -> TokenStream2 {
+ quote! {
+ if let Ok(view) = #core::v8::Local::<#core::v8::Float64Array>::try_from(args.get(#idx as i32)) {
+ let (offset, len) = (view.byte_offset(), view.byte_length());
+ let buffer = match view.buffer(scope) {
+ Some(v) => v,
+ None => {
+ return #core::_ops::throw_type_error(scope, format!("Expected Float64Array at position {}", #idx));
+ }
+ };
+ if let Some(data) = buffer.data() {
+ let store = data.cast::<u8>().as_ptr();
+ unsafe { ::std::slice::from_raw_parts_mut(store.add(offset) as *mut f64, len / 8) }
+ } else {
+ &mut []
+ }
+ } else {
+ return #core::_ops::throw_type_error(scope, format!("Expected Float64Array at position {}", #idx));
+ }
+ }
+}
+
fn codegen_sync_ret(
core: &TokenStream2,
output: &syn::ReturnType,
@@ -655,6 +684,7 @@ enum SliceType {
U8,
U8Mut,
U32Mut,
+ F64Mut,
}
fn is_ref_slice(ty: impl ToTokens) -> Option<SliceType> {
@@ -667,6 +697,9 @@ fn is_ref_slice(ty: impl ToTokens) -> Option<SliceType> {
if is_u32_slice_mut(&ty) {
return Some(SliceType::U32Mut);
}
+ if is_f64_slice_mut(&ty) {
+ return Some(SliceType::F64Mut);
+ }
None
}
@@ -682,6 +715,10 @@ fn is_u32_slice_mut(ty: impl ToTokens) -> bool {
tokens(ty) == "& mut [u32]"
}
+fn is_f64_slice_mut(ty: impl ToTokens) -> bool {
+ tokens(ty) == "& mut [f64]"
+}
+
fn is_ptr_u8(ty: impl ToTokens) -> bool {
tokens(ty) == "* const u8"
}
diff --git a/ops/optimizer.rs b/ops/optimizer.rs
index 7c19a7cfd..ae3175511 100644
--- a/ops/optimizer.rs
+++ b/ops/optimizer.rs
@@ -43,6 +43,7 @@ enum TransformKind {
V8Value,
SliceU32(bool),
SliceU8(bool),
+ SliceF64(bool),
PtrU8,
WasmMemory,
}
@@ -69,6 +70,13 @@ impl Transform {
}
}
+ fn slice_f64(index: usize, is_mut: bool) -> Self {
+ Transform {
+ kind: TransformKind::SliceF64(is_mut),
+ index,
+ }
+ }
+
fn wasm_memory(index: usize) -> Self {
Transform {
kind: TransformKind::WasmMemory,
@@ -150,6 +158,20 @@ impl Transform {
unsafe { (&*var).get_storage_if_aligned().unwrap_unchecked() };
})
}
+ TransformKind::SliceF64(_) => {
+ *ty =
+ parse_quote! { *const #core::v8::fast_api::FastApiTypedArray<f64> };
+
+ q!(Vars { var: &ident }, {
+ let var = match unsafe { &*var }.get_storage_if_aligned() {
+ Some(v) => v,
+ None => {
+ unsafe { &mut *fast_api_callback_options }.fallback = true;
+ return Default::default();
+ }
+ };
+ })
+ }
TransformKind::WasmMemory => {
// Note: `ty` is correctly set to __opts by the fast call tier.
// U8 slice is always byte-aligned.
@@ -214,6 +236,7 @@ pub(crate) enum FastValue {
V8Value,
Uint8Array,
Uint32Array,
+ Float64Array,
}
impl Default for FastValue {
@@ -620,6 +643,15 @@ impl Optimizer {
.insert(index, Transform::slice_u32(index, is_mut_ref))
.is_none());
}
+ // Is `T` a f64?
+ PathSegment { ident, .. } if ident == "f64" => {
+ self.needs_fast_callback_option = true;
+ self.fast_parameters.push(FastValue::Float64Array);
+ assert!(self
+ .transforms
+ .insert(index, Transform::slice_f64(index, is_mut_ref))
+ .is_none());
+ }
_ => return Err(BailoutReason::FastUnsupportedParamType),
}
}
diff --git a/ops/optimizer_tests/f64_slice.expected b/ops/optimizer_tests/f64_slice.expected
new file mode 100644
index 000000000..32182b004
--- /dev/null
+++ b/ops/optimizer_tests/f64_slice.expected
@@ -0,0 +1,11 @@
+=== Optimizer Dump ===
+returns_result: false
+has_ref_opstate: false
+has_rc_opstate: false
+has_fast_callback_option: false
+needs_fast_callback_option: true
+fast_result: Some(Void)
+fast_parameters: [V8Value, Float64Array]
+transforms: {0: Transform { kind: SliceF64(true), index: 0 }}
+is_async: false
+fast_compatible: true
diff --git a/ops/optimizer_tests/f64_slice.out b/ops/optimizer_tests/f64_slice.out
new file mode 100644
index 000000000..88ccd232a
--- /dev/null
+++ b/ops/optimizer_tests/f64_slice.out
@@ -0,0 +1,112 @@
+#[allow(non_camel_case_types)]
+///Auto-generated by `deno_ops`, i.e: `#[op]`
+///
+///Use `op_f64_buf::decl()` to get an op-declaration
+///you can include in a `deno_core::Extension`.
+pub struct op_f64_buf;
+#[doc(hidden)]
+impl op_f64_buf {
+ pub fn name() -> &'static str {
+ stringify!(op_f64_buf)
+ }
+ pub fn v8_fn_ptr<'scope>() -> deno_core::v8::FunctionCallback {
+ use deno_core::v8::MapFnTo;
+ Self::v8_func.map_fn_to()
+ }
+ pub fn decl<'scope>() -> deno_core::OpDecl {
+ deno_core::OpDecl {
+ name: Self::name(),
+ v8_fn_ptr: Self::v8_fn_ptr(),
+ enabled: true,
+ fast_fn: Some(
+ Box::new(op_f64_buf_fast {
+ _phantom: ::std::marker::PhantomData,
+ }),
+ ),
+ is_async: false,
+ is_unstable: false,
+ is_v8: false,
+ argc: 1usize,
+ }
+ }
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ fn call(buffer: &mut [f64]) {}
+ pub fn v8_func<'scope>(
+ scope: &mut deno_core::v8::HandleScope<'scope>,
+ args: deno_core::v8::FunctionCallbackArguments,
+ mut rv: deno_core::v8::ReturnValue,
+ ) {
+ let ctx = unsafe {
+ &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+ as *const deno_core::_ops::OpCtx)
+ };
+ let arg_0 = if let Ok(view)
+ = deno_core::v8::Local::<
+ deno_core::v8::Float64Array,
+ >::try_from(args.get(0usize as i32)) {
+ let (offset, len) = (view.byte_offset(), view.byte_length());
+ let buffer = match view.buffer(scope) {
+ Some(v) => v,
+ None => {
+ return deno_core::_ops::throw_type_error(
+ scope,
+ format!("Expected Float64Array at position {}", 0usize),
+ );
+ }
+ };
+ if let Some(data) = buffer.data() {
+ let store = data.cast::<u8>().as_ptr();
+ unsafe {
+ ::std::slice::from_raw_parts_mut(
+ store.add(offset) as *mut f64,
+ len / 8,
+ )
+ }
+ } else {
+ &mut []
+ }
+ } else {
+ return deno_core::_ops::throw_type_error(
+ scope,
+ format!("Expected Float64Array at position {}", 0usize),
+ );
+ };
+ let result = Self::call(arg_0);
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
+ }
+}
+struct op_f64_buf_fast {
+ _phantom: ::std::marker::PhantomData<()>,
+}
+impl<'scope> deno_core::v8::fast_api::FastFunction for op_f64_buf_fast {
+ fn function(&self) -> *const ::std::ffi::c_void {
+ op_f64_buf_fast_fn as *const ::std::ffi::c_void
+ }
+ fn args(&self) -> &'static [deno_core::v8::fast_api::Type] {
+ use deno_core::v8::fast_api::Type::*;
+ use deno_core::v8::fast_api::CType;
+ &[V8Value, TypedArray(CType::Float64), CallbackOptions]
+ }
+ fn return_type(&self) -> deno_core::v8::fast_api::CType {
+ deno_core::v8::fast_api::CType::Void
+ }
+}
+fn op_f64_buf_fast_fn<'scope>(
+ _: deno_core::v8::Local<deno_core::v8::Object>,
+ buffer: *const deno_core::v8::fast_api::FastApiTypedArray<f64>,
+ fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions,
+) -> () {
+ use deno_core::v8;
+ use deno_core::_ops;
+ let buffer = match unsafe { &*buffer }.get_storage_if_aligned() {
+ Some(v) => v,
+ None => {
+ unsafe { &mut *fast_api_callback_options }.fallback = true;
+ return Default::default();
+ }
+ };
+ let result = op_f64_buf::call(buffer);
+ result
+}
diff --git a/ops/optimizer_tests/f64_slice.rs b/ops/optimizer_tests/f64_slice.rs
new file mode 100644
index 000000000..fa2778531
--- /dev/null
+++ b/ops/optimizer_tests/f64_slice.rs
@@ -0,0 +1,3 @@
+fn op_f64_buf(buffer: &mut [f64]) {
+ // @test-attr:fast
+}