You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is there any method to implement such a function: executing embedded bytecode in a Rust addon? It provides a protected runtime environment to load and execute these bytecodes by embedding bytecode files. The core mechanism of the code is to convert the bytecodes embedded in Rust into JavaScript Buffer, and then execute them in a secure environment through Node.js's vm and v8 modules.
like this below:
#![deny(clippy::all)]use napi::bindgen_prelude::*;use napi_derive::napi;constBYTECODE_LOADER:&str = include_str!("../../dist/bytecode-loader.cjs");constMAIN_BYTECODE:&[u8] = include_bytes!("../../dist/index.jsc");constPRELOAD_BYTECODE:&[u8] = include_bytes!("../../dist/preload.jsc");constBYTECODE_EXECUTOR:&str = r#"(function(bytecodeBuffer) { "use strict"; console.log('Inside BYTECODE_EXECUTOR:'); console.log('typeof bytecodeBuffer:', typeof bytecodeBuffer); console.log('Is Buffer:', Buffer.isBuffer(bytecodeBuffer)); if (Buffer.isBuffer(bytecodeBuffer)) { console.log('BytecodeBuffer length:', bytecodeBuffer.length); } console.log('---------------------------------'); const vm = require("vm"); const v8 = require("v8"); v8.setFlagsFromString("--no-lazy"); v8.setFlagsFromString("--no-flush-bytecode"); const FLAG_HASH_OFFSET = 12; const SOURCE_HASH_OFFSET = 8; let dummyBytecode; function setFlagHashHeader(buffer) { if (!dummyBytecode) { const script = new vm.Script("", { produceCachedData: true }); dummyBytecode = script.createCachedData(); } dummyBytecode.slice(FLAG_HASH_OFFSET, FLAG_HASH_OFFSET + 4) .copy(buffer, FLAG_HASH_OFFSET); } function getSourceHashHeader(buffer) { return buffer.slice(SOURCE_HASH_OFFSET, SOURCE_HASH_OFFSET + 4); } function buffer2Number(buffer) { let ret = 0; ret |= buffer[3] << 24; ret |= buffer[2] << 16; ret |= buffer[1] << 8; ret |= buffer[0]; return ret; } if (!Buffer.isBuffer(bytecodeBuffer)) { throw new Error("BytecodeBuffer must be a Buffer"); } setFlagHashHeader(bytecodeBuffer); const length = buffer2Number(getSourceHashHeader(bytecodeBuffer)); let dummyCode = ""; if (length > 1) { dummyCode = '"' + "\u200b".repeat(length - 2) + '"'; } const script = new vm.Script(dummyCode, { filename: "<embedded-bytecode>", lineOffset: 0, displayErrors: true, cachedData: bytecodeBuffer }); if (script.cachedDataRejected) { throw new Error("Invalid bytecode - possibly wrong Node.js/V8 version"); } return script.runInThisContext();})"#;#[napi]pubstructProtectedRuntime{initialized:bool,}#[napi]implProtectedRuntime{#[napi(constructor)]pubfnnew() -> Result<Self>{Ok(Self{initialized:false})}#[napi]pubfninitialize(&mutself) -> Result<()>{ifself.initialized{returnOk(());}self.initialized = true;Ok(())}#[napi]pubfnexecute_main(&self,env:Env) -> Result<Unknown>{ProtectedRuntime::execute_bytecode_static(env,MAIN_BYTECODE,"main")}#[napi]pubfnexecute_preload(&self,env:Env) -> Result<Unknown>{ProtectedRuntime::execute_bytecode_static(env,PRELOAD_BYTECODE,"preload")}fnexecute_bytecode_static(env:Env,bytecode:&[u8],name:&str,) -> Result<Unknown>{println!("Rust NAPI Debug: Entering execute_bytecode_static for {}.", name);println!("Rust NAPI Debug: Bytecode length: {} bytes.", bytecode.len());let bytecode_buffer = Buffer::from(bytecode.to_vec());let bytecode_obj = bytecode_buffer.into_unknown(&env)?;println!("Rust NAPI Debug: Successfully created JS Buffer from Rust bytes.");let global = env.get_global()?;let eval_fn:Function<(String,),Unknown> = global.get_named_property("eval")?;println!("Rust NAPI Debug: Successfully got global.eval function.");let executor_unknown = eval_fn.call((BYTECODE_EXECUTOR.to_string(),))?;println!("Rust NAPI Debug: eval(BYTECODE_EXECUTOR) executed successfully.");let executor:Function<(Unknown,),Unknown> = executor_unknown.coerce_to_object();println!("Rust NAPI Debug: Successfully converted eval result into a typed Function.");println!("Rust NAPI Debug: Calling the final executor function...");let result = executor.call((bytecode_obj,))?;println!("Rust NAPI Debug: JS executor function call completed.");Ok(result)}#[napi]pubfnget_info(&self,env:Env) -> Result<Object>{letmut obj = Object::new(&env)?;
obj.set("mainBytecodeSize",MAIN_BYTECODE.len()asu32)?;
obj.set("preloadBytecodeSize",PRELOAD_BYTECODE.len()asu32)?;
obj.set("initialized",self.initialized)?;Ok(obj)}}#[napi]pubfnrun_protected_main(env:Env) -> Result<Unknown<'static>>{ProtectedRuntime::execute_bytecode_static(env,MAIN_BYTECODE,"main")}#[napi]pubfnrun_protected_preload(env:Env) -> Result<Unknown<'static>>{ProtectedRuntime::execute_bytecode_static(env,PRELOAD_BYTECODE,"preload")}// #[napi]// pub fn run_bytecode_from_buffer(env: Env, bytecode: Buffer) -> Result<Unknown<'static>> {// ProtectedRuntime::execute_bytecode_static(env, bytecode.as_ref(), "custom")// }#[napi]pubfnget_version() -> String{env!("CARGO_PKG_VERSION").to_string()}#[napi]pubfnhas_embedded_bytecode() -> bool{
!MAIN_BYTECODE.is_empty() && !PRELOAD_BYTECODE.is_empty()}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Is there any method to implement such a function: executing embedded bytecode in a Rust addon? It provides a protected runtime environment to load and execute these bytecodes by embedding bytecode files. The core mechanism of the code is to convert the bytecodes embedded in Rust into JavaScript Buffer, and then execute them in a secure environment through Node.js's vm and v8 modules.
like this below:
this code not working, always have errors
Beta Was this translation helpful? Give feedback.
All reactions