From bda409ca29cb6aa55528197dc3126fd55f110784 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sun, 5 Jan 2025 18:42:07 +0800 Subject: [PATCH 01/14] options are 'lua' and 'c' --- dev-cli/src/commands/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-cli/src/commands/init.js b/dev-cli/src/commands/init.js index c8c4d8642..59a299220 100644 --- a/dev-cli/src/commands/init.js +++ b/dev-cli/src/commands/init.js @@ -22,7 +22,7 @@ export const command = new Command() .usage('-l cpp ') .option( '-l, --lang ', - 'The starter to use. Defaults to Lua. Options are "lua" and "cpp"' + 'The starter to use. Defaults to Lua. Options are "lua" and "c"' ) .arguments('') .action(init) From c7d3aa0fa7dbc466b37c3f79932c3d9a3fbe6b83 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sun, 5 Jan 2025 18:44:06 +0800 Subject: [PATCH 02/14] fixed usage doc --- dev-cli/src/commands/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-cli/src/commands/init.js b/dev-cli/src/commands/init.js index 59a299220..897b301ad 100644 --- a/dev-cli/src/commands/init.js +++ b/dev-cli/src/commands/init.js @@ -19,7 +19,7 @@ export async function init ({ lang = 'lua' }, name) { export const command = new Command() .description('Create an ao Process Source Project') - .usage('-l cpp ') + .usage('-l c ') .option( '-l, --lang ', 'The starter to use. Defaults to Lua. Options are "lua" and "c"' From 565a986d93b826f883f36253027bcb7689011611 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 18 Jan 2025 19:45:45 +0800 Subject: [PATCH 03/14] fixed inject_files --- dev-cli/container/src/ao-build-module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-cli/container/src/ao-build-module b/dev-cli/container/src/ao-build-module index b1ce82e63..71ac2502d 100644 --- a/dev-cli/container/src/ao-build-module +++ b/dev-cli/container/src/ao-build-module @@ -70,7 +70,7 @@ def main(): # Inject c files into c_program if language is c if(language == 'c'): - c_program = inject_c_files(definition, c_program, c_source_files) + c_program = inject_c_files(definition, c_program, c_source_files, link_libraries) # Inject rust files into c_program if language is rust if(language == 'rust'): From 5fb9315f87c5ba273c3c7728775bf1733c6e39c4 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 18 Jan 2025 19:57:47 +0800 Subject: [PATCH 04/14] fixed root_dir --- dev-cli/tools/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-cli/tools/build.sh b/dev-cli/tools/build.sh index d03b0a5b3..2e8d736cf 100755 --- a/dev-cli/tools/build.sh +++ b/dev-cli/tools/build.sh @@ -3,7 +3,7 @@ # Build the ao cli into a set of platform binaries # change directory to root of dev-cli to ensure this script works no matter where it is ran -root_dir="$(dirname "$0")/.." +root_dir="$(realpath "$(dirname "$0")/..")" cd $root_dir OUTPUT_DIR="${root_dir}/dist" From 2886c845430848c082c63fda2cc3c843cfd21ae5 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 18 Jan 2025 21:33:56 +0800 Subject: [PATCH 05/14] fixed deno std issue --- dev-cli/src/deps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-cli/src/deps.js b/dev-cli/src/deps.js index 3a568d201..be4acd483 100644 --- a/dev-cli/src/deps.js +++ b/dev-cli/src/deps.js @@ -1,4 +1,4 @@ -export { Command } from 'https://deno.land/x/cliffy@v1.0.0-rc.3/command/mod.ts' +export { Command } from 'https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts' export { basename, resolve } from 'https://deno.land/std@0.224.0/path/mod.ts' export { copy } from 'https://deno.land/std@0.224.0/fs/copy.ts' export { parse } from 'jsr:@std/yaml' From 13fdf69f34770f8df1aadfdd62098c4df2716509 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sun, 19 Jan 2025 10:27:10 +0800 Subject: [PATCH 06/14] support custom image --- dev-cli/src/commands/build.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dev-cli/src/commands/build.js b/dev-cli/src/commands/build.js index 01020265d..48da9876c 100644 --- a/dev-cli/src/commands/build.js +++ b/dev-cli/src/commands/build.js @@ -3,8 +3,10 @@ import { Command } from '../deps.js' import { VERSION } from '../versions.js' -export async function build () { +export async function build(customImage) { const pwd = Deno.cwd() + const image = customImage || `p3rmaw3b/ao:${VERSION.IMAGE}` + const p = Deno.run({ cmd: [ 'docker', @@ -13,7 +15,7 @@ export async function build () { 'linux/amd64', '-v', `${pwd}:/src`, - `p3rmaw3b/ao:${VERSION.IMAGE}`, + image, 'ao-build-module' ] }) @@ -22,4 +24,7 @@ export async function build () { export const command = new Command() .description('Build the Lua Project into WASM') - .action(build) + .option('-i, --image ', 'Specify a custom Docker image to use') + .action(async (options) => { + await build(options.image) + }) From 652d1c510291a4c3fb30f5fbddb6c49c74196251 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sun, 19 Jan 2025 10:33:22 +0800 Subject: [PATCH 07/14] update document --- dev-cli/src/commands/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-cli/src/commands/build.js b/dev-cli/src/commands/build.js index 48da9876c..d8c69a754 100644 --- a/dev-cli/src/commands/build.js +++ b/dev-cli/src/commands/build.js @@ -23,7 +23,7 @@ export async function build(customImage) { } export const command = new Command() - .description('Build the Lua Project into WASM') + .description('Build the Project into WASM') .option('-i, --image ', 'Specify a custom Docker image to use') .action(async (options) => { await build(options.image) From 267f7b38c2ba93a7eba771ec3c8017d27148da7f Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Jan 2025 00:11:49 +0800 Subject: [PATCH 08/14] added rust binding --- dev-cli/container/Dockerfile | 26 +- dev-cli/container/src/ao-build-module | 42 +-- .../src/ao_module_lib/languages/rust.py | 40 +-- dev-cli/src/starters/rust/.gitignore | 11 + dev-cli/src/starters/rust/Cargo.toml | 12 + dev-cli/src/starters/rust/Makefile | 15 + dev-cli/src/starters/rust/cbindgen.toml | 7 + dev-cli/src/starters/rust/src/lib.rs | 72 +++++ dev-cli/src/starters/rust/src/libao.rs | 257 ++++++++++++++++++ 9 files changed, 441 insertions(+), 41 deletions(-) create mode 100644 dev-cli/src/starters/rust/.gitignore create mode 100644 dev-cli/src/starters/rust/Cargo.toml create mode 100644 dev-cli/src/starters/rust/Makefile create mode 100644 dev-cli/src/starters/rust/cbindgen.toml create mode 100644 dev-cli/src/starters/rust/src/lib.rs create mode 100644 dev-cli/src/starters/rust/src/libao.rs diff --git a/dev-cli/container/Dockerfile b/dev-cli/container/Dockerfile index d0dcfb529..920c31d5f 100644 --- a/dev-cli/container/Dockerfile +++ b/dev-cli/container/Dockerfile @@ -3,7 +3,7 @@ LABEL maintainer="tom wilson " # The working directory used by the base image is /src, so we can mount volumes to there # to expose files on the host to the ao container -# +# # https://github.com/emscripten-core/emsdk/blob/9b0db91883452051aca8deddc932363aab29060b/docker/Dockerfile#L120 RUN apt-get update --fix-missing -qq -y @@ -53,12 +53,12 @@ RUN cp -r /lua-${LUA_VERSION} /lua-${LUA_VERSION}-32 # And, re-compile lua with "generic WASM" RUN cd /lua-${LUA_VERSION} && \ make clean && \ - make generic CC='emcc -s WASM=1 -s MEMORY64=1 -s SUPPORT_LONGJMP=1' + make generic CC='emcc -s WASM=1 -s MEMORY64=1 -s SUPPORT_LONGJMP=1' # And, re-compile lua with "generic WASM 32-bit" RUN cd /lua-${LUA_VERSION}-32 && \ make clean && \ - make generic CC='emcc -s WASM=1 -s SUPPORT_LONGJMP=1' + make generic CC='emcc -s WASM=1 -s SUPPORT_LONGJMP=1' ############################# @@ -115,7 +115,7 @@ ENV NM='/emsdk/upstream/bin/llvm-nm' ########################################### # We first create a directory for the node impls to be placed # and dependencies installed -# +# # By running npm link, we allow any commands exposed by # the node module to be ran globally within the container RUN mkdir -p /opt/node @@ -124,3 +124,21 @@ RUN cd /opt/node && \ npm install --omit="dev" && \ npm link + +########################################### +### Rust and WASM toolchains ### +########################################### + +# Set environment variables +ENV RUSTUP_HOME=/usr/local/rustup \ + CARGO_HOME=/usr/local/cargo \ + PATH=/usr/local/cargo/bin:/usr/local/rustup/bin:$PATH + +# Install Rust, components, and cbindgen in a single step +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly && \ + rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu && \ + cargo install cbindgen && \ + rustc --version && cargo --version && cbindgen --version && rustup show + +# Make build directory +RUN mkdir /opt/aorustlib diff --git a/dev-cli/container/src/ao-build-module b/dev-cli/container/src/ao-build-module index 71ac2502d..715efef5a 100644 --- a/dev-cli/container/src/ao-build-module +++ b/dev-cli/container/src/ao-build-module @@ -37,7 +37,7 @@ def determine_language(): # raise Exception('Multiple languages detected in the module') if len(langs) == 0: raise Exception('No language detected in the module') - + if langs.count('lua') == 0 and langs.count('c') >= 1: lang = 'c' elif langs.count('lua') == 0 and langs.count('rust') >= 1: @@ -51,7 +51,7 @@ def determine_language(): def main(): # Load the definition file definition = Definition('/opt/definition.yml') - + # Load the config file config = Config('/src/config.yml') @@ -67,11 +67,11 @@ def main(): c_source_files = [] injected_lua_files = [] dependency_libraries = [] - + # Inject c files into c_program if language is c if(language == 'c'): c_program = inject_c_files(definition, c_program, c_source_files, link_libraries) - + # Inject rust files into c_program if language is rust if(language == 'rust'): c_program = inject_rust_files(definition, c_program) @@ -79,14 +79,14 @@ def main(): # Inject lua files into c_program always to load lua files and replace placeholders if(language == 'lua'): c_program = inject_lua_files(definition, c_program, injected_lua_files) - + # Load all libraries c_program = load_libraries(config, definition, c_program, link_libraries, c_source_files, injected_lua_files,dependency_libraries) - + # Inject the lua files into the c program c_program = c_program.replace( '__INJECT_LUA_FILES__', '\n'.join(injected_lua_files)) - + #Generate compile target file debug_print('Start to generate complie.c') @@ -97,25 +97,25 @@ def main(): debug_print('Start to compile as WASM') # Setup the compile command - cmd = ['emcc', '-O3', + cmd = ['emcc', '-O3', '-g2', # '-s', 'MAIN_MODULE', # This is required to load dynamic libraries at runtime '-s', 'ASYNCIFY=1', '-s', 'STACK_SIZE=' + str(config.stack_size), '-s', 'ASYNCIFY_STACK_SIZE=' + str(config.stack_size), - '-s', 'ALLOW_MEMORY_GROWTH=1', - '-s', 'INITIAL_MEMORY=' + str(config.initial_memory), - '-s', 'MAXIMUM_MEMORY=' + str(config.maximum_memory), - '-s', 'WASM=1', + '-s', 'ALLOW_MEMORY_GROWTH=1', + '-s', 'INITIAL_MEMORY=' + str(config.initial_memory), + '-s', 'MAXIMUM_MEMORY=' + str(config.maximum_memory), + '-s', 'WASM=1', '-s', 'MODULARIZE', - # '-s', 'FILESYSTEM=0', - '-s', 'DETERMINISTIC=1', - '-s', 'NODERAWFS=0', + # '-s', 'FILESYSTEM=0', + '-s', 'DETERMINISTIC=1', + '-s', 'NODERAWFS=0', '-s', 'FORCE_FILESYSTEM=1', '-msimd128', '--pre-js', '/opt/pre.js' ] - + # If the target is 64 bit, add the MEMORY64 flag and link against 64 bit libraries if config.target == 64: cmd.extend(['-sMEMORY64=1']) @@ -128,7 +128,7 @@ def main(): # Link Rust library if(language == 'rust'): - cmd.extend(['-L/opt/aorustlib', '-l:libaorust.a']) + cmd.extend(['-I/opt/aorustlib', '-L/opt/aorustlib', '-laorust']) cmd.extend(['-s','ASSERTIONS=1']) cmd.extend(definition.get_extra_args()) @@ -138,7 +138,7 @@ def main(): # Add all c source files if there are any for f in c_source_files: cmd.append(quote(f)) - + # Add the compile file and link libraries cmd.extend(['/tmp/compile.c']) cmd.extend([quote(v.filepath) for v in link_libraries]) @@ -157,8 +157,12 @@ def main(): # add metering library # meter_cmd = ['node', '/opt/node/apply-metering.cjs'] # shell_exec(*meter_cmd) + if config.keep_js is False: - shell_exec(*['rm', os.path.join(os.getcwd(), 'process.js')]) + process_js_path = os.path.join(os.getcwd(), 'process.js') + # For rust case, js code is not exists + if os.path.exists(process_js_path): + shell_exec(*['rm', process_js_path]) if __name__ == '__main__': main() diff --git a/dev-cli/container/src/ao_module_lib/languages/rust.py b/dev-cli/container/src/ao_module_lib/languages/rust.py index 5593c0f27..57e9fd4d3 100644 --- a/dev-cli/container/src/ao_module_lib/languages/rust.py +++ b/dev-cli/container/src/ao_module_lib/languages/rust.py @@ -9,31 +9,34 @@ def inject_rust_files(definition: Definition, c_program: str): c_header_files = [] - rust_source_files = [] + # rust_source_files = [] - c_header_files += glob.glob('/src/**/*.h', recursive=True) + c_header_files += glob.glob('/src/**/*.h', recursive=True) c_header_files += glob.glob('/src/**/*.hpp', recursive=True) inc = [] for header in c_header_files: c_program = '#include "{}"\n'.format(header) + c_program - # c_program = 'const char *process_handle(const char *arg_0, const char *arg_1);\n' + c_program + c_program = 'const char *process_handle(const char *arg_0, const char *arg_1);\n' + c_program c_program = c_program.replace('__FUNCTION_DECLARATIONS__', definition.make_c_function_delarations()) + c_program = c_program.replace('__LUA_BASE__', "") + c_program = c_program.replace('__LUA_MAIN__', "") - rust_source_files += glob.glob('/src/**/*.rs', recursive=True) - rust_src_dir = os.path.join(RUST_DIR, "src") + # rust_source_files += glob.glob('/src/**/*.rs', recursive=True) + # rust_src_dir = os.path.join(RUST_DIR, "src") - for file in rust_source_files: - if os.path.isfile(file): - shutil.copy2(file, os.path.join(rust_src_dir)) + # for file in rust_source_files: + # if os.path.isfile(file): + # shutil.copy2(file, os.path.join(rust_src_dir)) - prev_dir = os.getcwd() - os.chdir(RUST_DIR) +# prev_dir = os.getcwd() +# os.chdir(RUST_DIR) + # build rust code at '/src' os.environ["RUSTFLAGS"] = "--cfg=web_sys_unstable_apis --Z wasm_c_abi=spec" cmd = [ 'cargo', @@ -46,19 +49,20 @@ def inject_rust_files(definition: Definition, c_program: str): ] shell_exec(*cmd) - rust_lib = glob.glob('/opt/aorustlib/**/release/*.a', recursive=True)[0] + rust_lib = glob.glob('/src/target/wasm64-unknown-unknown/release/*.a', recursive=True)[0] rust_lib = shutil.copy2(rust_lib, RUST_DIR) cmd = [ - 'cbindgen', - '--config', + 'cbindgen', + '--config', 'cbindgen.toml', - '--crate', - 'aorust', - '--output', + '--crate', + 'aorust', + '--output', 'aorust.h' ] shell_exec(*cmd) - c_program = '#include "{}"\n'.format('/opt/aorustlib/aorust.h') + c_program - os.chdir(prev_dir) + rust_header = shutil.copy2('/src/aorust.h', RUST_DIR) + c_program = '#include "{}"\n'.format('aorust.h') + c_program +# os.chdir(prev_dir) return c_program diff --git a/dev-cli/src/starters/rust/.gitignore b/dev-cli/src/starters/rust/.gitignore new file mode 100644 index 000000000..f300cd9fb --- /dev/null +++ b/dev-cli/src/starters/rust/.gitignore @@ -0,0 +1,11 @@ +/target/ +Cargo.lock +**/*.log +**/*.tmp +*.swp +*.bak +*.bk +*.tmp +*.old +aorust.h +process.wasm diff --git a/dev-cli/src/starters/rust/Cargo.toml b/dev-cli/src/starters/rust/Cargo.toml new file mode 100644 index 000000000..3b5833d98 --- /dev/null +++ b/dev-cli/src/starters/rust/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "aorust" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["staticlib"] + +[dependencies] +serde = "1.0" +serde_json = "1.0" + diff --git a/dev-cli/src/starters/rust/Makefile b/dev-cli/src/starters/rust/Makefile new file mode 100644 index 000000000..d663da2e1 --- /dev/null +++ b/dev-cli/src/starters/rust/Makefile @@ -0,0 +1,15 @@ +all:build bindgen + +build: + RUSTFLAGS="--cfg=web_sys_unstable_apis --Z wasm_c_abi=spec" \ + cargo +nightly build \ + -Zbuild-std=std,panic_unwind,panic_abort \ + --target=wasm64-unknown-unknown \ + --release + +bindgen: + cbindgen --config cbindgen.toml --crate aorust --output aorust.h + +clean: + cargo clean + rm aorust.h diff --git a/dev-cli/src/starters/rust/cbindgen.toml b/dev-cli/src/starters/rust/cbindgen.toml new file mode 100644 index 000000000..863aad3de --- /dev/null +++ b/dev-cli/src/starters/rust/cbindgen.toml @@ -0,0 +1,7 @@ +language = "C" + +[defines] +MY_DEFINE = "1" + +[export] +include = ["process_handler"] diff --git a/dev-cli/src/starters/rust/src/lib.rs b/dev-cli/src/starters/rust/src/lib.rs new file mode 100644 index 000000000..c00d75cba --- /dev/null +++ b/dev-cli/src/starters/rust/src/lib.rs @@ -0,0 +1,72 @@ +pub mod libao; +use std::ffi::{CStr, CString}; +use std::os::raw::c_char; + +/// Processes the input `msg` and `env` strings, performs some operations, +/// and returns the result as a C-compatible string. +/// +/// # Safety +/// - The caller must ensure that the `msg` and `env` pointers are valid, null-terminated C strings. +/// - The caller is responsible for freeing the returned string using `free_c_string`. +/// +/// # Arguments +/// - `msg`: A pointer to a null-terminated C string representing the message. +/// - `env`: A pointer to a null-terminated C string representing the environment. +/// +/// # Returns +/// - A pointer to a null-terminated C string containing the result. The caller must not modify +/// or attempt to free this pointer. +#[no_mangle] +pub extern "C" fn process_handle(msg: *const c_char, env: *const c_char) -> *const c_char { + // Convert the C strings to Rust strings + let msg = unsafe { CStr::from_ptr(msg).to_str().unwrap_or("Invalid msg") }; + let env = unsafe { CStr::from_ptr(env).to_str().unwrap_or("Invalid env") }; + + // Call the Rust handler function to process the inputs + let ret = handler(msg, env); + + // Convert the Rust string result into a CString + let c_response = CString::new(ret).unwrap(); + + // Return the raw pointer to the C-compatible string + // The caller is now responsible for freeing this memory + c_response.into_raw() +} + +pub fn handler(msg: &str, env: &str) -> String { + let mut ao = libao::AO::new(); + ao.init(env); + ao.log("Normalize"); + let norm = ao.normalize(msg); + ao.log(&msg); + let send = &ao.send(&norm); + println!("Send: {}", send); + "{\"ok\": true,\"response\":{\"Output\":\"Success\"},\"Memory\":50000000}".to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + use std::ffi::{CStr, CString}; + + #[test] + fn test_process_handle() { + let msg_json = r#"{"key": "value"}"#; + let env_json = r#"{"env": "test"}"#; + + let c_msg = CString::new(msg_json).expect("Failed to create CString for msg"); + let c_env = CString::new(env_json).expect("Failed to create CString for env"); + + let c_result = process_handle(c_msg.as_ptr(), c_env.as_ptr()); + + assert!(!c_result.is_null(), "Returned pointer is null"); + + let result_str = unsafe { CStr::from_ptr(c_result).to_string_lossy().into_owned() }; + + let expected_result = r#"{"ok": true,"response":{"Output":"Success"},"Memory":50000000}"#; + assert_eq!( + result_str, expected_result, + "Output does not match expected result" + ); + } +} diff --git a/dev-cli/src/starters/rust/src/libao.rs b/dev-cli/src/starters/rust/src/libao.rs new file mode 100644 index 000000000..5be006ee4 --- /dev/null +++ b/dev-cli/src/starters/rust/src/libao.rs @@ -0,0 +1,257 @@ +use serde_json::{json, Map, Value}; + +#[derive(Default)] +pub struct AO { + version: String, + module: Option, + id: Option, + authorities: Option>, + outbox: Value, + ref_count: usize, +} + +impl AO { + pub fn new() -> AO { + AO { + version: "0.0.4".to_string(), + module: None, + id: None, + authorities: None, + outbox: json!({ + "Output": [], + "Messages": [], + "Spawns": [], + "Assignments": [], + "Error": null + }), + ref_count: 0, + } + } + + pub fn init(&mut self, env: &str) { + // Parse the environment JSON string into a Value (serde_json's equivalent of cJSON) + let env_json: Value = serde_json::from_str(env).unwrap(); + + // Retrieve the "Process" object from the parsed JSON + if let Some(process) = env_json.get("Process") { + // If id is None, retrieve it from the "Process" object + if self.id.is_none() { + self.id = process + .get("Id") + .and_then(Value::as_str) + .map(str::to_string); + } + + // Retrieve the "Tags" array from the "Process" object + if let Some(tags) = process.get("Tags").and_then(Value::as_array) { + // Search for the "Module" tag within "Tags" + if self.module.is_none() { + for tag in tags { + if let Some(name) = tag.get("name").and_then(Value::as_str) { + if name == "Module" { + self.module = + tag.get("value").and_then(Value::as_str).map(str::to_string); + break; + } + } + } + } + + // Initialize authorities as an empty vector if it's None + if self.authorities.is_none() { + self.authorities = Some(Vec::new()); + for tag in tags { + if let Some(name) = tag.get("name").and_then(Value::as_str) { + if name == "Authority" { + if let Some(value) = tag.get("value").and_then(Value::as_str) { + self.authorities.as_mut().unwrap().push(value.to_string()); + } + } + } + } + } + } + } + self.clear_outbox(); + } + + pub fn normalize(&self, msg: &str) -> String { + let msg_json: Value = serde_json::from_str(msg).unwrap(); + serde_json::to_string(&msg_json).unwrap() + } + + pub fn sanitize(&self, msg: &str) -> String { + let mut msg_json: Value = serde_json::from_str(msg).unwrap(); + let mut new_message = Map::new(); + + // Iterate over each key in the JSON object, excluding non-forwardable tags + for (key, value) in msg_json.as_object_mut().unwrap().iter_mut() { + if !self.is_string_in_array(&key, &self.non_forwardable_tags()) { + new_message.insert(key.clone(), value.clone()); + } + } + + serde_json::to_string(&new_message).unwrap() + } + + pub fn log(&mut self, msg: &str) { + let output = self.outbox.get_mut("Output").unwrap(); + if let Some(arr) = output.as_array_mut() { + arr.push(Value::String(msg.to_string())); + } + } + + pub fn send(&mut self, msg: &str) -> String { + let msg_json: Value = serde_json::from_str(msg).unwrap(); + self.ref_count += 1; + let padded_ref = format!("{:032}", self.ref_count); + + let mut message = Map::new(); + self.add_string_to_json_if_exists(&msg_json, &mut message, "Target"); + self.add_string_to_json_if_exists(&msg_json, &mut message, "Data"); + self.add_string_to_json_if_exists(&msg_json, &mut message, "Anchor"); + let default = vec![]; + let tags = msg_json + .get("Tags") + .and_then(Value::as_array) + .unwrap_or(&default); + let mut tags_array = Vec::new(); + self.add_tag_to_array(&mut tags_array, "Data-Protocol", "ao"); + self.add_tag_to_array(&mut tags_array, "Variant", "aoc.TN.1"); + self.add_tag_to_array(&mut tags_array, "Type", "Message"); + self.add_tag_to_array(&mut tags_array, "Reference", &padded_ref); + + for tag in tags { + if let Some(name) = tag.get("name").and_then(Value::as_str) { + if !self.is_string_in_array(name, &self.persistent_tags()) { + self.add_tag_to_array( + &mut tags_array, + name, + tag.get("value").and_then(Value::as_str).unwrap(), + ); + } + } + } + + message.insert("Tags".to_string(), Value::Array(tags_array)); + + let messages = self + .outbox + .get_mut("Messages") + .unwrap() + .as_array_mut() + .unwrap(); + messages.push(Value::Object(message.clone())); + + serde_json::to_string(&message).unwrap() + } + + pub fn assign(&mut self, assignment: &str) { + let assignment_json: Value = serde_json::from_str(assignment).unwrap(); + let assignments = self + .outbox + .get_mut("Assignments") + .unwrap() + .as_array_mut() + .unwrap(); + assignments.push(assignment_json); + } + + pub fn is_trusted(&self, msg: &str) -> bool { + let msg_json: Value = serde_json::from_str(msg).unwrap(); + + if let Some(authorities) = &self.authorities { + for authority in authorities { + if let Some(from) = msg_json.get("From").and_then(Value::as_str) { + if from == authority { + return true; + } + } + + if let Some(owner) = msg_json.get("Owner").and_then(Value::as_str) { + if owner == authority { + return true; + } + } + } + false + } else { + true + } + } + + pub fn result(&self, result: &str) -> String { + let result_json: Value = serde_json::from_str(result).unwrap(); + if let Some(error) = result_json.get("Error") { + if !error.is_null() { + return serde_json::to_string(&error).unwrap(); + } + } + + let output = result_json.get("Output").unwrap_or(&self.outbox["Output"]); + let mut result_out = Map::new(); + result_out.insert("Output".to_string(), output.clone()); + + serde_json::to_string(&result_out).unwrap() + } + + pub fn print(&self) { + println!("Version: {}", self.version); + println!("Module: {}", self.module.clone().unwrap_or_default()); + println!("Ref: {}", self.ref_count); + println!("Id: {}", self.id.clone().unwrap_or_default()); + println!( + "Authorities: {}", + serde_json::to_string(&self.authorities).unwrap() + ); + println!("Outbox: {}", serde_json::to_string(&self.outbox).unwrap()); + } + + pub fn clear_outbox(&mut self) { + self.outbox = json!({ + "Output": [], + "Messages": [], + "Spawns": [], + "Assignments": [], + "Error": null + }); + } + + pub fn add_tag_to_array(&self, tags_array: &mut Vec, name: &str, value: &str) { + tags_array.push(json!({ "name": name, "value": value })); + } + + pub fn is_string_in_array(&self, s: &str, array: &[&str]) -> bool { + array.contains(&s) + } + + pub fn non_forwardable_tags(&self) -> Vec<&str> { + vec![ + "Data-Protocol", + "Variant", + "From-Process", + "From-Module", + "Type", + "From", + "Owner", + "Anchor", + "Target", + "Tags", + ] + } + + pub fn persistent_tags(&self) -> Vec<&str> { + vec!["Target", "Data", "Anchor", "Tags", "From"] + } + + pub fn add_string_to_json_if_exists( + &self, + msg_json: &Value, + message: &mut Map, + key: &str, + ) { + if let Some(val) = msg_json.get(key) { + message.insert(key.to_string(), val.clone()); + } + } +} From 1004fa65fb6ce2b1941026b25433985060744fd1 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Jan 2025 17:42:07 +0800 Subject: [PATCH 09/14] use [no_std] --- .../src/ao_module_lib/languages/rust.py | 2 +- dev-cli/src/starters/rust/Cargo.toml | 10 ++++-- dev-cli/src/starters/rust/src/lib.rs | 34 ++++++++++++++----- dev-cli/src/starters/rust/src/libao.rs | 19 +++-------- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/dev-cli/container/src/ao_module_lib/languages/rust.py b/dev-cli/container/src/ao_module_lib/languages/rust.py index 57e9fd4d3..5b0f89cec 100644 --- a/dev-cli/container/src/ao_module_lib/languages/rust.py +++ b/dev-cli/container/src/ao_module_lib/languages/rust.py @@ -18,7 +18,7 @@ def inject_rust_files(definition: Definition, c_program: str): for header in c_header_files: c_program = '#include "{}"\n'.format(header) + c_program - c_program = 'const char *process_handle(const char *arg_0, const char *arg_1);\n' + c_program +# c_program = 'const char *process_handle(const char *arg_0, const char *arg_1);\n' + c_program c_program = c_program.replace('__FUNCTION_DECLARATIONS__', definition.make_c_function_delarations()) diff --git a/dev-cli/src/starters/rust/Cargo.toml b/dev-cli/src/starters/rust/Cargo.toml index 3b5833d98..1af9285b6 100644 --- a/dev-cli/src/starters/rust/Cargo.toml +++ b/dev-cli/src/starters/rust/Cargo.toml @@ -7,6 +7,12 @@ edition = "2021" crate-type = ["staticlib"] [dependencies] -serde = "1.0" -serde_json = "1.0" +serde = { version = "1.0", default-features = false, features = ["derive"] } +serde_json = { version="1.0", default-features = false, features = ["alloc"] } +wee_alloc = "0.4.5" +[profile.dev] +panic = "abort" + +[profile.release] +panic = "abort" \ No newline at end of file diff --git a/dev-cli/src/starters/rust/src/lib.rs b/dev-cli/src/starters/rust/src/lib.rs index c00d75cba..32270e63b 100644 --- a/dev-cli/src/starters/rust/src/lib.rs +++ b/dev-cli/src/starters/rust/src/lib.rs @@ -1,6 +1,24 @@ +#![no_std] + +#[macro_use] +extern crate alloc; +use alloc::string::String; +use alloc::string::ToString; pub mod libao; -use std::ffi::{CStr, CString}; -use std::os::raw::c_char; +use alloc::ffi::CString; +use core::ffi::c_char; +use core::ffi::CStr; +use wee_alloc::WeeAlloc; + +#[global_allocator] +static ALLOC: WeeAlloc = WeeAlloc::INIT; + +/// halt the thread on panic; messages are discarded: +#[cfg(not(test))] +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} /// Processes the input `msg` and `env` strings, performs some operations, /// and returns the result as a C-compatible string. @@ -17,7 +35,7 @@ use std::os::raw::c_char; /// - A pointer to a null-terminated C string containing the result. The caller must not modify /// or attempt to free this pointer. #[no_mangle] -pub extern "C" fn process_handle(msg: *const c_char, env: *const c_char) -> *const c_char { +pub unsafe extern "C" fn process_handle(msg: *const c_char, env: *const c_char) -> *const c_char { // Convert the C strings to Rust strings let msg = unsafe { CStr::from_ptr(msg).to_str().unwrap_or("Invalid msg") }; let env = unsafe { CStr::from_ptr(env).to_str().unwrap_or("Invalid env") }; @@ -38,16 +56,15 @@ pub fn handler(msg: &str, env: &str) -> String { ao.init(env); ao.log("Normalize"); let norm = ao.normalize(msg); - ao.log(&msg); - let send = &ao.send(&norm); - println!("Send: {}", send); + ao.log(msg); + let _send = &ao.send(&norm); "{\"ok\": true,\"response\":{\"Output\":\"Success\"},\"Memory\":50000000}".to_string() } #[cfg(test)] mod tests { + use super::*; - use std::ffi::{CStr, CString}; #[test] fn test_process_handle() { @@ -56,8 +73,7 @@ mod tests { let c_msg = CString::new(msg_json).expect("Failed to create CString for msg"); let c_env = CString::new(env_json).expect("Failed to create CString for env"); - - let c_result = process_handle(c_msg.as_ptr(), c_env.as_ptr()); + let c_result = unsafe { process_handle(c_msg.as_ptr(), c_env.as_ptr()) }; assert!(!c_result.is_null(), "Returned pointer is null"); diff --git a/dev-cli/src/starters/rust/src/libao.rs b/dev-cli/src/starters/rust/src/libao.rs index 5be006ee4..36b68067d 100644 --- a/dev-cli/src/starters/rust/src/libao.rs +++ b/dev-cli/src/starters/rust/src/libao.rs @@ -1,8 +1,11 @@ +use alloc::string::String; +use alloc::string::ToString; +use alloc::vec::Vec; use serde_json::{json, Map, Value}; #[derive(Default)] pub struct AO { - version: String, + pub version: String, module: Option, id: Option, authorities: Option>, @@ -86,7 +89,7 @@ impl AO { // Iterate over each key in the JSON object, excluding non-forwardable tags for (key, value) in msg_json.as_object_mut().unwrap().iter_mut() { - if !self.is_string_in_array(&key, &self.non_forwardable_tags()) { + if !self.is_string_in_array(key, &self.non_forwardable_tags()) { new_message.insert(key.clone(), value.clone()); } } @@ -195,18 +198,6 @@ impl AO { serde_json::to_string(&result_out).unwrap() } - pub fn print(&self) { - println!("Version: {}", self.version); - println!("Module: {}", self.module.clone().unwrap_or_default()); - println!("Ref: {}", self.ref_count); - println!("Id: {}", self.id.clone().unwrap_or_default()); - println!( - "Authorities: {}", - serde_json::to_string(&self.authorities).unwrap() - ); - println!("Outbox: {}", serde_json::to_string(&self.outbox).unwrap()); - } - pub fn clear_outbox(&mut self) { self.outbox = json!({ "Output": [], From a238d60246b769393b230471a3bf462390471c20 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Jan 2025 17:50:01 +0800 Subject: [PATCH 10/14] use dlmalloc --- dev-cli/src/starters/rust/Cargo.toml | 2 +- dev-cli/src/starters/rust/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-cli/src/starters/rust/Cargo.toml b/dev-cli/src/starters/rust/Cargo.toml index 1af9285b6..7fcdfe4b5 100644 --- a/dev-cli/src/starters/rust/Cargo.toml +++ b/dev-cli/src/starters/rust/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["staticlib"] [dependencies] serde = { version = "1.0", default-features = false, features = ["derive"] } serde_json = { version="1.0", default-features = false, features = ["alloc"] } -wee_alloc = "0.4.5" +dlmalloc = { version="0.2.7", default-features = false, features = ["global"] } [profile.dev] panic = "abort" diff --git a/dev-cli/src/starters/rust/src/lib.rs b/dev-cli/src/starters/rust/src/lib.rs index 32270e63b..f4e4f86bc 100644 --- a/dev-cli/src/starters/rust/src/lib.rs +++ b/dev-cli/src/starters/rust/src/lib.rs @@ -8,10 +8,10 @@ pub mod libao; use alloc::ffi::CString; use core::ffi::c_char; use core::ffi::CStr; -use wee_alloc::WeeAlloc; +use dlmalloc::GlobalDlmalloc; #[global_allocator] -static ALLOC: WeeAlloc = WeeAlloc::INIT; +static GLOBAL: GlobalDlmalloc = GlobalDlmalloc; /// halt the thread on panic; messages are discarded: #[cfg(not(test))] From e2e2820fad2bf7138fd89fcaee4e7d783b5a5592 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Jan 2025 18:32:53 +0800 Subject: [PATCH 11/14] handle errors --- dev-cli/src/starters/rust/src/lib.rs | 26 +++++++----- dev-cli/src/starters/rust/src/libao.rs | 57 +++++++++++++++++--------- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/dev-cli/src/starters/rust/src/lib.rs b/dev-cli/src/starters/rust/src/lib.rs index f4e4f86bc..4d5369fe8 100644 --- a/dev-cli/src/starters/rust/src/lib.rs +++ b/dev-cli/src/starters/rust/src/lib.rs @@ -1,5 +1,4 @@ #![no_std] - #[macro_use] extern crate alloc; use alloc::string::String; @@ -37,28 +36,35 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { #[no_mangle] pub unsafe extern "C" fn process_handle(msg: *const c_char, env: *const c_char) -> *const c_char { // Convert the C strings to Rust strings + let mut ao = libao::AO::new(); let msg = unsafe { CStr::from_ptr(msg).to_str().unwrap_or("Invalid msg") }; let env = unsafe { CStr::from_ptr(env).to_str().unwrap_or("Invalid env") }; // Call the Rust handler function to process the inputs - let ret = handler(msg, env); + match handler(&mut ao, msg, env) { + Ok(ret) => { + let c_response = CString::new(ret).unwrap(); + c_response.into_raw() + } + Err(_) => { + let c_response = CString::new("Internal Error").unwrap(); + c_response.into_raw() + } + } // Convert the Rust string result into a CString - let c_response = CString::new(ret).unwrap(); // Return the raw pointer to the C-compatible string // The caller is now responsible for freeing this memory - c_response.into_raw() } -pub fn handler(msg: &str, env: &str) -> String { - let mut ao = libao::AO::new(); - ao.init(env); +pub fn handler(ao: &mut libao::AO, msg: &str, env: &str) -> Result { + let _ = ao.init(env)?; ao.log("Normalize"); - let norm = ao.normalize(msg); + let norm = ao.normalize(msg)?; ao.log(msg); - let _send = &ao.send(&norm); - "{\"ok\": true,\"response\":{\"Output\":\"Success\"},\"Memory\":50000000}".to_string() + let _send = &ao.send(&norm)?; + Ok("{\"ok\": true,\"response\":{\"Output\":\"Success\"},\"Memory\":50000000}".to_string()) } #[cfg(test)] diff --git a/dev-cli/src/starters/rust/src/libao.rs b/dev-cli/src/starters/rust/src/libao.rs index 36b68067d..ea5cd6ee7 100644 --- a/dev-cli/src/starters/rust/src/libao.rs +++ b/dev-cli/src/starters/rust/src/libao.rs @@ -3,7 +3,20 @@ use alloc::string::ToString; use alloc::vec::Vec; use serde_json::{json, Map, Value}; -#[derive(Default)] +pub enum Error { + SerdeError(serde_json::Error), + FailedToGetAuthorities, + FailedToGetTag, + FailedToGetMessageInOutbox, + FailedToGetArrayAsMut, +} + +impl From for Error { + fn from(err: serde_json::Error) -> Error { + Error::SerdeError(err) + } +} + pub struct AO { pub version: String, module: Option, @@ -31,9 +44,9 @@ impl AO { } } - pub fn init(&mut self, env: &str) { + pub fn init(&mut self, env: &str) -> Result<(), Error> { // Parse the environment JSON string into a Value (serde_json's equivalent of cJSON) - let env_json: Value = serde_json::from_str(env).unwrap(); + let env_json: Value = serde_json::from_str(env)?; // Retrieve the "Process" object from the parsed JSON if let Some(process) = env_json.get("Process") { @@ -67,7 +80,10 @@ impl AO { if let Some(name) = tag.get("name").and_then(Value::as_str) { if name == "Authority" { if let Some(value) = tag.get("value").and_then(Value::as_str) { - self.authorities.as_mut().unwrap().push(value.to_string()); + self.authorities + .as_mut() + .ok_or(Error::FailedToGetAuthorities)? + .push(value.to_string()); } } } @@ -76,15 +92,16 @@ impl AO { } } self.clear_outbox(); + Ok(()) } - pub fn normalize(&self, msg: &str) -> String { - let msg_json: Value = serde_json::from_str(msg).unwrap(); - serde_json::to_string(&msg_json).unwrap() + pub fn normalize(&self, msg: &str) -> Result { + let msg_json: Value = serde_json::from_str(msg)?; + Ok(serde_json::to_string(&msg_json)?) } - pub fn sanitize(&self, msg: &str) -> String { - let mut msg_json: Value = serde_json::from_str(msg).unwrap(); + pub fn sanitize(&self, msg: &str) -> Result { + let mut msg_json: Value = serde_json::from_str(msg)?; let mut new_message = Map::new(); // Iterate over each key in the JSON object, excluding non-forwardable tags @@ -93,8 +110,7 @@ impl AO { new_message.insert(key.clone(), value.clone()); } } - - serde_json::to_string(&new_message).unwrap() + Ok(serde_json::to_string(&new_message)?) } pub fn log(&mut self, msg: &str) { @@ -104,8 +120,8 @@ impl AO { } } - pub fn send(&mut self, msg: &str) -> String { - let msg_json: Value = serde_json::from_str(msg).unwrap(); + pub fn send(&mut self, msg: &str) -> Result { + let msg_json: Value = serde_json::from_str(msg)?; self.ref_count += 1; let padded_ref = format!("{:032}", self.ref_count); @@ -130,7 +146,9 @@ impl AO { self.add_tag_to_array( &mut tags_array, name, - tag.get("value").and_then(Value::as_str).unwrap(), + tag.get("value") + .and_then(Value::as_str) + .ok_or(Error::FailedToGetTag)?, ); } } @@ -141,16 +159,16 @@ impl AO { let messages = self .outbox .get_mut("Messages") - .unwrap() + .ok_or(Error::FailedToGetMessageInOutbox)? .as_array_mut() - .unwrap(); + .ok_or(Error::FailedToGetArrayAsMut)?; messages.push(Value::Object(message.clone())); - serde_json::to_string(&message).unwrap() + Ok(serde_json::to_string(&message)?) } - pub fn assign(&mut self, assignment: &str) { - let assignment_json: Value = serde_json::from_str(assignment).unwrap(); + pub fn assign(&mut self, assignment: &str) -> Result<(), Error> { + let assignment_json: Value = serde_json::from_str(assignment)?; let assignments = self .outbox .get_mut("Assignments") @@ -158,6 +176,7 @@ impl AO { .as_array_mut() .unwrap(); assignments.push(assignment_json); + Ok(()) } pub fn is_trusted(&self, msg: &str) -> bool { From 67a221743f6cddd8eb451df6047159f1cd6c1d0f Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Jan 2025 20:10:30 +0800 Subject: [PATCH 12/14] support build with 32bit wasm --- dev-cli/container/src/ao-build-module | 7 ++----- .../src/ao_module_lib/languages/rust.py | 8 +++++--- dev-cli/src/starters/rust/Makefile | 5 ++++- dev-cli/src/starters/rust/src/lib.rs | 16 ++++++++-------- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/dev-cli/container/src/ao-build-module b/dev-cli/container/src/ao-build-module index 715efef5a..34d033062 100644 --- a/dev-cli/container/src/ao-build-module +++ b/dev-cli/container/src/ao-build-module @@ -74,7 +74,7 @@ def main(): # Inject rust files into c_program if language is rust if(language == 'rust'): - c_program = inject_rust_files(definition, c_program) + c_program = inject_rust_files(definition, c_program, config) # Inject lua files into c_program always to load lua files and replace placeholders if(language == 'lua'): @@ -159,10 +159,7 @@ def main(): # shell_exec(*meter_cmd) if config.keep_js is False: - process_js_path = os.path.join(os.getcwd(), 'process.js') - # For rust case, js code is not exists - if os.path.exists(process_js_path): - shell_exec(*['rm', process_js_path]) + shell_exec(*['rm', os.path.join(os.getcwd(), 'process.js')]) if __name__ == '__main__': main() diff --git a/dev-cli/container/src/ao_module_lib/languages/rust.py b/dev-cli/container/src/ao_module_lib/languages/rust.py index 5b0f89cec..6da7cd06a 100644 --- a/dev-cli/container/src/ao_module_lib/languages/rust.py +++ b/dev-cli/container/src/ao_module_lib/languages/rust.py @@ -4,9 +4,10 @@ from ao_module_lib.helper import shell_exec from ao_module_lib.definition import Definition +from ao_module_lib.config import Config RUST_DIR = '/opt/aorustlib' -def inject_rust_files(definition: Definition, c_program: str): +def inject_rust_files(definition: Definition, c_program: str, config: Config): c_header_files = [] # rust_source_files = [] @@ -37,6 +38,7 @@ def inject_rust_files(definition: Definition, c_program: str): # os.chdir(RUST_DIR) # build rust code at '/src' + target = config.target == 64 and 'wasm64-unknown-unknown' or 'wasm32-unknown-unknown' os.environ["RUSTFLAGS"] = "--cfg=web_sys_unstable_apis --Z wasm_c_abi=spec" cmd = [ 'cargo', @@ -44,12 +46,12 @@ def inject_rust_files(definition: Definition, c_program: str): 'build', '-Zbuild-std=std,panic_unwind,panic_abort', # '-Zbuild-std-features=panic_immediate_abort', - '--target=wasm64-unknown-unknown', + f'--target={target}', '--release' ] shell_exec(*cmd) - rust_lib = glob.glob('/src/target/wasm64-unknown-unknown/release/*.a', recursive=True)[0] + rust_lib = glob.glob(f'/src/target/{target}/release/*.a', recursive=True)[0] rust_lib = shutil.copy2(rust_lib, RUST_DIR) cmd = [ diff --git a/dev-cli/src/starters/rust/Makefile b/dev-cli/src/starters/rust/Makefile index d663da2e1..48a5dcf0b 100644 --- a/dev-cli/src/starters/rust/Makefile +++ b/dev-cli/src/starters/rust/Makefile @@ -1,7 +1,7 @@ all:build bindgen build: - RUSTFLAGS="--cfg=web_sys_unstable_apis --Z wasm_c_abi=spec" \ + RUSTFLAGS="--Z wasm_c_abi=spec " \ cargo +nightly build \ -Zbuild-std=std,panic_unwind,panic_abort \ --target=wasm64-unknown-unknown \ @@ -13,3 +13,6 @@ bindgen: clean: cargo clean rm aorust.h + +opt: + wasm-opt --post-emscripten -O3 --low-memory-unused process.wasm --enable-bulk-memory --enable-memory64 --no-validation -o process.wasm diff --git a/dev-cli/src/starters/rust/src/lib.rs b/dev-cli/src/starters/rust/src/lib.rs index 4d5369fe8..4260441ab 100644 --- a/dev-cli/src/starters/rust/src/lib.rs +++ b/dev-cli/src/starters/rust/src/lib.rs @@ -9,15 +9,15 @@ use core::ffi::c_char; use core::ffi::CStr; use dlmalloc::GlobalDlmalloc; -#[global_allocator] -static GLOBAL: GlobalDlmalloc = GlobalDlmalloc; +// #[global_allocator] +// static GLOBAL: GlobalDlmalloc = GlobalDlmalloc; -/// halt the thread on panic; messages are discarded: -#[cfg(not(test))] -#[panic_handler] -fn panic(_info: &core::panic::PanicInfo) -> ! { - loop {} -} +// /// halt the thread on panic; messages are discarded: +// #[cfg(not(test))] +// #[panic_handler] +// fn panic(_info: &core::panic::PanicInfo) -> ! { +// loop {} +// } /// Processes the input `msg` and `env` strings, performs some operations, /// and returns the result as a C-compatible string. From cac077bdf29381610db86e4c85eba5226115c93f Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Jan 2025 20:11:49 +0800 Subject: [PATCH 13/14] use globacl alloc back --- dev-cli/src/starters/rust/src/lib.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dev-cli/src/starters/rust/src/lib.rs b/dev-cli/src/starters/rust/src/lib.rs index 4260441ab..4d5369fe8 100644 --- a/dev-cli/src/starters/rust/src/lib.rs +++ b/dev-cli/src/starters/rust/src/lib.rs @@ -9,15 +9,15 @@ use core::ffi::c_char; use core::ffi::CStr; use dlmalloc::GlobalDlmalloc; -// #[global_allocator] -// static GLOBAL: GlobalDlmalloc = GlobalDlmalloc; +#[global_allocator] +static GLOBAL: GlobalDlmalloc = GlobalDlmalloc; -// /// halt the thread on panic; messages are discarded: -// #[cfg(not(test))] -// #[panic_handler] -// fn panic(_info: &core::panic::PanicInfo) -> ! { -// loop {} -// } +/// halt the thread on panic; messages are discarded: +#[cfg(not(test))] +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} /// Processes the input `msg` and `env` strings, performs some operations, /// and returns the result as a C-compatible string. From 5e296130225958de6ba3094c1949400d3a1901cb Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 20 Jan 2025 21:35:00 +0800 Subject: [PATCH 14/14] added comfig.yaml --- dev-cli/src/starters/rust/Cargo.toml | 1 - dev-cli/src/starters/rust/config.yml | 2 ++ dev-cli/src/starters/rust/src/lib.rs | 12 ------------ 3 files changed, 2 insertions(+), 13 deletions(-) create mode 100644 dev-cli/src/starters/rust/config.yml diff --git a/dev-cli/src/starters/rust/Cargo.toml b/dev-cli/src/starters/rust/Cargo.toml index 7fcdfe4b5..0f6929fda 100644 --- a/dev-cli/src/starters/rust/Cargo.toml +++ b/dev-cli/src/starters/rust/Cargo.toml @@ -9,7 +9,6 @@ crate-type = ["staticlib"] [dependencies] serde = { version = "1.0", default-features = false, features = ["derive"] } serde_json = { version="1.0", default-features = false, features = ["alloc"] } -dlmalloc = { version="0.2.7", default-features = false, features = ["global"] } [profile.dev] panic = "abort" diff --git a/dev-cli/src/starters/rust/config.yml b/dev-cli/src/starters/rust/config.yml new file mode 100644 index 000000000..5e0db7002 --- /dev/null +++ b/dev-cli/src/starters/rust/config.yml @@ -0,0 +1,2 @@ +target: 32 +preset: 'sm' diff --git a/dev-cli/src/starters/rust/src/lib.rs b/dev-cli/src/starters/rust/src/lib.rs index 4d5369fe8..2cbbb7495 100644 --- a/dev-cli/src/starters/rust/src/lib.rs +++ b/dev-cli/src/starters/rust/src/lib.rs @@ -1,4 +1,3 @@ -#![no_std] #[macro_use] extern crate alloc; use alloc::string::String; @@ -7,17 +6,6 @@ pub mod libao; use alloc::ffi::CString; use core::ffi::c_char; use core::ffi::CStr; -use dlmalloc::GlobalDlmalloc; - -#[global_allocator] -static GLOBAL: GlobalDlmalloc = GlobalDlmalloc; - -/// halt the thread on panic; messages are discarded: -#[cfg(not(test))] -#[panic_handler] -fn panic(_info: &core::panic::PanicInfo) -> ! { - loop {} -} /// Processes the input `msg` and `env` strings, performs some operations, /// and returns the result as a C-compatible string.