Skip to content

Commit

Permalink
Separate out wasm-rt.h and wasm-rt-impl.{c,h} (#813)
Browse files Browse the repository at this point in the history
This makes it easier to use outside of running wasm2c spec tests.
  • Loading branch information
binji authored Mar 20, 2018
1 parent 565d0b4 commit ab9e0b5
Show file tree
Hide file tree
Showing 7 changed files with 371 additions and 215 deletions.
53 changes: 1 addition & 52 deletions src/prebuilt/wasm2c.include.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,9 @@ const char SECTION_NAME(top)[] =
"extern \"C\" {\n"
"#endif\n"
"\n"
"#ifndef WASM_RT_INCLUDED_\n"
"#define WASM_RT_INCLUDED_\n"
"\n"
"#include <stdint.h>\n"
"\n"
"#ifndef WASM_RT_MAX_CALL_STACK_DEPTH\n"
"#define WASM_RT_MAX_CALL_STACK_DEPTH 500\n"
"#endif\n"
"#include \"wasm-rt.h\"\n"
"\n"
"#ifndef WASM_RT_MODULE_PREFIX\n"
"#define WASM_RT_MODULE_PREFIX\n"
Expand All @@ -35,52 +30,6 @@ const char SECTION_NAME(top)[] =
"typedef float f32;\n"
"typedef double f64;\n"
"\n"
"typedef enum {\n"
" WASM_RT_TRAP_NONE,\n"
" WASM_RT_TRAP_OOB,\n"
" WASM_RT_TRAP_INT_OVERFLOW,\n"
" WASM_RT_TRAP_DIV_BY_ZERO,\n"
" WASM_RT_TRAP_INVALID_CONVERSION,\n"
" WASM_RT_TRAP_UNREACHABLE,\n"
" WASM_RT_TRAP_CALL_INDIRECT,\n"
" WASM_RT_TRAP_EXHAUSTION,\n"
"} wasm_rt_trap_t;\n"
"\n"
"typedef enum {\n"
" WASM_RT_I32,\n"
" WASM_RT_I64,\n"
" WASM_RT_F32,\n"
" WASM_RT_F64,\n"
"} wasm_rt_type_t;\n"
"\n"
"typedef void (*wasm_rt_anyfunc_t)(void);\n"
"\n"
"typedef struct {\n"
" uint32_t func_type;\n"
" wasm_rt_anyfunc_t func;\n"
"} wasm_rt_elem_t;\n"
"\n"
"typedef struct {\n"
" uint8_t* data;\n"
" uint32_t pages, max_pages;\n"
" uint32_t size;\n"
"} wasm_rt_memory_t;\n"
"\n"
"typedef struct {\n"
" wasm_rt_elem_t* data;\n"
" uint32_t max_size;\n"
" uint32_t size;\n"
"} wasm_rt_table_t;\n"
"\n"
"extern void wasm_rt_trap(wasm_rt_trap_t) __attribute__((noreturn));\n"
"extern uint32_t wasm_rt_register_func_type(uint32_t params, uint32_t results, ...);\n"
"extern void wasm_rt_allocate_memory(wasm_rt_memory_t*, uint32_t initial_pages, uint32_t max_pages);\n"
"extern uint32_t wasm_rt_grow_memory(wasm_rt_memory_t*, uint32_t pages);\n"
"extern void wasm_rt_allocate_table(wasm_rt_table_t*, uint32_t elements, uint32_t max_elements);\n"
"extern uint32_t wasm_rt_call_stack_depth;\n"
"\n"
"#endif /* WASM_RT_INCLUDED_ */\n"
"\n"
"extern void WASM_RT_ADD_PREFIX(init)(void);\n"
;

Expand Down
53 changes: 1 addition & 52 deletions src/wasm2c.h.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@
extern "C" {
#endif

#ifndef WASM_RT_INCLUDED_
#define WASM_RT_INCLUDED_

#include <stdint.h>

#ifndef WASM_RT_MAX_CALL_STACK_DEPTH
#define WASM_RT_MAX_CALL_STACK_DEPTH 500
#endif
#include "wasm-rt.h"

#ifndef WASM_RT_MODULE_PREFIX
#define WASM_RT_MODULE_PREFIX
Expand All @@ -34,52 +29,6 @@ typedef int64_t s64;
typedef float f32;
typedef double f64;

typedef enum {
WASM_RT_TRAP_NONE,
WASM_RT_TRAP_OOB,
WASM_RT_TRAP_INT_OVERFLOW,
WASM_RT_TRAP_DIV_BY_ZERO,
WASM_RT_TRAP_INVALID_CONVERSION,
WASM_RT_TRAP_UNREACHABLE,
WASM_RT_TRAP_CALL_INDIRECT,
WASM_RT_TRAP_EXHAUSTION,
} wasm_rt_trap_t;

typedef enum {
WASM_RT_I32,
WASM_RT_I64,
WASM_RT_F32,
WASM_RT_F64,
} wasm_rt_type_t;

typedef void (*wasm_rt_anyfunc_t)(void);

typedef struct {
uint32_t func_type;
wasm_rt_anyfunc_t func;
} wasm_rt_elem_t;

typedef struct {
uint8_t* data;
uint32_t pages, max_pages;
uint32_t size;
} wasm_rt_memory_t;

typedef struct {
wasm_rt_elem_t* data;
uint32_t max_size;
uint32_t size;
} wasm_rt_table_t;

extern void wasm_rt_trap(wasm_rt_trap_t) __attribute__((noreturn));
extern uint32_t wasm_rt_register_func_type(uint32_t params, uint32_t results, ...);
extern void wasm_rt_allocate_memory(wasm_rt_memory_t*, uint32_t initial_pages, uint32_t max_pages);
extern uint32_t wasm_rt_grow_memory(wasm_rt_memory_t*, uint32_t pages);
extern void wasm_rt_allocate_table(wasm_rt_table_t*, uint32_t elements, uint32_t max_elements);
extern uint32_t wasm_rt_call_stack_depth;

#endif /* WASM_RT_INCLUDED_ */

extern void WASM_RT_ADD_PREFIX(init)(void);
%%bottom
#ifdef __cplusplus
Expand Down
32 changes: 24 additions & 8 deletions test/run-spec-wasm2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from utils import Error

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
WASM2C_DIR = os.path.join(find_exe.REPO_ROOT_DIR, 'wasm2c')


def ReinterpretF32(f32_bits):
Expand Down Expand Up @@ -294,6 +295,18 @@ def _Action(self, command):
raise Error('Unexpected action type: %s' % type_)


def Compile(cc, c_filename, out_dir, *args):
out_dir = os.path.abspath(out_dir)
o_filename = utils.ChangeDir(utils.ChangeExt(c_filename, '.o'), out_dir)
cc.RunWithArgs('-c', '-o', o_filename, c_filename, *args, cwd=out_dir)
return o_filename


def Link(cc, o_filenames, main_exe, out_dir, *args):
args = ['-o', main_exe] + o_filenames + list(args)
cc.RunWithArgs(*args, cwd=out_dir)


def main(args):
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--out-dir', metavar='PATH',
Expand All @@ -303,6 +316,8 @@ def main(args):
parser.add_argument('--bindir', metavar='PATH',
default=find_exe.GetDefaultPath(),
help='directory to search for all executables.')
parser.add_argument('--wasmrt-dir', metavar='PATH',
help='directory with wasm-rt files', default=WASM2C_DIR)
parser.add_argument('--cc', metavar='PATH',
help='the path to the C compiler', default='cc')
parser.add_argument('--cflags', metavar='FLAGS',
Expand Down Expand Up @@ -361,23 +376,24 @@ def main(args):
out_main_file.write(output.getvalue())

o_filenames = []
includes = '-I%s' % options.wasmrt_dir

# Compile wasm-rt-impl.
wasm_rt_impl_c = os.path.join(options.wasmrt_dir, 'wasm-rt-impl.c')
o_filenames.append(Compile(cc, wasm_rt_impl_c, out_dir, includes))

for i, wasm_filename in enumerate(cwriter.GetModuleFilenames()):
c_filename = utils.ChangeExt(wasm_filename, '.c')
wasm2c.RunWithArgs(wasm_filename, '-o', c_filename, cwd=out_dir)
if options.compile:
o_filename = utils.ChangeExt(wasm_filename, '.o')
o_filenames.append(o_filename)
cc.RunWithArgs(
'-c', '-o', o_filename,
'-DWASM_RT_MODULE_PREFIX=%s' % cwriter.GetModulePrefix(i),
c_filename, cwd=out_dir)
defines = '-DWASM_RT_MODULE_PREFIX=%s' % cwriter.GetModulePrefix(i)
o_filenames.append(Compile(cc, c_filename, out_dir, includes, defines))

if options.compile:
main_c = os.path.basename(main_filename)
o_filenames.append(Compile(cc, main_c, out_dir, includes, defines))
main_exe = os.path.basename(utils.ChangeExt(json_file_path, ''))
args = ['-o', main_exe, main_c] + o_filenames + ['-lm']
cc.RunWithArgs(*args, cwd=out_dir)
Link(cc, o_filenames, main_exe, out_dir, '-lm')

if options.compile and options.run:
utils.Executable(os.path.join(out_dir, main_exe),
Expand Down
110 changes: 7 additions & 103 deletions test/spec-wasm2c-prefix.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,18 @@
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <math.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define PAGE_SIZE 65536

typedef struct FuncType {
wasm_rt_type_t* params;
wasm_rt_type_t* results;
u32 param_count;
u32 result_count;
} FuncType;
#include "wasm-rt.h"
#include "wasm-rt-impl.h"

int g_tests_run;
int g_tests_passed;
jmp_buf g_jmp_buf;
FuncType* g_func_types;
u32 g_func_type_count;

static void run_spec_tests(void);

Expand All @@ -38,7 +28,7 @@ static void error(const char* file, int line, const char* format, ...) {
#define ASSERT_TRAP(f) \
do { \
g_tests_run++; \
if (setjmp(g_jmp_buf) != 0) { \
if (wasm_rt_impl_try() != 0) { \
g_tests_passed++; \
} else { \
(void)(f); \
Expand All @@ -49,7 +39,7 @@ static void error(const char* file, int line, const char* format, ...) {
#define ASSERT_EXHAUSTION(f) \
do { \
g_tests_run++; \
wasm_rt_trap_t code = setjmp(g_jmp_buf); \
wasm_rt_trap_t code = wasm_rt_impl_try(); \
switch (code) { \
case WASM_RT_TRAP_NONE: \
(void)(f); \
Expand All @@ -70,7 +60,7 @@ static void error(const char* file, int line, const char* format, ...) {
#define ASSERT_RETURN(f) \
do { \
g_tests_run++; \
if (setjmp(g_jmp_buf) != 0) { \
if (wasm_rt_impl_try() != 0) { \
error(__FILE__, __LINE__, #f " trapped.\n"); \
} else { \
f; \
Expand All @@ -81,7 +71,7 @@ static void error(const char* file, int line, const char* format, ...) {
#define ASSERT_RETURN_T(type, fmt, f, expected) \
do { \
g_tests_run++; \
if (setjmp(g_jmp_buf) != 0) { \
if (wasm_rt_impl_try() != 0) { \
error(__FILE__, __LINE__, #f " trapped.\n"); \
} else { \
type actual = f; \
Expand All @@ -98,7 +88,7 @@ static void error(const char* file, int line, const char* format, ...) {
#define ASSERT_RETURN_NAN_T(type, itype, fmt, f, kind) \
do { \
g_tests_run++; \
if (setjmp(g_jmp_buf) != 0) { \
if (wasm_rt_impl_try() != 0) { \
error(__FILE__, __LINE__, #f " trapped.\n"); \
} else { \
type actual = f; \
Expand Down Expand Up @@ -181,91 +171,6 @@ static bool is_arithmetic_nan_f64(u64 x) {
return (x & 0x7ff8000000000000) == 0x7ff8000000000000;
}

static bool func_types_are_equal(FuncType* a, FuncType* b) {
if (a->param_count != b->param_count || a->result_count != b->result_count)
return 0;
int i;
for (i = 0; i < a->param_count; ++i)
if (a->params[i] != b->params[i])
return 0;
for (i = 0; i < a->result_count; ++i)
if (a->results[i] != b->results[i])
return 0;
return 1;
}


/*
* wasm_rt_* implementations
*/

uint32_t wasm_rt_call_stack_depth;

void wasm_rt_trap(wasm_rt_trap_t code) {
assert(code != WASM_RT_TRAP_NONE);
longjmp(g_jmp_buf, code);
}

u32 wasm_rt_register_func_type(u32 param_count, u32 result_count, ...) {
FuncType func_type;
func_type.param_count = param_count;
func_type.params = malloc(param_count * sizeof(wasm_rt_type_t));
func_type.result_count = result_count;
func_type.results = malloc(result_count * sizeof(wasm_rt_type_t));

va_list args;
va_start(args, result_count);

u32 i;
for (i = 0; i < param_count; ++i)
func_type.params[i] = va_arg(args, wasm_rt_type_t);
for (i = 0; i < result_count; ++i)
func_type.results[i] = va_arg(args, wasm_rt_type_t);
va_end(args);

for (i = 0; i < g_func_type_count; ++i) {
if (func_types_are_equal(&g_func_types[i], &func_type)) {
free(func_type.params);
free(func_type.results);
return i + 1;
}
}

u32 idx = g_func_type_count++;
g_func_types = realloc(g_func_types, g_func_type_count * sizeof(FuncType));
g_func_types[idx] = func_type;
return idx + 1;
}

void wasm_rt_allocate_memory(wasm_rt_memory_t* memory,
u32 initial_pages,
u32 max_pages) {
memory->pages = initial_pages;
memory->max_pages = max_pages;
memory->size = initial_pages * PAGE_SIZE;
memory->data = calloc(memory->size, 1);
}

u32 wasm_rt_grow_memory(wasm_rt_memory_t* memory, u32 delta) {
u32 old_pages = memory->pages;
u32 new_pages = memory->pages + delta;
if (new_pages < old_pages || new_pages > memory->max_pages) {
return (u32)-1;
}
memory->data = realloc(memory->data, new_pages);
memory->pages = new_pages;
memory->size = new_pages * PAGE_SIZE;
return old_pages;
}

void wasm_rt_allocate_table(wasm_rt_table_t* table,
u32 elements,
u32 max_elements) {
table->size = elements;
table->max_size = max_elements;
table->data = calloc(table->size, sizeof(wasm_rt_elem_t));
}


/*
* spectest implementations
Expand Down Expand Up @@ -322,4 +227,3 @@ int main(int argc, char** argv) {
printf("%u/%u tests passed.\n", g_tests_passed, g_tests_run);
return g_tests_passed != g_tests_run;
}

Loading

0 comments on commit ab9e0b5

Please sign in to comment.