Skip to content

Commit 6d1968e

Browse files
committed
General code cleanup, plus more comments
1 parent 2362f08 commit 6d1968e

File tree

17 files changed

+103
-241
lines changed

17 files changed

+103
-241
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ authors = ["Gregor Peach <[email protected]>"]
66
[dependencies]
77
llvm-alt = { git = "https://github.com/Others/llvm-rs.git"}
88
structopt = "0.2"
9-
wasmparser = "0.16.1"
9+
wasmparser = "0.22"
1010

1111
[profile.release]
1212
debug = true

code_benches/dummy.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
// !!! HACK ALERT !!!
2+
// We need the __init_libc symbol in the output executable (so the runtime can initialize libc)
3+
// We can't directly export it since it's in a linked library
4+
// Thus we export a dummy function that uses it, forcing it to be included
5+
6+
17
#define IMPORT __attribute__ ((visibility ("default")))
28
#define EXPORT __attribute__ ((visibility ("default")))
39

code_benches/run.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
1-
from collections import namedtuple
21
import os
32
import subprocess as sp
43
import sys
54
import timeit
65

6+
# Absolute path to the `code_benches` directory
77
BENCH_ROOT = os.getcwd()
8+
# Absolute path to the `silverfish` directory
89
ROOT_PATH = os.path.dirname(BENCH_ROOT)
10+
911
RUNTIME_PATH = ROOT_PATH + "/runtime"
1012
SILVERFISH_PATH = ROOT_PATH + "/target/release/silverfish"
1113
WASMCEPTION_PATH = ROOT_PATH + "/wasmception"
1214

15+
# Our special WASM clang is under this wasmception path
1316
WASM_CLANG = WASMCEPTION_PATH + "/dist/bin/clang"
17+
# These flags are all somewhat important -- see @Others for more information
1418
WASM_LINKER_FLAGS = "-Wl,--allow-undefined,-z,stack-size={stack_size},--no-threads,--stack-first,--no-entry,--export-all,--export=main,--export=dummy"
19+
# Point WASM to our custom libc
1520
WASM_SYSROOT_FLAGS = "--sysroot={}/sysroot".format(WASMCEPTION_PATH)
1621
WASM_FLAGS = WASM_LINKER_FLAGS + " --target=wasm32-unknown-unknown-wasm -nostartfiles -O3 -flto " + WASM_SYSROOT_FLAGS
1722

23+
# What is the machine we're running on like?
1824
IS_64_BIT = sys.maxsize > 2**32
1925
IS_X86 = '86' in os.uname()[-1]
2026
IS_32_BIT_X86 = (not IS_64_BIT) and IS_X86
2127

28+
# TODO: Add an option to output a CSV instead of human readable output
29+
30+
# How many times should we run our benchmarks
2231
RUN_COUNT = 10
23-
ENABLE_DEBUG_SYMBOLS = False
32+
ENABLE_DEBUG_SYMBOLS = True
2433

2534

2635
# FIXME: Mibench runs many of these programs multiple times, which is probably worth replicating
@@ -73,7 +82,7 @@ def __str__(self):
7382
]
7483

7584

76-
# Now some helper methods for compiling code
85+
# Compile the C code in `program`'s directory into a native executable
7786
def compile_to_executable(program):
7887
opt = "-O3"
7988
if program.do_lto:
@@ -83,21 +92,25 @@ def compile_to_executable(program):
8392
sp.check_call("clang {} -lm {} *.c -o bin/{}".format(program.custom_arguments, opt, program.name), shell=True, cwd=program.name)
8493

8594

95+
# Compile the C code in `program`'s directory into WASM
8696
def compile_to_wasm(program):
8797
flags = WASM_FLAGS.format(stack_size=program.stack_size)
8898
command = "{clang} {flags} {args} -O3 -flto ../dummy.c *.c -o bin/{pname}.wasm" \
8999
.format(clang=WASM_CLANG, flags=flags, args=program.custom_arguments, pname=program.name)
90100
sp.check_call(command, shell=True, cwd=program.name)
91101

92102

