-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Export the rust version to WASM + Use it in a Go library
- Loading branch information
Showing
10 changed files
with
221 additions
and
0 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
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,4 @@ | ||
.PHONY: wasm | ||
wasm: | ||
cargo build --target wasm32-unknown-unknown --features wasm --release | ||
cp target/wasm32-unknown-unknown/release/evmole.wasm go/evmole.wasm |
Binary file not shown.
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,78 @@ | ||
package evmole | ||
|
||
import ( | ||
"context" | ||
_ "embed" | ||
"encoding/binary" | ||
"fmt" | ||
|
||
"github.com/tetratelabs/wazero" | ||
) | ||
|
||
//go:embed evmole.wasm | ||
var evmoleWASM []byte | ||
|
||
// FunctionSelectors tries to extract from the given bytecode the function selectors. | ||
func FunctionSelectors(ctx context.Context, code []byte) ([][4]byte, error) { | ||
// Create a new WebAssembly runtime | ||
runtime := wazero.NewRuntime(ctx) | ||
defer func() { _ = runtime.Close(ctx) }() | ||
|
||
instance, err := runtime.Instantiate(ctx, evmoleWASM) | ||
if err != nil { | ||
panic(fmt.Errorf("failed to instantiate WASM module: %w", err)) | ||
} | ||
defer func() { _ = instance.Close(ctx) }() | ||
|
||
gasLimit := 0 | ||
|
||
memory := instance.Memory() | ||
functionSelectorsFunc := instance.ExportedFunction("function_selectors") | ||
if functionSelectorsFunc == nil { | ||
panic("could not find exported function: function_selectors") | ||
} | ||
|
||
codeOffset := uint32(0) | ||
resultLenOffset := uint32(len(code)) | ||
resultOffset := resultLenOffset + 4 | ||
resultCapacity := uint32(512 * 4) | ||
|
||
// Write input to memory | ||
ok := memory.Write(codeOffset, code) | ||
if !ok { | ||
return nil, fmt.Errorf("failed to write input to memory") | ||
} | ||
|
||
// Call the WASM function | ||
results, err := functionSelectorsFunc.Call(ctx, | ||
uint64(codeOffset), uint64(len(code)), uint64(gasLimit), | ||
uint64(resultLenOffset), uint64(resultOffset), uint64(resultCapacity)) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to call function_selectors: %w", err) | ||
} | ||
|
||
if status := uint32(results[0]); status != 0 { | ||
return nil, fmt.Errorf("error: status=%d", status) | ||
} | ||
|
||
// Read the actual result length | ||
rawResultLen, ok := memory.Read(resultLenOffset, 4) | ||
if !ok { | ||
return nil, fmt.Errorf("failed to read result length") | ||
} | ||
resultLen := binary.LittleEndian.Uint32(rawResultLen) | ||
|
||
// Success, read the result | ||
result, ok := memory.Read(resultOffset, resultLen) | ||
if !ok { | ||
return nil, fmt.Errorf("failed to read result from memory") | ||
} | ||
|
||
// Convert to [][4]byte | ||
selectors := make([][4]byte, len(result)/4) | ||
for i := 0; i < len(result); i += 4 { | ||
copy(selectors[i/4][:], result[i:i+4]) | ||
} | ||
|
||
return selectors, nil | ||
} |
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
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,5 @@ | ||
module github.com/cdump/evmole/go | ||
|
||
go 1.22.5 | ||
|
||
require github.com/tetratelabs/wazero v1.7.3 |
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,2 @@ | ||
github.com/tetratelabs/wazero v1.7.3 h1:PBH5KVahrt3S2AHgEjKu4u+LlDbbk+nsGE3KLucy6Rw= | ||
github.com/tetratelabs/wazero v1.7.3/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= |
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,30 @@ | ||
#[no_mangle] | ||
pub extern "C" fn function_selectors( | ||
code_ptr: *const u8, | ||
code_len: usize, | ||
gas_limit: u32, | ||
result_len_ptr: *mut u32, | ||
result_ptr: *mut u8, | ||
result_capacity: usize, | ||
) -> u32 { | ||
let code = unsafe { std::slice::from_raw_parts(code_ptr, code_len) }; | ||
let selectors = crate::selectors::function_selectors(code, gas_limit); | ||
|
||
let flattened: Vec<u8> = selectors.into_iter().flatten().collect(); | ||
let result_len = flattened.len(); | ||
|
||
unsafe { | ||
*result_len_ptr = result_len as u32; | ||
} | ||
|
||
if result_len > result_capacity { | ||
// Buffer too small | ||
return 1; | ||
} | ||
|
||
unsafe { | ||
std::ptr::copy_nonoverlapping(flattened.as_ptr(), result_ptr, result_len); | ||
} | ||
// Success | ||
0 | ||
} |
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 |
---|---|---|
|
@@ -21,3 +21,6 @@ mod interface_py; | |
|
||
#[cfg(feature = "javascript")] | ||
mod interface_js; | ||
|
||
#[cfg(feature = "wasm")] | ||
mod interface_wasm; |