Skip to content

Commit

Permalink
WIP use Decl2 more thoroughly
Browse files Browse the repository at this point in the history
  • Loading branch information
titzer committed Oct 10, 2023
1 parent 0c2e5ad commit 55df9dd
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 58 deletions.
67 changes: 51 additions & 16 deletions src/engine/Instantiator.v3
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,29 @@ class Instantiator(extensions: Extension.set, module: Module, var imports: Array
for (j < module.decls.length) {
if (error.error()) return null;
match (module.decls[j]) {
Sig(index) => {
RecGroup(abstract, index, length) => {
if (abstract) {
for (i < length) {
instance.heaptypes[index + i] = mapHeapType(module.heaptypes[index + i]);
}
Canon.globalCache.doGroup(Vectors.ofN(instance.heaptypes), index, length);
} else {
for (i < length) {
instance.heaptypes[index + i] = module.heaptypes[index + i];
}
}
}
Sig(abstract, index) => {
var decl = SigDecl.!(module.heaptypes[index]);
instance.heaptypes[index] = mapSig(decl); // TODO: respect recursion group
instance.heaptypes[index] = if(abstract, mapSig(decl), decl);
}
Struct(index) => {
Struct(abstract, index) => {
var decl = StructDecl.!(module.heaptypes[index]);
// TODO: substitute type declarations in struct
instance.heaptypes[index] = if(abstract, mapStruct(decl), decl);
}
Array(index) => {
Array(abstract, index) => {
var decl = ArrayDecl.!(module.heaptypes[index]);
instance.heaptypes[index] = if(abstract, mapArray(decl), decl);
}
AbsType(index) => {
var decl = module.abstypes[index];
Expand All @@ -79,7 +92,7 @@ class Instantiator(extensions: Extension.set, module: Module, var imports: Array
}
instance.abscodes[index] = code;
}
Func(index, sig_index) => {
Func(index) => {
var decl = module.functions[index];
if (decl.imp != null) {
var r = imports[decl.imp.import_index];
Expand Down Expand Up @@ -331,16 +344,16 @@ class Instantiator(extensions: Extension.set, module: Module, var imports: Array
return null;
}

def getDecl(d: Decl) -> Exportable {
def getDecl(d: Decl2) -> Exportable {
match (d) {
x: AbsTypeDecl => return instance.abstypes[x.abstype_index];
x: FuncDecl => return instance.functions[x.func_index];
x: TableDecl => return instance.tables[x.table_index];
x: MemoryDecl => return instance.memories[x.memory_index];
x: GlobalDecl => return instance.globals[x.global_index];
x: TagDecl => return instance.tags[x.tag_index];
AbsType(index) => return instance.abstypes[index];
Func(index) => return instance.functions[index];
Table(index) => return instance.tables[index];
Memory(index) => return instance.memories[index];
Global(index) => return instance.globals[index];
Tag(index) => return instance.tags[index];
_ => return null; // TODO
}
return null;
}
def getSigDecl(sig_index: int) -> SigDecl {
if (u32.view(sig_index) >= instance.heaptypes.length) return null;
Expand All @@ -360,9 +373,29 @@ class Instantiator(extensions: Extension.set, module: Module, var imports: Array
if (sig == null) return null;
var p = Arrays.map(sig.params, mapType);
var r = Arrays.map(sig.results, mapType);
var nsig = Canon.sigPR(p, r); // TODO: respect recursion group
var nsig = Canon.sigPR(p, r);
return nsig;
}
def mapStruct(decl: StructDecl) -> StructDecl {
return decl; // TODO: substitute and canonicalize
}
def mapArray(decl: ArrayDecl) -> ArrayDecl {
return decl; // TODO: substitute and canonicalize
}
def mapHeapTypeDecl(t: HeapTypeDecl) -> HeapTypeDecl {
match (t) {
x: SigDecl => {
var p = Arrays.map(x.params, mapType);
var r = Arrays.map(x.results, mapType);
return SigDecl.new(x.final, Arrays.map(x.supertypes, mapHeapType), p, r); // TODO: map super decls
}
x: StructDecl => {
}
x: ArrayDecl => {
}
_ => return t;
}
}
def mapType(t: ValueType) -> ValueType {
if (!module.isAbstract()) return t;
// TODO: memoize results of previous type mappings
Expand All @@ -378,7 +411,9 @@ class Instantiator(extensions: Extension.set, module: Module, var imports: Array
_ => ; // no change, but constraints may change
}
}
// TODO: struct and arrays
Ref(nullable, ht) => match(ht) {
_ => ; // TODO: struct and arrays
}
_ => ;
}
return (false, t); // no change
Expand Down
28 changes: 14 additions & 14 deletions src/engine/Module.v3
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Module(filename: string) {
def memories = Vector<MemoryDecl>.new();
def globals = Vector<GlobalDecl>.new();
def tags = Vector<TagDecl>.new(); // exception-handling extension
def exports = Vector<(string, Decl)>.new();
def exports = Vector<(string, Decl2)>.new();
def elems = Vector<ElemDecl>.new();
def data = Vector<DataDecl>.new();
def custom_sections = Vector<CustomSection>.new();
Expand All @@ -35,17 +35,17 @@ class Module(filename: string) {
match (d) {
x: SigDecl => {
var index = heaptypes.length;
decls.put(Decl2.Sig(x.heaptype_index = index));
decls.put(Decl2.Sig(false, x.heaptype_index = index));
heaptypes.put(x);
}
x: StructDecl => {
var index = heaptypes.length;
decls.put(Decl2.Struct(x.heaptype_index = index));
decls.put(Decl2.Struct(false, x.heaptype_index = index));
heaptypes.put(x);
}
x: ArrayDecl => {
var index = heaptypes.length;
decls.put(Decl2.Array(x.heaptype_index = index));
decls.put(Decl2.Array(false, x.heaptype_index = index));
heaptypes.put(x);
}
x: AbsTypeDecl => {
Expand All @@ -55,7 +55,7 @@ class Module(filename: string) {
}
x: FuncDecl => {
var index = functions.length;
decls.put(Decl2.Func(x.func_index = index, x.sig_index));
decls.put(Decl2.Func(x.func_index = index));
functions.put(x);
if (u32.view(x.sig_index) < heaptypes.length) {
var d = heaptypes[x.sig_index];
Expand All @@ -69,7 +69,7 @@ class Module(filename: string) {
}
x: MemoryDecl => {
var index = memories.length;
decls.put(Decl2.Memory(x.memory_index = index));
decls.put(Decl2.Memory(index));
memories.put(x);
}
x: GlobalDecl => {
Expand All @@ -93,7 +93,7 @@ class Module(filename: string) {
}
}
// Add a new import declaration to this module. Adds this declaration to {imports} as well.
def addImport(module_name: string, field_name: string, args: Array<Decl>, d: Decl) {
def addImport(module_name: string, field_name: string, args: Array<Decl2>, d: Decl) {
if (d == null) return;
if (args == null) args = Modules.NO_IMPORT_ARGS;
d.imp = ImportInfo.new(module_name, field_name, imports.length, args);
Expand All @@ -111,7 +111,7 @@ class Module(filename: string) {
}

// For imported quantities, the module name, field name, index, and args.
class ImportInfo(module_name: string, field_name: string, import_index: int, args: Array<Decl>) {
class ImportInfo(module_name: string, field_name: string, import_index: int, args: Array<Decl2>) {
}

// Superclass of all declared and importable/exportable declarations.
Expand Down Expand Up @@ -225,7 +225,6 @@ class TableDecl(elemtype: ValueType, initial: u32, maximum: Max) extends Decl {

// Memory declaration, including limits, shared attribute, and index type.
class MemoryDecl(initial: u64, maximum: Max, shared: bool, indexType: ValueType) extends Decl {
var memory_index = -1;
}

// Global variable declaration, including type and mutability.
Expand Down Expand Up @@ -312,17 +311,18 @@ type Max {

// Globals associated with modules.
component Modules {
def NO_IMPORT_ARGS: Array<Decl> = [];
def NO_IMPORT_ARGS: Array<Decl2> = [];
def EX_TAG_ALL = -1;
def EX_TAG_DELEGATE = -2;
}

type Decl2 {
case Sig(index: int);
case Struct(index: int);
case Array(index: int);
case RecGroup(abstract: bool, index: int, length: int);
case Sig(abstract: bool, index: int);
case Struct(abstract: bool, index: int);
case Array(abstract: bool, index: int);
case AbsType(index: int);
case Func(index: int, sig_index: int);
case Func(index: int);
case Table(index: int);
case Memory(index: int);
case Global(index: int);
Expand Down
77 changes: 76 additions & 1 deletion src/engine/Type.v3
Original file line number Diff line number Diff line change
Expand Up @@ -539,4 +539,79 @@ component HeapTypeDecls {
}
return buf;
}
}
}

// Handles substituting type arguments in for {AbsTypeDecl}s in a module.
class TypeSubst {
def cache: HeapTypeCache;
def args: Array<ValueType>;
def inputs: Vector<HeapTypeDecl>;
def outputs: Vector<HeapTypeDecl> = Vectors.ofN(inputs.copy());
private var refNullTypes: Array<ValueType>;
private var refNonnullTypes: Array<ValueType>;

new(cache, args, inputs) { }

def mapSig(sig: SigDecl) -> SigDecl {
if (args.length == 0 || sig == null) return sig; // TODO: check sig.open
return SigDecl.!(cache.doOne(substSig(sig)));
}
def mapStruct(decl: StructDecl) -> StructDecl {
if (args.length == 0 || decl == null) return decl; // TODO: check sig.open
return StructDecl.!(cache.doOne(substStruct(decl)));
}
def mapArray(decl: ArrayDecl) -> ArrayDecl {
if (args.length == 0 || decl == null) return decl; // TODO: check sig.open
return ArrayDecl.!(cache.doOne(substArray(decl)));
}
def mapHeapTypeDecl(t: HeapTypeDecl) -> HeapTypeDecl {
match (t) {
x: SigDecl => return substSig(x);
x: StructDecl => return substStruct(x);
x: ArrayDecl => return substArray(x);
_ => return t;
}
}
def mapType(t: ValueType) -> ValueType {
if (args.length == 0) return t;
match (t) {
Ref(nullable, ht) => match(ht) {
Func(sig) => {
var nsig = outputs[sig.heaptype_index];
if (nsig == sig) return t;
}
Struct(decl) => {
var ndecl = outputs[decl.heaptype_index];
if (ndecl == decl) return t;
}
Array(decl) => {
var ndecl = outputs[decl.heaptype_index];
if (ndecl == decl) return t;
}
_ => return t;
}
Abstract(it) => return args[it.abstype_index];
_ => return t;
}
// TODO: memoize results of previous type mappings
return ValueTypes.map(t, mapAbs).1;
}
private def substSig(sig: SigDecl) -> SigDecl {
if (args.length == 0) return sig; // TODO: check sig.open
var p = Arrays.map(sig.params, mapType);
var r = Arrays.map(sig.results, mapType);
return SigDecl.new(sig.final, mapSupertypes(sig.supertypes), p, r);
}
private def substStruct(decl: StructDecl) -> StructDecl {
if (args.length == 0) return decl; // TODO: check decl.open
return decl; // TODO
}
private def substArray(decl: ArrayDecl) -> ArrayDecl {
if (args.length == 0) return decl; // TODO: check decl.open
return decl; // TODO
}
private def mapSupertypes(supertypes: Array<HeapType>) -> Array<HeapType> {
if (supertypes == null || supertypes.length == 0) return supertypes;
return Arrays.map(supertypes, mapHeapType);
}
}
14 changes: 8 additions & 6 deletions src/monitors/MemoryMonitor.v3
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ class MemoryMonitor extends Monitor {
OUT.puts(Palette.LNO)
.rjustify(' ', TraceUtil.renderedLength(OUT, TraceBuilder.put1(_, "+%x", dynamicLoc.pc)), 5);
}
private def beforeMemRead(dynamicLoc: DynamicLoc, mem: Memory, address: u64, size: u64) -> Resumption {
private def beforeMemRead(imm: MemArg, dynamicLoc: DynamicLoc, address: u64, size: u64) -> Resumption {
if (locations) putLocation(dynamicLoc);
OUT.puts(Palette.SOURCE)
.rjustify(' ', TraceUtil.renderedLength(OUT, TraceBuilder.puts(_, "read")), 7)
.putc(' ');
putMemIndexAndAddress(mem.decl.memory_index, address);
putMemIndexAndAddress(imm.memory_index, address);
var mem = dynamicLoc.func.instance.memories[imm.memory_index];
OUT.putc(' ').puts(Palette.DEFAULT);
for (i < size) {
var b = mem.read1w(address + i);
Expand All @@ -53,12 +54,13 @@ class MemoryMonitor extends Monitor {
.outln();
return Resumption.Continue;
}
private def beforeMemWrite(dynamicLoc: DynamicLoc, mem: Memory, address: u64, size: u64) -> Resumption {
private def beforeMemWrite(imm: MemArg, dynamicLoc: DynamicLoc, address: u64, size: u64) -> Resumption {
if (locations) putLocation(dynamicLoc);
OUT.puts(Palette.TARGET)
.rjustify(' ', TraceUtil.renderedLength(OUT, TraceBuilder.puts(_, "write")), 7)
.putc(' ');
putMemIndexAndAddress(mem.decl.memory_index, address);
putMemIndexAndAddress(imm.memory_index, address);
var mem = dynamicLoc.func.instance.memories[imm.memory_index];
OUT.putc(' ').puts(Palette.DEFAULT);
var val = dynamicLoc.frame.getFrameAccessor().getOperand(0);
match (size) {
Expand Down Expand Up @@ -89,12 +91,12 @@ class MemoryMonitor extends Monitor {
.outln();
return Resumption.Continue;
}
private def beforeMemGrow(dynamicLoc: DynamicLoc, mem: Memory, pages: u32) -> Resumption {
private def beforeMemGrow(memory_index: u31, dynamicLoc: DynamicLoc, pages: u32) -> Resumption {
if (locations) putLocation(dynamicLoc);
OUT.puts(Palette.SUCCESS)
.rjustify(' ', TraceUtil.renderedLength(OUT, TraceBuilder.puts(_, "grow")), 7)
.putc(' ').puts(Palette.DEFAULT);
putMemIndex(mem.decl.memory_index);
putMemIndex(memory_index);
OUT.putx_32(pages);
OUT.putc(' ');
// TODO: put result
Expand Down
Loading

0 comments on commit 55df9dd

Please sign in to comment.