Fixed the functions
This commit is contained in:
parent
6f942fe9c2
commit
83d91cfffe
4 changed files with 495996 additions and 41 deletions
495942
sideros.asm
Normal file
495942
sideros.asm
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -22,7 +22,7 @@ pub fn main() !void {
|
||||||
// defer global_runtime.deinit();
|
// defer global_runtime.deinit();
|
||||||
// try global_runtime.addFunction("debug", mods.Wasm.debug);
|
// try global_runtime.addFunction("debug", mods.Wasm.debug);
|
||||||
|
|
||||||
// //const file = try std.fs.cwd().openFile("assets/core.wasm", .{});
|
// // const file = try std.fs.cwd().openFile("assets/core.wasm", .{});
|
||||||
// const file = try std.fs.cwd().openFile("./test.wasm", .{});
|
// const file = try std.fs.cwd().openFile("./test.wasm", .{});
|
||||||
// const all = try file.readToEndAlloc(allocator, 1_000_000); // 1 MB
|
// const all = try file.readToEndAlloc(allocator, 1_000_000); // 1 MB
|
||||||
// defer allocator.free(all);
|
// defer allocator.free(all);
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,13 @@ functions: []vm.Function,
|
||||||
memory: Memtype,
|
memory: Memtype,
|
||||||
exports: vm.Exports,
|
exports: vm.Exports,
|
||||||
importCount: u32,
|
importCount: u32,
|
||||||
|
exported_memory: u32,
|
||||||
|
|
||||||
globalValues: []vm.Value,
|
globalValues: []vm.Value,
|
||||||
globalTypes: []Globaltype,
|
globalTypes: []Globaltype,
|
||||||
|
|
||||||
const Parser = @This();
|
const Parser = @This();
|
||||||
|
const PAGE_SIZE = 64_000;
|
||||||
|
|
||||||
pub const Error = error{
|
pub const Error = error{
|
||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
|
|
@ -45,6 +47,7 @@ pub const Error = error{
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, bytes: []const u8) !Parser {
|
pub fn init(allocator: Allocator, bytes: []const u8) !Parser {
|
||||||
return .{
|
return .{
|
||||||
|
.exported_memory = 0,
|
||||||
.importCount = 0,
|
.importCount = 0,
|
||||||
.bytes = bytes,
|
.bytes = bytes,
|
||||||
.byte_idx = 0,
|
.byte_idx = 0,
|
||||||
|
|
@ -79,6 +82,8 @@ pub fn module(self: *Parser) vm.Module {
|
||||||
.min = self.memory.lim.min,
|
.min = self.memory.lim.min,
|
||||||
.max = self.memory.lim.max,
|
.max = self.memory.lim.max,
|
||||||
},
|
},
|
||||||
|
.imported_funcs = self.importCount,
|
||||||
|
.exported_memory = self.exported_memory,
|
||||||
.functions = self.functions,
|
.functions = self.functions,
|
||||||
.exports = self.exports,
|
.exports = self.exports,
|
||||||
};
|
};
|
||||||
|
|
@ -226,12 +231,12 @@ const Limits = struct {
|
||||||
fn parseLimits(self: *Parser) !Limits {
|
fn parseLimits(self: *Parser) !Limits {
|
||||||
return switch (try self.readByte()) {
|
return switch (try self.readByte()) {
|
||||||
0x00 => .{
|
0x00 => .{
|
||||||
.min = try self.readU32(),
|
.min = try self.readU32() * PAGE_SIZE,
|
||||||
.max = null,
|
.max = null,
|
||||||
},
|
},
|
||||||
0x01 => .{
|
0x01 => .{
|
||||||
.min = try self.readU32(),
|
.min = try self.readU32() * PAGE_SIZE,
|
||||||
.max = try self.readU32(),
|
.max = try self.readU32() * PAGE_SIZE,
|
||||||
},
|
},
|
||||||
else => Error.invalid_limits,
|
else => Error.invalid_limits,
|
||||||
};
|
};
|
||||||
|
|
@ -305,18 +310,6 @@ pub fn parseModule(self: *Parser) !void {
|
||||||
if (self.exports.preinit != null and self.exports.preinit.? != 0){
|
if (self.exports.preinit != null and self.exports.preinit.? != 0){
|
||||||
self.exports.preinit.? -= self.importCount;
|
self.exports.preinit.? -= self.importCount;
|
||||||
}
|
}
|
||||||
if (self.exports.logDebug != null and self.exports.logDebug.? != 0){
|
|
||||||
self.exports.logDebug.? -= self.importCount;
|
|
||||||
}
|
|
||||||
if (self.exports.logInfo != null and self.exports.logInfo.? != 0){
|
|
||||||
self.exports.logInfo.? -= self.importCount;
|
|
||||||
}
|
|
||||||
if (self.exports.logWarn != null and self.exports.logWarn.? != 0){
|
|
||||||
self.exports.logWarn.? -= self.importCount;
|
|
||||||
}
|
|
||||||
if (self.exports.logErr != null and self.exports.logErr.? != 0){
|
|
||||||
self.exports.logErr.? -= self.importCount;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseCustomsec(self: *Parser) !void {
|
fn parseCustomsec(self: *Parser) !void {
|
||||||
|
|
@ -365,24 +358,26 @@ fn parseImportsec(self: *Parser) !void {
|
||||||
const size = try self.readU32();
|
const size = try self.readU32();
|
||||||
const end_idx = self.byte_idx + size;
|
const end_idx = self.byte_idx + size;
|
||||||
|
|
||||||
// TODO(ernesto): this should be used to do name resolution.
|
|
||||||
const imports = try self.parseVector(Parser.parseImport);
|
const imports = try self.parseVector(Parser.parseImport);
|
||||||
self.importCount = @intCast(imports.len);
|
self.importCount = @intCast(imports.len);
|
||||||
|
|
||||||
|
var index: u32 = 0;
|
||||||
|
|
||||||
for (imports) |i| {
|
for (imports) |i| {
|
||||||
switch (i.importdesc) {
|
switch (i.importdesc) {
|
||||||
.func => {
|
.func => {
|
||||||
if (std.mem.eql(u8, i.name, "logDebug")) {
|
if (std.mem.eql(u8, i.name, "logDebug")) {
|
||||||
self.exports.logDebug = i.importdesc.func;
|
self.exports.logDebug = index;
|
||||||
} else if (std.mem.eql(u8, i.name, "logInfo")) {
|
} else if (std.mem.eql(u8, i.name, "logInfo")) {
|
||||||
self.exports.logInfo = i.importdesc.func;
|
self.exports.logInfo = index;
|
||||||
} else if (std.mem.eql(u8, i.name, "logWarn")) {
|
} else if (std.mem.eql(u8, i.name, "logWarn")) {
|
||||||
self.exports.logWarn = i.importdesc.func;
|
self.exports.logWarn = index;
|
||||||
} else if (std.mem.eql(u8, i.name, "logErr")) {
|
} else if (std.mem.eql(u8, i.name, "logErr")) {
|
||||||
self.exports.logErr = i.importdesc.func;
|
self.exports.logErr = index;
|
||||||
} else {
|
} else {
|
||||||
std.log.warn("imported function {s} not supported\n", .{i.name});
|
std.log.warn("imported function {s} not supported\n", .{i.name});
|
||||||
}
|
}
|
||||||
|
index += 1;
|
||||||
},
|
},
|
||||||
else => std.debug.print("[TODO]: Handle import desc {any}\n", .{i.importdesc}),
|
else => std.debug.print("[TODO]: Handle import desc {any}\n", .{i.importdesc}),
|
||||||
}
|
}
|
||||||
|
|
@ -514,6 +509,9 @@ fn parseExportsec(self: *Parser) !void {
|
||||||
std.log.warn("exported function {s} not supported\n", .{e.name});
|
std.log.warn("exported function {s} not supported\n", .{e.name});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.mem => {
|
||||||
|
self.exported_memory = e.exportdesc.mem * PAGE_SIZE;
|
||||||
|
},
|
||||||
else => std.debug.print("[WARN]: export ignored\n", .{}),
|
else => std.debug.print("[WARN]: export ignored\n", .{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ pub const Module = struct {
|
||||||
memory: Memory,
|
memory: Memory,
|
||||||
functions: []Function,
|
functions: []Function,
|
||||||
exports: Exports,
|
exports: Exports,
|
||||||
|
exported_memory: u32,
|
||||||
|
imported_funcs: u32,
|
||||||
|
|
||||||
pub fn deinit(self: Module, allocator: Allocator) void {
|
pub fn deinit(self: Module, allocator: Allocator) void {
|
||||||
// self.exports.deinit(allocator);
|
// self.exports.deinit(allocator);
|
||||||
|
|
@ -96,9 +98,9 @@ pub const Runtime = struct {
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, module: Module, global_runtime: *wasm.GlobalRuntime) !Runtime {
|
pub fn init(allocator: Allocator, module: Module, global_runtime: *wasm.GlobalRuntime) !Runtime {
|
||||||
// if memory max is not set the memory is allowed to grow but it is not supported at the moment
|
// if memory max is not set the memory is allowed to grow but it is not supported at the moment
|
||||||
const max = module.memory.max orelse 1_000;
|
const max = module.memory.max orelse module.memory.min;
|
||||||
if (module.memory.max == null) {
|
if (module.memory.max == null) {
|
||||||
std.log.warn("Growing memory is not yet supported, usign a default value of 1Kb\n", .{});
|
std.log.warn("Growing memory is not yet supported, usign the minimum memory\n", .{});
|
||||||
}
|
}
|
||||||
const memory = try allocator.alloc(u8, max);
|
const memory = try allocator.alloc(u8, max);
|
||||||
return Runtime{
|
return Runtime{
|
||||||
|
|
@ -137,13 +139,22 @@ pub const Runtime = struct {
|
||||||
.br_table => @panic("UNIMPLEMENTED"),
|
.br_table => @panic("UNIMPLEMENTED"),
|
||||||
.@"return" => break :loop,
|
.@"return" => break :loop,
|
||||||
.call => {
|
.call => {
|
||||||
// TODO: figure out how many parameters to push
|
if (index.u32 == self.module.exports.logDebug) {
|
||||||
|
std.debug.print("TODO: logDebug\n", .{});
|
||||||
|
} else if (index.u32 == self.module.exports.logInfo) {
|
||||||
|
std.debug.print("TODO: logInfo\n", .{});
|
||||||
|
} else if (index.u32 == self.module.exports.logWarn) {
|
||||||
|
std.debug.print("TODO: logWarn\n", .{});
|
||||||
|
} else if (index.u32 == self.module.exports.logErr) {
|
||||||
|
std.debug.print("TODO: logErr\n", .{});
|
||||||
|
} else {
|
||||||
var parameters = std.ArrayList(Value).init(allocator);
|
var parameters = std.ArrayList(Value).init(allocator);
|
||||||
defer parameters.deinit();
|
defer parameters.deinit();
|
||||||
for (self.module.functions[index.u32].func_type.parameters) |_| {
|
for (self.module.functions[index.u32 - self.module.imported_funcs].func_type.parameters) |_| {
|
||||||
try parameters.append(self.stack.pop().?);
|
try parameters.append(self.stack.pop().?);
|
||||||
}
|
}
|
||||||
try self.call(allocator, index.u32, parameters.items);
|
try self.call(allocator, index.u32 - self.module.imported_funcs, parameters.items);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.call_indirect => @panic("UNIMPLEMENTED"),
|
.call_indirect => @panic("UNIMPLEMENTED"),
|
||||||
|
|
||||||
|
|
@ -212,15 +223,19 @@ pub const Runtime = struct {
|
||||||
.i64_load16_u => @panic("UNIMPLEMENTED"),
|
.i64_load16_u => @panic("UNIMPLEMENTED"),
|
||||||
.i64_load32_s => @panic("UNIMPLEMENTED"),
|
.i64_load32_s => @panic("UNIMPLEMENTED"),
|
||||||
.i64_load32_u => @panic("UNIMPLEMENTED"),
|
.i64_load32_u => @panic("UNIMPLEMENTED"),
|
||||||
// .i32_store => {
|
|
||||||
// // TODO(ernesto): I'm pretty sure this is wrong
|
|
||||||
// const start = index.memarg.offset + index.memarg.alignment;
|
|
||||||
// const end = start + @sizeOf(u32);
|
|
||||||
// const val = std.mem.nativeToLittle(i32, self.stack.pop().?.i32);
|
|
||||||
// @memcpy(self.memory[start..end], std.mem.asBytes(&val));
|
|
||||||
// },
|
|
||||||
.i32_store => @panic("UNIMPLEMENTED"),
|
.i32_store => @panic("UNIMPLEMENTED"),
|
||||||
.i64_store => @panic("UNIMPLEMENTED"),
|
.i64_store => {
|
||||||
|
// TODO(ernesto): I'm pretty sure this is wrong
|
||||||
|
const val = std.mem.nativeToLittle(i64, self.stack.pop().?.i64);
|
||||||
|
const offsetVal = self.stack.pop().?.i32;
|
||||||
|
if (offsetVal < 0) {
|
||||||
|
std.debug.panic("offsetVal is negative (val: {any})\n", .{offsetVal});
|
||||||
|
}
|
||||||
|
const offset: u64 = @intCast(offsetVal);
|
||||||
|
const start: usize = @intCast(@as(u64, index.memarg.offset) + offset);
|
||||||
|
const end = start + @sizeOf(u64);
|
||||||
|
@memcpy(self.memory[start..end], std.mem.asBytes(&val));
|
||||||
|
},
|
||||||
.f32_store => @panic("UNIMPLEMENTED"),
|
.f32_store => @panic("UNIMPLEMENTED"),
|
||||||
.f64_store => @panic("UNIMPLEMENTED"),
|
.f64_store => @panic("UNIMPLEMENTED"),
|
||||||
.i32_store8 => @panic("UNIMPLEMENTED"),
|
.i32_store8 => @panic("UNIMPLEMENTED"),
|
||||||
|
|
@ -497,18 +512,18 @@ pub fn handleGlobalInit(allocator: Allocator, ir: IR) !Value {
|
||||||
var instruction_pointer: usize = 0;
|
var instruction_pointer: usize = 0;
|
||||||
var stack = try std.ArrayList(Value).initCapacity(allocator, 10);
|
var stack = try std.ArrayList(Value).initCapacity(allocator, 10);
|
||||||
defer stack.deinit();
|
defer stack.deinit();
|
||||||
while (instruction_pointer < ir.opcodes.len){
|
while (instruction_pointer < ir.opcodes.len) {
|
||||||
const opcode: IR.Opcode = ir.opcodes[instruction_pointer];
|
const opcode: IR.Opcode = ir.opcodes[instruction_pointer];
|
||||||
const index = ir.indices[instruction_pointer];
|
const index = ir.indices[instruction_pointer];
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
.i32_const => try stack.append(Value{ .i32 = index.i32 }),
|
.i32_const => try stack.append(Value{ .i32 = index.i32 }),
|
||||||
else => {
|
else => {
|
||||||
std.debug.panic("TODO: Handle opcode {any}\n", .{opcode});
|
std.debug.panic("TODO: Handle opcode {any}\n", .{opcode});
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
instruction_pointer += 1;
|
instruction_pointer += 1;
|
||||||
}
|
}
|
||||||
if (stack.items.len != 1){
|
if (stack.items.len != 1) {
|
||||||
std.debug.panic("Improper amount of variables at end\n", .{});
|
std.debug.panic("Improper amount of variables at end\n", .{});
|
||||||
}
|
}
|
||||||
return stack.pop().?;
|
return stack.pop().?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue