mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-30 21:02:27 +00:00 
			
		
		
		
	 3698f2279b
			
		
	
	
		3698f2279b
		
			
		
	
	
	
	
		
			
			Add APIs to help prepare the imports for the wasm-c-api `wasm_instance_new`: - wasm_importtype_is_linked - wasm_runtime_is_import_func_linked - wasm_runtime_is_import_global_linked - wasm_extern_new_empty For wasm-c-api, developer may use `wasm_module_imports` to get the import types info, check whether an import func/global is linked with the above API, and ignore the linking of an import func/global with `wasm_extern_new_empty`. Sample `wasm-c-api-import` is added and document is updated.
		
			
				
	
	
		
			204 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2019 Intel Corporation.  All rights reserved.
 | |
|  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
|  */
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <stdio.h>
 | |
| #include "wasm_c_api.h"
 | |
| #include "wasm_export.h"
 | |
| 
 | |
| static wasm_trap_t *
 | |
| host_logs(const wasm_val_vec_t *args, wasm_val_vec_t *results)
 | |
| {
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| static bool
 | |
| build_imports(wasm_store_t *store, const wasm_module_t *module,
 | |
|               wasm_extern_vec_t *out)
 | |
| {
 | |
|     wasm_importtype_vec_t importtypes = { 0 };
 | |
|     wasm_module_imports(module, &importtypes);
 | |
| 
 | |
|     wasm_extern_t *externs[32] = { 0 };
 | |
| 
 | |
|     for (unsigned i = 0; i < importtypes.num_elems; i++) {
 | |
|         wasm_importtype_t *importtype = importtypes.data[i];
 | |
| 
 | |
|         /* use wasm_extern_new_empty() to create a placeholder */
 | |
|         if (wasm_importtype_is_linked(importtype)) {
 | |
|             externs[i] = wasm_extern_new_empty(
 | |
|                 store, wasm_externtype_kind(wasm_importtype_type(importtype)));
 | |
|             continue;
 | |
|         }
 | |
| 
 | |
|         const wasm_name_t *module_name =
 | |
|             wasm_importtype_module(importtypes.data[i]);
 | |
|         const wasm_name_t *field_name =
 | |
|             wasm_importtype_name(importtypes.data[i]);
 | |
| 
 | |
|         if (strncmp(module_name->data, "env", strlen("env")) == 0
 | |
|             && strncmp(field_name->data, "log", strlen("log")) == 0) {
 | |
|             wasm_functype_t *log_type = wasm_functype_new_2_0(
 | |
|                 wasm_valtype_new_i64(), wasm_valtype_new_i32());
 | |
|             wasm_func_t *log_func = wasm_func_new(store, log_type, host_logs);
 | |
|             wasm_functype_delete(log_type);
 | |
| 
 | |
|             externs[i] = wasm_func_as_extern(log_func);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     wasm_extern_vec_new(out, importtypes.num_elems, externs);
 | |
|     wasm_importtype_vec_delete(&importtypes);
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| int
 | |
| main()
 | |
| {
 | |
|     int main_ret = EXIT_FAILURE;
 | |
| 
 | |
|     // Initialize.
 | |
|     printf("Initializing...\n");
 | |
|     wasm_engine_t *engine = wasm_engine_new();
 | |
|     if (!engine)
 | |
|         goto quit;
 | |
| 
 | |
|     wasm_store_t *store = wasm_store_new(engine);
 | |
|     if (!store)
 | |
|         goto delete_engine;
 | |
| 
 | |
|     // Load binary.
 | |
|     printf("Loading binary...\n");
 | |
| #if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
 | |
|     FILE *file = fopen("send_recv.aot", "rb");
 | |
|     printf("> Load .aot\n");
 | |
| #else
 | |
|     FILE *file = fopen("send_recv.wasm", "rb");
 | |
|     printf("> Load .wasm\n");
 | |
| #endif
 | |
|     if (!file) {
 | |
|         printf("> Error loading module!\n");
 | |
|         goto delete_store;
 | |
|     }
 | |
| 
 | |
|     int ret = fseek(file, 0L, SEEK_END);
 | |
|     if (ret == -1) {
 | |
|         printf("> Error loading module!\n");
 | |
|         goto close_file;
 | |
|     }
 | |
| 
 | |
|     long file_size = ftell(file);
 | |
|     if (file_size == -1) {
 | |
|         printf("> Error loading module!\n");
 | |
|         goto close_file;
 | |
|     }
 | |
| 
 | |
|     ret = fseek(file, 0L, SEEK_SET);
 | |
|     if (ret == -1) {
 | |
|         printf("> Error loading module!\n");
 | |
|         goto close_file;
 | |
|     }
 | |
| 
 | |
|     wasm_byte_vec_t binary;
 | |
|     wasm_byte_vec_new_uninitialized(&binary, file_size);
 | |
| 
 | |
|     if (fread(binary.data, file_size, 1, file) != 1) {
 | |
|         printf("> Error loading module!\n");
 | |
|         goto delete_binary;
 | |
|     }
 | |
| 
 | |
|     // Compile.
 | |
|     printf("Compiling module...\n");
 | |
|     wasm_module_t *module = wasm_module_new(store, &binary);
 | |
|     if (!module) {
 | |
|         printf("> Error compiling module!\n");
 | |
|         goto delete_binary;
 | |
|     }
 | |
| 
 | |
|     // Set Wasi Context
 | |
|     const char *addr_pool[1] = { "127.0.0.1" };
 | |
|     wasm_runtime_set_wasi_addr_pool(*module, addr_pool, 1);
 | |
| 
 | |
|     // Instantiate.
 | |
|     printf("Instantiating module...\n");
 | |
|     wasm_extern_vec_t imports = { 0 };
 | |
|     ret = build_imports(store, module, &imports);
 | |
|     if (!ret) {
 | |
|         printf("> Error building imports!\n");
 | |
|         goto delete_module;
 | |
|     }
 | |
| 
 | |
|     wasm_instance_t *instance =
 | |
|         wasm_instance_new(store, module, &imports, NULL);
 | |
|     if (!instance) {
 | |
|         printf("> Error instantiating module!\n");
 | |
|         goto delete_imports;
 | |
|     }
 | |
| 
 | |
|     // Extract export.
 | |
|     printf("Extracting export...\n");
 | |
|     wasm_extern_vec_t exports;
 | |
|     wasm_instance_exports(instance, &exports);
 | |
|     if (exports.size == 0) {
 | |
|         printf("> Error accessing exports!\n");
 | |
|         goto delete_instance;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * should use information from wasm_module_exports to avoid hard coding "1"
 | |
|      */
 | |
|     const wasm_func_t *start_func = wasm_extern_as_func(exports.data[1]);
 | |
|     if (start_func == NULL) {
 | |
|         printf("> Error accessing export!\n");
 | |
|         goto delete_exports;
 | |
|     }
 | |
| 
 | |
|     // Call. "_start(nil) -> i32"
 | |
|     printf("Calling _start ...\n");
 | |
|     wasm_val_t rs[1] = { WASM_I32_VAL(0) };
 | |
|     wasm_val_vec_t args = WASM_EMPTY_VEC;
 | |
|     wasm_val_vec_t results = WASM_ARRAY_VEC(rs);
 | |
|     wasm_trap_t *trap = wasm_func_call(start_func, &args, &results);
 | |
|     if (trap) {
 | |
|         wasm_name_t message = { 0 };
 | |
|         wasm_trap_message(trap, &message);
 | |
| 
 | |
|         printf("> Error calling function! %s\n", message.data);
 | |
| 
 | |
|         wasm_name_delete(&message);
 | |
|         wasm_trap_delete(trap);
 | |
|         goto delete_exports;
 | |
|     }
 | |
| 
 | |
|     // Print result.
 | |
|     printf("Printing result...\n");
 | |
|     printf("> %u\n", rs[0].of.i32);
 | |
| 
 | |
|     // Shut down.
 | |
|     printf("Shutting down...\n");
 | |
| 
 | |
|     // All done.
 | |
|     printf("Done.\n");
 | |
|     main_ret = EXIT_SUCCESS;
 | |
| 
 | |
| delete_exports:
 | |
|     wasm_extern_vec_delete(&exports);
 | |
| delete_instance:
 | |
|     wasm_instance_delete(instance);
 | |
| delete_imports:
 | |
|     wasm_extern_vec_delete(&imports);
 | |
| delete_module:
 | |
|     wasm_module_delete(module);
 | |
| delete_binary:
 | |
|     wasm_byte_vec_delete(&binary);
 | |
| close_file:
 | |
|     fclose(file);
 | |
| delete_store:
 | |
|     wasm_store_delete(store);
 | |
| delete_engine:
 | |
|     wasm_engine_delete(engine);
 | |
| quit:
 | |
|     return main_ret;
 | |
| } |