public WebAssemblyExecutionContext(WebAssemblyFile file) { if (file.table != null) { InitTable(file); } if (file.global != null) { InitGlobal(file); } if (file.memory != null) { InitMemory(file); } if (file.data != null) { InitData(file); } if (file.import != null) { InitImport(file); } InitFunctions(file); if (file.export != null) { InitExport(file); } // TODO: InitElement(ctx); }
public WebAssemblyInterpreter(WebAssemblyFile file) { this.file = file; if (file.type == null) { throw new Exception("No type information!"); } if (file.function == null) { throw new Exception("No type information!"); } if (file.code == null) { throw new Exception("No code to execute!"); } if (file.start == null) { throw new Exception("No start function!"); } ctx = new WebAssemblyExecutionContext(file); ResolveExternalFunctions(); uint start_func = file.start.index; logger.Debug($"Start function index is {start_func}. This index does {(ctx.functions.ContainsKey(start_func) ? "" : "not")} exist."); if (!ctx.functions.ContainsKey(start_func)) { throw new Exception("Corrupt file."); } }
private void InitFunctions(WebAssemblyFile file) { logger.Debug("Instanciating Functions."); Dictionary <uint, FuncType> type_info = new Dictionary <uint, FuncType>(); for (uint i = 0; i < (uint)file.type.entries.Length; i++) { type_info[i] = file.type.entries[i]; logger.ConditionalTrace($"Type {i} = {file.type.entries[i]}."); } logger.ConditionalTrace($"file.function.types.Length = {file.function.types.Length} and file.code.bodies.Length = {file.code.bodies.Length}."); if (file.function.types.Length != file.code.bodies.Length) { throw new Exception("Invalid file"); } uint import_count = (uint)functions.Count; logger.ConditionalTrace($"Import count = {import_count}."); for (uint i = 0; i < (uint)file.code.bodies.Length; i++) { uint index = file.function.types[i]; FunctionBody body = file.code.bodies[i]; uint func_indx = i + import_count; logger.ConditionalTrace($"Function {func_indx} = {body}."); functions[func_indx] = new FunctionInstance { module = "this", is_in_module = true, code = body.code, parameters = type_info[index].param_types, return_type = type_info[index].return_type, }; List <WebAssemblyType> locals_unwrapped = new List <WebAssemblyType>(); foreach (var local in body.locals) { locals_unwrapped.AddRange(Enumerable.Repeat(local.type, (int)local.count)); } functions[func_indx].locals = locals_unwrapped.ToArray(); logger.ConditionalTrace($"Final object = {functions[func_indx]}."); } logger.Debug("Done instanciating Functions."); }
private void InitData(WebAssemblyFile file) { logger.Debug("Instanciating Data."); foreach (var entry in file.data.entries) { var offset = WebAssemblyHelper.GetOffset(entry.offset); logger.ConditionalTrace($"Copying: {BitConverter.ToString(entry.data).Replace("-", "")} to [{offset},{offset + entry.data.Length}]."); Array.Copy(entry.data, 0, linear_memory[entry.memory_index].memory, offset, entry.data.Length); } logger.Debug("Done instanciating Data."); }
private void InitMemory(WebAssemblyFile file) { logger.Debug("Instanciating Memory."); for (uint i = 0; i < (uint)file.memory.entries.Length; i++) { var limits = file.memory.entries[i].limits; logger.ConditionalTrace($"Instanciating MemoryInstance({limits.initial}, {limits.maximum})."); linear_memory[i] = new MemoryInstance(limits.initial, limits.maximum); } logger.Debug("Done instanciating Memory."); }
private void InitTable(WebAssemblyFile file) { logger.Debug("Instanciating Table."); for (uint i = 0; i < (uint)file.table.entries.Length; i++) { var entry = file.table.entries[i]; logger.ConditionalTrace($"Instanciating TableInstance({entry.element_type}, {entry.limits.initial}, {entry.limits.maximum ?? 0})."); tables[i] = new TableInstance(entry.element_type, entry.limits.initial, entry.limits.maximum); } logger.Debug("Done instanciating Table."); }
private void InitGlobal(WebAssemblyFile file) { logger.Debug("Instanciating Globals."); List <GlobalInstance> finalized_globals = new List <GlobalInstance>(); for (uint i = 0; i < (uint)file.global.globals.Length; i++) { var global = file.global.globals[i]; var value = WebAssemblyHelper.GetInitExpr(global.init, finalized_globals); logger.ConditionalTrace($"Instanciating GlobalInstance({global.type.mutability}, {global.type.content_type}, {value})."); globals[i] = new GlobalInstance(global.type.mutability, global.type.content_type, value); finalized_globals.Add(globals[i]); } logger.Debug("Done instanciating Globals."); }
private void InitExport(WebAssemblyFile file) { logger.Debug("Instanciating Export."); for (uint i = 0; i < (uint)file.export.entries.Length; i++) { var entry = file.export.entries[i]; logger.ConditionalTrace($"Export is {entry.index}: {entry.kind} {entry.field_str}."); switch (entry.kind) { case WebAssemblyExternalKind.Function: var index = entry.index; functions[index].is_export = true; functions[index].name = entry.field_str; break; } } logger.Debug("Done instanciating Export."); }
private void InitImport(WebAssemblyFile file) { logger.Debug("Instanciating Export."); Dictionary <uint, FuncType> type_info = new Dictionary <uint, FuncType>(); for (uint i = 0; i < (uint)file.type.entries.Length; i++) { type_info[i] = file.type.entries[i]; logger.ConditionalTrace($"Type {i} = {file.type.entries[i]}."); } for (uint i = 0; i < (uint)file.import.entries.Length; i++) { var entry = file.import.entries[i]; logger.Debug($"Entry = {entry}."); switch (entry.kind) { case WebAssemblyExternalKind.Function: uint index = (uint)entry.type; functions[i] = new FunctionInstance { module = entry.module_str, name = entry.field_str, parameters = type_info[index].param_types, return_type = type_info[index].return_type }; logger.ConditionalTrace($"Function {i} = {functions[i]}."); break; } } logger.Debug("Done instanciating Export."); }