@@ -659,27 +659,50 @@ fn run_vm(stack: *Interpreter, in: *Instance, r: *Reader) !void {
659659 }
660660}
661661
662- pub fn eval_constant_expr (r : * Reader , typ : defs.ValType , preglobals : []const StackValue ) ! StackValue {
662+ pub fn eval_constant_expr (r : * Reader , typ : defs.ValType , preglobals : []const StackValue , gpa : std.mem.Allocator ) ! StackValue {
663663 // shortcut: `expr` is just "i??.const VAL end"
664- const eval = try r .readByte ();
665- const init_typ : defs.OpCode = @enumFromInt (eval );
666664 _ = typ ;
667- const val : StackValue = val : switch (init_typ ) {
668- .i32_const = > .{ .i32 = try r .readLeb (i32 ) },
669- .i64_const = > .{ .i64 = try r .readLeb (i64 ) },
670- .f32_const = > .{ .f32 = try r .readf (f32 ) },
671- .f64_const = > .{ .f64 = try r .readf (f64 ) },
672- .ref_null = > {
665+
666+ var stack : std .ArrayList (StackValue ) = .empty ;
667+
668+ while (true ) {
669+ const eval = try r .readByte ();
670+ const init_typ : defs.OpCode = @enumFromInt (eval );
671+ const val : StackValue = val : switch (init_typ ) {
672+ .i32_const = > .{ .i32 = try r .readLeb (i32 ) },
673+ .i64_const = > .{ .i64 = try r .readLeb (i64 ) },
674+ .f32_const = > .{ .f32 = try r .readf (f32 ) },
675+ .f64_const = > .{ .f64 = try r .readf (f64 ) },
676+ .ref_null = > {
677+ _ = try r .readByte ();
678+ break :val .{ .ref = 0 };
679+ },
680+ .global_get = > {
681+ const idx = try r .readu ();
682+ if (idx >= preglobals .len ) return error .InvalidFormat ;
683+ break :val preglobals [idx ].indir .* ;
684+ },
685+ .i32_add , .i32_sub , .i32_mul , .i64_add , .i64_sub , .i64_mul = > {
686+ const rhs = stack .pop () orelse return error .InvalidFormat ;
687+ const lhs = stack .pop () orelse return error .InvalidFormat ;
688+ break :val switch (init_typ ) {
689+ .i32_add = > .{ .i32 = lhs .i32 + rhs .i32 },
690+ .i32_sub = > .{ .i32 = lhs .i32 - rhs .i32 },
691+ .i32_mul = > .{ .i32 = lhs .i32 * rhs .i32 },
692+ .i64_add = > .{ .i64 = lhs .i64 + rhs .i64 },
693+ .i64_sub = > .{ .i64 = lhs .i64 - rhs .i64 },
694+ .i64_mul = > .{ .i64 = lhs .i64 * rhs .i64 },
695+ else = > unreachable ,
696+ };
697+ },
698+ else = > return error .InvalidFormat ,
699+ };
700+ if (r .peekByte () == 0x0b ) {
673701 _ = try r .readByte ();
674- break :val .{ .ref = 0 };
675- },
676- .global_get = > {
677- const idx = try r .readu ();
678- if (idx >= preglobals .len ) return error .InvalidFormat ;
679- break :val preglobals [idx ].indir .* ;
680- },
681- else = > return error .InvalidFormat ,
682- };
683- if (try r .readByte () != 0x0b ) return error .InvalidFormat ;
684- return val ;
702+ if (stack .items .len > 0 ) return error .InvalidFormat ;
703+ return val ;
704+ } else {
705+ try stack .append (gpa , val );
706+ }
707+ }
685708}
0 commit comments