Support AssemblyScript's new/retain/release APIs (#460)
This commit is contained in:
@ -1681,6 +1681,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
||||
/* Resolve malloc and free function */
|
||||
module->malloc_func_index = (uint32)-1;
|
||||
module->free_func_index = (uint32)-1;
|
||||
module->retain_func_index = (uint32)-1;
|
||||
|
||||
exports = module->exports;
|
||||
for (i = 0; i < module->export_count; i++) {
|
||||
@ -1694,21 +1695,73 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
||||
&& func_type->result_count == 1
|
||||
&& func_type->types[0] == VALUE_TYPE_I32
|
||||
&& func_type->types[1] == VALUE_TYPE_I32) {
|
||||
bh_assert(module->malloc_func_index == (uint32)-1);
|
||||
module->malloc_func_index = func_index;
|
||||
LOG_VERBOSE("Found malloc function, index: %u",
|
||||
exports[i].index);
|
||||
LOG_VERBOSE("Found malloc function, name: %s, index: %u",
|
||||
exports[i].name, exports[i].index);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(exports[i].name, "free")) {
|
||||
else if (!strcmp(exports[i].name, "__new")) {
|
||||
func_index = exports[i].index - module->import_func_count;
|
||||
func_type_index = module->func_type_indexes[func_index];
|
||||
func_type = module->func_types[func_type_index];
|
||||
if (func_type->param_count == 2
|
||||
&& func_type->result_count == 1
|
||||
&& func_type->types[0] == VALUE_TYPE_I32
|
||||
&& func_type->types[1] == VALUE_TYPE_I32
|
||||
&& func_type->types[2] == VALUE_TYPE_I32) {
|
||||
uint32 j;
|
||||
WASMExport *export_tmp;
|
||||
|
||||
bh_assert(module->malloc_func_index == (uint32)-1);
|
||||
module->malloc_func_index = func_index;
|
||||
LOG_VERBOSE("Found malloc function, name: %s, index: %u",
|
||||
exports[i].name, exports[i].index);
|
||||
|
||||
/* resolve retain function.
|
||||
If not find, reset malloc function index */
|
||||
export_tmp = module->exports;
|
||||
for (j = 0; j < module->export_count; j++, export_tmp++) {
|
||||
if ((export_tmp->kind == EXPORT_KIND_FUNC)
|
||||
&& (!strcmp(export_tmp->name, "__retain"))) {
|
||||
func_index = export_tmp->index
|
||||
- module->import_func_count;
|
||||
func_type_index =
|
||||
module->func_type_indexes[func_index];
|
||||
func_type = module->func_types[func_type_index];
|
||||
if (func_type->param_count == 1
|
||||
&& func_type->result_count == 1
|
||||
&& func_type->types[0] == VALUE_TYPE_I32
|
||||
&& func_type->types[1] == VALUE_TYPE_I32) {
|
||||
bh_assert(
|
||||
module->retain_func_index == (uint32)-1);
|
||||
module->retain_func_index = export_tmp->index;
|
||||
LOG_VERBOSE(
|
||||
"Found retain function, name: %s, index: %u",
|
||||
export_tmp->name, export_tmp->index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j == module->export_count) {
|
||||
module->malloc_func_index = (uint32)-1;
|
||||
LOG_VERBOSE("Can't find retain function,"
|
||||
"reset malloc function index to -1");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((!strcmp(exports[i].name, "free"))
|
||||
|| (!strcmp(exports[i].name, "__release"))) {
|
||||
func_index = exports[i].index - module->import_func_count;
|
||||
func_type_index = module->func_type_indexes[func_index];
|
||||
func_type = module->func_types[func_type_index];
|
||||
if (func_type->param_count == 1
|
||||
&& func_type->result_count == 0
|
||||
&& func_type->types[0] == VALUE_TYPE_I32) {
|
||||
bh_assert(module->free_func_index == (uint32)-1);
|
||||
module->free_func_index = func_index;
|
||||
LOG_VERBOSE("Found free function, index: %u",
|
||||
exports[i].index);
|
||||
LOG_VERBOSE("Found free function, name: %s, index: %u",
|
||||
exports[i].name, exports[i].index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2057,6 +2110,7 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
|
||||
|
||||
module->malloc_func_index = comp_data->malloc_func_index;
|
||||
module->free_func_index = comp_data->free_func_index;
|
||||
module->retain_func_index = comp_data->retain_func_index;
|
||||
|
||||
module->aux_data_end_global_index = comp_data->aux_data_end_global_index;
|
||||
module->aux_data_end = comp_data->aux_data_end;
|
||||
|
||||
@ -1263,23 +1263,39 @@ aot_clear_exception(AOTModuleInstance *module_inst)
|
||||
static bool
|
||||
execute_malloc_function(AOTModuleInstance *module_inst,
|
||||
AOTFunctionInstance *malloc_func,
|
||||
AOTFunctionInstance *retain_func,
|
||||
uint32 size, uint32 *p_result)
|
||||
{
|
||||
uint32 argv[2];
|
||||
uint32 argv[2], argc;
|
||||
bool ret;
|
||||
|
||||
argv[0] = size;
|
||||
argc = 1;
|
||||
if (retain_func) {
|
||||
argv[1] = 0;
|
||||
argc = 2;
|
||||
}
|
||||
|
||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||
if (aot_exec_env != NULL) {
|
||||
bh_assert(aot_exec_env->module_inst
|
||||
== (WASMModuleInstanceCommon *)module_inst);
|
||||
ret = aot_call_function(aot_exec_env, malloc_func, 1, argv);
|
||||
ret = aot_call_function(aot_exec_env, malloc_func, argc, argv);
|
||||
|
||||
if (retain_func && ret) {
|
||||
ret = aot_call_function(aot_exec_env, retain_func, 1, argv);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = aot_create_exec_env_and_call_function
|
||||
(module_inst, malloc_func, 1, argv);
|
||||
(module_inst, malloc_func, argc, argv);
|
||||
|
||||
if (retain_func && ret) {
|
||||
ret = aot_create_exec_env_and_call_function
|
||||
(module_inst, retain_func, 1, argv);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
@ -1328,11 +1344,27 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
|
||||
}
|
||||
else if (module->malloc_func_index != (uint32)-1
|
||||
&& module->free_func_index != (uint32)-1) {
|
||||
AOTFunctionInstance *malloc_func =
|
||||
aot_lookup_function(module_inst, "malloc", "(i)i");
|
||||
AOTFunctionInstance *malloc_func, *retain_func = NULL;
|
||||
char *malloc_func_name;
|
||||
char *malloc_func_sig;
|
||||
|
||||
if (module->retain_func_index != (uint32)-1) {
|
||||
malloc_func_name = "__new";
|
||||
malloc_func_sig = "(ii)i";
|
||||
retain_func =
|
||||
aot_lookup_function(module_inst, "__retain", "(i)i");
|
||||
bh_assert(retain_func);
|
||||
}
|
||||
else {
|
||||
malloc_func_name = "malloc";
|
||||
malloc_func_sig = "(i)i";
|
||||
}
|
||||
malloc_func =
|
||||
aot_lookup_function(module_inst,
|
||||
malloc_func_name, malloc_func_sig);
|
||||
|
||||
bh_assert(malloc_func);
|
||||
if (!execute_malloc_function(module_inst, malloc_func,
|
||||
if (!execute_malloc_function(module_inst, malloc_func, retain_func,
|
||||
size, &offset)) {
|
||||
return 0;
|
||||
}
|
||||
@ -1371,8 +1403,17 @@ aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
|
||||
&& module->free_func_index != (uint32)-1
|
||||
&& (uint8 *)memory_inst->memory_data.ptr <= addr
|
||||
&& addr < (uint8 *)memory_inst->memory_data_end.ptr) {
|
||||
AOTFunctionInstance *free_func =
|
||||
aot_lookup_function(module_inst, "free", "(i)i");
|
||||
AOTFunctionInstance *free_func;
|
||||
char *free_func_name;
|
||||
|
||||
if (module->retain_func_index != (uint32)-1) {
|
||||
free_func_name = "__release";
|
||||
}
|
||||
else {
|
||||
free_func_name = "free";
|
||||
}
|
||||
free_func =
|
||||
aot_lookup_function(module_inst, free_func_name, "(i)i");
|
||||
|
||||
bh_assert(free_func);
|
||||
execute_free_function(module_inst, free_func, ptr);
|
||||
|
||||
@ -149,6 +149,7 @@ typedef struct AOTModule {
|
||||
|
||||
uint32 malloc_func_index;
|
||||
uint32 free_func_index;
|
||||
uint32 retain_func_index;
|
||||
|
||||
/* AOTed code, NULL for JIT mode */
|
||||
void *code;
|
||||
|
||||
Reference in New Issue
Block a user