@@ -21,75 +21,115 @@ struct Num {
2121 int32_t toInt () const { return static_cast <int32_t >(value); }
2222 uint32_t toUInt () const { return static_cast <uint32_t >(value); }
2323
24+ // debug printer: enabled only when -DDEBUG
25+ static inline void debug_print (const char *op, const Num &a, const Num &b,
26+ const Num &res) {
27+ #ifdef DEBUG_OP
28+ std::cout << " [Debug] " << op << " : lhs=" << static_cast <int32_t >(a.value )
29+ << " rhs=" << static_cast <int32_t >(b.value )
30+ << " -> res=" << static_cast <int32_t >(res.value ) << std::endl;
31+ #endif
32+ }
33+
2434 // Helper to create a Wasm Boolean result (1 or 0 as Num)
25- Num WasmBool (bool condition) const { return Num (condition ? 1 : 0 ); }
35+ Num WasmBool (bool condition) const {
36+ Num res (condition ? 1 : 0 );
37+ debug_print (" WasmBool" , *this , *this , res);
38+ return res;
39+ }
2640 // TODO: support different bit width operations, for now we just assume all
2741 // oprands are i32
2842 // i32.eq (Equals): *this == other
2943 inline Num i32_eq (const Num &other) const {
30- return WasmBool (this ->toUInt () == other.toUInt ());
44+ Num res = WasmBool (this ->toUInt () == other.toUInt ());
45+ debug_print (" i32.eq" , *this , other, res);
46+ return res;
3147 }
3248
3349 // i32.ne (Not Equals): *this != other
3450 inline Num i32_ne (const Num &other) const {
35- return WasmBool (this ->toUInt () != other.toUInt ());
51+ Num res = WasmBool (this ->toUInt () != other.toUInt ());
52+ debug_print (" i32.ne" , *this , other, res);
53+ return res;
3654 }
3755
3856 // i32.lt_s (Signed Less Than): *this < other
3957 inline Num i32_lt_s (const Num &other) const {
40- return WasmBool (this ->toInt () < other.toInt ());
58+ Num res = WasmBool (this ->toInt () < other.toInt ());
59+ debug_print (" i32.lt_s" , *this , other, res);
60+ return res;
4161 }
4262
4363 // i32.lt_u (Unsigned Less Than): *this < other (unsigned)
4464 inline Num i32_lt_u (const Num &other) const {
45- return WasmBool (this ->toUInt () < other.toUInt ());
65+ Num res = WasmBool (this ->toUInt () < other.toUInt ());
66+ debug_print (" i32.lt_u" , *this , other, res);
67+ return res;
4668 }
4769
4870 // i32.le_s (Signed Less Than or Equal): *this <= other
4971 inline Num i32_le_s (const Num &other) const {
50- return WasmBool (this ->toInt () <= other.toInt ());
72+ Num res = WasmBool (this ->toInt () <= other.toInt ());
73+ debug_print (" i32.le_s" , *this , other, res);
74+ return res;
5175 }
5276 // i32.le_u (Unsigned Less Than or Equal): *this <= other (unsigned)
5377 inline Num i32_le_u (const Num &other) const {
54- return WasmBool (this ->toUInt () <= other.toUInt ());
78+ Num res = WasmBool (this ->toUInt () <= other.toUInt ());
79+ debug_print (" i32.le_u" , *this , other, res);
80+ return res;
5581 }
5682
5783 // i32.gt_s (Signed Greater Than): *this > other
5884 inline Num i32_gt_s (const Num &other) const {
59- return WasmBool (this ->toInt () > other.toInt ());
85+ Num res = WasmBool (this ->toInt () > other.toInt ());
86+ debug_print (" i32.gt_s" , *this , other, res);
87+ return res;
6088 }
6189
6290 // i32.gt_u (Unsigned Greater Than): *this > other (unsigned)
6391 inline Num i32_gt_u (const Num &other) const {
64- return WasmBool (this ->toUInt () > other.toUInt ());
92+ Num res = WasmBool (this ->toUInt () > other.toUInt ());
93+ debug_print (" i32.gt_u" , *this , other, res);
94+ return res;
6595 }
6696
6797 // i32.ge_s (Signed Greater Than or Equal): *this >= other
6898 inline Num i32_ge_s (const Num &other) const {
69- return WasmBool (this ->toInt () >= other.toInt ());
99+ Num res = WasmBool (this ->toInt () >= other.toInt ());
100+ debug_print (" i32.ge_s" , *this , other, res);
101+ return res;
70102 }
71103
72104 // i32.ge_u (Unsigned Greater Than or Equal): *this >= other (unsigned)
73105 inline Num i32_ge_u (const Num &other) const {
74- return WasmBool (this ->toUInt () >= other.toUInt ());
106+ Num res = WasmBool (this ->toUInt () >= other.toUInt ());
107+ debug_print (" i32.ge_u" , *this , other, res);
108+ return res;
75109 }
76110
77111 // i32.add (Wrapping addition)
78112 inline Num i32_add (const Num &other) const {
79113 uint32_t result_u = this ->toUInt () + other.toUInt ();
80- return Num (static_cast <int32_t >(result_u));
114+ Num res (static_cast <int32_t >(result_u));
115+ debug_print (" i32.add" , *this , other, res);
116+ return res;
81117 }
82118
83119 // i32.sub (Wrapping subtraction)
84120 inline Num i32_sub (const Num &other) const {
85121 uint32_t result_u = this ->toUInt () - other.toUInt ();
86- return Num (static_cast <int32_t >(result_u));
122+ Num res (static_cast <int32_t >(result_u));
123+ debug_print (" i32.sub" , *this , other, res);
124+ return res;
87125 }
88126
89127 // i32.mul (Wrapping multiplication)
90128 inline Num i32_mul (const Num &other) const {
91129 uint32_t result_u = this ->toUInt () * other.toUInt ();
92- return Num (static_cast <int32_t >(result_u));
130+ Num res (static_cast <int32_t >(result_u));
131+ debug_print (" i32.mul" , *this , other, res);
132+ return res;
93133 }
94134
95135 // i32.div_s (Signed division with traps)
@@ -101,36 +141,46 @@ struct Num {
101141 throw std::runtime_error (" i32.div_s: Division by zero" );
102142 }
103143
104- return Num (dividend / divisor);
144+ Num res (dividend / divisor);
145+ debug_print (" i32.div_s" , *this , other, res);
146+ return res;
105147 }
106148
107149 // i32.shl (Shift Left): *this << other (shift count masked by 31)
108150 inline Num i32_shl (const Num &other) const {
109151 uint32_t shift_amount = other.toUInt () & 0x1F ;
110152 uint32_t result_u = toUInt () << shift_amount;
111- return Num (static_cast <int32_t >(result_u));
153+ Num res (static_cast <int32_t >(result_u));
154+ debug_print (" i32.shl" , *this , other, res);
155+ return res;
112156 }
113157
114158 // i32.shr_s (Signed Shift Right): *this >> other (Arithmetic shift)
115159 inline Num i32_shr_s (const Num &other) const {
116160 // Wasm masks the shift amount by 31 (0x1F)
117161 uint32_t shift_amount = other.toUInt () & 0x1F ;
118162 int32_t result_s = toInt () >> shift_amount;
119- return Num (result_s);
163+ Num res (result_s);
164+ debug_print (" i32.shr_s" , *this , other, res);
165+ return res;
120166 }
121167
122168 // i32.shr_u (Unsigned Shift Right): *this >>> other (Logical shift)
123169 inline Num i32_shr_u (const Num &other) const {
124170 // Wasm masks the shift amount by 31 (0x1F)
125171 uint32_t shift_amount = other.toUInt () & 0x1F ;
126172 uint32_t result_u = toUInt () >> shift_amount;
127- return Num (static_cast <int32_t >(result_u));
173+ Num res (static_cast <int32_t >(result_u));
174+ debug_print (" i32.shr_u" , *this , other, res);
175+ return res;
128176 }
129177
130178 // i32.and (Bitwise AND)
131179 inline Num i32_and (const Num &other) const {
132180 uint32_t result_u = this ->toUInt () & other.toUInt ();
133- return Num (static_cast <int32_t >(result_u));
181+ Num res (static_cast <int32_t >(result_u));
182+ debug_print (" i32.and" , *this , other, res);
183+ return res;
134184 }
135185};
136186
@@ -272,6 +322,10 @@ class Frames_t {
272322 void pushFrame (std::int32_t size) {
273323 assert (size >= 0 );
274324 count += size;
325+ // Zero-initialize the new stack frames.
326+ for (std::int32_t i = 0 ; i < size; ++i) {
327+ stack_ptr[count - 1 - i] = Num (0 );
328+ }
275329 }
276330
277331 void reset () { count = 0 ; }
0 commit comments