diff options
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r-- | src/lj_carith.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c index 134a61fb..bba9f6b9 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c | |||
@@ -148,21 +148,6 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm) | |||
148 | setboolV(L->top-1, | 148 | setboolV(L->top-1, |
149 | id == CTID_INT64 ? ((int64_t)u0 <= (int64_t)u1) : (u0 <= u1)); | 149 | id == CTID_INT64 ? ((int64_t)u0 <= (int64_t)u1) : (u0 <= u1)); |
150 | return 1; | 150 | return 1; |
151 | case MM_div: case MM_mod: | ||
152 | if (u1 == 0) { /* Division by zero. */ | ||
153 | if (u0 == 0) | ||
154 | setnanV(L->top-1); | ||
155 | else if (id == CTID_INT64 && (int64_t)u0 < 0) | ||
156 | setminfV(L->top-1); | ||
157 | else | ||
158 | setpinfV(L->top-1); | ||
159 | return 1; | ||
160 | } else if (id == CTID_INT64 && (int64_t)u1 == -1 && | ||
161 | u0 == U64x(80000000,00000000)) { /* MIN64 / -1. */ | ||
162 | if (mm == MM_div) id = CTID_UINT64; else u0 = 0; | ||
163 | mm = MM_unm; /* Result is 0x8000000000000000ULL or 0LL. */ | ||
164 | } | ||
165 | break; | ||
166 | default: break; | 151 | default: break; |
167 | } | 152 | } |
168 | cd = lj_cdata_new(cts, id, 8); | 153 | cd = lj_cdata_new(cts, id, 8); |
@@ -174,15 +159,15 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm) | |||
174 | case MM_mul: *up = u0 * u1; break; | 159 | case MM_mul: *up = u0 * u1; break; |
175 | case MM_div: | 160 | case MM_div: |
176 | if (id == CTID_INT64) | 161 | if (id == CTID_INT64) |
177 | *up = (uint64_t)((int64_t)u0 / (int64_t)u1); | 162 | *up = (uint64_t)lj_carith_divi64((int64_t)u0, (int64_t)u1); |
178 | else | 163 | else |
179 | *up = u0 / u1; | 164 | *up = lj_carith_divu64(u0, u1); |
180 | break; | 165 | break; |
181 | case MM_mod: | 166 | case MM_mod: |
182 | if (id == CTID_INT64) | 167 | if (id == CTID_INT64) |
183 | *up = (uint64_t)((int64_t)u0 % (int64_t)u1); | 168 | *up = (uint64_t)lj_carith_modi64((int64_t)u0, (int64_t)u1); |
184 | else | 169 | else |
185 | *up = u0 % u1; | 170 | *up = lj_carith_modu64(u0, u1); |
186 | break; | 171 | break; |
187 | case MM_pow: | 172 | case MM_pow: |
188 | if (id == CTID_INT64) | 173 | if (id == CTID_INT64) |
@@ -231,13 +216,43 @@ int lj_carith_op(lua_State *L, MMS mm) | |||
231 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ | 216 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ |
232 | 217 | ||
233 | #if LJ_32 | 218 | #if LJ_32 |
234 | /* Signed/unsigned 64 bit multiply. */ | 219 | /* Signed/unsigned 64 bit multiplication. */ |
235 | int64_t lj_carith_mul64(int64_t a, int64_t b) | 220 | int64_t lj_carith_mul64(int64_t a, int64_t b) |
236 | { | 221 | { |
237 | return a * b; | 222 | return a * b; |
238 | } | 223 | } |
239 | #endif | 224 | #endif |
240 | 225 | ||
226 | /* Unsigned 64 bit division. */ | ||
227 | uint64_t lj_carith_divu64(uint64_t a, uint64_t b) | ||
228 | { | ||
229 | if (b == 0) return U64x(80000000,00000000); | ||
230 | return a / b; | ||
231 | } | ||
232 | |||
233 | /* Signed 64 bit division. */ | ||
234 | int64_t lj_carith_divi64(int64_t a, int64_t b) | ||
235 | { | ||
236 | if (b == 0 || (a == (int64_t)U64x(80000000,00000000) && b == -1)) | ||
237 | return U64x(80000000,00000000); | ||
238 | return a / b; | ||
239 | } | ||
240 | |||
241 | /* Unsigned 64 bit modulo. */ | ||
242 | uint64_t lj_carith_modu64(uint64_t a, uint64_t b) | ||
243 | { | ||
244 | if (b == 0) return U64x(80000000,00000000); | ||
245 | return a % b; | ||
246 | } | ||
247 | |||
248 | /* Signed 64 bit modulo. */ | ||
249 | int64_t lj_carith_modi64(int64_t a, int64_t b) | ||
250 | { | ||
251 | if (b == 0) return U64x(80000000,00000000); | ||
252 | if (a == (int64_t)U64x(80000000,00000000) && b == -1) return 0; | ||
253 | return a % b; | ||
254 | } | ||
255 | |||
241 | /* Unsigned 64 bit x^k. */ | 256 | /* Unsigned 64 bit x^k. */ |
242 | uint64_t lj_carith_powu64(uint64_t x, uint64_t k) | 257 | uint64_t lj_carith_powu64(uint64_t x, uint64_t k) |
243 | { | 258 | { |