diff --git a/src/fast_api.rs b/src/fast_api.rs index 7f899281..525caefb 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -79,6 +79,7 @@ pub enum SequenceType { pub enum CType { Void = 0, Bool, + Uint8, Int32, Uint32, Int64, diff --git a/tests/test_api.rs b/tests/test_api.rs index 1001e925..de7d0af4 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -7239,6 +7239,85 @@ fn test_fast_calls_arraybuffer() { assert_eq!("fast", unsafe { WHO }); } +#[test] +fn test_fast_calls_typedarray() { + static mut WHO: &str = "none"; + fn fast_fn( + _recv: v8::Local, + data: *const fast_api::FastApiTypedArray, + ) -> u32 { + unsafe { WHO = "fast" }; + let first = unsafe { &*data }.get(0); + let second = unsafe { &*data }.get(1); + let third = unsafe { &*data }.get(2); + assert_eq!(first, 4); + assert_eq!(second, 5); + assert_eq!(third, 6); + let sum = first + second + third; + sum.into() + } + + pub struct FastTest; + impl fast_api::FastFunction for FastTest { + fn args(&self) -> &'static [fast_api::Type] { + &[ + fast_api::Type::V8Value, + fast_api::Type::TypedArray(fast_api::CType::Uint8), + ] + } + + fn return_type(&self) -> fast_api::CType { + fast_api::CType::Uint32 + } + + fn function(&self) -> *const c_void { + fast_fn as _ + } + } + + fn slow_fn( + scope: &mut v8::HandleScope, + _: v8::FunctionCallbackArguments, + mut rv: v8::ReturnValue, + ) { + unsafe { WHO = "slow" }; + rv.set(v8::Boolean::new(scope, false).into()); + } + + let _setup_guard = setup(); + let isolate = &mut v8::Isolate::new(Default::default()); + let scope = &mut v8::HandleScope::new(isolate); + let context = v8::Context::new(scope); + let scope = &mut v8::ContextScope::new(scope, context); + + let global = context.global(scope); + + let template = + v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &FastTest, None); + + let name = v8::String::new(scope, "func").unwrap(); + let value = template.get_function(scope).unwrap(); + global.set(scope, name.into(), value.into()).unwrap(); + let source = r#" + function f(data) { return func(data); } + %PrepareFunctionForOptimization(f); + const arr = new Uint8Array([4, 5, 6]); + f(arr); +"#; + eval(scope, source).unwrap(); + assert_eq!("slow", unsafe { WHO }); + + let source = r#" + %OptimizeFunctionOnNextCall(f); + const result = f(arr); + if (result != 15) { + throw new Error("wrong result"); + } + "#; + eval(scope, source).unwrap(); + assert_eq!("fast", unsafe { WHO }); +} + #[test] fn test_fast_calls_reciever() { const V8_WRAPPER_TYPE_INDEX: i32 = 0; diff --git a/v8 b/v8 index d50c91cc..151c55f5 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit d50c91cc9e5baab72fd876b7c05acb002810e0d6 +Subproject commit 151c55f530a172751dcb719b3b31cee7fdde0029