-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathInstance.v3
150 lines (144 loc) · 5.18 KB
/
Instance.v3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2020 Ben L. Titzer. All rights reserved.
// See LICENSE for details of Apache 2.0 license.
// Superclass of all import/exportable objects.
class Exportable {
def render(buf: StringBuilder) -> StringBuilder {
return buf.puts("<exportable>");
}
}
// Abstract base class of host and wasm functions.
class Function(sig: SigDecl) extends Object {
}
// An instantiated wasm function, i.e. one bound to an instance.
class WasmFunction(instance: Instance, decl: FuncDecl) extends Function {
new() super(decl.sig) { }
def render(buf: StringBuilder) -> StringBuilder {
return buf.put1("<wasm func %q>", renderShort);
}
def renderShort(buf: StringBuilder) -> StringBuilder {
var names = if(instance != null, instance.module.names);
return decl.render(names, buf);
}
}
// An instantiated tag.
class Tag(sig: SigDecl, decl: TagDecl) extends Exportable {
}
// An instantiated global.
class Global(valtype: ValueType, decl: GlobalDecl) extends Exportable {
var value: Value;
}
// Superclass of all exported types.
class ExportedType extends Exportable {
}
// ext:typed-continuation
// `top` is the stack that was newly created or one that called `suspend`. When
// resuming, the control flow will jump to `top`.
// `bottom` is the stack that was a child to the receiver stack of this
// continuation.
//
// e.g., assuming stack A resumed B, which in turn resumed C:
//
// A -> B -> C
//
// If `suspend $t1` happened on C and was caught by A, then the continuation
// will be:
//
// Continuation.new(C, B)
//
class Continuation extends Object {
var top: WasmStack;
var bottom: WasmStack;
var used = false;
new(top, bottom) { }
def render(buf: StringBuilder) -> StringBuilder {
return buf.puts("cont");
}
}
// Wraps a source or host external type with its Wasm-level representation.
class ExportedValueType(src: ExportedType, vt: ValueType) extends ExportedType {
def render(buf: StringBuilder) -> StringBuilder {
if (src != null) buf.put2("<exported_type %q, %q>", src.render, vt.render);
else buf.put1("<exported_type %q>", vt.render);
return buf;
}
}
// An instantiated module, including memories, tables, functions, etc.
class Instance(module: Module, imports: Array<Exportable>) {
def memories = Array<Memory>.new(module.memories.length);
def functions = Array<Function>.new(module.functions.length);
def sig_ids = Array<int>.new(module.heaptypes.length);
def tags = Array<Tag>.new(module.tags.length);
def globals = Array<Global>.new(module.globals.length);
def tables = Array<Table>.new(module.tables.length);
def exports = Array<Exportable>.new(module.exports.length);
def heaptypes = module.heaptypes.copy();
def dropped_elems = Array<bool>.new(module.elems.length);
def dropped_data = Array<bool>.new(module.data.length);
def getFunctionAsVal(func_index: int) -> Value.Ref {
return Value.Ref(functions[func_index]);
}
def evalInitExpr(init: InitExpr) -> Value {
match (init) {
I32(val) => return Value.I32(u32.view(val));
I64(val) => return Value.I64(u64.view(val));
F32(val) => return Value.F32(val);
F64(val) => return Value.F64(val);
V128(low, high) => return Value.V128(low, high);
FuncRefNull,
RefNull(ht),
ExternRefNull => return Values.REF_NULL;
Global(global_index, g) => {
return globals[global_index].value;
}
FuncRef(func_index, f) => {
return Value.Ref(functions[func_index]);
}
Const(val) => return val;
I31(val) => {
var v = evalInitExpr(val);
return Value.I31(u31.view(Values.unbox_i(v)));
}
Array(t, len, elem) => {
var vlen = Values.unbox_i(evalInitExpr(len));
var vvals = Array<Value>.new(vlen); // TODO: check for OOM
var velem = evalInitExpr(elem);
for (i < vvals.length) vvals[i] = velem;
return Value.Ref(HeapArray.new(t.array, vvals));
}
FixedArray(t, vals) => {
var vvals = Arrays.map(vals, evalInitExpr);
return Value.Ref(HeapArray.new(t.array, vvals));
}
Struct(t, vals) => {
var vvals = Arrays.map(vals, evalInitExpr);
return Value.Ref(HeapStruct.new(t.sdecl, vvals));
}
ArrayNewData(t, data_index, offset, len) => {
var voffset = evalInitExpr(offset);
var vlen = evalInitExpr(len);
return Values.I32_0; // TODO
}
ArrayNewElem(t, elem_index, offset, len) => {
var voffset = evalInitExpr(offset);
var vlen = evalInitExpr(len);
return Values.I32_0; // TODO
}
I32_ADD(a, b) => return Value.I32(Values.unbox_u(evalInitExpr(a)) + Values.unbox_u(evalInitExpr(b)));
I32_SUB(a, b) => return Value.I32(Values.unbox_u(evalInitExpr(a)) - Values.unbox_u(evalInitExpr(b)));
I32_MUL(a, b) => return Value.I32(Values.unbox_u(evalInitExpr(a)) * Values.unbox_u(evalInitExpr(b)));
I64_ADD(a, b) => return Value.I64(Values.unbox_w(evalInitExpr(a)) + Values.unbox_w(evalInitExpr(b)));
I64_SUB(a, b) => return Value.I64(Values.unbox_w(evalInitExpr(a)) - Values.unbox_w(evalInitExpr(b)));
I64_MUL(a, b) => return Value.I64(Values.unbox_w(evalInitExpr(a)) * Values.unbox_w(evalInitExpr(b)));
}
}
def findExportOfType<T>(matcher: GlobMatcher) -> T {
var decls = module.exports;
for (i < decls.length) {
if (matcher != null && !matcher.matches(decls[i].0)) continue;
var iex = exports[i];
if (T.?(iex)) return T.!(iex);
}
var d: T;
return d;
}
}