103+
# Compile the WASM in `program`'s directory into llvm bytecode
93104
def compile_wasm_to_bc(program):
94105
command = "{silverfish} bin/{pname}.wasm -o bin/{pname}.bc".format(silverfish=SILVERFISH_PATH, pname=program.name)
95106
sp.check_call(command, shell=True, cwd=program.name)
96-
# Compile a second version with runtime globlas
107+
# Compile a second version with runtime globals
108+
# FIXME: Runtime globals were a failed experiment -- evaluate removing all traces of it
97109
command = "{silverfish} -i --runtime_globals bin/{pname}.wasm -o bin/{pname}_rg.bc".format(silverfish=SILVERFISH_PATH, pname=program.name)
98110
sp.check_call(command, shell=True, cwd=program.name)
99111

100112

113+
# Compile the WASM in `program`'s directory into llvm bytecode
101114
def compile_wasm_to_executable(program, exe_postfix, memory_impl, runtime_globals=False):
102115
bc_file = "bin/{pname}.bc".format(pname=program.name)
103116
if runtime_globals:
@@ -112,18 +125,24 @@ def compile_wasm_to_executable(program, exe_postfix, memory_impl, runtime_global
112125
sp.check_call(command, shell=True, cwd=program.name)
113126

114127

128+
# Execute executable `p` with arguments `args` in directory `dir`
115129
def execute(p, args, dir):
116130
command = p + " " + args
117131
sp.check_call(command, shell=True, stdout=sp.DEVNULL, stderr=sp.DEVNULL, cwd=dir)
118132

119133

134+
# Benchmark the given program's executable
135+
# p = the program
136+
# exe_postfix = what postfix we gave the executable in `compile_wasm_to_executable`
137+
# name = the human readable name for this version of the executable
120138
def bench(p, exe_postfix, name):
121139
print("Testing {} {}".format(p, name))
122140
path = "{broot}/{pname}/bin/{pname}{pf}".format(broot=BENCH_ROOT, pname=p.name, pf=exe_postfix)
123141
command = "execute('{path}', '{args}', '{dir}')".format(path=path, args=' '.join(map(str, p.parameters)), dir=p.name)
124142
return min(timeit.repeat(command, 'from __main__ import execute', number=1, repeat=RUN_COUNT))
125143

126144

145+
# Output a run's execution time, telling us how much faster or slower it is
127146
def output_run(base_time, execution_time):
128147
base_time = round(base_time, 4)
129148
execution_time = round(execution_time, 4)
@@ -133,6 +152,7 @@ def output_run(base_time, execution_time):
133152
print("{:.4f} ({:.2f}% faster)".format(execution_time, ((base_time - execution_time) / base_time) * 100))
134153

135154

155+
# Compile all our programs
136156
for i, p in enumerate(programs):
137157
print("Compiling {} {}/{}".format(p.name, i + 1, len(programs)))
138158

@@ -151,6 +171,7 @@ def output_run(base_time, execution_time):
151171

152172
print()
153173

174+
# Benchmark and output timing info for each of our programs
154175
for p in programs:
155176
base_speed = bench(p, "", "native")
156177
print("{:.4f}".format(base_speed))

example_code/binarytrees.wasm

-21.7 KB
Binary file not shown.

example_code/m.out

-11.9 MB
Binary file not shown.

example_code/mandelbrot.wasm

-51.9 KB
Binary file not shown.

runtime/libc/libc_backing.c

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#include "../runtime.h"
22

3+
// What should we tell the child program its UID and GID are?
34
#define UID 0xFF
45
#define GID 0xFE
56

6-
// Elf auxilary vector values
7+
// Elf auxilary vector values (see google for what those are)
78
#define AT_NULL 0
89
#define AT_IGNORE 1
910
#define AT_EXECFD 2
@@ -24,10 +25,14 @@
2425
#define AT_BASE_PLATFORM 24
2526
#define AT_RANDOM 25
2627

28+
// The symbol the binary gives us to init libc
2729
void wasmf___init_libc(i32 envp, i32 pn);
2830

31+
// offset = a WASM ptr to memory the runtime can use
2932
void stub_init(i32 offset) {
33+
// What program name will we put in the auxiliary vectors
3034
char program_name[] = "wasm_program";
35+
// Copy the program name into WASM accessible memory
3136
i32 program_name_offset = offset;
3237
strcpy(get_memory_ptr_for_runtime(offset, sizeof(program_name)), program_name);
3338
offset += sizeof(program_name);
@@ -37,7 +42,7 @@ void stub_init(i32 offset) {
3742
i32 env_vec[] = {
3843
// Env variables would live here, but we don't supply any
3944
0,
40-
// We supply nessesary
45+
// We supply only the bare minimum AUX vectors
4146
AT_PAGESZ,
4247
WASM_PAGE_SIZE,
4348
AT_UID,
@@ -62,7 +67,7 @@ void stub_init(i32 offset) {
6267
switch_into_runtime();
6368
}
6469

65-
// Syscall stuff
70+
// Emulated syscall implementations
6671

6772
// We define our own syscall numbers, because WASM uses x86_64 values even on systems that are not x86_64
6873
#define SYS_READ 0
@@ -90,8 +95,7 @@ i32 wasm_write(i32 fd, i32 buf_offset, i32 buf_size) {
9095

9196
#define SYS_OPEN 2
9297
i32 wasm_open(i32 path_off, i32 flags, i32 mode) {
93-
// TODO: Handle string being bad
94-
char* path = get_memory_ptr_void(path_off, 0);
98+
char* path = get_memory_string(path_off);
9599
i32 res = (i32) open(path, flags, mode);
96100

97101
if (res == -1) {
@@ -111,6 +115,8 @@ i32 wasm_close(i32 fd) {
111115
return res;
112116
}
113117

118+
#define SYS_FSTAT 5
119+
// What the wasm stat structure looks like
114120
struct wasm_stat {
115121
i64 st_dev;
116122
u64 st_ino;
@@ -131,6 +137,7 @@ struct wasm_stat {
131137
i32 __pad1[3];
132138
};
133139

140+
// What the OSX stat structure looks like:
134141
// struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is NOT defined */
135142
// dev_t st_dev; /* device inode resides on */
136143
// ino_t st_ino; /* inode's number */
@@ -150,7 +157,6 @@ struct wasm_stat {
150157
// };
151158

152159

153-
#define SYS_FSTAT 5
154160
i32 wasm_fstat(i32 filedes, i32 stat_offset) {
155161
struct wasm_stat* stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat));
156162

@@ -217,16 +223,13 @@ u32 wasm_mmap(i32 addr, i32 len, i32 prot, i32 flags, i32 fd, i32 offset) {
217223

218224
#define SYS_RT_SIGACTION 13
219225

220-
221226
#define SYS_RT_SIGPROGMASK 14
222-
//i32 wasm_sigprocmask(i32 how, i32 set_ptr, i32 oset_ptr) {
223-
// return 0;
224-
//}
225227

226228
#define SYS_IOCTL 16
227229
i32 wasm_ioctl(i32 fd, i32 request, i32 data_offet) {
228-
/* musl libc does some ioctls to stdout, so just allow these to silently go through */
229-
return 0;
230+
// musl libc does some ioctls to stdout, so just allow these to silently go through
231+
// FIXME: The above is idiotic
232+
return 0;
230233
}
231234

232235
#define SYS_READV 19
@@ -492,24 +495,3 @@ INLINE double env_cos(double d) {
492495
return cos(d);
493496
}
494497

495-
496-
// gdbm code
497-
//int gdbm_file = 0;
498-
//GDBM_FILE gdbm_files[100];
499-
//
500-
//i32 env_gdbm_open(i32 name_off, i32 block_size, i32 read_write, i32 mode, i32 fatal_func) {
501-
// char* name = get_memory_ptr_void(name, 0);
502-
// GDBM_FILE f = gdbm_open(name, block_size, read_write, mode, NULL);
503-
// gdbm_files[gdbm_file] = f;
504-
// gdbm_file++;
505-
// return (i32) gdbm_file;
506-
//}
507-
//
508-
//i32 env_gdbm_close(i32 gf) {
509-
//
510-
//}
511-
//
512-
//
513-
//void env_gdbm_fetch(i32 a, i32 b, i32 c) {
514-
//}
515-
//

0 commit comments

Comments
 (0)