WebAssembly Micro Runtime first version
This commit is contained in:
92
core/iwasm/runtime/vmcore_wasm/invokeNative_general.c
Normal file
92
core/iwasm/runtime/vmcore_wasm/invokeNative_general.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "wasm-runtime.h"
|
||||
|
||||
void invokeNative(uint32 argv[], uint32 argc, void (*native_code)())
|
||||
{
|
||||
WASMThread *self;
|
||||
switch(argc) {
|
||||
case 0:
|
||||
native_code();
|
||||
break;
|
||||
case 1:
|
||||
native_code(argv[0]);
|
||||
break;
|
||||
case 2:
|
||||
native_code(argv[0], argv[1]);
|
||||
break;
|
||||
case 3:
|
||||
native_code(argv[0], argv[1], argv[2]);
|
||||
break;
|
||||
case 4:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3]);
|
||||
break;
|
||||
case 5:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4]);
|
||||
break;
|
||||
case 6:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
|
||||
break;
|
||||
case 7:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
|
||||
break;
|
||||
case 8:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
|
||||
break;
|
||||
case 9:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
|
||||
break;
|
||||
case 10:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
|
||||
break;
|
||||
case 11:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
|
||||
break;
|
||||
case 12:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]);
|
||||
break;
|
||||
case 13:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]);
|
||||
break;
|
||||
case 14:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]);
|
||||
break;
|
||||
case 15:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]);
|
||||
break;
|
||||
case 16:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15]);
|
||||
break;
|
||||
case 17:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16]);
|
||||
break;
|
||||
case 18:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17]);
|
||||
break;
|
||||
case 19:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18]);
|
||||
break;
|
||||
case 20:
|
||||
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18], argv[19]);
|
||||
break;
|
||||
default:
|
||||
/* FIXME: If this happen, add more cases. */
|
||||
self = wasm_runtime_get_self();
|
||||
wasm_runtime_set_exception(self->module_inst, "the argument number of native function exceeds maximum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
56
core/iwasm/runtime/vmcore_wasm/invokeNative_ia32.s
Normal file
56
core/iwasm/runtime/vmcore_wasm/invokeNative_ia32.s
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
// contributor license agreements. See the NOTICE file distributed with
|
||||
// this work for additional information regarding copyright ownership.
|
||||
// The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
// (the "License"); you may not use this file except in compliance with
|
||||
// the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Author: Ivan Volosyuk
|
||||
//
|
||||
.text
|
||||
.align 2
|
||||
.globl invokeNative
|
||||
.type invokeNative, @function
|
||||
invokeNative:
|
||||
|
||||
push %ebp
|
||||
movl %esp, %ebp
|
||||
push %ecx
|
||||
movl 8(%ebp), %eax /* eax = argv */
|
||||
movl 12(%ebp), %ecx /* ecx = argc */
|
||||
test %ecx, %ecx
|
||||
je restore_ecx /* if ecx == 0, skip pushing arguments */
|
||||
leal -4(%eax,%ecx,4), %eax /* eax = eax + ecx * 4 - 4 */
|
||||
subl %esp, %eax /* eax = eax - esp */
|
||||
1:
|
||||
push 0(%esp,%eax)
|
||||
loop 1b /* loop ecx counts */
|
||||
restore_ecx:
|
||||
movl -4(%ebp), %ecx /* restore ecx */
|
||||
movl 16(%ebp), %eax /* eax = func_ptr */
|
||||
call *%eax
|
||||
leave
|
||||
ret
|
||||
|
||||
28
core/iwasm/runtime/vmcore_wasm/vmcore.cmake
Normal file
28
core/iwasm/runtime/vmcore_wasm/vmcore.cmake
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set (VMCORE_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${VMCORE_LIB_DIR})
|
||||
include_directories(${VMCORE_LIB_DIR}/../include)
|
||||
|
||||
if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES")
|
||||
file (GLOB_RECURSE source_all ${VMCORE_LIB_DIR}/*.c)
|
||||
else ()
|
||||
file (GLOB_RECURSE source_all ${VMCORE_LIB_DIR}/*.c ${VMCORE_LIB_DIR}/*.s)
|
||||
list (REMOVE_ITEM source_all ${VMCORE_LIB_DIR}/invokeNative_general.c)
|
||||
endif ()
|
||||
|
||||
set (VMCORE_LIB_SOURCE ${source_all})
|
||||
|
||||
390
core/iwasm/runtime/vmcore_wasm/wasm-application.c
Normal file
390
core/iwasm/runtime/vmcore_wasm/wasm-application.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "wasm.h"
|
||||
#include "wasm-interp.h"
|
||||
#include "wasm-runtime.h"
|
||||
#include "wasm-thread.h"
|
||||
#include "wasm_assert.h"
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "wasm_platform_log.h"
|
||||
|
||||
|
||||
static WASMFunctionInstance*
|
||||
resolve_main_function(const WASMModuleInstance *module_inst)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < module_inst->export_func_count; i++)
|
||||
if (!strcmp(module_inst->export_functions[i].name, "_main")
|
||||
|| !strcmp(module_inst->export_functions[i].name, "main"))
|
||||
return module_inst->export_functions[i].function;
|
||||
|
||||
LOG_ERROR("WASM execute application failed: main function not found.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_main_func_type(const WASMType *type)
|
||||
{
|
||||
if (!(type->param_count == 0 || type->param_count == 2)
|
||||
||type->result_count > 1) {
|
||||
LOG_ERROR("WASM execute application failed: invalid main function type.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type->param_count == 2
|
||||
&& !(type->types[0] == VALUE_TYPE_I32
|
||||
&& type->types[1] == VALUE_TYPE_I32)) {
|
||||
LOG_ERROR("WASM execute application failed: invalid main function type.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type->result_count
|
||||
&& type->types[type->param_count] != VALUE_TYPE_I32) {
|
||||
LOG_ERROR("WASM execute application failed: invalid main function type.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_application_execute_main(WASMModuleInstance *module_inst,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
WASMFunctionInstance *func = resolve_main_function(module_inst);
|
||||
uint32 argc1 = 0, argv1[2] = { 0 };
|
||||
uint32 total_argv_size = 0, total_size;
|
||||
int32 argv_buf_offset, i;
|
||||
char *argv_buf, *p;
|
||||
int32 *argv_offsets;
|
||||
|
||||
if (!func || func->is_import_func)
|
||||
return false;
|
||||
|
||||
if (!check_main_func_type(func->u.func->func_type))
|
||||
return false;
|
||||
|
||||
if (func->u.func->func_type->param_count) {
|
||||
for (i = 0; i < argc; i++)
|
||||
total_argv_size += strlen(argv[i]) + 1;
|
||||
total_argv_size = align_uint(total_argv_size, 4);
|
||||
|
||||
total_size = total_argv_size + sizeof(int32) * argc;
|
||||
|
||||
if (!(argv_buf_offset = wasm_runtime_module_malloc(module_inst, total_size)))
|
||||
return false;
|
||||
|
||||
argv_buf = p = wasm_runtime_addr_app_to_native(module_inst, argv_buf_offset);
|
||||
argv_offsets = (int32*)(p + total_argv_size);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
memcpy(p, argv[i], strlen(argv[i]) + 1);
|
||||
argv_offsets[i] = argv_buf_offset + (p - argv_buf);
|
||||
p += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
argc1 = 2;
|
||||
argv1[0] = argc;
|
||||
argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
|
||||
}
|
||||
|
||||
return wasm_runtime_call_wasm(module_inst, NULL, func, argc1, argv1);
|
||||
}
|
||||
|
||||
static WASMFunctionInstance*
|
||||
resolve_function(const WASMModuleInstance *module_inst, char *name)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < module_inst->export_func_count; i++)
|
||||
if (!strcmp(module_inst->export_functions[i].name, name))
|
||||
return module_inst->export_functions[i].function;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
union ieee754_float {
|
||||
float f;
|
||||
|
||||
/* This is the IEEE 754 single-precision format. */
|
||||
union {
|
||||
struct {
|
||||
unsigned int negative:1;
|
||||
unsigned int exponent:8;
|
||||
unsigned int mantissa:23;
|
||||
} ieee_big_endian;
|
||||
struct {
|
||||
unsigned int mantissa:23;
|
||||
unsigned int exponent:8;
|
||||
unsigned int negative:1;
|
||||
} ieee_little_endian;
|
||||
} ieee;
|
||||
};
|
||||
|
||||
union ieee754_double {
|
||||
double d;
|
||||
|
||||
/* This is the IEEE 754 double-precision format. */
|
||||
union {
|
||||
struct {
|
||||
unsigned int negative:1;
|
||||
unsigned int exponent:11;
|
||||
/* Together these comprise the mantissa. */
|
||||
unsigned int mantissa0:20;
|
||||
unsigned int mantissa1:32;
|
||||
} ieee_big_endian;
|
||||
|
||||
struct {
|
||||
/* Together these comprise the mantissa. */
|
||||
unsigned int mantissa1:32;
|
||||
unsigned int mantissa0:20;
|
||||
unsigned int exponent:11;
|
||||
unsigned int negative:1;
|
||||
} ieee_little_endian;
|
||||
} ieee;
|
||||
};
|
||||
|
||||
bool
|
||||
wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
char *name, int argc, char *argv[])
|
||||
{
|
||||
WASMFunctionInstance *func;
|
||||
WASMType *type;
|
||||
uint32 argc1, *argv1;
|
||||
int32 i, p;
|
||||
const char *exception;
|
||||
|
||||
wasm_assert(argc >= 0);
|
||||
func = resolve_function(module_inst, name);
|
||||
if (!func || func->is_import_func) {
|
||||
LOG_ERROR("Wasm lookup function %s failed.\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
type = func->u.func->func_type;
|
||||
if (type->param_count != (uint32)argc) {
|
||||
LOG_ERROR("Wasm prepare param failed: invalid param count.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
argc1 = func->param_cell_num;
|
||||
argv1 = wasm_malloc(sizeof(uint32) * (argc1 > 2 ? argc1 : 2));
|
||||
if (argv1 == NULL) {
|
||||
LOG_ERROR("Wasm prepare param failed: malloc failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Parse arguments */
|
||||
for (i = 0, p = 0; i < argc; i++) {
|
||||
char *endptr;
|
||||
wasm_assert(argv[i] != NULL);
|
||||
if (argv[i][0] == '\0') {
|
||||
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
switch (type->types[i]) {
|
||||
case VALUE_TYPE_I32:
|
||||
argv1[p++] = strtoul(argv[i], &endptr, 0);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
{
|
||||
union { uint64 val; uint32 parts[2]; } u;
|
||||
u.val = strtoull(argv[i], &endptr, 0);
|
||||
argv1[p++] = u.parts[0];
|
||||
argv1[p++] = u.parts[1];
|
||||
break;
|
||||
}
|
||||
case VALUE_TYPE_F32:
|
||||
{
|
||||
float32 f32 = strtof(argv[i], &endptr);
|
||||
if (isnan(f32)) {
|
||||
if (argv[i][0] == '-') {
|
||||
f32 = -f32;
|
||||
}
|
||||
if (endptr[0] == ':') {
|
||||
uint32 sig;
|
||||
union ieee754_float u;
|
||||
sig = strtoul(endptr + 1, &endptr, 0);
|
||||
u.f = f32;
|
||||
if (is_little_endian)
|
||||
u.ieee.ieee_little_endian.mantissa = sig;
|
||||
else
|
||||
u.ieee.ieee_big_endian.mantissa = sig;
|
||||
f32 = u.f;
|
||||
}
|
||||
}
|
||||
*(float32*)&argv1[p++] = f32;
|
||||
break;
|
||||
}
|
||||
case VALUE_TYPE_F64:
|
||||
{
|
||||
union { float64 val; uint32 parts[2]; } u;
|
||||
u.val = strtod(argv[i], &endptr);
|
||||
if (isnan(u.val)) {
|
||||
if (argv[i][0] == '-') {
|
||||
u.val = -u.val;
|
||||
}
|
||||
if (endptr[0] == ':') {
|
||||
uint64 sig;
|
||||
union ieee754_double ud;
|
||||
sig = strtoull(endptr + 1, &endptr, 0);
|
||||
ud.d = u.val;
|
||||
if (is_little_endian) {
|
||||
ud.ieee.ieee_little_endian.mantissa0 = sig >> 32;
|
||||
ud.ieee.ieee_little_endian.mantissa1 = sig;
|
||||
}
|
||||
else {
|
||||
ud.ieee.ieee_big_endian.mantissa0 = sig >> 32;
|
||||
ud.ieee.ieee_big_endian.mantissa1 = sig;
|
||||
}
|
||||
u.val = ud.d;
|
||||
}
|
||||
}
|
||||
argv1[p++] = u.parts[0];
|
||||
argv1[p++] = u.parts[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*endptr != '\0' && *endptr != '_') {
|
||||
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
if (errno != 0) {
|
||||
LOG_ERROR("Wasm prepare param failed: errno %d.\n", errno);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
wasm_assert(p == (int32)argc1);
|
||||
|
||||
wasm_runtime_set_exception(module_inst, NULL);
|
||||
if (!wasm_runtime_call_wasm(module_inst, NULL, func, argc1, argv1)) {
|
||||
exception = wasm_runtime_get_exception(module_inst);
|
||||
wasm_printf("%s\n", exception);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* print return value */
|
||||
switch (type->types[type->param_count]) {
|
||||
case VALUE_TYPE_I32:
|
||||
wasm_printf("0x%x:i32", argv1[0]);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
{
|
||||
union { uint64 val; uint32 parts[2]; } u;
|
||||
u.parts[0] = argv1[0];
|
||||
u.parts[1] = argv1[1];
|
||||
wasm_printf("0x%llx:i64", u.val);
|
||||
break;
|
||||
}
|
||||
case VALUE_TYPE_F32:
|
||||
wasm_printf("%.7g:f32", *(float32*)argv1);
|
||||
break;
|
||||
case VALUE_TYPE_F64:
|
||||
{
|
||||
union { float64 val; uint32 parts[2]; } u;
|
||||
u.parts[0] = argv1[0];
|
||||
u.parts[1] = argv1[1];
|
||||
wasm_printf("%.7g:f64", u.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
wasm_printf("\n");
|
||||
|
||||
wasm_free(argv1);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
wasm_free(argv1);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_type(uint8 type, const char *p)
|
||||
{
|
||||
const char *str = "i32";
|
||||
|
||||
if (strlen(p) < 3)
|
||||
return false;
|
||||
|
||||
switch (type) {
|
||||
case VALUE_TYPE_I32:
|
||||
str = "i32";
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
str = "i64";
|
||||
break;
|
||||
case VALUE_TYPE_F32:
|
||||
str = "f32";
|
||||
break;
|
||||
case VALUE_TYPE_F64:
|
||||
str = "f64";
|
||||
break;
|
||||
}
|
||||
if (strncmp(p, str, 3))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_function_type(const WASMType *type,
|
||||
const char *signature)
|
||||
{
|
||||
uint32 i;
|
||||
const char *p = signature;
|
||||
|
||||
if (!p || *p++ != '(')
|
||||
return false;
|
||||
|
||||
for (i = 0; i < type->param_count; i++) {
|
||||
if (!check_type(type->types[i], p))
|
||||
return false;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
if (*p++ != ')')
|
||||
return false;
|
||||
|
||||
if (type->result_count) {
|
||||
if (!check_type(type->types[type->param_count], p))
|
||||
return false;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
if (*p != '\0')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
WASMFunctionInstance*
|
||||
wasm_runtime_lookup_function(const WASMModuleInstance *module_inst,
|
||||
const char *name,
|
||||
const char *signature)
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < module_inst->export_func_count; i++)
|
||||
if (!strcmp(module_inst->export_functions[i].name, name)
|
||||
&& check_function_type(
|
||||
module_inst->export_functions[i].function->u.func->func_type,
|
||||
signature))
|
||||
return module_inst->export_functions[i].function;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
2160
core/iwasm/runtime/vmcore_wasm/wasm-interp.c
Normal file
2160
core/iwasm/runtime/vmcore_wasm/wasm-interp.c
Normal file
File diff suppressed because it is too large
Load Diff
79
core/iwasm/runtime/vmcore_wasm/wasm-interp.h
Normal file
79
core/iwasm/runtime/vmcore_wasm/wasm-interp.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _WASM_INTERP_H
|
||||
#define _WASM_INTERP_H
|
||||
|
||||
#include "wasm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct WASMFunctionInstance;
|
||||
|
||||
typedef struct WASMInterpFrame {
|
||||
/* The frame of the caller that are calling the current function. */
|
||||
struct WASMInterpFrame *prev_frame;
|
||||
|
||||
/* The current WASM function. */
|
||||
struct WASMFunctionInstance *function;
|
||||
|
||||
/* Instruction pointer of the bytecode array. */
|
||||
uint8 *ip;
|
||||
|
||||
/* Operand stack top pointer of the current frame. The bottom of
|
||||
the stack is the next cell after the last local variable. */
|
||||
uint32 *sp_bottom;
|
||||
uint32 *sp_boundary;
|
||||
uint32 *sp;
|
||||
|
||||
WASMBranchBlock *csp_bottom;
|
||||
WASMBranchBlock *csp_boundary;
|
||||
WASMBranchBlock *csp;
|
||||
|
||||
/* Frame data, the layout is:
|
||||
lp: param_cell_count + local_cell_count
|
||||
sp_bottom to sp_boundary: stack of data
|
||||
csp_bottom to csp_boundary: stack of block
|
||||
ref to frame end: data types of local vairables and stack data
|
||||
*/
|
||||
uint32 lp[1];
|
||||
} WASMInterpFrame;
|
||||
|
||||
/**
|
||||
* Calculate the size of interpreter area of frame of a function.
|
||||
*
|
||||
* @param all_cell_num number of all cells including local variables
|
||||
* and the working stack slots
|
||||
*
|
||||
* @return the size of interpreter area of the frame
|
||||
*/
|
||||
static inline unsigned
|
||||
wasm_interp_interp_frame_size(unsigned all_cell_num)
|
||||
{
|
||||
return align_uint(offsetof(WASMInterpFrame, lp) + all_cell_num * 5, 4);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_interp_call_wasm(struct WASMFunctionInstance *function,
|
||||
uint32 argc, uint32 argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_INTERP_H */
|
||||
2874
core/iwasm/runtime/vmcore_wasm/wasm-loader.c
Normal file
2874
core/iwasm/runtime/vmcore_wasm/wasm-loader.c
Normal file
File diff suppressed because it is too large
Load Diff
92
core/iwasm/runtime/vmcore_wasm/wasm-loader.h
Normal file
92
core/iwasm/runtime/vmcore_wasm/wasm-loader.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef _WASM_LOADER_H
|
||||
#define _WASM_LOADER_H
|
||||
|
||||
#include "wasm.h"
|
||||
#include "wasm_hashmap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Load a WASM module from a specified byte buffer.
|
||||
*
|
||||
* @param buf the byte buffer which contains the WASM binary data
|
||||
* @param size the size of the buffer
|
||||
* @param error_buf output of the exception info
|
||||
* @param error_buf_size the size of the exception string
|
||||
*
|
||||
* @return return module loaded, NULL if failed
|
||||
*/
|
||||
WASMModule*
|
||||
wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size);
|
||||
|
||||
/**
|
||||
* Load a WASM module from a specified WASM section list.
|
||||
*
|
||||
* @param section_list the section list which contains each section data
|
||||
* @param error_buf output of the exception info
|
||||
* @param error_buf_size the size of the exception string
|
||||
*
|
||||
* @return return WASM module loaded, NULL if failed
|
||||
*/
|
||||
WASMModule*
|
||||
wasm_loader_load_from_sections(WASMSection *section_list,
|
||||
char *error_buf, uint32_t error_buf_size);
|
||||
|
||||
/**
|
||||
* Unload a WASM module.
|
||||
*
|
||||
* @param module the module to be unloaded
|
||||
*/
|
||||
void
|
||||
wasm_loader_unload(WASMModule *module);
|
||||
|
||||
/**
|
||||
* Find address of related else opcode and end opcode of opcode block/loop/if
|
||||
* according to the start address of opcode.
|
||||
*
|
||||
* @param branch_set the hashtable to store the else/end adress info of
|
||||
* block/loop/if opcode. The function will lookup the hashtable firstly,
|
||||
* if not found, it will then search the code from start_addr, and if success,
|
||||
* stores the result to the hashtable.
|
||||
* @param start_addr the next address of opcode block/loop/if
|
||||
* @param code_end_addr the end address of function code block
|
||||
* @param block_type the type of block, 0/1/2 denotes block/loop/if
|
||||
* @param p_else_addr returns the else addr if found
|
||||
* @param p_end_addr returns the end addr if found
|
||||
* @param error_buf returns the error log for this function
|
||||
* @param error_buf_size returns the error log string length
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
wasm_loader_find_block_addr(HashMap *map,
|
||||
const uint8 *start_addr,
|
||||
const uint8 *code_end_addr,
|
||||
uint8 block_type,
|
||||
uint8 **p_else_addr,
|
||||
uint8 **p_end_addr,
|
||||
char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_LOADER_H */
|
||||
66
core/iwasm/runtime/vmcore_wasm/wasm-native.h
Normal file
66
core/iwasm/runtime/vmcore_wasm/wasm-native.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _WASM_NATIVE_H
|
||||
#define _WASM_NATIVE_H
|
||||
|
||||
#include "wasm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the native module, e.g. sort the function defs
|
||||
* and the global defs.
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
wasm_native_init();
|
||||
|
||||
/**
|
||||
* Lookup native function implementation of a given import function.
|
||||
*
|
||||
* @param module_name the module name of the import function
|
||||
* @param func_name the function name of the import function
|
||||
*
|
||||
* @return return the native function pointer if success, NULL otherwise
|
||||
*/
|
||||
void*
|
||||
wasm_native_func_lookup(const char *module_name, const char *func_name);
|
||||
|
||||
/**
|
||||
* Lookup global variable of a given import global
|
||||
*
|
||||
* @param module_name the module name of the import global
|
||||
* @param global_name the global name of the import global
|
||||
* @param global return the global data
|
||||
*
|
||||
* @param return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
wasm_native_global_lookup(const char *module_name, const char *global_name,
|
||||
WASMGlobalImport *global);
|
||||
|
||||
void* wasm_platform_native_func_lookup(const char *module_name,
|
||||
const char *func_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_NATIVE_H */
|
||||
472
core/iwasm/runtime/vmcore_wasm/wasm-opcode.h
Normal file
472
core/iwasm/runtime/vmcore_wasm/wasm-opcode.h
Normal file
@ -0,0 +1,472 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _WASM_OPCODE_H
|
||||
#define _WASM_OPCODE_H
|
||||
|
||||
#include "wasm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum WASMOpcode {
|
||||
/* control instructions */
|
||||
WASM_OP_UNREACHABLE = 0x00, /* unreachable */
|
||||
WASM_OP_NOP = 0x01, /* nop */
|
||||
WASM_OP_BLOCK = 0x02, /* block */
|
||||
WASM_OP_LOOP = 0x03, /* loop */
|
||||
WASM_OP_IF = 0x04, /* if */
|
||||
WASM_OP_ELSE = 0x05, /* else */
|
||||
|
||||
WASM_OP_UNUSED_0x06 = 0x06,
|
||||
WASM_OP_UNUSED_0x07 = 0x07,
|
||||
WASM_OP_UNUSED_0x08 = 0x08,
|
||||
WASM_OP_UNUSED_0x09 = 0x09,
|
||||
WASM_OP_UNUSED_0x0a = 0x0a,
|
||||
|
||||
WASM_OP_END = 0x0b, /* end */
|
||||
WASM_OP_BR = 0x0c, /* br */
|
||||
WASM_OP_BR_IF = 0x0d, /* br if */
|
||||
WASM_OP_BR_TABLE = 0x0e, /* br table */
|
||||
WASM_OP_RETURN = 0x0f, /* return */
|
||||
WASM_OP_CALL = 0x10, /* call */
|
||||
WASM_OP_CALL_INDIRECT = 0x11, /* call_indirect */
|
||||
|
||||
WASM_OP_UNUSED_0x12 = 0x12,
|
||||
WASM_OP_UNUSED_0x13 = 0x13,
|
||||
WASM_OP_UNUSED_0x14 = 0x14,
|
||||
WASM_OP_UNUSED_0x15 = 0x15,
|
||||
WASM_OP_UNUSED_0x16 = 0x16,
|
||||
WASM_OP_UNUSED_0x17 = 0x17,
|
||||
WASM_OP_UNUSED_0x18 = 0x18,
|
||||
WASM_OP_UNUSED_0x19 = 0x19,
|
||||
|
||||
/* parametric instructions */
|
||||
WASM_OP_DROP = 0x1a, /* drop */
|
||||
WASM_OP_SELECT = 0x1b, /* select */
|
||||
|
||||
WASM_OP_UNUSED_0x1c = 0x1c,
|
||||
WASM_OP_UNUSED_0x1d = 0x1d,
|
||||
WASM_OP_UNUSED_0x1e = 0x1e,
|
||||
WASM_OP_UNUSED_0x1f = 0x1f,
|
||||
|
||||
/* variable instructions */
|
||||
WASM_OP_GET_LOCAL = 0x20, /* get_local */
|
||||
WASM_OP_SET_LOCAL = 0x21, /* set_local */
|
||||
WASM_OP_TEE_LOCAL = 0x22, /* tee_local */
|
||||
WASM_OP_GET_GLOBAL = 0x23, /* get_global */
|
||||
WASM_OP_SET_GLOBAL = 0x24, /* set_global */
|
||||
|
||||
WASM_OP_UNUSED_0x25 = 0x25,
|
||||
WASM_OP_UNUSED_0x26 = 0x26,
|
||||
WASM_OP_UNUSED_0x27 = 0x27,
|
||||
|
||||
/* memory instructions */
|
||||
WASM_OP_I32_LOAD = 0x28, /* i32.load */
|
||||
WASM_OP_I64_LOAD = 0x29, /* i64.load */
|
||||
WASM_OP_F32_LOAD = 0x2a, /* f32.load */
|
||||
WASM_OP_F64_LOAD = 0x2b, /* f64.load */
|
||||
WASM_OP_I32_LOAD8_S = 0x2c, /* i32.load8_s */
|
||||
WASM_OP_I32_LOAD8_U = 0x2d, /* i32.load8_u */
|
||||
WASM_OP_I32_LOAD16_S = 0x2e, /* i32.load16_s */
|
||||
WASM_OP_I32_LOAD16_U = 0x2f, /* i32.load16_u */
|
||||
WASM_OP_I64_LOAD8_S = 0x30, /* i64.load8_s */
|
||||
WASM_OP_I64_LOAD8_U = 0x31, /* i64.load8_u */
|
||||
WASM_OP_I64_LOAD16_S = 0x32, /* i64.load16_s */
|
||||
WASM_OP_I64_LOAD16_U = 0x33, /* i64.load16_u */
|
||||
WASM_OP_I64_LOAD32_S = 0x34, /* i32.load32_s */
|
||||
WASM_OP_I64_LOAD32_U = 0x35, /* i32.load32_u */
|
||||
WASM_OP_I32_STORE = 0x36, /* i32.store */
|
||||
WASM_OP_I64_STORE = 0x37, /* i64.store */
|
||||
WASM_OP_F32_STORE = 0x38, /* f32.store */
|
||||
WASM_OP_F64_STORE = 0x39, /* f64.store */
|
||||
WASM_OP_I32_STORE8 = 0x3a, /* i32.store8 */
|
||||
WASM_OP_I32_STORE16 = 0x3b, /* i32.store16 */
|
||||
WASM_OP_I64_STORE8 = 0x3c, /* i64.store8 */
|
||||
WASM_OP_I64_STORE16 = 0x3d, /* i64.sotre16 */
|
||||
WASM_OP_I64_STORE32 = 0x3e, /* i64.store32 */
|
||||
WASM_OP_MEMORY_SIZE = 0x3f, /* memory.size */
|
||||
WASM_OP_MEMORY_GROW = 0x40, /* memory.grow */
|
||||
|
||||
/* constant instructions */
|
||||
WASM_OP_I32_CONST = 0x41, /* i32.const */
|
||||
WASM_OP_I64_CONST = 0x42, /* i64.const */
|
||||
WASM_OP_F32_CONST = 0x43, /* f32.const */
|
||||
WASM_OP_F64_CONST = 0x44, /* f64.const */
|
||||
|
||||
/* comparison instructions */
|
||||
WASM_OP_I32_EQZ = 0x45, /* i32.eqz */
|
||||
WASM_OP_I32_EQ = 0x46, /* i32.eq */
|
||||
WASM_OP_I32_NE = 0x47, /* i32.ne */
|
||||
WASM_OP_I32_LT_S = 0x48, /* i32.lt_s */
|
||||
WASM_OP_I32_LT_U = 0x49, /* i32.lt_u */
|
||||
WASM_OP_I32_GT_S = 0x4a, /* i32.gt_s */
|
||||
WASM_OP_I32_GT_U = 0x4b, /* i32.gt_u */
|
||||
WASM_OP_I32_LE_S = 0x4c, /* i32.le_s */
|
||||
WASM_OP_I32_LE_U = 0x4d, /* i32.le_u */
|
||||
WASM_OP_I32_GE_S = 0x4e, /* i32.ge_s */
|
||||
WASM_OP_I32_GE_U = 0x4f, /* i32.ge_u */
|
||||
|
||||
WASM_OP_I64_EQZ = 0x50, /* i64.eqz */
|
||||
WASM_OP_I64_EQ = 0x51, /* i64.eq */
|
||||
WASM_OP_I64_NE = 0x52, /* i64.ne */
|
||||
WASM_OP_I64_LT_S = 0x53, /* i64.lt_s */
|
||||
WASM_OP_I64_LT_U = 0x54, /* i64.lt_u */
|
||||
WASM_OP_I64_GT_S = 0x55, /* i64.gt_s */
|
||||
WASM_OP_I64_GT_U = 0x56, /* i64.gt_u */
|
||||
WASM_OP_I64_LE_S = 0x57, /* i64.le_s */
|
||||
WASM_OP_I64_LE_U = 0x58, /* i64.le_u */
|
||||
WASM_OP_I64_GE_S = 0x59, /* i64.ge_s */
|
||||
WASM_OP_I64_GE_U = 0x5a, /* i64.ge_u */
|
||||
|
||||
WASM_OP_F32_EQ = 0x5b, /* f32.eq */
|
||||
WASM_OP_F32_NE = 0x5c, /* f32.ne */
|
||||
WASM_OP_F32_LT = 0x5d, /* f32.lt */
|
||||
WASM_OP_F32_GT = 0x5e, /* f32.gt */
|
||||
WASM_OP_F32_LE = 0x5f, /* f32.le */
|
||||
WASM_OP_F32_GE = 0x60, /* f32.ge */
|
||||
|
||||
WASM_OP_F64_EQ = 0x61, /* f64.eq */
|
||||
WASM_OP_F64_NE = 0x62, /* f64.ne */
|
||||
WASM_OP_F64_LT = 0x63, /* f64.lt */
|
||||
WASM_OP_F64_GT = 0x64, /* f64.gt */
|
||||
WASM_OP_F64_LE = 0x65, /* f64.le */
|
||||
WASM_OP_F64_GE = 0x66, /* f64.ge */
|
||||
|
||||
/* numeric operators */
|
||||
WASM_OP_I32_CLZ = 0x67, /* i32.clz */
|
||||
WASM_OP_I32_CTZ = 0x68, /* i32.ctz */
|
||||
WASM_OP_I32_POPCNT = 0x69, /* i32.popcnt */
|
||||
WASM_OP_I32_ADD = 0x6a, /* i32.add */
|
||||
WASM_OP_I32_SUB = 0x6b, /* i32.sub */
|
||||
WASM_OP_I32_MUL = 0x6c, /* i32.mul */
|
||||
WASM_OP_I32_DIV_S = 0x6d, /* i32.div_s */
|
||||
WASM_OP_I32_DIV_U = 0x6e, /* i32.div_u */
|
||||
WASM_OP_I32_REM_S = 0x6f, /* i32.rem_s */
|
||||
WASM_OP_I32_REM_U = 0x70, /* i32.rem_u */
|
||||
WASM_OP_I32_AND = 0x71, /* i32.and */
|
||||
WASM_OP_I32_OR = 0x72, /* i32.or */
|
||||
WASM_OP_I32_XOR = 0x73, /* i32.xor */
|
||||
WASM_OP_I32_SHL = 0x74, /* i32.shl */
|
||||
WASM_OP_I32_SHR_S = 0x75, /* i32.shr_s */
|
||||
WASM_OP_I32_SHR_U = 0x76, /* i32.shr_u */
|
||||
WASM_OP_I32_ROTL = 0x77, /* i32.rotl */
|
||||
WASM_OP_I32_ROTR = 0x78, /* i32.rotr */
|
||||
|
||||
WASM_OP_I64_CLZ = 0x79, /* i64.clz */
|
||||
WASM_OP_I64_CTZ = 0x7a, /* i64.ctz */
|
||||
WASM_OP_I64_POPCNT = 0x7b, /* i64.popcnt */
|
||||
WASM_OP_I64_ADD = 0x7c, /* i64.add */
|
||||
WASM_OP_I64_SUB = 0x7d, /* i64.sub */
|
||||
WASM_OP_I64_MUL = 0x7e, /* i64.mul */
|
||||
WASM_OP_I64_DIV_S = 0x7f, /* i64.div_s */
|
||||
WASM_OP_I64_DIV_U = 0x80, /* i64.div_u */
|
||||
WASM_OP_I64_REM_S = 0x81, /* i64.rem_s */
|
||||
WASM_OP_I64_REM_U = 0x82, /* i64.rem_u */
|
||||
WASM_OP_I64_AND = 0x83, /* i64.and */
|
||||
WASM_OP_I64_OR = 0x84, /* i64.or */
|
||||
WASM_OP_I64_XOR = 0x85, /* i64.xor */
|
||||
WASM_OP_I64_SHL = 0x86, /* i64.shl */
|
||||
WASM_OP_I64_SHR_S = 0x87, /* i64.shr_s */
|
||||
WASM_OP_I64_SHR_U = 0x88, /* i64.shr_u */
|
||||
WASM_OP_I64_ROTL = 0x89, /* i64.rotl */
|
||||
WASM_OP_I64_ROTR = 0x8a, /* i64.rotr */
|
||||
|
||||
WASM_OP_F32_ABS = 0x8b, /* f32.abs */
|
||||
WASM_OP_F32_NEG = 0x8c, /* f32.neg */
|
||||
WASM_OP_F32_CEIL = 0x8d, /* f32.ceil */
|
||||
WASM_OP_F32_FLOOR = 0x8e, /* f32.floor */
|
||||
WASM_OP_F32_TRUNC = 0x8f, /* f32.trunc */
|
||||
WASM_OP_F32_NEAREST = 0x90, /* f32.nearest */
|
||||
WASM_OP_F32_SQRT = 0x91, /* f32.sqrt */
|
||||
WASM_OP_F32_ADD = 0x92, /* f32.add */
|
||||
WASM_OP_F32_SUB = 0x93, /* f32.sub */
|
||||
WASM_OP_F32_MUL = 0x94, /* f32.mul */
|
||||
WASM_OP_F32_DIV = 0x95, /* f32.div */
|
||||
WASM_OP_F32_MIN = 0x96, /* f32.min */
|
||||
WASM_OP_F32_MAX = 0x97, /* f32.max */
|
||||
WASM_OP_F32_COPYSIGN = 0x98, /* f32.copysign */
|
||||
|
||||
WASM_OP_F64_ABS = 0x99, /* f64.abs */
|
||||
WASM_OP_F64_NEG = 0x9a, /* f64.neg */
|
||||
WASM_OP_F64_CEIL = 0x9b, /* f64.ceil */
|
||||
WASM_OP_F64_FLOOR = 0x9c, /* f64.floor */
|
||||
WASM_OP_F64_TRUNC = 0x9d, /* f64.trunc */
|
||||
WASM_OP_F64_NEAREST = 0x9e, /* f64.nearest */
|
||||
WASM_OP_F64_SQRT = 0x9f, /* f64.sqrt */
|
||||
WASM_OP_F64_ADD = 0xa0, /* f64.add */
|
||||
WASM_OP_F64_SUB = 0xa1, /* f64.sub */
|
||||
WASM_OP_F64_MUL = 0xa2, /* f64.mul */
|
||||
WASM_OP_F64_DIV = 0xa3, /* f64.div */
|
||||
WASM_OP_F64_MIN = 0xa4, /* f64.min */
|
||||
WASM_OP_F64_MAX = 0xa5, /* f64.max */
|
||||
WASM_OP_F64_COPYSIGN = 0xa6, /* f64.copysign */
|
||||
|
||||
/* conversions */
|
||||
WASM_OP_I32_WRAP_I64 = 0xa7, /* i32.wrap/i64 */
|
||||
WASM_OP_I32_TRUNC_S_F32 = 0xa8, /* i32.trunc_s/f32 */
|
||||
WASM_OP_I32_TRUNC_U_F32 = 0xa9, /* i32.trunc_u/f32 */
|
||||
WASM_OP_I32_TRUNC_S_F64 = 0xaa, /* i32.trunc_s/f64 */
|
||||
WASM_OP_I32_TRUNC_U_F64 = 0xab, /* i32.trunc_u/f64 */
|
||||
|
||||
WASM_OP_I64_EXTEND_S_I32 = 0xac, /* i64.extend_s/i32 */
|
||||
WASM_OP_I64_EXTEND_U_I32 = 0xad, /* i64.extend_u/i32 */
|
||||
WASM_OP_I64_TRUNC_S_F32 = 0xae, /* i64.trunc_s/f32 */
|
||||
WASM_OP_I64_TRUNC_U_F32 = 0xaf, /* i64.trunc_u/f32 */
|
||||
WASM_OP_I64_TRUNC_S_F64 = 0xb0, /* i64.trunc_s/f64 */
|
||||
WASM_OP_I64_TRUNC_U_F64 = 0xb1, /* i64.trunc_u/f64 */
|
||||
|
||||
WASM_OP_F32_CONVERT_S_I32 = 0xb2, /* f32.convert_s/i32 */
|
||||
WASM_OP_F32_CONVERT_U_I32 = 0xb3, /* f32.convert_u/i32 */
|
||||
WASM_OP_F32_CONVERT_S_I64 = 0xb4, /* f32.convert_s/i64 */
|
||||
WASM_OP_F32_CONVERT_U_I64 = 0xb5, /* f32.convert_u/i64 */
|
||||
WASM_OP_F32_DEMOTE_F64 = 0xb6, /* f32.demote/f64 */
|
||||
|
||||
WASM_OP_F64_CONVERT_S_I32 = 0xb7, /* f64.convert_s/i32 */
|
||||
WASM_OP_F64_CONVERT_U_I32 = 0xb8, /* f64.convert_u/i32 */
|
||||
WASM_OP_F64_CONVERT_S_I64 = 0xb9, /* f64.convert_s/i64 */
|
||||
WASM_OP_F64_CONVERT_U_I64 = 0xba, /* f64.convert_u/i64 */
|
||||
WASM_OP_F64_PROMOTE_F32 = 0xbb, /* f64.promote/f32 */
|
||||
|
||||
/* reinterpretations */
|
||||
WASM_OP_I32_REINTERPRET_F32 = 0xbc, /* i32.reinterpret/f32 */
|
||||
WASM_OP_I64_REINTERPRET_F64 = 0xbd, /* i64.reinterpret/f64 */
|
||||
WASM_OP_F32_REINTERPRET_I32 = 0xbe, /* f32.reinterpret/i32 */
|
||||
WASM_OP_F64_REINTERPRET_I64 = 0xbf, /* f64.reinterpret/i64 */
|
||||
|
||||
/* drop/select specified types*/
|
||||
WASM_OP_DROP_32 = 0xc0,
|
||||
WASM_OP_DROP_64 = 0xc1,
|
||||
WASM_OP_SELECT_32 = 0xc2,
|
||||
WASM_OP_SELECT_64 = 0xc3,
|
||||
|
||||
WASM_OP_IMPDEP1 = WASM_OP_SELECT_64 + 1,
|
||||
WASM_OP_IMPDEP2 = WASM_OP_IMPDEP1 + 1
|
||||
} WASMOpcode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro used to generate computed goto tables for the C interpreter.
|
||||
*/
|
||||
#define WASM_INSTRUCTION_NUM 256
|
||||
|
||||
#define DEFINE_GOTO_TABLE(_name) \
|
||||
static const void *_name[WASM_INSTRUCTION_NUM] = { \
|
||||
HANDLE_OPCODE (WASM_OP_UNREACHABLE), /* 0x00 */ \
|
||||
HANDLE_OPCODE (WASM_OP_NOP), /* 0x01 */ \
|
||||
HANDLE_OPCODE (WASM_OP_BLOCK), /* 0x02 */ \
|
||||
HANDLE_OPCODE (WASM_OP_LOOP), /* 0x03 */ \
|
||||
HANDLE_OPCODE (WASM_OP_IF), /* 0x04 */ \
|
||||
HANDLE_OPCODE (WASM_OP_ELSE), /* 0x05 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x06), /* 0x06 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x07), /* 0x07 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x08), /* 0x08 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x09), /* 0x09 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x0a), /* 0x0a */ \
|
||||
HANDLE_OPCODE (WASM_OP_END), /* 0x0b */ \
|
||||
HANDLE_OPCODE (WASM_OP_BR), /* 0x0c */ \
|
||||
HANDLE_OPCODE (WASM_OP_BR_IF), /* 0x0d */ \
|
||||
HANDLE_OPCODE (WASM_OP_BR_TABLE), /* 0x0e */ \
|
||||
HANDLE_OPCODE (WASM_OP_RETURN), /* 0x0f */ \
|
||||
HANDLE_OPCODE (WASM_OP_CALL), /* 0x10 */ \
|
||||
HANDLE_OPCODE (WASM_OP_CALL_INDIRECT), /* 0x11 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x12), /* 0x12 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x13), /* 0x13 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x14), /* 0x14 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x15), /* 0x15 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x16), /* 0x16 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x17), /* 0x17 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x18), /* 0x18 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x19), /* 0x19 */ \
|
||||
HANDLE_OPCODE (WASM_OP_DROP), /* 0x1a */ \
|
||||
HANDLE_OPCODE (WASM_OP_SELECT), /* 0x1b */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x1c), /* 0x1c */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x1d), /* 0x1d */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x1e), /* 0x1e */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x1f), /* 0x1f */ \
|
||||
HANDLE_OPCODE (WASM_OP_GET_LOCAL), /* 0x20 */ \
|
||||
HANDLE_OPCODE (WASM_OP_SET_LOCAL), /* 0x21 */ \
|
||||
HANDLE_OPCODE (WASM_OP_TEE_LOCAL), /* 0x22 */ \
|
||||
HANDLE_OPCODE (WASM_OP_GET_GLOBAL), /* 0x23 */ \
|
||||
HANDLE_OPCODE (WASM_OP_SET_GLOBAL), /* 0x24 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x25), /* 0x25 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x26), /* 0x26 */ \
|
||||
HANDLE_OPCODE (WASM_OP_UNUSED_0x27), /* 0x27 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LOAD), /* 0x28 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LOAD), /* 0x29 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_LOAD), /* 0x2a */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_LOAD), /* 0x2b */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LOAD8_S), /* 0x2c */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LOAD8_U), /* 0x2d */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LOAD16_S), /* 0x2e */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LOAD16_U), /* 0x2f */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LOAD8_S), /* 0x30 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LOAD8_U), /* 0x31 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LOAD16_S), /* 0x32 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LOAD16_U), /* 0x33 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LOAD32_S), /* 0x34 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LOAD32_U), /* 0x35 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_STORE), /* 0x36 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_STORE), /* 0x37 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_STORE), /* 0x38 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_STORE), /* 0x39 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_STORE8), /* 0x3a */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_STORE16), /* 0x3b */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_STORE8), /* 0x3c */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_STORE16), /* 0x3d */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_STORE32), /* 0x3e */ \
|
||||
HANDLE_OPCODE (WASM_OP_MEMORY_SIZE), /* 0x3f */ \
|
||||
HANDLE_OPCODE (WASM_OP_MEMORY_GROW), /* 0x40 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_CONST), /* 0x41 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_CONST), /* 0x42 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_CONST), /* 0x43 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_CONST), /* 0x44 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_EQZ), /* 0x45 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_EQ), /* 0x46 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_NE), /* 0x47 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LT_S), /* 0x48 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LT_U), /* 0x49 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_GT_S), /* 0x4a */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_GT_U), /* 0x4b */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LE_S), /* 0x4c */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_LE_U), /* 0x4d */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_GE_S), /* 0x4e */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_GE_U), /* 0x4f */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_EQZ), /* 0x50 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_EQ), /* 0x51 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_NE), /* 0x52 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LT_S), /* 0x53 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LT_U), /* 0x54 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_GT_S), /* 0x55 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_GT_U), /* 0x56 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LE_S), /* 0x57 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_LE_U), /* 0x58 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_GE_S), /* 0x59 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_GE_U), /* 0x5a */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_EQ), /* 0x5b */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_NE), /* 0x5c */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_LT), /* 0x5d */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_GT), /* 0x5e */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_LE), /* 0x5f */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_GE), /* 0x60 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_EQ), /* 0x61 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_NE), /* 0x62 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_LT), /* 0x63 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_GT), /* 0x64 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_LE), /* 0x65 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_GE), /* 0x66 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_CLZ), /* 0x67 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_CTZ), /* 0x68 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_POPCNT), /* 0x69 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_ADD), /* 0x6a */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_SUB), /* 0x6b */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_MUL), /* 0x6c */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_DIV_S), /* 0x6d */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_DIV_U), /* 0x6e */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_REM_S), /* 0x6f */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_REM_U), /* 0x70 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_AND), /* 0x71 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_OR), /* 0x72 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_XOR), /* 0x73 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_SHL), /* 0x74 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_SHR_S), /* 0x75 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_SHR_U), /* 0x76 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_ROTL), /* 0x77 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_ROTR), /* 0x78 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_CLZ), /* 0x79 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_CTZ), /* 0x7a */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_POPCNT), /* 0x7b */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_ADD), /* 0x7c */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_SUB), /* 0x7d */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_MUL), /* 0x7e */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_DIV_S), /* 0x7f */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_DIV_U), /* 0x80 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_REM_S), /* 0x81 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_REM_U), /* 0x82 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_AND), /* 0x83 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_OR), /* 0x84 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_XOR), /* 0x85 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_SHL), /* 0x86 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_SHR_S), /* 0x87 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_SHR_U), /* 0x88 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_ROTL), /* 0x89 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_ROTR), /* 0x8a */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_ABS), /* 0x8b */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_NEG), /* 0x8c */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_CEIL), /* 0x8d */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_FLOOR), /* 0x8e */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_TRUNC), /* 0x8f */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_NEAREST), /* 0x90 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_SQRT), /* 0x91 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_ADD), /* 0x92 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_SUB), /* 0x93 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_MUL), /* 0x94 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_DIV), /* 0x95 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_MIN), /* 0x96 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_MAX), /* 0x97 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_COPYSIGN), /* 0x98 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_ABS), /* 0x99 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_NEG), /* 0x9a */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_CEIL), /* 0x9b */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_FLOOR), /* 0x9c */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_TRUNC), /* 0x9d */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_NEAREST), /* 0x9e */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_SQRT), /* 0x9f */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_ADD), /* 0xa0 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_SUB), /* 0xa1 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_MUL), /* 0xa2 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_DIV), /* 0xa3 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_MIN), /* 0xa4 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_MAX), /* 0xa5 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_COPYSIGN), /* 0xa6 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_WRAP_I64), /* 0xa7 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_TRUNC_S_F32), /* 0xa8 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_TRUNC_U_F32), /* 0xa9 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_TRUNC_S_F64), /* 0xaa */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_TRUNC_U_F64), /* 0xab */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_EXTEND_S_I32), /* 0xac */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_EXTEND_U_I32), /* 0xad */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_TRUNC_S_F32), /* 0xae */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_TRUNC_U_F32), /* 0xaf */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_TRUNC_S_F64), /* 0xb0 */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_TRUNC_U_F64), /* 0xb1 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_CONVERT_S_I32), /* 0xb2 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_CONVERT_U_I32), /* 0xb3 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_CONVERT_S_I64), /* 0xb4 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_CONVERT_U_I64), /* 0xb5 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_DEMOTE_F64), /* 0xb6 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_CONVERT_S_I32), /* 0xb7 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_CONVERT_U_I32), /* 0xb8 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_CONVERT_S_I64), /* 0xb9 */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_CONVERT_U_I64), /* 0xba */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_PROMOTE_F32), /* 0xbb */ \
|
||||
HANDLE_OPCODE (WASM_OP_I32_REINTERPRET_F32), /* 0xbc */ \
|
||||
HANDLE_OPCODE (WASM_OP_I64_REINTERPRET_F64), /* 0xbd */ \
|
||||
HANDLE_OPCODE (WASM_OP_F32_REINTERPRET_I32), /* 0xbe */ \
|
||||
HANDLE_OPCODE (WASM_OP_F64_REINTERPRET_I64), /* 0xbf */ \
|
||||
HANDLE_OPCODE (WASM_OP_DROP_32), /* 0xc0 */ \
|
||||
HANDLE_OPCODE (WASM_OP_DROP_64), /* 0xc1 */ \
|
||||
HANDLE_OPCODE (WASM_OP_SELECT_32), /* 0xc2 */ \
|
||||
HANDLE_OPCODE (WASM_OP_SELECT_64), /* 0xc3 */ \
|
||||
HANDLE_OPCODE (WASM_OP_IMPDEP1), /* 0xc4 */ \
|
||||
HANDLE_OPCODE (WASM_OP_IMPDEP2), /* 0xc5 */ \
|
||||
}
|
||||
|
||||
#endif /* end of _WASM_OPCODE_H */
|
||||
1220
core/iwasm/runtime/vmcore_wasm/wasm-runtime.c
Normal file
1220
core/iwasm/runtime/vmcore_wasm/wasm-runtime.c
Normal file
File diff suppressed because it is too large
Load Diff
328
core/iwasm/runtime/vmcore_wasm/wasm-runtime.h
Normal file
328
core/iwasm/runtime/vmcore_wasm/wasm-runtime.h
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _WASM_RUNTIME_H
|
||||
#define _WASM_RUNTIME_H
|
||||
|
||||
#include "wasm.h"
|
||||
#include "wasm-thread.h"
|
||||
#include "wasm_hashmap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define DEFAULT_WASM_STACK_SIZE (8 * 1024)
|
||||
#define DEFAULT_WASM_HEAP_SIZE (8 * 1024)
|
||||
#define MIN_WASM_HEAP_SIZE (1 * 1024)
|
||||
|
||||
typedef struct WASMMemoryInstance {
|
||||
/* Current page count */
|
||||
uint32 cur_page_count;
|
||||
/* Maximum page count */
|
||||
uint32 max_page_count;
|
||||
/* Data of import globals with address info, like _stdin/_stdout/_stderr,
|
||||
stdin/stdout/stderr is stored here, but the actual addr info, or offset
|
||||
to memory_data is stored in global_data section */
|
||||
uint8 *addr_data;
|
||||
/* Size of addr_data */
|
||||
uint32 addr_data_size;
|
||||
|
||||
/* Thunk data of argument strings */
|
||||
uint8 *thunk_argv_data;
|
||||
uint32 thunk_argv_data_size;
|
||||
/* Thunk argument count */
|
||||
uint32 thunk_argc;
|
||||
/* Thunk argument offsets */
|
||||
uint8 *thunk_argv_offsets;
|
||||
|
||||
/* Heap data */
|
||||
uint8 *heap_data;
|
||||
/* Heap size */
|
||||
uint32 heap_data_size;
|
||||
/* The heap created */
|
||||
void *heap_handle;
|
||||
|
||||
/* Memory data */
|
||||
uint8 *memory_data;
|
||||
/* Global data of global instances */
|
||||
uint8 *global_data;
|
||||
uint32 global_data_size;
|
||||
|
||||
/* End address of memory */
|
||||
uint8 *end_addr;
|
||||
|
||||
/* Base address, the layout is:
|
||||
addr_data + thunk_argv data + thunk arg offsets +
|
||||
heap data + memory data + global data
|
||||
memory data init size is: NumBytesPerPage * cur_page_count
|
||||
addr data size and global data size is calculated in module instantiating
|
||||
Note: when memory is re-allocated, the addr data, thunk argv data, thunk
|
||||
argv offsets and memory data must be copied to new memory also.
|
||||
*/
|
||||
uint8 base_addr[1];
|
||||
} WASMMemoryInstance;
|
||||
|
||||
typedef struct WASMTableInstance {
|
||||
/* The element type, TABLE_ELEM_TYPE_ANY_FUNC currently */
|
||||
uint8 elem_type;
|
||||
/* Current size */
|
||||
uint32 cur_size;
|
||||
/* Maximum size */
|
||||
uint32 max_size;
|
||||
/* Base address */
|
||||
uint8 base_addr[1];
|
||||
} WASMTableInstance;
|
||||
|
||||
typedef struct WASMGlobalInstance {
|
||||
/* value type, VALUE_TYPE_I32/I64/F32/F64 */
|
||||
uint8 type;
|
||||
/* mutable or constant */
|
||||
bool is_mutable;
|
||||
bool is_addr;
|
||||
/* data offset to base_addr of WASMMemoryInstance */
|
||||
uint32 data_offset;
|
||||
/* initial value */
|
||||
WASMValue initial_value;
|
||||
} WASMGlobalInstance;
|
||||
|
||||
typedef struct WASMFunctionInstance {
|
||||
/* whether it is import function or WASM function */
|
||||
bool is_import_func;
|
||||
/* cell num of parameters */
|
||||
uint16 param_cell_num;
|
||||
/* cell num of return type */
|
||||
uint16 ret_cell_num;
|
||||
/* cell num of local variables, 0 for import function */
|
||||
uint16 local_cell_num;
|
||||
uint16 *local_offsets;
|
||||
union {
|
||||
WASMFunctionImport *func_import;
|
||||
WASMFunction *func;
|
||||
} u;
|
||||
} WASMFunctionInstance;
|
||||
|
||||
typedef struct WASMExportFuncInstance {
|
||||
char *name;
|
||||
WASMFunctionInstance *function;
|
||||
} WASMExportFuncInstance;
|
||||
|
||||
/* Package Type */
|
||||
typedef enum {
|
||||
Wasm_Module_Bytecode = 0,
|
||||
Wasm_Module_AoT,
|
||||
Package_Type_Unknown = 0xFFFF
|
||||
} PackageType;
|
||||
|
||||
typedef struct WASMModuleInstance {
|
||||
/* Module instance type, for module instance loaded from
|
||||
WASM bytecode binary, this field is Wasm_Module_Bytecode;
|
||||
for module instance loaded from AOT package, this field is
|
||||
Wasm_Module_AoT, and this structure should be treated as
|
||||
WASMAOTContext structure. */
|
||||
uint32 module_type;
|
||||
|
||||
uint32 memory_count;
|
||||
uint32 table_count;
|
||||
uint32 global_count;
|
||||
uint32 function_count;
|
||||
uint32 export_func_count;
|
||||
|
||||
WASMMemoryInstance **memories;
|
||||
WASMTableInstance **tables;
|
||||
WASMGlobalInstance *globals;
|
||||
WASMFunctionInstance *functions;
|
||||
WASMExportFuncInstance *export_functions;
|
||||
|
||||
WASMMemoryInstance *default_memory;
|
||||
WASMTableInstance *default_table;
|
||||
|
||||
WASMFunctionInstance *start_function;
|
||||
|
||||
HashMap *branch_set;
|
||||
const WASMModule *module;
|
||||
|
||||
uint32 DYNAMICTOP_PTR_offset;
|
||||
uint32 temp_ret;
|
||||
uint32 llvm_stack;
|
||||
|
||||
/* Default WASM stack size of threads of this Module instance. */
|
||||
uint32 wasm_stack_size;
|
||||
|
||||
/* Default WASM stack */
|
||||
uint8 *wasm_stack;
|
||||
|
||||
/* The exception buffer of wasm interpreter for current thread. */
|
||||
char cur_exception[128];
|
||||
|
||||
/* The thread data of the attaching thread */
|
||||
void *thread_data;
|
||||
|
||||
/* Main Thread */
|
||||
WASMThread main_tlr;
|
||||
} WASMModuleInstance;
|
||||
|
||||
/* Execution environment, e.g. stack info */
|
||||
typedef struct WASMExecEnv {
|
||||
uint8_t *stack;
|
||||
uint32_t stack_size;
|
||||
} WASMExecEnv;
|
||||
|
||||
struct WASMInterpFrame;
|
||||
typedef struct WASMInterpFrame WASMRuntimeFrame;
|
||||
|
||||
/**
|
||||
* Return the current thread.
|
||||
*
|
||||
* @return the current thread
|
||||
*/
|
||||
static inline WASMThread*
|
||||
wasm_runtime_get_self()
|
||||
{
|
||||
return (WASMThread*)ws_tls_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set self as the current thread.
|
||||
*
|
||||
* @param self the thread to be set as current thread
|
||||
*/
|
||||
static inline void
|
||||
wasm_runtime_set_tlr(WASMThread *self)
|
||||
{
|
||||
ws_tls_put(self);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the code block of a function.
|
||||
*
|
||||
* @param func the WASM function instance
|
||||
*
|
||||
* @return the code block of the function
|
||||
*/
|
||||
static inline uint8*
|
||||
wasm_runtime_get_func_code(WASMFunctionInstance *func)
|
||||
{
|
||||
return func->is_import_func ? NULL : func->u.func->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the code block end of a function.
|
||||
*
|
||||
* @param func the WASM function instance
|
||||
*
|
||||
* @return the code block end of the function
|
||||
*/
|
||||
static inline uint8*
|
||||
wasm_runtime_get_func_code_end(WASMFunctionInstance *func)
|
||||
{
|
||||
return func->is_import_func
|
||||
? NULL : func->u.func->code + func->u.func->code_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given WASM function of a WASM module instance with arguments (bytecode and AoT).
|
||||
*
|
||||
* @param module_inst the WASM module instance which the function belongs to
|
||||
* @param exec_env the execution environment to call the function. If the module instance
|
||||
* is created by AoT mode, it is ignored and just set it to NULL. If the module instance
|
||||
* is created by bytecode mode and it is NULL, a temporary env object will be created
|
||||
* @param function the function to be called
|
||||
* @param argc the number of arguments
|
||||
* @param argv the arguments. If the function method has return value,
|
||||
* the first (or first two in case 64-bit return value) element of
|
||||
* argv stores the return value of the called WASM function after this
|
||||
* function returns.
|
||||
*
|
||||
* @return true if success, false otherwise and exception will be thrown,
|
||||
* the caller can call wasm_runtime_get_exception to get exception info.
|
||||
*/
|
||||
bool
|
||||
wasm_runtime_call_wasm(WASMModuleInstance *module,
|
||||
WASMExecEnv *exec_env,
|
||||
WASMFunctionInstance *function,
|
||||
unsigned argc, uint32 argv[]);
|
||||
|
||||
/**
|
||||
* Set current exception string to global exception string.
|
||||
*
|
||||
* @param module the wasm module instance
|
||||
*
|
||||
* @param exception current exception string
|
||||
*/
|
||||
void
|
||||
wasm_runtime_set_exception(WASMModuleInstance *module,
|
||||
const char *exception);
|
||||
|
||||
/**
|
||||
* Get current exception string.
|
||||
*
|
||||
* @param module the wasm module instance
|
||||
*
|
||||
* @return return exception string if exception is thrown, NULL otherwise
|
||||
*/
|
||||
const char*
|
||||
wasm_runtime_get_exception(WASMModuleInstance *module);
|
||||
|
||||
/**
|
||||
* Enlarge wasm memory data space.
|
||||
*
|
||||
* @param module the wasm module instance
|
||||
* @param inc_page_count denote the page number to increase
|
||||
* @return return true if enlarge successfully, false otherwise
|
||||
*/
|
||||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
WASMModuleInstance *
|
||||
wasm_runtime_get_current_module_inst();
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
int32_t
|
||||
wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32_t size);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
void
|
||||
wasm_runtime_module_free(WASMModuleInstance *module_inst, int32_t ptr);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
bool
|
||||
wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
|
||||
int32_t app_offset, uint32_t size);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
bool
|
||||
wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst,
|
||||
void *native_ptr, uint32_t size);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
void *
|
||||
wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst,
|
||||
int32_t app_offset);
|
||||
|
||||
/* See wasm-export.h for description */
|
||||
int32_t
|
||||
wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
|
||||
void *native_ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_RUNTIME_H */
|
||||
|
||||
146
core/iwasm/runtime/vmcore_wasm/wasm-thread.h
Normal file
146
core/iwasm/runtime/vmcore_wasm/wasm-thread.h
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _WASM_RUNTIME_THREAD_H
|
||||
#define _WASM_RUNTIME_THREAD_H
|
||||
|
||||
#include "wasm_assert.h"
|
||||
#include "wasm_thread.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct WASMModuleInstance;
|
||||
struct WASMInterpFrame;
|
||||
|
||||
typedef struct WASMStack {
|
||||
/* The bottom of the stack, must be 8-bytes align. */
|
||||
uint8 *bottom;
|
||||
/* Top cell index which is free. */
|
||||
uint8 *top;
|
||||
/* The top boundary of the stack. */
|
||||
uint8 *top_boundary;
|
||||
} WASMStack;
|
||||
|
||||
typedef struct WASMThread {
|
||||
/* Previous thread's tlr of an instance. */
|
||||
struct WASMThread *prev;
|
||||
|
||||
/* Next thread's tlr of an instance. */
|
||||
struct WASMThread *next;
|
||||
|
||||
/* The WASM module instance of current thread */
|
||||
struct WASMModuleInstance *module_inst;
|
||||
|
||||
/* Current frame of current thread. */
|
||||
struct WASMInterpFrame *cur_frame;
|
||||
|
||||
/* The boundary of native stack. When interpreter detects that native
|
||||
frame may overrun this boundary, it will throw a stack overflow
|
||||
exception. */
|
||||
void *native_stack_boundary;
|
||||
|
||||
/* The WASM stack of current thread. */
|
||||
WASMStack wasm_stack;
|
||||
|
||||
/* The native thread handle of current thread. */
|
||||
korp_tid handle;
|
||||
|
||||
/* Current suspend count of this thread. */
|
||||
uint32 suspend_count;
|
||||
} WASMThread;
|
||||
|
||||
/**
|
||||
* Allocate a WASM frame from the WASM stack.
|
||||
*
|
||||
* @param tlr the current thread
|
||||
* @param size size of the WASM frame, it must be a multiple of 4
|
||||
*
|
||||
* @return the WASM frame if there is enough space in the stack area
|
||||
* with a protection area, NULL otherwise
|
||||
*/
|
||||
static inline void*
|
||||
wasm_thread_alloc_wasm_frame(WASMThread *tlr, unsigned size)
|
||||
{
|
||||
uint8 *addr = tlr->wasm_stack.top;
|
||||
|
||||
wasm_assert(!(size & 3));
|
||||
|
||||
/* The outs area size cannot be larger than the frame size, so
|
||||
multiplying by 2 is enough. */
|
||||
if (addr + size * 2 > tlr->wasm_stack.top_boundary) {
|
||||
/* WASM stack overflow. */
|
||||
/* When throwing SOE, the preserved space must be enough. */
|
||||
/*wasm_assert(!tlr->throwing_soe);*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tlr->wasm_stack.top += size;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline void
|
||||
wasm_thread_free_wasm_frame(WASMThread *tlr, void *prev_top)
|
||||
{
|
||||
wasm_assert((uint8 *)prev_top >= tlr->wasm_stack.bottom);
|
||||
tlr->wasm_stack.top = (uint8 *)prev_top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current WASM stack top pointer.
|
||||
*
|
||||
* @param tlr the current thread
|
||||
*
|
||||
* @return the current WASM stack top pointer
|
||||
*/
|
||||
static inline void*
|
||||
wasm_thread_wasm_stack_top(WASMThread *tlr)
|
||||
{
|
||||
return tlr->wasm_stack.top;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current frame pointer.
|
||||
*
|
||||
* @param tlr the current thread
|
||||
* @param frame the WASM frame to be set for the current thread
|
||||
*/
|
||||
static inline void
|
||||
wasm_thread_set_cur_frame(WASMThread *tlr, struct WASMInterpFrame *frame)
|
||||
{
|
||||
tlr->cur_frame = frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current frame pointer.
|
||||
*
|
||||
* @param tlr the current thread
|
||||
*
|
||||
* @return the current frame pointer
|
||||
*/
|
||||
static inline struct WASMInterpFrame*
|
||||
wasm_thread_get_cur_frame(WASMThread *tlr)
|
||||
{
|
||||
return tlr->cur_frame;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_RUNTIME_THREAD_H */
|
||||
392
core/iwasm/runtime/vmcore_wasm/wasm.h
Normal file
392
core/iwasm/runtime/vmcore_wasm/wasm.h
Normal file
@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _WASM_H_
|
||||
#define _WASM_H_
|
||||
|
||||
#include "wasm_platform.h"
|
||||
#include "wasm_hashmap.h"
|
||||
#include "wasm_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Value Type */
|
||||
#define VALUE_TYPE_I32 0x7F
|
||||
#define VALUE_TYPE_I64 0X7E
|
||||
#define VALUE_TYPE_F32 0x7D
|
||||
#define VALUE_TYPE_F64 0x7C
|
||||
#define VALUE_TYPE_VOID 0x00
|
||||
|
||||
/* Table Element Type */
|
||||
#define TABLE_ELEM_TYPE_ANY_FUNC 0x70
|
||||
|
||||
#define MaxMemoryPages 65536
|
||||
#define MaxTableElems UINT32_MAX
|
||||
#define NumBytesPerPage 65536
|
||||
#define NumBytesPerPageLog2 16
|
||||
#define MaxReturnValues 16
|
||||
|
||||
#define INIT_EXPR_TYPE_I32_CONST 0x41
|
||||
#define INIT_EXPR_TYPE_I64_CONST 0x42
|
||||
#define INIT_EXPR_TYPE_F32_CONST 0x43
|
||||
#define INIT_EXPR_TYPE_F64_CONST 0x44
|
||||
#define INIT_EXPR_TYPE_GET_GLOBAL 0x23
|
||||
#define INIT_EXPR_TYPE_ERROR 0xff
|
||||
|
||||
#define WASM_MAGIC_NUMBER 0x6d736100
|
||||
#define WASM_CURRENT_VERSION 1
|
||||
|
||||
#define SECTION_TYPE_USER 0
|
||||
#define SECTION_TYPE_TYPE 1
|
||||
#define SECTION_TYPE_IMPORT 2
|
||||
#define SECTION_TYPE_FUNC 3
|
||||
#define SECTION_TYPE_TABLE 4
|
||||
#define SECTION_TYPE_MEMORY 5
|
||||
#define SECTION_TYPE_GLOBAL 6
|
||||
#define SECTION_TYPE_EXPORT 7
|
||||
#define SECTION_TYPE_START 8
|
||||
#define SECTION_TYPE_ELEM 9
|
||||
#define SECTION_TYPE_CODE 10
|
||||
#define SECTION_TYPE_DATA 11
|
||||
|
||||
#define IMPORT_KIND_FUNC 0
|
||||
#define IMPORT_KIND_TABLE 1
|
||||
#define IMPORT_KIND_MEMORY 2
|
||||
#define IMPORT_KIND_GLOBAL 3
|
||||
|
||||
#define EXPORT_KIND_FUNC 0
|
||||
#define EXPORT_KIND_TABLE 1
|
||||
#define EXPORT_KIND_MEMORY 2
|
||||
#define EXPORT_KIND_GLOBAL 3
|
||||
|
||||
#define BLOCK_TYPE_BLOCK 0
|
||||
#define BLOCK_TYPE_LOOP 1
|
||||
#define BLOCK_TYPE_IF 2
|
||||
#define BLOCK_TYPE_FUNCTION 3
|
||||
|
||||
#define CALL_TYPE_WRAPPER 0
|
||||
#define CALL_TYPE_C_INTRINSIC 1
|
||||
|
||||
typedef union WASMValue {
|
||||
int32 i32;
|
||||
uint32 u32;
|
||||
int64 i64;
|
||||
uint64 u64;
|
||||
float32 f32;
|
||||
float64 f64;
|
||||
uintptr_t addr;
|
||||
} WASMValue;
|
||||
|
||||
typedef struct InitializerExpression {
|
||||
/* type of INIT_EXPR_TYPE_XXX */
|
||||
uint8 init_expr_type;
|
||||
union {
|
||||
int32 i32;
|
||||
int64 i64;
|
||||
float32 f32;
|
||||
float64 f64;
|
||||
uint32 global_index;
|
||||
} u;
|
||||
} InitializerExpression;
|
||||
|
||||
typedef struct WASMType {
|
||||
uint32 param_count;
|
||||
/* only one result is supported currently */
|
||||
uint32 result_count;
|
||||
/* types of params and results */
|
||||
uint8 types[1];
|
||||
} WASMType;
|
||||
|
||||
typedef struct WASMTable {
|
||||
uint8 elem_type;
|
||||
uint32 flags;
|
||||
uint32 init_size;
|
||||
/* specified if (flags & 1), else it is 0x10000 */
|
||||
uint32 max_size;
|
||||
} WASMTable;
|
||||
|
||||
typedef struct WASMMemory {
|
||||
uint32 flags;
|
||||
/* 64 kbytes one page by default */
|
||||
uint32 init_page_count;
|
||||
uint32 max_page_count;
|
||||
} WASMMemory;
|
||||
|
||||
typedef struct WASMTableImport {
|
||||
char *module_name;
|
||||
char *field_name;
|
||||
uint8 elem_type;
|
||||
uint32 flags;
|
||||
uint32 init_size;
|
||||
/* specified if (flags & 1), else it is 0x10000 */
|
||||
uint32 max_size;
|
||||
} WASMTableImport;
|
||||
|
||||
typedef struct WASMMemoryImport {
|
||||
char *module_name;
|
||||
char *field_name;
|
||||
uint32 flags;
|
||||
/* 64 kbytes one page by default */
|
||||
uint32 init_page_count;
|
||||
uint32 max_page_count;
|
||||
} WASMMemoryImport;
|
||||
|
||||
typedef struct WASMFunctionImport {
|
||||
char *module_name;
|
||||
char *field_name;
|
||||
/* function type */
|
||||
WASMType *func_type;
|
||||
/* c intrinsic function or wrapper function */
|
||||
uint32 call_type;
|
||||
/* function pointer after linked */
|
||||
void *func_ptr_linked;
|
||||
} WASMFunctionImport;
|
||||
|
||||
typedef struct WASMGlobalImport {
|
||||
char *module_name;
|
||||
char *field_name;
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
bool is_addr;
|
||||
/* global data after linked */
|
||||
WASMValue global_data_linked;
|
||||
} WASMGlobalImport;
|
||||
|
||||
typedef struct WASMImport {
|
||||
uint8 kind;
|
||||
union {
|
||||
WASMFunctionImport function;
|
||||
WASMTableImport table;
|
||||
WASMMemoryImport memory;
|
||||
WASMGlobalImport global;
|
||||
struct {
|
||||
char *module_name;
|
||||
char *field_name;
|
||||
} names;
|
||||
} u;
|
||||
} WASMImport;
|
||||
|
||||
typedef struct WASMFunction {
|
||||
/* the type of function */
|
||||
WASMType *func_type;
|
||||
uint32 local_count;
|
||||
uint8 *local_types;
|
||||
uint32 max_stack_cell_num;
|
||||
uint32 max_block_num;
|
||||
uint32 code_size;
|
||||
uint8 *code;
|
||||
} WASMFunction;
|
||||
|
||||
typedef struct WASMGlobal {
|
||||
uint8 type;
|
||||
bool is_mutable;
|
||||
bool is_addr;
|
||||
InitializerExpression init_expr;
|
||||
} WASMGlobal;
|
||||
|
||||
typedef struct WASMExport {
|
||||
char *name;
|
||||
uint8 kind;
|
||||
uint32 index;
|
||||
} WASMExport;
|
||||
|
||||
typedef struct WASMTableSeg {
|
||||
uint32 table_index;
|
||||
InitializerExpression base_offset;
|
||||
uint32 function_count;
|
||||
uint32 *func_indexes;
|
||||
} WASMTableSeg;
|
||||
|
||||
typedef struct WASMDataSeg {
|
||||
uint32 memory_index;
|
||||
InitializerExpression base_offset;
|
||||
uint32 data_length;
|
||||
uint8 *data;
|
||||
} WASMDataSeg;
|
||||
|
||||
typedef struct WASMModule {
|
||||
uint32 type_count;
|
||||
uint32 import_count;
|
||||
uint32 function_count;
|
||||
uint32 table_count;
|
||||
uint32 memory_count;
|
||||
uint32 global_count;
|
||||
uint32 export_count;
|
||||
uint32 table_seg_count;
|
||||
uint32 data_seg_count;
|
||||
|
||||
uint32 import_function_count;
|
||||
uint32 import_table_count;
|
||||
uint32 import_memory_count;
|
||||
uint32 import_global_count;
|
||||
|
||||
WASMImport *import_functions;
|
||||
WASMImport *import_tables;
|
||||
WASMImport *import_memories;
|
||||
WASMImport *import_globals;
|
||||
|
||||
WASMType **types;
|
||||
WASMImport *imports;
|
||||
WASMFunction **functions;
|
||||
WASMTable *tables;
|
||||
WASMMemory *memories;
|
||||
WASMGlobal *globals;
|
||||
WASMExport *exports;
|
||||
WASMTableSeg *table_segments;
|
||||
WASMDataSeg **data_segments;
|
||||
uint32 start_function;
|
||||
|
||||
HashMap *const_str_set;
|
||||
HashMap *branch_set;
|
||||
} WASMModule;
|
||||
|
||||
typedef struct WASMBranchBlock {
|
||||
uint8 block_type;
|
||||
uint8 return_type;
|
||||
uint8 *start_addr;
|
||||
uint8 *else_addr;
|
||||
uint8 *end_addr;
|
||||
uint32 *frame_sp;
|
||||
uint8 *frame_ref;
|
||||
} WASMBranchBlock;
|
||||
|
||||
typedef struct WASMSection {
|
||||
struct WASMSection *next;
|
||||
/* section type */
|
||||
int section_type;
|
||||
/* section body, not include type and size */
|
||||
const uint8_t *section_body;
|
||||
/* section body size */
|
||||
uint32_t section_body_size;
|
||||
} WASMSection;
|
||||
|
||||
/* Execution environment, e.g. stack info */
|
||||
/**
|
||||
* Align an unsigned value on a alignment boundary.
|
||||
*
|
||||
* @param v the value to be aligned
|
||||
* @param b the alignment boundary (2, 4, 8, ...)
|
||||
*
|
||||
* @return the aligned value
|
||||
*/
|
||||
inline static unsigned
|
||||
align_uint (unsigned v, unsigned b)
|
||||
{
|
||||
unsigned m = b - 1;
|
||||
return (v + m) & ~m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hash value of c string.
|
||||
*/
|
||||
inline static uint32
|
||||
wasm_string_hash(const char *str)
|
||||
{
|
||||
unsigned h = strlen(str);
|
||||
const uint8 *p = (uint8*)str;
|
||||
const uint8 *end = p + h;
|
||||
|
||||
while (p != end)
|
||||
h = ((h << 5) - h) + *p++;
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether two c strings are equal.
|
||||
*/
|
||||
inline static bool
|
||||
wasm_string_equal(const char *s1, const char *s2)
|
||||
{
|
||||
return strcmp(s1, s2) == 0 ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the byte size of value type.
|
||||
*
|
||||
*/
|
||||
inline static uint32
|
||||
wasm_value_type_size(uint8 value_type)
|
||||
{
|
||||
switch (value_type) {
|
||||
case VALUE_TYPE_I32:
|
||||
case VALUE_TYPE_F32:
|
||||
return sizeof(int32);
|
||||
case VALUE_TYPE_I64:
|
||||
case VALUE_TYPE_F64:
|
||||
return sizeof(int64);
|
||||
default:
|
||||
wasm_assert(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline static uint16
|
||||
wasm_value_type_cell_num(uint8 value_type)
|
||||
{
|
||||
switch (value_type) {
|
||||
case VALUE_TYPE_I32:
|
||||
case VALUE_TYPE_F32:
|
||||
return 1;
|
||||
case VALUE_TYPE_I64:
|
||||
case VALUE_TYPE_F64:
|
||||
return 2;
|
||||
default:
|
||||
wasm_assert(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline static uint16
|
||||
wasm_get_cell_num(const uint8 *types, uint32 type_count)
|
||||
{
|
||||
uint16 cell_num = 0;
|
||||
uint32 i;
|
||||
for (i = 0; i < type_count; i++)
|
||||
cell_num += wasm_value_type_cell_num(types[i]);
|
||||
return cell_num;
|
||||
}
|
||||
|
||||
inline static uint16
|
||||
wasm_type_param_cell_num(const WASMType *type)
|
||||
{
|
||||
return wasm_get_cell_num(type->types, type->param_count);
|
||||
}
|
||||
|
||||
inline static uint16
|
||||
wasm_type_return_cell_num(const WASMType *type)
|
||||
{
|
||||
return wasm_get_cell_num(type->types + type->param_count,
|
||||
type->result_count);
|
||||
}
|
||||
|
||||
inline static bool
|
||||
wasm_type_equal(const WASMType *type1, const WASMType *type2)
|
||||
{
|
||||
return (type1->param_count == type2->param_count
|
||||
&& type1->result_count == type2->result_count
|
||||
&& memcmp(type1->types, type2->types,
|
||||
type1->param_count + type1->result_count) == 0)
|
||||
? true : false;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_H_ */
|
||||
|
||||
Reference in New Issue
Block a user