Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 98 additions & 15 deletions src/engine/Instance.v3
Original file line number Diff line number Diff line change
Expand Up @@ -101,23 +101,12 @@ class Instance(module: Module, imports: Array<Exportable>) {
}
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));
return Value.I31(u31.view(Values.unbox_i(evalInitExpr(val))));
}
Array(t, len, elem),
FixedArray(t, vals),
Struct(t, vals) => {
var vvals = Arrays.map(vals, evalInitExpr);
return Value.Ref(HeapStruct.new(t.sdecl, vvals));
return Value.Ref(evalInitExprObject(init));
}
ArrayNewData(t, data_index, offset, len) => {
var voffset = evalInitExpr(offset);
Expand All @@ -137,6 +126,100 @@ class Instance(module: Module, imports: Array<Exportable>) {
I64_MUL(a, b) => return Value.I64(Values.unbox_w(evalInitExpr(a)) * Values.unbox_w(evalInitExpr(b)));
}
}
// most init exprs are pure and can be evaluated repeatedly, but object ones are not pure
def initExprCacheObject = HashMap<InitExpr, Object>.new(fun (ie: InitExpr) => int.!(ie.tag), InitExpr.==);
def evalInitExprObject(init: InitExpr) -> Object {
if (initExprCacheObject.has(init)) return initExprCacheObject[init];
match (init) {
FuncRefNull,
RefNull(ht),
ExternRefNull => return null;
Global(global_index, g) => {
return Values.unbox<Object>(globals[global_index].get());
}
FuncRef(func_index, f) => {
return functions[func_index];
}
Const(val) => return Values.unbox<Object>(val);
I31(val) => {
return ObjectI31.new(u31.view(Values.unbox_i(evalInitExpr(val))));
}
Array(t, len, elem) => {
var vlen = Values.unbox_i(evalInitExpr(len));
var decl = t.array;
var st = decl.elem_types[0];
var velem = evalInitExpr(elem);
var obj: Object;
if (ObjReps.arrayMode == ArrayMode.Original) {
var vvals = Array<Value>.new(vlen);
for (i < vvals.length) vvals[i] = velem;
obj = HeapArrayValue.new(t.array, vvals);
} else {
obj = ObjectRuntime.evalInitExprObjectArray(t, st, velem, vlen);
}
initExprCacheObject[init] = obj;
return obj;
}
FixedArray(t, vals) => {
var decl = t.array;
var st = decl.elem_types[0];
var obj: Object;
if (ObjReps.arrayMode == ArrayMode.Original) {
obj = HeapArrayValue.new(t.array, Arrays.map(vals, evalInitExpr));
} else {
obj = ObjectRuntime.evalInitExprObjectFixedArray(this, t, st, vals);
}
initExprCacheObject[init] = obj;
return obj;
}
Struct(t, vals) => {
var vvals = Arrays.map(vals, evalInitExpr);
var obj: Object;
if (ObjReps.structMode == StructMode.Original) {
obj = HeapStructValue.new(t.sdecl, vvals);
} else {
obj = ObjectRuntime.evalInitExprObjectStruct(t, vvals);
}
initExprCacheObject[init] = obj;
return obj;
}
ArrayNewData(t, data_index, offset, len) => {
var voffset = evalInitExpr(offset);
var vlen = evalInitExpr(len);
return null; // TODO
}
ArrayNewElem(t, elem_index, offset, len) => {
var voffset = evalInitExpr(offset);
var vlen = evalInitExpr(len);
return null; // TODO
}
_ => return null;
}
}
def evalInitExprScalar<T>(init: InitExpr) -> T {
match (init) {
I32(val) => return T.!(u32.view(val));
I64(val) => return T.!(u64.view(val));
F32(val) => return T.!(val);
F64(val) => return T.!(val);
V128(low, high) => return T.!((low, high));
Global(global_index, g) => {
return Values.unbox<T>(globals[global_index].get());
}
Const(val) => return Values.unbox<T>(val);
I31(val) => {
var v = evalInitExpr(val);
return T.!(u31.view(Values.unbox_i(v)));
}
I32_ADD(a, b) => return T.!(Values.unbox_u(evalInitExpr(a)) + Values.unbox_u(evalInitExpr(b)));
I32_SUB(a, b) => return T.!(Values.unbox_u(evalInitExpr(a)) - Values.unbox_u(evalInitExpr(b)));
I32_MUL(a, b) => return T.!(Values.unbox_u(evalInitExpr(a)) * Values.unbox_u(evalInitExpr(b)));
I64_ADD(a, b) => return T.!(Values.unbox_w(evalInitExpr(a)) + Values.unbox_w(evalInitExpr(b)));
I64_SUB(a, b) => return T.!(Values.unbox_w(evalInitExpr(a)) - Values.unbox_w(evalInitExpr(b)));
I64_MUL(a, b) => return T.!(Values.unbox_w(evalInitExpr(a)) * Values.unbox_w(evalInitExpr(b)));
_ => return T.!(0);
}
}
def findExportOfType<T>(matcher: GlobMatcher) -> T {
var decls = module.exports;
for (i < decls.length) {
Expand Down
Loading
Loading