forked from denoland/deno
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ops): fast calls for Wasm (denoland#16776)
This PR introduces Wasm ops. These calls are optimized for entry from Wasm land. The `#[op(wasm)]` attribute is opt-in. Last parameter `Option<&mut [u8]>` is the memory slice of the Wasm module *when entered from a Fast API call*. Otherwise, the user is expected to implement logic to obtain the memory if `None` ```rust #[op(wasm)] pub fn op_args_get( offset: i32, buffer_offset: i32, memory: Option<&mut [u8]>, ) { // ... } ```
- Loading branch information
1 parent
9ffc6ac
commit ca66978
Showing
11 changed files
with
291 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
|
||
// asc wasm.ts --exportStart --initialMemory 6400 -O -o wasm.wasm | ||
// deno-fmt-ignore | ||
const bytes = new Uint8Array([ | ||
0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 2, | ||
15, 1, 3, 111, 112, 115, 7, 111, 112, 95, 119, 97, 115, 109, 0, | ||
0, 3, 3, 2, 0, 0, 5, 4, 1, 0, 128, 50, 7, 36, 4, | ||
7, 111, 112, 95, 119, 97, 115, 109, 0, 0, 4, 99, 97, 108, 108, | ||
0, 1, 6, 109, 101, 109, 111, 114, 121, 2, 0, 6, 95, 115, 116, | ||
97, 114, 116, 0, 2, 10, 10, 2, 4, 0, 16, 0, 11, 3, 0, | ||
1, 11 | ||
]); | ||
|
||
const { ops } = Deno.core; | ||
|
||
const module = new WebAssembly.Module(bytes); | ||
const instance = new WebAssembly.Instance(module, { ops }); | ||
ops.op_set_wasm_mem(instance.exports.memory); | ||
|
||
instance.exports.call(); | ||
|
||
const memory = instance.exports.memory; | ||
const view = new Uint8Array(memory.buffer); | ||
|
||
if (view[0] !== 69) { | ||
throw new Error("Expected first byte to be 69"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
|
||
use deno_core::op; | ||
use deno_core::Extension; | ||
use deno_core::JsRuntime; | ||
use deno_core::RuntimeOptions; | ||
use std::mem::transmute; | ||
use std::ptr::NonNull; | ||
|
||
// This is a hack to make the `#[op]` macro work with | ||
// deno_core examples. | ||
// You can remove this: | ||
|
||
use deno_core::*; | ||
|
||
struct WasmMemory(NonNull<v8::WasmMemoryObject>); | ||
|
||
fn wasm_memory_unchecked(state: &mut OpState) -> &mut [u8] { | ||
let WasmMemory(global) = state.borrow::<WasmMemory>(); | ||
// SAFETY: `v8::Local` is always non-null pointer; the `HandleScope` is | ||
// already on the stack, but we don't have access to it. | ||
let memory_object = unsafe { | ||
transmute::<NonNull<v8::WasmMemoryObject>, v8::Local<v8::WasmMemoryObject>>( | ||
*global, | ||
) | ||
}; | ||
let backing_store = memory_object.buffer().get_backing_store(); | ||
let ptr = backing_store.data().unwrap().as_ptr() as *mut u8; | ||
let len = backing_store.byte_length(); | ||
// SAFETY: `ptr` is a valid pointer to `len` bytes. | ||
unsafe { std::slice::from_raw_parts_mut(ptr, len) } | ||
} | ||
|
||
#[op(wasm)] | ||
fn op_wasm(state: &mut OpState, memory: Option<&mut [u8]>) { | ||
let memory = memory.unwrap_or_else(|| wasm_memory_unchecked(state)); | ||
memory[0] = 69; | ||
} | ||
|
||
#[op(v8)] | ||
fn op_set_wasm_mem( | ||
scope: &mut v8::HandleScope, | ||
state: &mut OpState, | ||
memory: serde_v8::Value, | ||
) { | ||
let memory = | ||
v8::Local::<v8::WasmMemoryObject>::try_from(memory.v8_value).unwrap(); | ||
let global = v8::Global::new(scope, memory); | ||
state.put(WasmMemory(global.into_raw())); | ||
} | ||
|
||
fn main() { | ||
// Build a deno_core::Extension providing custom ops | ||
let ext = Extension::builder() | ||
.ops(vec![op_wasm::decl(), op_set_wasm_mem::decl()]) | ||
.build(); | ||
|
||
// Initialize a runtime instance | ||
let mut runtime = JsRuntime::new(RuntimeOptions { | ||
extensions: vec![ext], | ||
..Default::default() | ||
}); | ||
|
||
runtime | ||
.execute_script("<usage>", include_str!("wasm.js")) | ||
.unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
|
||
export declare function op_wasm(): void; | ||
|
||
export function call(): void { | ||
op_wasm(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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] | ||
transforms: {0: Transform { kind: WasmMemory, index: 0 }} | ||
is_async: false | ||
fast_compatible: true |
Oops, something went wrong.