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
|
|
@ -12,11 +12,13 @@ functions: []vm.Function,
|
|||
memory: Memtype,
|
||||
exports: vm.Exports,
|
||||
importCount: u32,
|
||||
exported_memory: u32,
|
||||
|
||||
globalValues: []vm.Value,
|
||||
globalTypes: []Globaltype,
|
||||
|
||||
const Parser = @This();
|
||||
const PAGE_SIZE = 64_000;
|
||||
|
||||
pub const Error = error{
|
||||
OutOfMemory,
|
||||
|
|
@ -45,6 +47,7 @@ pub const Error = error{
|
|||
|
||||
pub fn init(allocator: Allocator, bytes: []const u8) !Parser {
|
||||
return .{
|
||||
.exported_memory = 0,
|
||||
.importCount = 0,
|
||||
.bytes = bytes,
|
||||
.byte_idx = 0,
|
||||
|
|
@ -79,6 +82,8 @@ pub fn module(self: *Parser) vm.Module {
|
|||
.min = self.memory.lim.min,
|
||||
.max = self.memory.lim.max,
|
||||
},
|
||||
.imported_funcs = self.importCount,
|
||||
.exported_memory = self.exported_memory,
|
||||
.functions = self.functions,
|
||||
.exports = self.exports,
|
||||
};
|
||||
|
|
@ -226,12 +231,12 @@ const Limits = struct {
|
|||
fn parseLimits(self: *Parser) !Limits {
|
||||
return switch (try self.readByte()) {
|
||||
0x00 => .{
|
||||
.min = try self.readU32(),
|
||||
.min = try self.readU32() * PAGE_SIZE,
|
||||
.max = null,
|
||||
},
|
||||
0x01 => .{
|
||||
.min = try self.readU32(),
|
||||
.max = try self.readU32(),
|
||||
.min = try self.readU32() * PAGE_SIZE,
|
||||
.max = try self.readU32() * PAGE_SIZE,
|
||||
},
|
||||
else => Error.invalid_limits,
|
||||
};
|
||||
|
|
@ -305,18 +310,6 @@ pub fn parseModule(self: *Parser) !void {
|
|||
if (self.exports.preinit != null and self.exports.preinit.? != 0){
|
||||
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 {
|
||||
|
|
@ -365,24 +358,26 @@ fn parseImportsec(self: *Parser) !void {
|
|||
const size = try self.readU32();
|
||||
const end_idx = self.byte_idx + size;
|
||||
|
||||
// TODO(ernesto): this should be used to do name resolution.
|
||||
const imports = try self.parseVector(Parser.parseImport);
|
||||
self.importCount = @intCast(imports.len);
|
||||
|
||||
var index: u32 = 0;
|
||||
|
||||
for (imports) |i| {
|
||||
switch (i.importdesc) {
|
||||
.func => {
|
||||
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")) {
|
||||
self.exports.logInfo = i.importdesc.func;
|
||||
self.exports.logInfo = index;
|
||||
} 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")) {
|
||||
self.exports.logErr = i.importdesc.func;
|
||||
self.exports.logErr = index;
|
||||
} else {
|
||||
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}),
|
||||
}
|
||||
|
|
@ -514,6 +509,9 @@ fn parseExportsec(self: *Parser) !void {
|
|||
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", .{}),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ pub const Module = struct {
|
|||
memory: Memory,
|
||||
functions: []Function,
|
||||
exports: Exports,
|
||||
exported_memory: u32,
|
||||
imported_funcs: u32,
|
||||
|
||||
pub fn deinit(self: Module, allocator: Allocator) void {
|
||||
// self.exports.deinit(allocator);
|
||||
|
|
@ -96,9 +98,9 @@ pub const Runtime = struct {
|
|||
|
||||
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
|
||||
const max = module.memory.max orelse 1_000;
|
||||
const max = module.memory.max orelse module.memory.min;
|
||||
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);
|
||||
return Runtime{
|
||||
|
|
@ -137,13 +139,22 @@ pub const Runtime = struct {
|
|||
.br_table => @panic("UNIMPLEMENTED"),
|
||||
.@"return" => break :loop,
|
||||
.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);
|
||||
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 self.call(allocator, index.u32, parameters.items);
|
||||
try self.call(allocator, index.u32 - self.module.imported_funcs, parameters.items);
|
||||
}
|
||||
},
|
||||
.call_indirect => @panic("UNIMPLEMENTED"),
|
||||
|
||||
|
|
@ -212,15 +223,19 @@ pub const Runtime = struct {
|
|||
.i64_load16_u => @panic("UNIMPLEMENTED"),
|
||||
.i64_load32_s => @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"),
|
||||
.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"),
|
||||
.f64_store => @panic("UNIMPLEMENTED"),
|
||||
.i32_store8 => @panic("UNIMPLEMENTED"),
|
||||
|
|
@ -504,7 +519,7 @@ pub fn handleGlobalInit(allocator: Allocator, ir: IR) !Value {
|
|||
.i32_const => try stack.append(Value{ .i32 = index.i32 }),
|
||||
else => {
|
||||
std.debug.panic("TODO: Handle opcode {any}\n", .{opcode});
|
||||
}
|
||||
},
|
||||
}
|
||||
instruction_pointer += 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue