package/wprobe: {enhancement} make printing attributes optional. A delay interval...
[openwrt.git] / package / lua / patches / 010-lua-5.1.3-lnum-full-260308.patch
1 --- a/src/Makefile
2 +++ b/src/Makefile
3 @@ -25,7 +25,7 @@ PLATS= aix ansi bsd freebsd generic linu
4 LUA_A= liblua.a
5 CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
6 lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
7 - lundump.o lvm.o lzio.o
8 + lundump.o lvm.o lzio.o lnum.o
9 LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
10 lstrlib.o loadlib.o linit.o
11
12 @@ -148,6 +148,7 @@ llex.o: llex.c lua.h luaconf.h ldo.h lob
13 lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
14 lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
15 ltm.h lzio.h lmem.h ldo.h
16 +lnum.o: lnum.c lua.h llex.h lnum.h
17 loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
18 lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \
19 ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h
20 @@ -179,4 +180,18 @@ lzio.o: lzio.c lua.h luaconf.h llimits.h
21 print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \
22 ltm.h lzio.h lmem.h lopcodes.h lundump.h
23
24 +luaconf.h: lnum_config.h
25 +lapi.c: lnum.h
26 +lauxlib.c: llimits.h
27 +lbaselib.c: llimits.h lobject.h lapi.h
28 +lcode.c: lnum.h
29 +liolib.c: lnum.h llex.h
30 +llex.c: lnum.h
31 +lnum.h: lobject.h
32 +lobject.c: llex.h lnum.h
33 +ltable.c: lnum.h
34 +lua.c: llimits.h
35 +lvm.c: llex.h lnum.h
36 +print.c: lnum.h
37 +
38 # (end of Makefile)
39 --- a/src/lapi.c
40 +++ b/src/lapi.c
41 @@ -28,7 +28,7 @@
42 #include "ltm.h"
43 #include "lundump.h"
44 #include "lvm.h"
45 -
46 +#include "lnum.h"
47
48
49 const char lua_ident[] =
50 @@ -241,12 +241,13 @@ LUA_API void lua_pushvalue (lua_State *L
51
52 LUA_API int lua_type (lua_State *L, int idx) {
53 StkId o = index2adr(L, idx);
54 - return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
55 + return (o == luaO_nilobject) ? LUA_TNONE : ttype_ext(o);
56 }
57
58
59 LUA_API const char *lua_typename (lua_State *L, int t) {
60 UNUSED(L);
61 + lua_assert( t!= LUA_TINT );
62 return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
63 }
64
65 @@ -264,6 +265,14 @@ LUA_API int lua_isnumber (lua_State *L,
66 }
67
68
69 +LUA_API int lua_isinteger (lua_State *L, int idx) {
70 + TValue tmp;
71 + lua_Integer dum;
72 + const TValue *o = index2adr(L, idx);
73 + return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum));
74 +}
75 +
76 +
77 LUA_API int lua_isstring (lua_State *L, int idx) {
78 int t = lua_type(L, idx);
79 return (t == LUA_TSTRING || t == LUA_TNUMBER);
80 @@ -309,31 +318,66 @@ LUA_API int lua_lessthan (lua_State *L,
81 }
82
83
84 -
85 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
86 TValue n;
87 const TValue *o = index2adr(L, idx);
88 - if (tonumber(o, &n))
89 + if (tonumber(o, &n)) {
90 +#ifdef LNUM_COMPLEX
91 + if (nvalue_img(o) != 0)
92 + luaG_runerror(L, "expecting a real number");
93 +#endif
94 return nvalue(o);
95 - else
96 - return 0;
97 + }
98 + return 0;
99 }
100
101
102 LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
103 TValue n;
104 + /* Lua 5.1 documented behaviour is to return nonzero for non-integer:
105 + * "If the number is not an integer, it is truncated in some non-specified way."
106 + * I would suggest to change this, to return 0 for anything that would
107 + * not fit in 'lua_Integer'.
108 + */
109 +#ifdef LUA_COMPAT_TOINTEGER
110 + /* Lua 5.1 compatible */
111 const TValue *o = index2adr(L, idx);
112 if (tonumber(o, &n)) {
113 - lua_Integer res;
114 - lua_Number num = nvalue(o);
115 - lua_number2integer(res, num);
116 - return res;
117 + lua_Integer i;
118 + lua_Number d;
119 + if (ttisint(o)) return ivalue(o);
120 + d= nvalue_fast(o);
121 +# ifdef LNUM_COMPLEX
122 + if (nvalue_img_fast(o) != 0)
123 + luaG_runerror(L, "expecting a real number");
124 +# endif
125 + lua_number2integer(i, d);
126 + return i;
127 }
128 - else
129 - return 0;
130 +#else
131 + /* New suggestion */
132 + const TValue *o = index2adr(L, idx);
133 + if (tonumber(o, &n)) {
134 + lua_Integer i;
135 + if (ttisint(o)) return ivalue(o);
136 + if (tt_integer_valued(o,&i)) return i;
137 + }
138 +#endif
139 + return 0;
140 }
141
142
143 +#ifdef LNUM_COMPLEX
144 +LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) {
145 + TValue tmp;
146 + const TValue *o = index2adr(L, idx);
147 + if (tonumber(o, &tmp))
148 + return nvalue_complex(o);
149 + return 0;
150 +}
151 +#endif
152 +
153 +
154 LUA_API int lua_toboolean (lua_State *L, int idx) {
155 const TValue *o = index2adr(L, idx);
156 return !l_isfalse(o);
157 @@ -364,6 +408,7 @@ LUA_API size_t lua_objlen (lua_State *L,
158 case LUA_TSTRING: return tsvalue(o)->len;
159 case LUA_TUSERDATA: return uvalue(o)->len;
160 case LUA_TTABLE: return luaH_getn(hvalue(o));
161 + case LUA_TINT:
162 case LUA_TNUMBER: {
163 size_t l;
164 lua_lock(L); /* `luaV_tostring' may create a new string */
165 @@ -426,6 +471,8 @@ LUA_API void lua_pushnil (lua_State *L)
166 }
167
168
169 +/* 'lua_pushnumber()' may lose accuracy on integers, 'lua_pushinteger' will not.
170 + */
171 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
172 lua_lock(L);
173 setnvalue(L->top, n);
174 @@ -434,12 +481,22 @@ LUA_API void lua_pushnumber (lua_State *
175 }
176
177
178 -LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
179 +LUA_API void lua_pushinteger (lua_State *L, lua_Integer i) {
180 + lua_lock(L);
181 + setivalue(L->top, i);
182 + api_incr_top(L);
183 + lua_unlock(L);
184 +}
185 +
186 +
187 +#ifdef LNUM_COMPLEX
188 +LUA_API void lua_pushcomplex (lua_State *L, lua_Complex v) {
189 lua_lock(L);
190 - setnvalue(L->top, cast_num(n));
191 + setnvalue_complex( L->top, v );
192 api_incr_top(L);
193 lua_unlock(L);
194 }
195 +#endif
196
197
198 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
199 @@ -569,7 +626,7 @@ LUA_API void lua_rawgeti (lua_State *L,
200 lua_lock(L);
201 o = index2adr(L, idx);
202 api_check(L, ttistable(o));
203 - setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
204 + setobj2s(L, L->top, luaH_getint(hvalue(o), n));
205 api_incr_top(L);
206 lua_unlock(L);
207 }
208 @@ -597,6 +654,9 @@ LUA_API int lua_getmetatable (lua_State
209 case LUA_TUSERDATA:
210 mt = uvalue(obj)->metatable;
211 break;
212 + case LUA_TINT:
213 + mt = G(L)->mt[LUA_TNUMBER];
214 + break;
215 default:
216 mt = G(L)->mt[ttype(obj)];
217 break;
218 @@ -687,7 +747,7 @@ LUA_API void lua_rawseti (lua_State *L,
219 api_checknelems(L, 1);
220 o = index2adr(L, idx);
221 api_check(L, ttistable(o));
222 - setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
223 + setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
224 luaC_barriert(L, hvalue(o), L->top-1);
225 L->top--;
226 lua_unlock(L);
227 @@ -721,7 +781,7 @@ LUA_API int lua_setmetatable (lua_State
228 break;
229 }
230 default: {
231 - G(L)->mt[ttype(obj)] = mt;
232 + G(L)->mt[ttype_ext(obj)] = mt;
233 break;
234 }
235 }
236 @@ -1085,3 +1145,32 @@ LUA_API const char *lua_setupvalue (lua_
237 return name;
238 }
239
240 +
241 +/* Help function for 'luaB_tonumber()', avoids multiple str->number
242 + * conversions for Lua "tonumber()".
243 + *
244 + * Also pushes floating point numbers with integer value as integer, which
245 + * can be used by 'tonumber()' in scripts to bring values back to integer
246 + * realm.
247 + *
248 + * Note: The 'back to integer realm' is _not_ to affect string conversions:
249 + * 'tonumber("4294967295.1")' should give a floating point value, although
250 + * the value would be 4294967296 (and storable in int64 realm).
251 + */
252 +int lua_pushvalue_as_number (lua_State *L, int idx)
253 +{
254 + const TValue *o = index2adr(L, idx);
255 + TValue tmp;
256 + lua_Integer i;
257 + if (ttisnumber(o)) {
258 + if ( (!ttisint(o)) && tt_integer_valued(o,&i)) {
259 + lua_pushinteger( L, i );
260 + return 1;
261 + }
262 + } else if (!tonumber(o, &tmp)) {
263 + return 0;
264 + }
265 + if (ttisint(o)) lua_pushinteger( L, ivalue(o) );
266 + else lua_pushnumber( L, nvalue_fast(o) );
267 + return 1;
268 +}
269 --- a/src/lapi.h
270 +++ b/src/lapi.h
271 @@ -13,4 +13,6 @@
272
273 LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
274
275 +int lua_pushvalue_as_number (lua_State *L, int idx);
276 +
277 #endif
278 --- a/src/lauxlib.c
279 +++ b/src/lauxlib.c
280 @@ -23,7 +23,7 @@
281 #include "lua.h"
282
283 #include "lauxlib.h"
284 -
285 +#include "llimits.h"
286
287 #define FREELIST_REF 0 /* free list of references */
288
289 @@ -66,7 +66,7 @@ LUALIB_API int luaL_typerror (lua_State
290
291
292 static void tag_error (lua_State *L, int narg, int tag) {
293 - luaL_typerror(L, narg, lua_typename(L, tag));
294 + luaL_typerror(L, narg, tag==LUA_TINT ? "integer" : lua_typename(L, tag));
295 }
296
297
298 @@ -188,8 +188,8 @@ LUALIB_API lua_Number luaL_optnumber (lu
299
300 LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
301 lua_Integer d = lua_tointeger(L, narg);
302 - if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
303 - tag_error(L, narg, LUA_TNUMBER);
304 + if (d == 0 && !lua_isinteger(L, narg)) /* avoid extra test when d is not 0 */
305 + tag_error(L, narg, LUA_TINT);
306 return d;
307 }
308
309 @@ -200,6 +200,16 @@ LUALIB_API lua_Integer luaL_optinteger (
310 }
311
312
313 +#ifdef LNUM_COMPLEX
314 +LUALIB_API lua_Complex luaL_checkcomplex (lua_State *L, int narg) {
315 + lua_Complex c = lua_tocomplex(L, narg);
316 + if (c == 0 && !lua_isnumber(L, narg)) /* avoid extra test when c is not 0 */
317 + tag_error(L, narg, LUA_TNUMBER);
318 + return c;
319 +}
320 +#endif
321 +
322 +
323 LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
324 if (!lua_getmetatable(L, obj)) /* no metatable? */
325 return 0;
326 --- a/src/lauxlib.h
327 +++ b/src/lauxlib.h
328 @@ -57,6 +57,12 @@ LUALIB_API lua_Number (luaL_optnumber) (
329 LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
330 LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
331 lua_Integer def);
332 +#define luaL_checkint32(L,narg) ((int)luaL_checkinteger(L,narg))
333 +#define luaL_optint32(L,narg,def) ((int)luaL_optinteger(L,narg,def))
334 +
335 +#ifdef LNUM_COMPLEX
336 + LUALIB_API lua_Complex (luaL_checkcomplex) (lua_State *L, int narg);
337 +#endif
338
339 LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
340 LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
341 --- a/src/lbaselib.c
342 +++ b/src/lbaselib.c
343 @@ -18,7 +18,9 @@
344
345 #include "lauxlib.h"
346 #include "lualib.h"
347 -
348 +#include "llimits.h"
349 +#include "lobject.h"
350 +#include "lapi.h"
351
352
353
354 @@ -54,20 +56,25 @@ static int luaB_tonumber (lua_State *L)
355 int base = luaL_optint(L, 2, 10);
356 if (base == 10) { /* standard conversion */
357 luaL_checkany(L, 1);
358 - if (lua_isnumber(L, 1)) {
359 - lua_pushnumber(L, lua_tonumber(L, 1));
360 + if (lua_isnumber(L, 1)) { /* numeric string, or a number */
361 + lua_pushvalue_as_number(L,1); /* API extension (not to lose accuracy here) */
362 return 1;
363 - }
364 + }
365 }
366 else {
367 const char *s1 = luaL_checkstring(L, 1);
368 char *s2;
369 - unsigned long n;
370 + unsigned LUA_INTEGER n;
371 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
372 - n = strtoul(s1, &s2, base);
373 + n = lua_str2ul(s1, &s2, base);
374 if (s1 != s2) { /* at least one valid digit? */
375 while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
376 if (*s2 == '\0') { /* no invalid trailing characters? */
377 +
378 + /* Push as number, there needs to be separate 'luaB_tointeger' for
379 + * when the caller wants to preserve the bits (matters if unsigned
380 + * values are used).
381 + */
382 lua_pushnumber(L, (lua_Number)n);
383 return 1;
384 }
385 @@ -144,7 +151,7 @@ static int luaB_setfenv (lua_State *L) {
386 luaL_checktype(L, 2, LUA_TTABLE);
387 getfunc(L, 0);
388 lua_pushvalue(L, 2);
389 - if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
390 + if (lua_isnumber(L, 1) && lua_tointeger(L, 1) == 0) {
391 /* change environment of current thread */
392 lua_pushthread(L);
393 lua_insert(L, -2);
394 @@ -209,7 +216,7 @@ static int luaB_collectgarbage (lua_Stat
395 return 1;
396 }
397 default: {
398 - lua_pushnumber(L, res);
399 + lua_pushinteger(L, res);
400 return 1;
401 }
402 }
403 @@ -631,6 +638,8 @@ static void base_open (lua_State *L) {
404 luaL_register(L, "_G", base_funcs);
405 lua_pushliteral(L, LUA_VERSION);
406 lua_setglobal(L, "_VERSION"); /* set global _VERSION */
407 + lua_pushliteral(L, LUA_LNUM);
408 + lua_setglobal(L, "_LNUM"); /* "[complex] double|float|ldouble int32|int64" */
409 /* `ipairs' and `pairs' need auxliliary functions as upvalues */
410 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
411 auxopen(L, "pairs", luaB_pairs, luaB_next);
412 --- a/src/lcode.c
413 +++ b/src/lcode.c
414 @@ -22,13 +22,18 @@
415 #include "lopcodes.h"
416 #include "lparser.h"
417 #include "ltable.h"
418 +#include "lnum.h"
419
420
421 #define hasjumps(e) ((e)->t != (e)->f)
422
423 -
424 static int isnumeral(expdesc *e) {
425 - return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
426 + int ek=
427 +#ifdef LNUM_COMPLEX
428 + (e->k == VKNUM2) ||
429 +#endif
430 + (e->k == VKINT) || (e->k == VKNUM);
431 + return (ek && e->t == NO_JUMP && e->f == NO_JUMP);
432 }
433
434
435 @@ -231,12 +236,16 @@ static int addk (FuncState *fs, TValue *
436 TValue *idx = luaH_set(L, fs->h, k);
437 Proto *f = fs->f;
438 int oldsize = f->sizek;
439 - if (ttisnumber(idx)) {
440 - lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
441 - return cast_int(nvalue(idx));
442 + if (ttype(idx)==LUA_TNUMBER) {
443 + luai_normalize(idx);
444 + lua_assert( ttype(idx)==LUA_TINT ); /* had no fraction */
445 + }
446 + if (ttisint(idx)) {
447 + lua_assert(luaO_rawequalObj(&fs->f->k[ivalue(idx)], v));
448 + return cast_int(ivalue(idx));
449 }
450 else { /* constant not found; create a new entry */
451 - setnvalue(idx, cast_num(fs->nk));
452 + setivalue(idx, fs->nk);
453 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
454 MAXARG_Bx, "constant table overflow");
455 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
456 @@ -261,6 +270,21 @@ int luaK_numberK (FuncState *fs, lua_Num
457 }
458
459
460 +int luaK_integerK (FuncState *fs, lua_Integer r) {
461 + TValue o;
462 + setivalue(&o, r);
463 + return addk(fs, &o, &o);
464 +}
465 +
466 +
467 +#ifdef LNUM_COMPLEX
468 +static int luaK_imagK (FuncState *fs, lua_Number r) {
469 + TValue o;
470 + setnvalue_complex(&o, r*I);
471 + return addk(fs, &o, &o);
472 +}
473 +#endif
474 +
475 static int boolK (FuncState *fs, int b) {
476 TValue o;
477 setbvalue(&o, b);
478 @@ -359,6 +383,16 @@ static void discharge2reg (FuncState *fs
479 luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
480 break;
481 }
482 + case VKINT: {
483 + luaK_codeABx(fs, OP_LOADK, reg, luaK_integerK(fs, e->u.ival));
484 + break;
485 + }
486 +#ifdef LNUM_COMPLEX
487 + case VKNUM2: {
488 + luaK_codeABx(fs, OP_LOADK, reg, luaK_imagK(fs, e->u.nval));
489 + break;
490 + }
491 +#endif
492 case VRELOCABLE: {
493 Instruction *pc = &getcode(fs, e);
494 SETARG_A(*pc, reg);
495 @@ -444,6 +478,10 @@ void luaK_exp2val (FuncState *fs, expdes
496 int luaK_exp2RK (FuncState *fs, expdesc *e) {
497 luaK_exp2val(fs, e);
498 switch (e->k) {
499 +#ifdef LNUM_COMPLEX
500 + case VKNUM2:
501 +#endif
502 + case VKINT:
503 case VKNUM:
504 case VTRUE:
505 case VFALSE:
506 @@ -451,6 +489,10 @@ int luaK_exp2RK (FuncState *fs, expdesc
507 if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
508 e->u.s.info = (e->k == VNIL) ? nilK(fs) :
509 (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
510 + (e->k == VKINT) ? luaK_integerK(fs, e->u.ival) :
511 +#ifdef LNUM_COMPLEX
512 + (e->k == VKNUM2) ? luaK_imagK(fs, e->u.nval) :
513 +#endif
514 boolK(fs, (e->k == VTRUE));
515 e->k = VK;
516 return RKASK(e->u.s.info);
517 @@ -540,7 +582,10 @@ void luaK_goiftrue (FuncState *fs, expde
518 int pc; /* pc of last jump */
519 luaK_dischargevars(fs, e);
520 switch (e->k) {
521 - case VK: case VKNUM: case VTRUE: {
522 +#ifdef LNUM_COMPLEX
523 + case VKNUM2:
524 +#endif
525 + case VKINT: case VK: case VKNUM: case VTRUE: {
526 pc = NO_JUMP; /* always true; do nothing */
527 break;
528 }
529 @@ -598,7 +643,10 @@ static void codenot (FuncState *fs, expd
530 e->k = VTRUE;
531 break;
532 }
533 - case VK: case VKNUM: case VTRUE: {
534 +#ifdef LNUM_COMPLEX
535 + case VKNUM2:
536 +#endif
537 + case VKINT: case VK: case VKNUM: case VTRUE: {
538 e->k = VFALSE;
539 break;
540 }
541 @@ -634,25 +682,70 @@ void luaK_indexed (FuncState *fs, expdes
542
543 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
544 lua_Number v1, v2, r;
545 + int vkres= VKNUM;
546 if (!isnumeral(e1) || !isnumeral(e2)) return 0;
547 - v1 = e1->u.nval;
548 - v2 = e2->u.nval;
549 +
550 + /* real and imaginary parts don't mix. */
551 +#ifdef LNUM_COMPLEX
552 + if (e1->k == VKNUM2) {
553 + if ((op != OP_UNM) && (e2->k != VKNUM2)) return 0;
554 + vkres= VKNUM2; }
555 + else if (e2->k == VKNUM2) { return 0; }
556 +#endif
557 + if ((e1->k == VKINT) && (e2->k == VKINT)) {
558 + lua_Integer i1= e1->u.ival, i2= e2->u.ival;
559 + lua_Integer rr;
560 + int done= 0;
561 + /* Integer/integer calculations (may end up producing floating point) */
562 + switch (op) {
563 + case OP_ADD: done= try_addint( &rr, i1, i2 ); break;
564 + case OP_SUB: done= try_subint( &rr, i1, i2 ); break;
565 + case OP_MUL: done= try_mulint( &rr, i1, i2 ); break;
566 + case OP_DIV: done= try_divint( &rr, i1, i2 ); break;
567 + case OP_MOD: done= try_modint( &rr, i1, i2 ); break;
568 + case OP_POW: done= try_powint( &rr, i1, i2 ); break;
569 + case OP_UNM: done= try_unmint( &rr, i1 ); break;
570 + default: done= 0; break;
571 + }
572 + if (done) {
573 + e1->u.ival = rr; /* remained within integer range */
574 + return 1;
575 + }
576 + }
577 + v1 = (e1->k == VKINT) ? ((lua_Number)e1->u.ival) : e1->u.nval;
578 + v2 = (e2->k == VKINT) ? ((lua_Number)e2->u.ival) : e2->u.nval;
579 +
580 switch (op) {
581 case OP_ADD: r = luai_numadd(v1, v2); break;
582 case OP_SUB: r = luai_numsub(v1, v2); break;
583 - case OP_MUL: r = luai_nummul(v1, v2); break;
584 + case OP_MUL:
585 +#ifdef LNUM_COMPLEX
586 + if (vkres==VKNUM2) return 0; /* leave to runtime (could do here, but not worth it?) */
587 +#endif
588 + r = luai_nummul(v1, v2); break;
589 case OP_DIV:
590 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
591 - r = luai_numdiv(v1, v2); break;
592 +#ifdef LNUM_COMPLEX
593 + if (vkres==VKNUM2) return 0; /* leave to runtime */
594 +#endif
595 + r = luai_numdiv(v1, v2); break;
596 case OP_MOD:
597 if (v2 == 0) return 0; /* do not attempt to divide by 0 */
598 +#ifdef LNUM_COMPLEX
599 + if (vkres==VKNUM2) return 0; /* leave to runtime */
600 +#endif
601 r = luai_nummod(v1, v2); break;
602 - case OP_POW: r = luai_numpow(v1, v2); break;
603 + case OP_POW:
604 +#ifdef LNUM_COMPLEX
605 + if (vkres==VKNUM2) return 0; /* leave to runtime */
606 +#endif
607 + r = luai_numpow(v1, v2); break;
608 case OP_UNM: r = luai_numunm(v1); break;
609 case OP_LEN: return 0; /* no constant folding for 'len' */
610 default: lua_assert(0); r = 0; break;
611 }
612 if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
613 + e1->k = cast(expkind,vkres);
614 e1->u.nval = r;
615 return 1;
616 }
617 @@ -696,7 +789,8 @@ static void codecomp (FuncState *fs, OpC
618
619 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
620 expdesc e2;
621 - e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
622 + e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
623 +
624 switch (op) {
625 case OPR_MINUS: {
626 if (!isnumeral(e))
627 --- a/src/lcode.h
628 +++ b/src/lcode.h
629 @@ -71,6 +71,6 @@ LUAI_FUNC void luaK_prefix (FuncState *f
630 LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
631 LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
632 LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
633 -
634 +LUAI_FUNC int luaK_integerK (FuncState *fs, lua_Integer r);
635
636 #endif
637 --- a/src/ldebug.c
638 +++ b/src/ldebug.c
639 @@ -183,7 +183,7 @@ static void collectvalidlines (lua_State
640 int *lineinfo = f->l.p->lineinfo;
641 int i;
642 for (i=0; i<f->l.p->sizelineinfo; i++)
643 - setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
644 + setbvalue(luaH_setint(L, t, lineinfo[i]), 1);
645 sethvalue(L, L->top, t);
646 }
647 incr_top(L);
648 @@ -566,7 +566,7 @@ static int isinstack (CallInfo *ci, cons
649
650 void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
651 const char *name = NULL;
652 - const char *t = luaT_typenames[ttype(o)];
653 + const char *t = luaT_typenames[ttype_ext(o)];
654 const char *kind = (isinstack(L->ci, o)) ?
655 getobjname(L, L->ci, cast_int(o - L->base), &name) :
656 NULL;
657 @@ -594,8 +594,8 @@ void luaG_aritherror (lua_State *L, cons
658
659
660 int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
661 - const char *t1 = luaT_typenames[ttype(p1)];
662 - const char *t2 = luaT_typenames[ttype(p2)];
663 + const char *t1 = luaT_typenames[ttype_ext(p1)];
664 + const char *t2 = luaT_typenames[ttype_ext(p2)];
665 if (t1[2] == t2[2])
666 luaG_runerror(L, "attempt to compare two %s values", t1);
667 else
668 --- a/src/ldo.c
669 +++ b/src/ldo.c
670 @@ -219,9 +219,9 @@ static StkId adjust_varargs (lua_State *
671 luaC_checkGC(L);
672 htab = luaH_new(L, nvar, 1); /* create `arg' table */
673 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
674 - setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
675 + setobj2n(L, luaH_setint(L, htab, i+1), L->top - nvar + i);
676 /* store counter in field `n' */
677 - setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
678 + setivalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), nvar);
679 }
680 #endif
681 /* move fixed parameters to final position */
682 --- a/src/ldump.c
683 +++ b/src/ldump.c
684 @@ -52,6 +52,11 @@ static void DumpNumber(lua_Number x, Dum
685 DumpVar(x,D);
686 }
687
688 +static void DumpInteger(lua_Integer x, DumpState* D)
689 +{
690 + DumpVar(x,D);
691 +}
692 +
693 static void DumpVector(const void* b, int n, size_t size, DumpState* D)
694 {
695 DumpInt(n,D);
696 @@ -93,8 +98,11 @@ static void DumpConstants(const Proto* f
697 DumpChar(bvalue(o),D);
698 break;
699 case LUA_TNUMBER:
700 - DumpNumber(nvalue(o),D);
701 + DumpNumber(nvalue_fast(o),D);
702 break;
703 + case LUA_TINT:
704 + DumpInteger(ivalue(o),D);
705 + break;
706 case LUA_TSTRING:
707 DumpString(rawtsvalue(o),D);
708 break;
709 --- a/src/liolib.c
710 +++ b/src/liolib.c
711 @@ -9,6 +9,7 @@
712 #include <stdio.h>
713 #include <stdlib.h>
714 #include <string.h>
715 +#include <ctype.h>
716
717 #define liolib_c
718 #define LUA_LIB
719 @@ -18,7 +19,8 @@
720 #include "lauxlib.h"
721 #include "lualib.h"
722
723 -
724 +#include "lnum.h"
725 +#include "llex.h"
726
727 #define IO_INPUT 1
728 #define IO_OUTPUT 2
729 @@ -269,6 +271,13 @@ static int io_lines (lua_State *L) {
730 ** =======================================================
731 */
732
733 +/*
734 +* Many problems if we intend the same 'n' format specifier (see 'file:read()')
735 +* to work for both FP and integer numbers, without losing their accuracy. So
736 +* we don't. 'n' reads numbers as floating points, 'i' as integers. Old code
737 +* remains valid, but won't provide full integer accuracy (this only matters
738 +* with float FP and/or 64-bit integers).
739 +*/
740
741 static int read_number (lua_State *L, FILE *f) {
742 lua_Number d;
743 @@ -279,6 +288,43 @@ static int read_number (lua_State *L, FI
744 else return 0; /* read fails */
745 }
746
747 +static int read_integer (lua_State *L, FILE *f) {
748 + lua_Integer i;
749 + if (fscanf(f, LUA_INTEGER_SCAN, &i) == 1) {
750 + lua_pushinteger(L, i);
751 + return 1;
752 + }
753 + else return 0; /* read fails */
754 +}
755 +
756 +#ifdef LNUM_COMPLEX
757 +static int read_complex (lua_State *L, FILE *f) {
758 + /* NNN / NNNi / NNN+MMMi / NNN-MMMi */
759 + lua_Number a,b;
760 + if (fscanf(f, LUA_NUMBER_SCAN, &a) == 1) {
761 + int c=fgetc(f);
762 + switch(c) {
763 + case 'i':
764 + lua_pushcomplex(L, a*I);
765 + return 1;
766 + case '+':
767 + case '-':
768 + /* "i" is consumed if at the end; just 'NNN+MMM' will most likely
769 + * behave as if "i" was there? (TBD: test)
770 + */
771 + if (fscanf(f, LUA_NUMBER_SCAN "i", &b) == 1) {
772 + lua_pushcomplex(L, a+ (c=='+' ? b:-b)*I);
773 + return 1;
774 + }
775 + }
776 + ungetc( c,f );
777 + lua_pushnumber(L,a); /*real part only*/
778 + return 1;
779 + }
780 + return 0; /* read fails */
781 +}
782 +#endif
783 +
784
785 static int test_eof (lua_State *L, FILE *f) {
786 int c = getc(f);
787 @@ -352,6 +398,14 @@ static int g_read (lua_State *L, FILE *f
788 case 'n': /* number */
789 success = read_number(L, f);
790 break;
791 + case 'i': /* integer (full accuracy) */
792 + success = read_integer(L, f);
793 + break;
794 +#ifdef LNUM_COMPLEX
795 + case 'c': /* complex */
796 + success = read_complex(L, f);
797 + break;
798 +#endif
799 case 'l': /* line */
800 success = read_line(L, f);
801 break;
802 @@ -412,9 +466,10 @@ static int g_write (lua_State *L, FILE *
803 int status = 1;
804 for (; nargs--; arg++) {
805 if (lua_type(L, arg) == LUA_TNUMBER) {
806 - /* optimization: could be done exactly as for strings */
807 - status = status &&
808 - fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
809 + if (lua_isinteger(L,arg))
810 + status = status && fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) > 0;
811 + else
812 + status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
813 }
814 else {
815 size_t l;
816 @@ -457,7 +512,7 @@ static int f_setvbuf (lua_State *L) {
817 static const char *const modenames[] = {"no", "full", "line", NULL};
818 FILE *f = tofile(L);
819 int op = luaL_checkoption(L, 2, NULL, modenames);
820 - lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
821 + size_t sz = luaL_optint32(L, 3, LUAL_BUFFERSIZE);
822 int res = setvbuf(f, NULL, mode[op], sz);
823 return pushresult(L, res == 0, NULL);
824 }
825 --- a/src/llex.c
826 +++ b/src/llex.c
827 @@ -22,6 +22,7 @@
828 #include "lstring.h"
829 #include "ltable.h"
830 #include "lzio.h"
831 +#include "lnum.h"
832
833
834
835 @@ -34,13 +35,17 @@
836
837
838 /* ORDER RESERVED */
839 -const char *const luaX_tokens [] = {
840 +static const char *const luaX_tokens [] = {
841 "and", "break", "do", "else", "elseif",
842 "end", "false", "for", "function", "if",
843 "in", "local", "nil", "not", "or", "repeat",
844 "return", "then", "true", "until", "while",
845 "..", "...", "==", ">=", "<=", "~=",
846 "<number>", "<name>", "<string>", "<eof>",
847 + "<integer>",
848 +#ifdef LNUM_COMPLEX
849 + "<number2>",
850 +#endif
851 NULL
852 };
853
854 @@ -90,7 +95,11 @@ static const char *txtToken (LexState *l
855 switch (token) {
856 case TK_NAME:
857 case TK_STRING:
858 + case TK_INT:
859 case TK_NUMBER:
860 +#ifdef LNUM_COMPLEX
861 + case TK_NUMBER2:
862 +#endif
863 save(ls, '\0');
864 return luaZ_buffer(ls->buff);
865 default:
866 @@ -173,23 +182,27 @@ static void buffreplace (LexState *ls, c
867 if (p[n] == from) p[n] = to;
868 }
869
870 -
871 -static void trydecpoint (LexState *ls, SemInfo *seminfo) {
872 +/* TK_NUMBER (/ TK_NUMBER2) */
873 +static int trydecpoint (LexState *ls, SemInfo *seminfo) {
874 /* format error: try to update decimal point separator */
875 struct lconv *cv = localeconv();
876 char old = ls->decpoint;
877 + int ret;
878 ls->decpoint = (cv ? cv->decimal_point[0] : '.');
879 buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
880 - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
881 + ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, NULL);
882 + if (!ret) {
883 /* format error with correct decimal point: no more options */
884 buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
885 luaX_lexerror(ls, "malformed number", TK_NUMBER);
886 }
887 + return ret;
888 }
889
890
891 -/* LUA_NUMBER */
892 -static void read_numeral (LexState *ls, SemInfo *seminfo) {
893 +/* TK_NUMBER / TK_INT (/TK_NUMBER2) */
894 +static int read_numeral (LexState *ls, SemInfo *seminfo) {
895 + int ret;
896 lua_assert(isdigit(ls->current));
897 do {
898 save_and_next(ls);
899 @@ -200,8 +213,9 @@ static void read_numeral (LexState *ls,
900 save_and_next(ls);
901 save(ls, '\0');
902 buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
903 - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
904 - trydecpoint(ls, seminfo); /* try to update decimal point separator */
905 + ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, &seminfo->i );
906 + if (!ret) return trydecpoint(ls, seminfo); /* try to update decimal point separator */
907 + return ret;
908 }
909
910
911 @@ -329,6 +343,7 @@ static void read_string (LexState *ls, i
912 }
913
914
915 +/* char / TK_* */
916 static int llex (LexState *ls, SemInfo *seminfo) {
917 luaZ_resetbuffer(ls->buff);
918 for (;;) {
919 @@ -400,8 +415,7 @@ static int llex (LexState *ls, SemInfo *
920 }
921 else if (!isdigit(ls->current)) return '.';
922 else {
923 - read_numeral(ls, seminfo);
924 - return TK_NUMBER;
925 + return read_numeral(ls, seminfo);
926 }
927 }
928 case EOZ: {
929 @@ -414,8 +428,7 @@ static int llex (LexState *ls, SemInfo *
930 continue;
931 }
932 else if (isdigit(ls->current)) {
933 - read_numeral(ls, seminfo);
934 - return TK_NUMBER;
935 + return read_numeral(ls, seminfo);
936 }
937 else if (isalpha(ls->current) || ls->current == '_') {
938 /* identifier or reserved word */
939 --- a/src/llex.h
940 +++ b/src/llex.h
941 @@ -29,19 +29,22 @@ enum RESERVED {
942 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
943 /* other terminal symbols */
944 TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
945 - TK_NAME, TK_STRING, TK_EOS
946 + TK_NAME, TK_STRING, TK_EOS, TK_INT
947 +#ifdef LNUM_COMPLEX
948 + , TK_NUMBER2 /* imaginary constants: Ni */
949 +#endif
950 };
951
952 /* number of reserved words */
953 #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
954
955
956 -/* array with token `names' */
957 -LUAI_DATA const char *const luaX_tokens [];
958 -
959 -
960 +/* SemInfo is a local data structure of 'llex.c', used for carrying a string
961 + * or a number. A separate token (TK_*) will tell, how to interpret the data.
962 + */
963 typedef union {
964 lua_Number r;
965 + lua_Integer i;
966 TString *ts;
967 } SemInfo; /* semantics information */
968
969 --- a/src/llimits.h
970 +++ b/src/llimits.h
971 @@ -49,6 +49,7 @@ typedef LUAI_USER_ALIGNMENT_T L_Umaxalig
972
973 /* result of a `usual argument conversion' over lua_Number */
974 typedef LUAI_UACNUMBER l_uacNumber;
975 +typedef LUAI_UACINTEGER l_uacInteger;
976
977
978 /* internal assertions for in-house debugging */
979 @@ -80,7 +81,6 @@ typedef LUAI_UACNUMBER l_uacNumber;
980 #define cast_int(i) cast(int, (i))
981
982
983 -
984 /*
985 ** type for virtual-machine instructions
986 ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
987 --- a/src/lmathlib.c
988 +++ b/src/lmathlib.c
989 @@ -4,7 +4,6 @@
990 ** See Copyright Notice in lua.h
991 */
992
993 -
994 #include <stdlib.h>
995 #include <math.h>
996
997 @@ -16,113 +15,210 @@
998 #include "lauxlib.h"
999 #include "lualib.h"
1000
1001 +/* 'luai_vectpow()' as a replacement for 'cpow()'. Defined in the header; we
1002 + * don't intrude the code libs internal functions.
1003 + */
1004 +#ifdef LNUM_COMPLEX
1005 +# include "lnum.h"
1006 +#endif
1007
1008 #undef PI
1009 -#define PI (3.14159265358979323846)
1010 -#define RADIANS_PER_DEGREE (PI/180.0)
1011 -
1012 +#ifdef LNUM_FLOAT
1013 +# define PI (3.14159265358979323846F)
1014 +#elif defined(M_PI)
1015 +# define PI M_PI
1016 +#else
1017 +# define PI (3.14159265358979323846264338327950288)
1018 +#endif
1019 +#define RADIANS_PER_DEGREE (PI/180)
1020
1021 +#undef HUGE
1022 +#ifdef LNUM_FLOAT
1023 +# define HUGE HUGE_VALF
1024 +#elif defined(LNUM_LDOUBLE)
1025 +# define HUGE HUGE_VALL
1026 +#else
1027 +# define HUGE HUGE_VAL
1028 +#endif
1029
1030 static int math_abs (lua_State *L) {
1031 - lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
1032 +#ifdef LNUM_COMPLEX
1033 + lua_pushnumber(L, _LF(cabs) (luaL_checkcomplex(L,1)));
1034 +#else
1035 + lua_pushnumber(L, _LF(fabs) (luaL_checknumber(L, 1)));
1036 +#endif
1037 return 1;
1038 }
1039
1040 static int math_sin (lua_State *L) {
1041 - lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
1042 +#ifdef LNUM_COMPLEX
1043 + lua_pushcomplex(L, _LF(csin) (luaL_checkcomplex(L,1)));
1044 +#else
1045 + lua_pushnumber(L, _LF(sin) (luaL_checknumber(L, 1)));
1046 +#endif
1047 return 1;
1048 }
1049
1050 static int math_sinh (lua_State *L) {
1051 - lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
1052 +#ifdef LNUM_COMPLEX
1053 + lua_pushcomplex(L, _LF(csinh) (luaL_checkcomplex(L,1)));
1054 +#else
1055 + lua_pushnumber(L, _LF(sinh) (luaL_checknumber(L, 1)));
1056 +#endif
1057 return 1;
1058 }
1059
1060 static int math_cos (lua_State *L) {
1061 - lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
1062 +#ifdef LNUM_COMPLEX
1063 + lua_pushcomplex(L, _LF(ccos) (luaL_checkcomplex(L,1)));
1064 +#else
1065 + lua_pushnumber(L, _LF(cos) (luaL_checknumber(L, 1)));
1066 +#endif
1067 return 1;
1068 }
1069
1070 static int math_cosh (lua_State *L) {
1071 - lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
1072 +#ifdef LNUM_COMPLEX
1073 + lua_pushcomplex(L, _LF(ccosh) (luaL_checkcomplex(L,1)));
1074 +#else
1075 + lua_pushnumber(L, _LF(cosh) (luaL_checknumber(L, 1)));
1076 +#endif
1077 return 1;
1078 }
1079
1080 static int math_tan (lua_State *L) {
1081 - lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
1082 +#ifdef LNUM_COMPLEX
1083 + lua_pushcomplex(L, _LF(ctan) (luaL_checkcomplex(L,1)));
1084 +#else
1085 + lua_pushnumber(L, _LF(tan) (luaL_checknumber(L, 1)));
1086 +#endif
1087 return 1;
1088 }
1089
1090 static int math_tanh (lua_State *L) {
1091 - lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
1092 +#ifdef LNUM_COMPLEX
1093 + lua_pushcomplex(L, _LF(ctanh) (luaL_checkcomplex(L,1)));
1094 +#else
1095 + lua_pushnumber(L, _LF(tanh) (luaL_checknumber(L, 1)));
1096 +#endif
1097 return 1;
1098 }
1099
1100 static int math_asin (lua_State *L) {
1101 - lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
1102 +#ifdef LNUM_COMPLEX
1103 + lua_pushcomplex(L, _LF(casin) (luaL_checkcomplex(L,1)));
1104 +#else
1105 + lua_pushnumber(L, _LF(asin) (luaL_checknumber(L, 1)));
1106 +#endif
1107 return 1;
1108 }
1109
1110 static int math_acos (lua_State *L) {
1111 - lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
1112 +#ifdef LNUM_COMPLEX
1113 + lua_pushcomplex(L, _LF(cacos) (luaL_checkcomplex(L,1)));
1114 +#else
1115 + lua_pushnumber(L, _LF(acos) (luaL_checknumber(L, 1)));
1116 +#endif
1117 return 1;
1118 }
1119
1120 static int math_atan (lua_State *L) {
1121 - lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
1122 +#ifdef LNUM_COMPLEX
1123 + lua_pushcomplex(L, _LF(catan) (luaL_checkcomplex(L,1)));
1124 +#else
1125 + lua_pushnumber(L, _LF(atan) (luaL_checknumber(L, 1)));
1126 +#endif
1127 return 1;
1128 }
1129
1130 static int math_atan2 (lua_State *L) {
1131 - lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1132 + /* scalars only */
1133 + lua_pushnumber(L, _LF(atan2) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1134 return 1;
1135 }
1136
1137 static int math_ceil (lua_State *L) {
1138 - lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
1139 +#ifdef LNUM_COMPLEX
1140 + lua_Complex v= luaL_checkcomplex(L, 1);
1141 + lua_pushcomplex(L, _LF(ceil) (_LF(creal)(v)) + _LF(ceil) (_LF(cimag)(v))*I);
1142 +#else
1143 + lua_pushnumber(L, _LF(ceil) (luaL_checknumber(L, 1)));
1144 +#endif
1145 return 1;
1146 }
1147
1148 static int math_floor (lua_State *L) {
1149 - lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
1150 +#ifdef LNUM_COMPLEX
1151 + lua_Complex v= luaL_checkcomplex(L, 1);
1152 + lua_pushcomplex(L, _LF(floor) (_LF(creal)(v)) + _LF(floor) (_LF(cimag)(v))*I);
1153 +#else
1154 + lua_pushnumber(L, _LF(floor) (luaL_checknumber(L, 1)));
1155 +#endif
1156 return 1;
1157 }
1158
1159 -static int math_fmod (lua_State *L) {
1160 - lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1161 +static int math_fmod (lua_State *L) {
1162 + /* scalars only */
1163 + lua_pushnumber(L, _LF(fmod) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1164 return 1;
1165 }
1166
1167 static int math_modf (lua_State *L) {
1168 - double ip;
1169 - double fp = modf(luaL_checknumber(L, 1), &ip);
1170 + /* scalars only */
1171 + lua_Number ip;
1172 + lua_Number fp = _LF(modf) (luaL_checknumber(L, 1), &ip);
1173 lua_pushnumber(L, ip);
1174 lua_pushnumber(L, fp);
1175 return 2;
1176 }
1177
1178 static int math_sqrt (lua_State *L) {
1179 - lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
1180 +#ifdef LNUM_COMPLEX
1181 + lua_pushcomplex(L, _LF(csqrt) (luaL_checkcomplex(L,1)));
1182 +#else
1183 + lua_pushnumber(L, _LF(sqrt) (luaL_checknumber(L, 1)));
1184 +#endif
1185 return 1;
1186 }
1187
1188 static int math_pow (lua_State *L) {
1189 - lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1190 +#ifdef LNUM_COMPLEX
1191 + /* C99 'cpow' gives somewhat inaccurate results (i.e. (-1)^2 = -1+1.2246467991474e-16i).
1192 + * 'luai_vectpow' smoothens such, reusing it is the reason we need to #include "lnum.h".
1193 + */
1194 + lua_pushcomplex(L, luai_vectpow(luaL_checkcomplex(L,1), luaL_checkcomplex(L,2)));
1195 +#else
1196 + lua_pushnumber(L, _LF(pow) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
1197 +#endif
1198 return 1;
1199 }
1200
1201 static int math_log (lua_State *L) {
1202 - lua_pushnumber(L, log(luaL_checknumber(L, 1)));
1203 +#ifdef LNUM_COMPLEX
1204 + lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)));
1205 +#else
1206 + lua_pushnumber(L, _LF(log) (luaL_checknumber(L, 1)));
1207 +#endif
1208 return 1;
1209 }
1210
1211 static int math_log10 (lua_State *L) {
1212 - lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
1213 +#ifdef LNUM_COMPLEX
1214 + /* Not in standard <complex.h> , but easy to calculate: log_a(x) = log_b(x) / log_b(a)
1215 + */
1216 + lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)) / _LF(log) (10));
1217 +#else
1218 + lua_pushnumber(L, _LF(log10) (luaL_checknumber(L, 1)));
1219 +#endif
1220 return 1;
1221 }
1222
1223 static int math_exp (lua_State *L) {
1224 - lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
1225 +#ifdef LNUM_COMPLEX
1226 + lua_pushcomplex(L, _LF(cexp) (luaL_checkcomplex(L,1)));
1227 +#else
1228 + lua_pushnumber(L, _LF(exp) (luaL_checknumber(L, 1)));
1229 +#endif
1230 return 1;
1231 }
1232
1233 @@ -138,19 +234,20 @@ static int math_rad (lua_State *L) {
1234
1235 static int math_frexp (lua_State *L) {
1236 int e;
1237 - lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
1238 + lua_pushnumber(L, _LF(frexp) (luaL_checknumber(L, 1), &e));
1239 lua_pushinteger(L, e);
1240 return 2;
1241 }
1242
1243 static int math_ldexp (lua_State *L) {
1244 - lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
1245 + lua_pushnumber(L, _LF(ldexp) (luaL_checknumber(L, 1), luaL_checkint(L, 2)));
1246 return 1;
1247 }
1248
1249
1250
1251 static int math_min (lua_State *L) {
1252 + /* scalars only */
1253 int n = lua_gettop(L); /* number of arguments */
1254 lua_Number dmin = luaL_checknumber(L, 1);
1255 int i;
1256 @@ -165,6 +262,7 @@ static int math_min (lua_State *L) {
1257
1258
1259 static int math_max (lua_State *L) {
1260 + /* scalars only */
1261 int n = lua_gettop(L); /* number of arguments */
1262 lua_Number dmax = luaL_checknumber(L, 1);
1263 int i;
1264 @@ -182,25 +280,20 @@ static int math_random (lua_State *L) {
1265 /* the `%' avoids the (rare) case of r==1, and is needed also because on
1266 some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
1267 lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
1268 - switch (lua_gettop(L)) { /* check number of arguments */
1269 - case 0: { /* no arguments */
1270 - lua_pushnumber(L, r); /* Number between 0 and 1 */
1271 - break;
1272 - }
1273 - case 1: { /* only upper limit */
1274 - int u = luaL_checkint(L, 1);
1275 - luaL_argcheck(L, 1<=u, 1, "interval is empty");
1276 - lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
1277 - break;
1278 - }
1279 - case 2: { /* lower and upper limits */
1280 - int l = luaL_checkint(L, 1);
1281 - int u = luaL_checkint(L, 2);
1282 - luaL_argcheck(L, l<=u, 2, "interval is empty");
1283 - lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
1284 - break;
1285 - }
1286 - default: return luaL_error(L, "wrong number of arguments");
1287 + int n= lua_gettop(L); /* number of arguments */
1288 + if (n==0) { /* no arguments: range [0,1) */
1289 + lua_pushnumber(L, r);
1290 + } else if (n<=2) { /* int range [1,u] or [l,u] */
1291 + int l= n==1 ? 1 : luaL_checkint(L, 1);
1292 + int u = luaL_checkint(L, n);
1293 + int tmp;
1294 + lua_Number d;
1295 + luaL_argcheck(L, l<=u, n, "interval is empty");
1296 + d= _LF(floor)(r*(u-l+1));
1297 + lua_number2int(tmp,d);
1298 + lua_pushinteger(L, l+tmp);
1299 + } else {
1300 + return luaL_error(L, "wrong number of arguments");
1301 }
1302 return 1;
1303 }
1304 @@ -211,6 +304,66 @@ static int math_randomseed (lua_State *L
1305 return 0;
1306 }
1307
1308 +/*
1309 +* Lua 5.1 does not have acosh, asinh, atanh for scalars (not ANSI C)
1310 +*/
1311 +#if __STDC_VERSION__ >= 199901L
1312 +static int math_acosh (lua_State *L) {
1313 +# ifdef LNUM_COMPLEX
1314 + lua_pushcomplex(L, _LF(cacosh) (luaL_checkcomplex(L,1)));
1315 +# else
1316 + lua_pushnumber(L, _LF(acosh) (luaL_checknumber(L,1)));
1317 +# endif
1318 + return 1;
1319 +}
1320 +static int math_asinh (lua_State *L) {
1321 +# ifdef LNUM_COMPLEX
1322 + lua_pushcomplex(L, _LF(casinh) (luaL_checkcomplex(L,1)));
1323 +# else
1324 + lua_pushnumber(L, _LF(asinh) (luaL_checknumber(L,1)));
1325 +# endif
1326 + return 1;
1327 +}
1328 +static int math_atanh (lua_State *L) {
1329 +# ifdef LNUM_COMPLEX
1330 + lua_pushcomplex(L, _LF(catanh) (luaL_checkcomplex(L,1)));
1331 +# else
1332 + lua_pushnumber(L, _LF(atanh) (luaL_checknumber(L,1)));
1333 +# endif
1334 + return 1;
1335 +}
1336 +#endif
1337 +
1338 +/*
1339 + * C99 complex functions, not covered above.
1340 +*/
1341 +#ifdef LNUM_COMPLEX
1342 +static int math_arg (lua_State *L) {
1343 + lua_pushnumber(L, _LF(carg) (luaL_checkcomplex(L,1)));
1344 + return 1;
1345 +}
1346 +
1347 +static int math_imag (lua_State *L) {
1348 + lua_pushnumber(L, _LF(cimag) (luaL_checkcomplex(L,1)));
1349 + return 1;
1350 +}
1351 +
1352 +static int math_real (lua_State *L) {
1353 + lua_pushnumber(L, _LF(creal) (luaL_checkcomplex(L,1)));
1354 + return 1;
1355 +}
1356 +
1357 +static int math_conj (lua_State *L) {
1358 + lua_pushcomplex(L, _LF(conj) (luaL_checkcomplex(L,1)));
1359 + return 1;
1360 +}
1361 +
1362 +static int math_proj (lua_State *L) {
1363 + lua_pushcomplex(L, _LF(cproj) (luaL_checkcomplex(L,1)));
1364 + return 1;
1365 +}
1366 +#endif
1367 +
1368
1369 static const luaL_Reg mathlib[] = {
1370 {"abs", math_abs},
1371 @@ -241,6 +394,18 @@ static const luaL_Reg mathlib[] = {
1372 {"sqrt", math_sqrt},
1373 {"tanh", math_tanh},
1374 {"tan", math_tan},
1375 +#if __STDC_VERSION__ >= 199901L
1376 + {"acosh", math_acosh},
1377 + {"asinh", math_asinh},
1378 + {"atanh", math_atanh},
1379 +#endif
1380 +#ifdef LNUM_COMPLEX
1381 + {"arg", math_arg},
1382 + {"imag", math_imag},
1383 + {"real", math_real},
1384 + {"conj", math_conj},
1385 + {"proj", math_proj},
1386 +#endif
1387 {NULL, NULL}
1388 };
1389
1390 @@ -252,8 +417,10 @@ LUALIB_API int luaopen_math (lua_State *
1391 luaL_register(L, LUA_MATHLIBNAME, mathlib);
1392 lua_pushnumber(L, PI);
1393 lua_setfield(L, -2, "pi");
1394 - lua_pushnumber(L, HUGE_VAL);
1395 + lua_pushnumber(L, HUGE);
1396 lua_setfield(L, -2, "huge");
1397 + lua_pushinteger(L, LUA_INTEGER_MAX );
1398 + lua_setfield(L, -2, "hugeint");
1399 #if defined(LUA_COMPAT_MOD)
1400 lua_getfield(L, -1, "fmod");
1401 lua_setfield(L, -2, "mod");
1402 --- /dev/null
1403 +++ b/src/lnum.c
1404 @@ -0,0 +1,312 @@
1405 +/*
1406 +** $Id: lnum.c,v ... $
1407 +** Internal number model
1408 +** See Copyright Notice in lua.h
1409 +*/
1410 +
1411 +#include <stdlib.h>
1412 +#include <math.h>
1413 +#include <ctype.h>
1414 +#include <string.h>
1415 +#include <stdio.h>
1416 +#include <errno.h>
1417 +
1418 +#define lnum_c
1419 +#define LUA_CORE
1420 +
1421 +#include "lua.h"
1422 +#include "llex.h"
1423 +#include "lnum.h"
1424 +
1425 +/*
1426 +** lua_real2str converts a (non-complex) number to a string.
1427 +** lua_str2real converts a string to a (non-complex) number.
1428 +*/
1429 +#define lua_real2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
1430 +
1431 +/*
1432 +* Note: Only 'strtod()' is part of ANSI C; others are C99 and
1433 +* may need '--std=c99' compiler setting (at least on Ubuntu 7.10).
1434 +*
1435 +* Visual C++ 2008 Express does not have 'strtof()', nor 'strtold()'.
1436 +* References to '_strtold()' exist but don't compile. It seems best
1437 +* to leave Windows users with DOUBLE only (or compile with MinGW).
1438 +*
1439 +* In practise, using '(long double)strtod' is a risky thing, since
1440 +* it will cause accuracy loss in reading in numbers, and such losses
1441 +* will pile up in later processing. Get a real 'strtold()' or don't
1442 +* use that mode at all.
1443 +*/
1444 +#ifdef LNUM_DOUBLE
1445 +# define lua_str2real strtod
1446 +#elif defined(LNUM_FLOAT)
1447 +# define lua_str2real strtof
1448 +#elif defined(LNUM_LDOUBLE)
1449 +# define lua_str2real strtold
1450 +#endif
1451 +
1452 +#define lua_integer2str(s,v) sprintf((s), LUA_INTEGER_FMT, (v))
1453 +
1454 +/* 's' is expected to be LUAI_MAXNUMBER2STR long (enough for any number)
1455 +*/
1456 +void luaO_num2buf( char *s, const TValue *o )
1457 +{
1458 + lua_Number n;
1459 + lua_assert( ttisnumber(o) );
1460 +
1461 + /* Reason to handle integers differently is not only speed, but accuracy as
1462 + * well. We want to make any integer tostring() without roundings, at all.
1463 + */
1464 + if (ttisint(o)) {
1465 + lua_integer2str( s, ivalue(o) );
1466 + return;
1467 + }
1468 + n= nvalue_fast(o);
1469 + lua_real2str(s, n);
1470 +
1471 +#ifdef LNUM_COMPLEX
1472 + lua_Number n2= nvalue_img_fast(o);
1473 + if (n2!=0) { /* Postfix with +-Ni */
1474 + int re0= (n == 0);
1475 + char *s2= re0 ? s : strchr(s,'\0');
1476 + if ((!re0) && (n2>0)) *s2++= '+';
1477 + lua_real2str( s2, n2 );
1478 + strcat(s2,"i");
1479 + }
1480 +#endif
1481 +}
1482 +
1483 +/*
1484 +* If a LUA_TNUMBER has integer value, give it.
1485 +*/
1486 +int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ) {
1487 + lua_Number d;
1488 + lua_Integer i;
1489 +
1490 + lua_assert( ttype(o)==LUA_TNUMBER );
1491 + lua_assert( ref );
1492 +#ifdef LNUM_COMPLEX
1493 + if (nvalue_img_fast(o)!=0) return 0;
1494 +#endif
1495 + d= nvalue_fast(o);
1496 + lua_number2integer(i, d);
1497 + if (cast_num(i) == d) {
1498 + *ref= i; return 1;
1499 + }
1500 + return 0;
1501 +}
1502 +
1503 +/*
1504 + * Lua 5.1.3 (using 'strtod()') allows 0x+hex but not 0+octal. This is good,
1505 + * and we should NOT use 'autobase' 0 with 'strtoul[l]()' for this reason.
1506 + *
1507 + * Lua 5.1.3 allows '0x...' numbers to overflow and lose precision; this is not
1508 + * good. On Visual C++ 2008, 'strtod()' does not even take them in. Better to
1509 + * require hex values to fit 'lua_Integer' or give an error that they don't?
1510 + *
1511 + * Full hex range (0 .. 0xff..ff) is stored as integers, not to lose any bits.
1512 + * Numerical value of 0xff..ff will be -1, if used in calculations.
1513 + *
1514 + * Returns: TK_INT for a valid integer, '*endptr_ref' updated
1515 + * TK_NUMBER for seemingly numeric, to be parsed as floating point
1516 + * 0 for bad characters, not a number (or '0x' out of range)
1517 + */
1518 +static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) {
1519 + char *endptr;
1520 + /* 'v' gets ULONG_MAX on possible overflow (which is > LUA_INTEGER_MAX);
1521 + * we don't have to check 'errno' here.
1522 + */
1523 + unsigned LUA_INTEGER v= lua_str2ul(s, &endptr, 10);
1524 + if (endptr == s) return 0; /* nothing numeric */
1525 + if (v==0 && *endptr=='x') {
1526 + errno= 0; /* needs to be set, 'strtoul[l]' does not clear it */
1527 + v= lua_str2ul(endptr+1, &endptr, 16); /* retry as hex, unsigned range */
1528 + if (errno==ERANGE) { /* clamped to 0xff..ff */
1529 +#if (defined(LNUM_INT32) && !defined(LNUM_FLOAT)) || defined(LNUM_LDOUBLE)
1530 + return TK_NUMBER; /* Allow to be read as floating point (has more integer range) */
1531 +#else
1532 + return 0; /* Reject the number */
1533 +#endif
1534 + }
1535 + } else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
1536 + return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
1537 + }
1538 + *res= (lua_Integer)v;
1539 + *endptr_ref= endptr;
1540 + return TK_INT;
1541 +}
1542 +
1543 +/* 0 / TK_NUMBER / TK_INT (/ TK_NUMBER2) */
1544 +int luaO_str2d (const char *s, lua_Number *res_n, lua_Integer *res_i) {
1545 + char *endptr;
1546 + int ret= TK_NUMBER;
1547 + /* Check integers first, if caller is allowing.
1548 + * If 'res2'==NULL, they're only looking for floating point.
1549 + */
1550 + if (res_i) {
1551 + ret= luaO_str2i(s,res_i,&endptr);
1552 + if (ret==0) return 0;
1553 + }
1554 + if (ret==TK_NUMBER) {
1555 + lua_assert(res_n);
1556 + /* Note: Visual C++ 2008 Express 'strtod()' does not read in "0x..."
1557 + * numbers; it will read '0' and spit 'x' as endptr.
1558 + * This means hex constants not fitting in 'lua_Integer' won't
1559 + * be read in at all. What to do?
1560 + */
1561 + *res_n = lua_str2real(s, &endptr);
1562 + if (endptr == s) return 0; /* conversion failed */
1563 + /* Visual C++ 2008 'strtod()' does not allow "0x..." input. */
1564 +#if defined(_MSC_VER) && !defined(LNUM_FLOAT) && !defined(LNUM_INT64)
1565 + if (*res_n==0 && *endptr=='x') {
1566 + /* Hex constant too big for 'lua_Integer' but that could fit in 'lua_Number'
1567 + * integer bits
1568 + */
1569 + unsigned __int64 v= _strtoui64( s, &endptr, 16 );
1570 + /* We just let > 64 bit values be clamped to _UI64_MAX (MSDN does not say 'errno'==ERANGE would be set) */
1571 + *res_n= cast_num(v);
1572 + if (*res_n != v) return 0; /* Would have lost accuracy */
1573 + }
1574 +#endif
1575 +#ifdef LNUM_COMPLEX
1576 + if (*endptr == 'i') { endptr++; ret= TK_NUMBER2; }
1577 +#endif
1578 + }
1579 + if (*endptr) {
1580 + while (isspace(cast(unsigned char, *endptr))) endptr++;
1581 + if (*endptr) return 0; /* invalid trail */
1582 + }
1583 + return ret;
1584 +}
1585 +
1586 +
1587 +/* Functions for finding out, when integer operations remain in range
1588 + * (and doing them).
1589 + */
1590 +int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1591 + lua_Integer v= ib+ic; /* may overflow */
1592 + if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ }
1593 + else if (ib<0 && ic<0) { if (v >= 0) return 0; }
1594 + *r= v;
1595 + return 1;
1596 +}
1597 +
1598 +int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1599 + lua_Integer v= ib-ic; /* may overflow */
1600 + if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ }
1601 + else if (ib<0 && ic>0) { if (v >= 0) return 0; }
1602 + *r= v;
1603 + return 1;
1604 +}
1605 +
1606 +int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1607 + if (ib!=LUA_INTEGER_MIN && ic!=LUA_INTEGER_MIN) {
1608 + lua_Integer b= luai_abs(ib), c= luai_abs(ic);
1609 + if ( (ib==0) || (LUA_INTEGER_MAX/b >= c) ) {
1610 + *r= ib*ic; /* no overflow */
1611 + return 1;
1612 + }
1613 + } else if (ib==0 || ic==0) {
1614 + *r= 0; return 1;
1615 + }
1616 +
1617 + /* Result can be LUA_INTEGER_MIN; if it is, calculating it using floating
1618 + * point will not cause accuracy loss.
1619 + */
1620 + if ( luai_nummul( cast_num(ib), cast_num(ic) ) == LUA_INTEGER_MIN ) {
1621 + *r= LUA_INTEGER_MIN;
1622 + return 1;
1623 + }
1624 + return 0;
1625 +}
1626 +
1627 +int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1628 + /* N/0: leave to float side, to give an error
1629 + */
1630 + if (ic==0) return 0;
1631 +
1632 + /* N/LUA_INTEGER_MIN: always non-integer results, or 0 or +1
1633 + */
1634 + if (ic==LUA_INTEGER_MIN) {
1635 + if (ib==LUA_INTEGER_MIN) { *r=1; return 1; }
1636 + if (ib==0) { *r=0; return 1; }
1637 +
1638 + /* LUA_INTEGER_MIN (-2^31|63)/N: calculate using float side (either the division
1639 + * causes non-integer results, or there is no accuracy loss in int->fp->int
1640 + * conversions (N=2,4,8,..,256 and N=2^30,2^29,..2^23).
1641 + */
1642 + } else if (ib==LUA_INTEGER_MIN) {
1643 + lua_Number d= luai_numdiv( cast_num(LUA_INTEGER_MIN), cast_num(ic) );
1644 + lua_Integer i; lua_number2integer(i,d);
1645 + if (cast_num(i)==d) { *r= i; return 1; }
1646 +
1647 + } else {
1648 + /* Note: We _can_ use ANSI C mod here, even on negative values, since
1649 + * we only test for == 0 (the sign would be implementation dependent).
1650 + */
1651 + if (ib%ic == 0) { *r= ib/ic; return 1; }
1652 + }
1653 +
1654 + return 0;
1655 +}
1656 +
1657 +int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1658 + if (ic!=0) {
1659 + /* ANSI C can be trusted when b%c==0, or when values are non-negative.
1660 + * b - (floor(b/c) * c)
1661 + * -->
1662 + * + +: b - (b/c) * c (b % c can be used)
1663 + * - -: b - (b/c) * c (b % c could work, but not defined by ANSI C)
1664 + * 0 -: b - (b/c) * c (=0, b % c could work, but not defined by ANSI C)
1665 + * - +: b - (b/c-1) * c (when b!=-c)
1666 + * + -: b - (b/c-1) * c (when b!=-c)
1667 + *
1668 + * o MIN%MIN ends up 0, via overflow in calcs but that does not matter.
1669 + * o MIN%MAX ends up MAX-1 (and other such numbers), also after overflow,
1670 + * but that does not matter, results do.
1671 + */
1672 + lua_Integer v= ib % ic;
1673 + if ( v!=0 && (ib<0 || ic<0) ) {
1674 + v= ib - ((ib/ic) - ((ib<=0 && ic<0) ? 0:1)) * ic;
1675 + }
1676 + /* Result should always have same sign as 2nd argument. (PIL2) */
1677 + lua_assert( (v<0) ? (ic<0) : (v>0) ? (ic>0) : 1 );
1678 + *r= v;
1679 + return 1;
1680 + }
1681 + return 0; /* let float side return NaN */
1682 +}
1683 +
1684 +int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
1685 +
1686 + /* In FLOAT/INT32 or FLOAT|DOUBLE/INT64 modes, calculating integer powers
1687 + * via FP realm may lose accuracy (i.e. 7^11 = 1977326743, which fits int32
1688 + * but not 23-bit float mantissa).
1689 + *
1690 + * The current solution is dumb, but it works and uses little code. Use of
1691 + * integer powers is not anticipated to be very frequent (apart from 2^x,
1692 + * which is separately optimized).
1693 + */
1694 + if (ib==0) *r=0;
1695 + else if (ic<0) return 0; /* FP realm */
1696 + else if (ib==2 && ic < (int)sizeof(lua_Integer)*8-1) *r= ((lua_Integer)1)<<ic; /* 1,2,4,...2^30 | 2^62 optimization */
1697 + else if (ic==0) *r=1;
1698 + else if (luai_abs(ib)==1) *r= (ic%2) ? ib:1;
1699 + else {
1700 + lua_Integer x= ib;
1701 + while( --ic ) {
1702 + if (!try_mulint( &x, x, ib ))
1703 + return 0; /* FP realm */
1704 + }
1705 + *r= x;
1706 + }
1707 + return 1;
1708 +}
1709 +
1710 +int try_unmint( lua_Integer *r, lua_Integer ib ) {
1711 + /* Negating LUA_INTEGER_MIN leaves the range. */
1712 + if ( ib != LUA_INTEGER_MIN )
1713 + { *r= -ib; return 1; }
1714 + return 0;
1715 +}
1716 +
1717 --- /dev/null
1718 +++ b/src/lnum.h
1719 @@ -0,0 +1,116 @@
1720 +/*
1721 +** $Id: lnum.h,v ... $
1722 +** Internal Number model
1723 +** See Copyright Notice in lua.h
1724 +*/
1725 +
1726 +#ifndef lnum_h
1727 +#define lnum_h
1728 +
1729 +#include <math.h>
1730 +
1731 +#include "lobject.h"
1732 +
1733 +/*
1734 +** The luai_num* macros define the primitive operations over 'lua_Number's
1735 +** (not 'lua_Integer's, not 'lua_Complex').
1736 +*/
1737 +#define luai_numadd(a,b) ((a)+(b))
1738 +#define luai_numsub(a,b) ((a)-(b))
1739 +#define luai_nummul(a,b) ((a)*(b))
1740 +#define luai_numdiv(a,b) ((a)/(b))
1741 +#define luai_nummod(a,b) ((a) - _LF(floor)((a)/(b))*(b))
1742 +#define luai_numpow(a,b) (_LF(pow)(a,b))
1743 +#define luai_numunm(a) (-(a))
1744 +#define luai_numeq(a,b) ((a)==(b))
1745 +#define luai_numlt(a,b) ((a)<(b))
1746 +#define luai_numle(a,b) ((a)<=(b))
1747 +#define luai_numisnan(a) (!luai_numeq((a), (a)))
1748 +
1749 +int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1750 +int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1751 +int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1752 +int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1753 +int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1754 +int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
1755 +int try_unmint( lua_Integer *r, lua_Integer ib );
1756 +
1757 +#ifdef LNUM_COMPLEX
1758 + static inline lua_Complex luai_vectunm( lua_Complex a ) { return -a; }
1759 + static inline lua_Complex luai_vectadd( lua_Complex a, lua_Complex b ) { return a+b; }
1760 + static inline lua_Complex luai_vectsub( lua_Complex a, lua_Complex b ) { return a-b; }
1761 + static inline lua_Complex luai_vectmul( lua_Complex a, lua_Complex b ) { return a*b; }
1762 + static inline lua_Complex luai_vectdiv( lua_Complex a, lua_Complex b ) { return a/b; }
1763 +
1764 +/*
1765 + * C99 does not provide modulus for complex numbers. It most likely is not
1766 + * meaningful at all.
1767 + */
1768 +
1769 +/*
1770 + * Complex power
1771 + *
1772 + * C99 'cpow' gives inaccurate results for many common cases s.a. (1i)^2 ->
1773 + * -1+1.2246467991474e-16i (OS X 10.4, gcc 4.0.1 build 5367)
1774 + *
1775 + * [(a+bi)^(c+di)] = (r^c) * exp(-d*t) * cos(c*t + d*ln(r)) +
1776 + * = (r^c) * exp(-d*t) * sin(c*t + d*ln(r)) *i
1777 + * r = sqrt(a^2+b^2), t = arctan( b/a )
1778 + *
1779 + * Reference: <http://home.att.net/~srschmitt/complexnumbers.html>
1780 + * Could also be calculated using: x^y = exp(ln(x)*y)
1781 + *
1782 + * Note: Defined here (and not in .c) so 'lmathlib.c' can share the
1783 + * implementation.
1784 + */
1785 + static inline
1786 + lua_Complex luai_vectpow( lua_Complex a, lua_Complex b )
1787 + {
1788 +# if 1
1789 + lua_Number ar= _LF(creal)(a), ai= _LF(cimag)(a);
1790 + lua_Number br= _LF(creal)(b), bi= _LF(cimag)(b);
1791 +
1792 + if (ai==0 && bi==0) { /* a^c (real) */
1793 + return luai_numpow( ar, br );
1794 + }
1795 +
1796 + int br_int= (int)br;
1797 +
1798 + if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) {
1799 + /* (a+bi)^N, N = { +-1,+-2, ... +-INT_MAX }
1800 + */
1801 + lua_Number k= luai_numpow( _LF(sqrt) (ar*ar + ai*ai), br );
1802 + lua_Number cos_z, sin_z;
1803 +
1804 + /* Situation depends upon c (N) in the following manner:
1805 + *
1806 + * N%4==0 => cos(c*t)=1, sin(c*t)=0
1807 + * (N*sign(b))%4==1 or (N*sign(b))%4==-3 => cos(c*t)=0, sin(c*t)=1
1808 + * N%4==2 or N%4==-2 => cos(c*t)=-1, sin(c*t)=0
1809 + * (N*sign(b))%4==-1 or (N*sign(b))%4==3 => cos(c*t)=0, sin(c*t)=-1
1810 + */
1811 + int br_int_abs = br_int<0 ? -br_int:br_int;
1812 +
1813 + switch( (br_int_abs%4) * (br_int<0 ? -1:1) * (ai<0 ? -1:1) ) {
1814 + case 0: cos_z=1, sin_z=0; break;
1815 + case 2: case -2: cos_z=-1, sin_z=0; break;
1816 + case 1: case -3: cos_z=0, sin_z=1; break;
1817 + case 3: case -1: cos_z=0, sin_z=-1; break;
1818 + default: lua_assert(0); return 0;
1819 + }
1820 + return k*cos_z + (k*sin_z)*I;
1821 + }
1822 +# endif
1823 + return _LF(cpow) ( a, b );
1824 + }
1825 +#endif
1826 +
1827 +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *res1, lua_Integer *res2);
1828 +LUAI_FUNC void luaO_num2buf( char *s, const TValue *o );
1829 +
1830 +LUAI_FUNC int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref );
1831 +
1832 +#define luai_normalize(o) \
1833 +{ lua_Integer _i; if (tt_integer_valued(o,&_i)) setivalue(o,_i); }
1834 +
1835 +#endif
1836 --- /dev/null
1837 +++ b/src/lnum_config.h
1838 @@ -0,0 +1,221 @@
1839 +/*
1840 +** $Id: lnum_config.h,v ... $
1841 +** Internal Number model
1842 +** See Copyright Notice in lua.h
1843 +*/
1844 +
1845 +#ifndef lnum_config_h
1846 +#define lnum_config_h
1847 +
1848 +/*
1849 +** Default number modes
1850 +*/
1851 +#if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE)
1852 +# define LNUM_FLOAT
1853 +#endif
1854 +#if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64)
1855 +# define LNUM_INT32
1856 +#endif
1857 +
1858 +/*
1859 +** Require C99 mode for COMPLEX, FLOAT and LDOUBLE (only DOUBLE is ANSI C).
1860 +*/
1861 +#if defined(LNUM_COMPLEX) && (__STDC_VERSION__ < 199901L)
1862 +# error "Need C99 for complex (use '--std=c99' or similar)"
1863 +#elif defined(LNUM_LDOUBLE) && (__STDC_VERSION__ < 199901L) && !defined(_MSC_VER)
1864 +# error "Need C99 for 'long double' (use '--std=c99' or similar)"
1865 +#elif defined(LNUM_FLOAT) && (__STDC_VERSION__ < 199901L)
1866 +/* LNUM_FLOAT not supported on Windows */
1867 +# error "Need C99 for 'float' (use '--std=c99' or similar)"
1868 +#endif
1869 +
1870 +/*
1871 +** Number mode identifier to accompany the version string.
1872 +*/
1873 +#ifdef LNUM_COMPLEX
1874 +# define _LNUM1 "complex "
1875 +#else
1876 +# define _LNUM1 ""
1877 +#endif
1878 +#ifdef LNUM_DOUBLE
1879 +# define _LNUM2 "double"
1880 +#elif defined(LNUM_FLOAT)
1881 +# define _LNUM2 "float"
1882 +#elif defined(LNUM_LDOUBLE)
1883 +# define _LNUM2 "ldouble"
1884 +#endif
1885 +#ifdef LNUM_INT32
1886 +# define _LNUM3 "int32"
1887 +#elif defined(LNUM_INT64)
1888 +# define _LNUM3 "int64"
1889 +#elif defined(LNUM_INT16)
1890 +# define _LNUM3 "int16"
1891 +#endif
1892 +#define LUA_LNUM _LNUM1 _LNUM2 " " _LNUM3
1893 +
1894 +/*
1895 +** LUA_NUMBER is the type of floating point number in Lua
1896 +** LUA_NUMBER_SCAN is the format for reading numbers.
1897 +** LUA_NUMBER_FMT is the format for writing numbers.
1898 +*/
1899 +#ifdef LNUM_FLOAT
1900 +# define LUA_NUMBER float
1901 +# define LUA_NUMBER_SCAN "%f"
1902 +# define LUA_NUMBER_FMT "%g"
1903 +#elif (defined LNUM_DOUBLE)
1904 +# define LUA_NUMBER double
1905 +# define LUA_NUMBER_SCAN "%lf"
1906 +# define LUA_NUMBER_FMT "%.14g"
1907 +#elif (defined LNUM_LDOUBLE)
1908 +# define LUA_NUMBER long double
1909 +# define LUA_NUMBER_SCAN "%Lg"
1910 +# define LUA_NUMBER_FMT "%.20Lg"
1911 +#endif
1912 +
1913 +
1914 +/*
1915 +** LUAI_MAXNUMBER2STR: size of a buffer fitting any number->string result.
1916 +**
1917 +** double: 24 (sign, x.xxxxxxxxxxxxxxe+nnnn, and \0)
1918 +** int64: 21 (19 digits, sign, and \0)
1919 +** long double: 43 for 128-bit (sign, x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
1920 +** 30 for 80-bit (sign, x.xxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
1921 +*/
1922 +#ifdef LNUM_LDOUBLE
1923 +# define _LUAI_MN2S 44
1924 +#else
1925 +# define _LUAI_MN2S 24
1926 +#endif
1927 +
1928 +#ifdef LNUM_COMPLEX
1929 +# define LUAI_MAXNUMBER2STR (2*_LUAI_MN2S)
1930 +#else
1931 +# define LUAI_MAXNUMBER2STR _LUAI_MN2S
1932 +#endif
1933 +
1934 +/*
1935 +** LUA_INTEGER is the integer type used by lua_pushinteger/lua_tointeger/lua_isinteger.
1936 +** LUA_INTEGER_SCAN is the format for reading integers
1937 +** LUA_INTEGER_FMT is the format for writing integers
1938 +**
1939 +** Note: Visual C++ 2005 does not have 'strtoull()', use '_strtoui64()' instead.
1940 +*/
1941 +#ifdef LNUM_INT32
1942 +# if LUAI_BITSINT > 16
1943 +# define LUA_INTEGER int
1944 +# define LUA_INTEGER_SCAN "%d"
1945 +# define LUA_INTEGER_FMT "%d"
1946 +# else
1947 +/* Note: 'LUA_INTEGER' being 'ptrdiff_t' (as in Lua 5.1) causes problems with
1948 + * 'printf()' operations. Also 'unsigned ptrdiff_t' is invalid.
1949 + */
1950 +# define LUA_INTEGER long
1951 +# define LUA_INTEGER_SCAN "%ld"
1952 +# define LUA_INTEGER_FMT "%ld"
1953 +# endif
1954 +# define LUA_INTEGER_MAX 0x7FFFFFFF /* 2^31-1 */
1955 +/* */
1956 +#elif defined(LNUM_INT64)
1957 +# define LUA_INTEGER long long
1958 +# ifdef _MSC_VER
1959 +# define lua_str2ul _strtoui64
1960 +# else
1961 +# define lua_str2ul strtoull
1962 +# endif
1963 +# define LUA_INTEGER_SCAN "%lld"
1964 +# define LUA_INTEGER_FMT "%lld"
1965 +# define LUA_INTEGER_MAX 0x7fffffffffffffffLL /* 2^63-1 */
1966 +# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX - 1LL) /* -2^63 */
1967 +/* */
1968 +#elif defined(LNUM_INT16)
1969 +# if LUAI_BITSINT > 16
1970 +# define LUA_INTEGER short
1971 +# define LUA_INTEGER_SCAN "%hd"
1972 +# define LUA_INTEGER_FMT "%hd"
1973 +# else
1974 +# define LUA_INTEGER int
1975 +# define LUA_INTEGER_SCAN "%d"
1976 +# define LUA_INTEGER_FMT "%d"
1977 +# endif
1978 +# define LUA_INTEGER_MAX 0x7FFF /* 2^16-1 */
1979 +#endif
1980 +
1981 +#ifndef lua_str2ul
1982 +# define lua_str2ul (unsigned LUA_INTEGER)strtoul
1983 +#endif
1984 +#ifndef LUA_INTEGER_MIN
1985 +# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
1986 +#endif
1987 +
1988 +/*
1989 +@@ lua_number2int is a macro to convert lua_Number to int.
1990 +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
1991 +** CHANGE them if you know a faster way to convert a lua_Number to
1992 +** int (with any rounding method and without throwing errors) in your
1993 +** system. In Pentium machines, a naive typecast from double to int
1994 +** in C is extremely slow, so any alternative is worth trying.
1995 +*/
1996 +
1997 +/* On a Pentium, resort to a trick */
1998 +#if defined(LNUM_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
1999 + (defined(__i386) || defined (_M_IX86) || defined(__i386__))
2000 +
2001 +/* On a Microsoft compiler, use assembler */
2002 +# if defined(_MSC_VER)
2003 +# define lua_number2int(i,d) __asm fld d __asm fistp i
2004 +# else
2005 +
2006 +/* the next trick should work on any Pentium, but sometimes clashes
2007 + with a DirectX idiosyncrasy */
2008 +union luai_Cast { double l_d; long l_l; };
2009 +# define lua_number2int(i,d) \
2010 + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
2011 +# endif
2012 +
2013 +# ifndef LNUM_INT64
2014 +# define lua_number2integer lua_number2int
2015 +# endif
2016 +
2017 +/* this option always works, but may be slow */
2018 +#else
2019 +# define lua_number2int(i,d) ((i)=(int)(d))
2020 +#endif
2021 +
2022 +/* Note: Some compilers (OS X gcc 4.0?) may choke on double->long long conversion
2023 + * since it can lose precision. Others do require 'long long' there.
2024 + */
2025 +#ifndef lua_number2integer
2026 +# define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
2027 +#endif
2028 +
2029 +/*
2030 +** 'luai_abs()' to give absolute value of 'lua_Integer'
2031 +*/
2032 +#ifdef LNUM_INT32
2033 +# define luai_abs abs
2034 +#elif defined(LNUM_INT64) && (__STDC_VERSION__ >= 199901L)
2035 +# define luai_abs llabs
2036 +#else
2037 +# define luai_abs(v) ((v) >= 0 ? (v) : -(v))
2038 +#endif
2039 +
2040 +/*
2041 +** LUAI_UACNUMBER is the result of an 'usual argument conversion' over a number.
2042 +** LUAI_UACINTEGER the same, over an integer.
2043 +*/
2044 +#define LUAI_UACNUMBER double
2045 +#define LUAI_UACINTEGER long
2046 +
2047 +/* ANSI C only has math funcs for 'double. C99 required for float and long double
2048 + * variants.
2049 + */
2050 +#ifdef LNUM_DOUBLE
2051 +# define _LF(name) name
2052 +#elif defined(LNUM_FLOAT)
2053 +# define _LF(name) name ## f
2054 +#elif defined(LNUM_LDOUBLE)
2055 +# define _LF(name) name ## l
2056 +#endif
2057 +
2058 +#endif
2059 +
2060 --- a/src/lobject.c
2061 +++ b/src/lobject.c
2062 @@ -21,7 +21,8 @@
2063 #include "lstate.h"
2064 #include "lstring.h"
2065 #include "lvm.h"
2066 -
2067 +#include "llex.h"
2068 +#include "lnum.h"
2069
2070
2071 const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
2072 @@ -70,12 +71,31 @@ int luaO_log2 (unsigned int x) {
2073
2074
2075 int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
2076 - if (ttype(t1) != ttype(t2)) return 0;
2077 + if (!ttype_ext_same(t1,t2)) return 0;
2078 else switch (ttype(t1)) {
2079 case LUA_TNIL:
2080 return 1;
2081 + case LUA_TINT:
2082 + if (ttype(t2)==LUA_TINT)
2083 + return ivalue(t1) == ivalue(t2);
2084 + else { /* t1:int, t2:num */
2085 +#ifdef LNUM_COMPLEX
2086 + if (nvalue_img_fast(t2) != 0) return 0;
2087 +#endif
2088 + /* Avoid doing accuracy losing cast, if possible. */
2089 + lua_Integer tmp;
2090 + if (tt_integer_valued(t2,&tmp))
2091 + return ivalue(t1) == tmp;
2092 + else
2093 + return luai_numeq( cast_num(ivalue(t1)), nvalue_fast(t2) );
2094 + }
2095 case LUA_TNUMBER:
2096 - return luai_numeq(nvalue(t1), nvalue(t2));
2097 + if (ttype(t2)==LUA_TINT)
2098 + return luaO_rawequalObj(t2, t1); /* swap LUA_TINT to left */
2099 +#ifdef LNUM_COMPLEX
2100 + if (!luai_numeq(nvalue_img_fast(t1), nvalue_img_fast(t2))) return 0;
2101 +#endif
2102 + return luai_numeq(nvalue_fast(t1), nvalue_fast(t2));
2103 case LUA_TBOOLEAN:
2104 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
2105 case LUA_TLIGHTUSERDATA:
2106 @@ -86,21 +106,6 @@ int luaO_rawequalObj (const TValue *t1,
2107 }
2108 }
2109
2110 -
2111 -int luaO_str2d (const char *s, lua_Number *result) {
2112 - char *endptr;
2113 - *result = lua_str2number(s, &endptr);
2114 - if (endptr == s) return 0; /* conversion failed */
2115 - if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
2116 - *result = cast_num(strtoul(s, &endptr, 16));
2117 - if (*endptr == '\0') return 1; /* most common case */
2118 - while (isspace(cast(unsigned char, *endptr))) endptr++;
2119 - if (*endptr != '\0') return 0; /* invalid trailing characters? */
2120 - return 1;
2121 -}
2122 -
2123 -
2124 -
2125 static void pushstr (lua_State *L, const char *str) {
2126 setsvalue2s(L, L->top, luaS_new(L, str));
2127 incr_top(L);
2128 @@ -131,7 +136,11 @@ const char *luaO_pushvfstring (lua_State
2129 break;
2130 }
2131 case 'd': {
2132 - setnvalue(L->top, cast_num(va_arg(argp, int)));
2133 + /* This is tricky for 64-bit integers; maybe they even cannot be
2134 + * supported on all compilers; depends on the conversions applied to
2135 + * variable argument lists. TBD: test!
2136 + */
2137 + setivalue(L->top, (lua_Integer) va_arg(argp, l_uacInteger));
2138 incr_top(L);
2139 break;
2140 }
2141 @@ -212,3 +221,4 @@ void luaO_chunkid (char *out, const char
2142 }
2143 }
2144 }
2145 +
2146 --- a/src/lobject.h
2147 +++ b/src/lobject.h
2148 @@ -17,7 +17,11 @@
2149
2150
2151 /* tags for values visible from Lua */
2152 -#define LAST_TAG LUA_TTHREAD
2153 +#if LUA_TINT > LUA_TTHREAD
2154 +# define LAST_TAG LUA_TINT
2155 +#else
2156 +# define LAST_TAG LUA_TTHREAD
2157 +#endif
2158
2159 #define NUM_TAGS (LAST_TAG+1)
2160
2161 @@ -59,7 +63,12 @@ typedef struct GCheader {
2162 typedef union {
2163 GCObject *gc;
2164 void *p;
2165 +#ifdef LNUM_COMPLEX
2166 + lua_Complex n;
2167 +#else
2168 lua_Number n;
2169 +#endif
2170 + lua_Integer i;
2171 int b;
2172 } Value;
2173
2174 @@ -77,7 +86,11 @@ typedef struct lua_TValue {
2175
2176 /* Macros to test type */
2177 #define ttisnil(o) (ttype(o) == LUA_TNIL)
2178 -#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
2179 +#define ttisint(o) (ttype(o) == LUA_TINT)
2180 +#define ttisnumber(o) ((ttype(o) == LUA_TINT) || (ttype(o) == LUA_TNUMBER))
2181 +#ifdef LNUM_COMPLEX
2182 +# define ttiscomplex(o) ((ttype(o) == LUA_TNUMBER) && (nvalue_img_fast(o)!=0))
2183 +#endif
2184 #define ttisstring(o) (ttype(o) == LUA_TSTRING)
2185 #define ttistable(o) (ttype(o) == LUA_TTABLE)
2186 #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
2187 @@ -90,7 +103,25 @@ typedef struct lua_TValue {
2188 #define ttype(o) ((o)->tt)
2189 #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
2190 #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
2191 -#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
2192 +
2193 +#define ttype_ext(o) ( ttype(o) == LUA_TINT ? LUA_TNUMBER : ttype(o) )
2194 +#define ttype_ext_same(o1,o2) ( (ttype(o1)==ttype(o2)) || (ttisnumber(o1) && ttisnumber(o2)) )
2195 +
2196 +/* '_fast' variants are for cases where 'ttype(o)' is known to be LUA_TNUMBER.
2197 + */
2198 +#ifdef LNUM_COMPLEX
2199 +# define nvalue_complex_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
2200 +# define nvalue_fast(o) ( _LF(creal) ( nvalue_complex_fast(o) ) )
2201 +# define nvalue_img_fast(o) ( _LF(cimag) ( nvalue_complex_fast(o) ) )
2202 +# define nvalue_complex(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? (o)->value.i : (o)->value.n )
2203 +# define nvalue_img(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? 0 : _LF(cimag)( (o)->value.n ) )
2204 +# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : _LF(creal)((o)->value.n) )
2205 +#else
2206 +# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : (o)->value.n )
2207 +# define nvalue_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
2208 +#endif
2209 +#define ivalue(o) check_exp( ttype(o)==LUA_TINT, (o)->value.i )
2210 +
2211 #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
2212 #define tsvalue(o) (&rawtsvalue(o)->tsv)
2213 #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
2214 @@ -116,8 +147,27 @@ typedef struct lua_TValue {
2215 /* Macros to set values */
2216 #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
2217
2218 -#define setnvalue(obj,x) \
2219 - { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
2220 +/* Must not have side effects, 'x' may be expression.
2221 +*/
2222 +#define setivalue(obj,x) \
2223 + { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; }
2224 +
2225 +# define setnvalue(obj,x) \
2226 + { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
2227 +
2228 +/* Note: Complex always has "inline", both are C99.
2229 +*/
2230 +#ifdef LNUM_COMPLEX
2231 + static inline void setnvalue_complex_fast( TValue *obj, lua_Complex x ) {
2232 + lua_assert( _LF(cimag)(x) != 0 );
2233 + obj->value.n= x; obj->tt= LUA_TNUMBER;
2234 + }
2235 + static inline void setnvalue_complex( TValue *obj, lua_Complex x ) {
2236 + if (_LF(cimag)(x) == 0) { setnvalue(obj, _LF(creal)(x)); }
2237 + else { obj->value.n= x; obj->tt= LUA_TNUMBER; }
2238 + }
2239 +#endif
2240 +
2241
2242 #define setpvalue(obj,x) \
2243 { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
2244 @@ -155,9 +205,6 @@ typedef struct lua_TValue {
2245 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
2246 checkliveness(G(L),i_o); }
2247
2248 -
2249 -
2250 -
2251 #define setobj(L,obj1,obj2) \
2252 { const TValue *o2=(obj2); TValue *o1=(obj1); \
2253 o1->value = o2->value; o1->tt=o2->tt; \
2254 @@ -185,8 +232,11 @@ typedef struct lua_TValue {
2255
2256 #define setttype(obj, tt) (ttype(obj) = (tt))
2257
2258 -
2259 -#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
2260 +#if LUA_TINT >= LUA_TSTRING
2261 +# define iscollectable(o) ((ttype(o) >= LUA_TSTRING) && (ttype(o) != LUA_TINT))
2262 +#else
2263 +# define iscollectable(o) (ttype(o) >= LUA_TSTRING)
2264 +#endif
2265
2266
2267
2268 @@ -370,12 +420,10 @@ LUAI_FUNC int luaO_log2 (unsigned int x)
2269 LUAI_FUNC int luaO_int2fb (unsigned int x);
2270 LUAI_FUNC int luaO_fb2int (int x);
2271 LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
2272 -LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
2273 LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
2274 va_list argp);
2275 LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
2276 LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
2277
2278 -
2279 #endif
2280
2281 --- a/src/loslib.c
2282 +++ b/src/loslib.c
2283 @@ -186,15 +186,30 @@ static int os_time (lua_State *L) {
2284 }
2285 if (t == (time_t)(-1))
2286 lua_pushnil(L);
2287 - else
2288 - lua_pushnumber(L, (lua_Number)t);
2289 + else {
2290 + /* On float systems the pushed value must be an integer, NOT a number.
2291 + * Otherwise, accuracy is lost in the time_t->float conversion.
2292 + */
2293 +#ifdef LNUM_FLOAT
2294 + lua_pushinteger(L, (lua_Integer) t);
2295 +#else
2296 + lua_pushnumber(L, (lua_Number) t);
2297 +#endif
2298 + }
2299 return 1;
2300 }
2301
2302
2303 static int os_difftime (lua_State *L) {
2304 +#ifdef LNUM_FLOAT
2305 + lua_Integer i= (lua_Integer)
2306 + difftime( (time_t)(luaL_checkinteger(L, 1)),
2307 + (time_t)(luaL_optinteger(L, 2, 0)));
2308 + lua_pushinteger(L, i);
2309 +#else
2310 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
2311 (time_t)(luaL_optnumber(L, 2, 0))));
2312 +#endif
2313 return 1;
2314 }
2315
2316 --- a/src/lparser.c
2317 +++ b/src/lparser.c
2318 @@ -33,7 +33,6 @@
2319
2320 #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
2321
2322 -
2323 /*
2324 ** nodes for block list (list of active blocks)
2325 */
2326 @@ -72,7 +71,7 @@ static void errorlimit (FuncState *fs, i
2327 const char *msg = (fs->f->linedefined == 0) ?
2328 luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
2329 luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
2330 - fs->f->linedefined, limit, what);
2331 + (fs->f->linedefined), limit, what);
2332 luaX_lexerror(fs->ls, msg, 0);
2333 }
2334
2335 @@ -733,6 +732,18 @@ static void simpleexp (LexState *ls, exp
2336 v->u.nval = ls->t.seminfo.r;
2337 break;
2338 }
2339 + case TK_INT: {
2340 + init_exp(v, VKINT, 0);
2341 + v->u.ival = ls->t.seminfo.i;
2342 + break;
2343 + }
2344 +#ifdef LNUM_COMPLEX
2345 + case TK_NUMBER2: {
2346 + init_exp(v, VKNUM2, 0);
2347 + v->u.nval = ls->t.seminfo.r;
2348 + break;
2349 + }
2350 +#endif
2351 case TK_STRING: {
2352 codestring(ls, v, ls->t.seminfo.ts);
2353 break;
2354 @@ -1079,7 +1090,7 @@ static void fornum (LexState *ls, TStrin
2355 if (testnext(ls, ','))
2356 exp1(ls); /* optional step */
2357 else { /* default step = 1 */
2358 - luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
2359 + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_integerK(fs, 1));
2360 luaK_reserveregs(fs, 1);
2361 }
2362 forbody(ls, base, line, 1, 1);
2363 --- a/src/lparser.h
2364 +++ b/src/lparser.h
2365 @@ -31,7 +31,11 @@ typedef enum {
2366 VRELOCABLE, /* info = instruction pc */
2367 VNONRELOC, /* info = result register */
2368 VCALL, /* info = instruction pc */
2369 - VVARARG /* info = instruction pc */
2370 + VVARARG, /* info = instruction pc */
2371 + VKINT /* ival = integer value */
2372 +#ifdef LNUM_COMPLEX
2373 + ,VKNUM2 /* nval = imaginary value */
2374 +#endif
2375 } expkind;
2376
2377 typedef struct expdesc {
2378 @@ -39,6 +43,7 @@ typedef struct expdesc {
2379 union {
2380 struct { int info, aux; } s;
2381 lua_Number nval;
2382 + lua_Integer ival;
2383 } u;
2384 int t; /* patch list of `exit when true' */
2385 int f; /* patch list of `exit when false' */
2386 --- a/src/lstrlib.c
2387 +++ b/src/lstrlib.c
2388 @@ -43,8 +43,8 @@ static ptrdiff_t posrelat (ptrdiff_t pos
2389 static int str_sub (lua_State *L) {
2390 size_t l;
2391 const char *s = luaL_checklstring(L, 1, &l);
2392 - ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
2393 - ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
2394 + ptrdiff_t start = posrelat(luaL_checkint32(L, 2), l);
2395 + ptrdiff_t end = posrelat(luaL_optint32(L, 3, -1), l);
2396 if (start < 1) start = 1;
2397 if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
2398 if (start <= end)
2399 @@ -106,8 +106,8 @@ static int str_rep (lua_State *L) {
2400 static int str_byte (lua_State *L) {
2401 size_t l;
2402 const char *s = luaL_checklstring(L, 1, &l);
2403 - ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
2404 - ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
2405 + ptrdiff_t posi = posrelat(luaL_optint32(L, 2, 1), l);
2406 + ptrdiff_t pose = posrelat(luaL_optint32(L, 3, posi), l);
2407 int n, i;
2408 if (posi <= 0) posi = 1;
2409 if ((size_t)pose > l) pose = l;
2410 @@ -496,7 +496,7 @@ static int str_find_aux (lua_State *L, i
2411 size_t l1, l2;
2412 const char *s = luaL_checklstring(L, 1, &l1);
2413 const char *p = luaL_checklstring(L, 2, &l2);
2414 - ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
2415 + ptrdiff_t init = posrelat(luaL_optint32(L, 3, 1), l1) - 1;
2416 if (init < 0) init = 0;
2417 else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
2418 if (find && (lua_toboolean(L, 4) || /* explicit request? */
2419 @@ -690,7 +690,7 @@ static int str_gsub (lua_State *L) {
2420 ** maximum size of each format specification (such as '%-099.99d')
2421 ** (+10 accounts for %99.99x plus margin of error)
2422 */
2423 -#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
2424 +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTEGER_FMT)-2 + 10)
2425
2426
2427 static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
2428 @@ -747,9 +747,9 @@ static const char *scanformat (lua_State
2429 static void addintlen (char *form) {
2430 size_t l = strlen(form);
2431 char spec = form[l - 1];
2432 - strcpy(form + l - 1, LUA_INTFRMLEN);
2433 - form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
2434 - form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
2435 + const char *tmp= LUA_INTEGER_FMT; /* "%lld" or "%ld" */
2436 + strcpy(form + l - 1, tmp+1);
2437 + form[l + sizeof(LUA_INTEGER_FMT)-4] = spec;
2438 }
2439
2440
2441 @@ -777,12 +777,12 @@ static int str_format (lua_State *L) {
2442 }
2443 case 'd': case 'i': {
2444 addintlen(form);
2445 - sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
2446 + sprintf(buff, form, luaL_checkinteger(L, arg));
2447 break;
2448 }
2449 case 'o': case 'u': case 'x': case 'X': {
2450 addintlen(form);
2451 - sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
2452 + sprintf(buff, form, (unsigned LUA_INTEGER)luaL_checkinteger(L, arg));
2453 break;
2454 }
2455 case 'e': case 'E': case 'f':
2456 --- a/src/ltable.c
2457 +++ b/src/ltable.c
2458 @@ -33,6 +33,7 @@
2459 #include "lobject.h"
2460 #include "lstate.h"
2461 #include "ltable.h"
2462 +#include "lnum.h"
2463
2464
2465 /*
2466 @@ -51,25 +52,15 @@
2467
2468 #define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
2469 #define hashboolean(t,p) hashpow2(t, p)
2470 -
2471 +#define hashint(t,i) hashpow2(t,i)
2472
2473 /*
2474 ** for some types, it is better to avoid modulus by power of 2, as
2475 ** they tend to have many 2 factors.
2476 */
2477 #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
2478 -
2479 -
2480 #define hashpointer(t,p) hashmod(t, IntPoint(p))
2481
2482 -
2483 -/*
2484 -** number of ints inside a lua_Number
2485 -*/
2486 -#define numints cast_int(sizeof(lua_Number)/sizeof(int))
2487 -
2488 -
2489 -
2490 #define dummynode (&dummynode_)
2491
2492 static const Node dummynode_ = {
2493 @@ -80,27 +71,46 @@ static const Node dummynode_ = {
2494
2495 /*
2496 ** hash for lua_Numbers
2497 +**
2498 +** for non-complex modes, never called with 'lua_Integer' value range (s.a. 0)
2499 */
2500 static Node *hashnum (const Table *t, lua_Number n) {
2501 - unsigned int a[numints];
2502 - int i;
2503 - if (luai_numeq(n, 0)) /* avoid problems with -0 */
2504 - return gnode(t, 0);
2505 - memcpy(a, &n, sizeof(a));
2506 - for (i = 1; i < numints; i++) a[0] += a[i];
2507 - return hashmod(t, a[0]);
2508 + const unsigned int *p= cast(const unsigned int *,&n);
2509 + unsigned int sum= *p;
2510 + unsigned int m= sizeof(lua_Number)/sizeof(int);
2511 + unsigned int i;
2512 + /* OS X Intel has 'm'==4 and gives "Bus error" if the last integer of
2513 + * 'n' is read; the actual size of long double is only 80 bits = 10 bytes.
2514 + * Linux x86 has 'm'==3, and does not require reduction.
2515 + */
2516 +#if defined(LNUM_LDOUBLE) && defined(__i386__)
2517 + if (m>3) m--;
2518 +#endif
2519 + for (i = 1; i < m; i++) sum += p[i];
2520 + return hashmod(t, sum);
2521 }
2522
2523
2524 -
2525 /*
2526 ** returns the `main' position of an element in a table (that is, the index
2527 ** of its hash value)
2528 +**
2529 +** Floating point numbers with integer value give the hash position of the
2530 +** integer (so they use the same table position).
2531 */
2532 static Node *mainposition (const Table *t, const TValue *key) {
2533 + lua_Integer i;
2534 switch (ttype(key)) {
2535 case LUA_TNUMBER:
2536 - return hashnum(t, nvalue(key));
2537 + if (tt_integer_valued(key,&i))
2538 + return hashint(t, i);
2539 +#ifdef LNUM_COMPLEX
2540 + if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0))
2541 + return gnode(t, 0); /* 0 and -0 to give same hash */
2542 +#endif
2543 + return hashnum(t, nvalue_fast(key));
2544 + case LUA_TINT:
2545 + return hashint(t, ivalue(key));
2546 case LUA_TSTRING:
2547 return hashstr(t, rawtsvalue(key));
2548 case LUA_TBOOLEAN:
2549 @@ -116,16 +126,20 @@ static Node *mainposition (const Table *
2550 /*
2551 ** returns the index for `key' if `key' is an appropriate key to live in
2552 ** the array part of the table, -1 otherwise.
2553 +**
2554 +** Anything <=0 is taken as not being in the array part.
2555 */
2556 -static int arrayindex (const TValue *key) {
2557 - if (ttisnumber(key)) {
2558 - lua_Number n = nvalue(key);
2559 - int k;
2560 - lua_number2int(k, n);
2561 - if (luai_numeq(cast_num(k), n))
2562 - return k;
2563 +static int arrayindex (const TValue *key, int max) {
2564 + lua_Integer k;
2565 + switch( ttype(key) ) {
2566 + case LUA_TINT:
2567 + k= ivalue(key); break;
2568 + case LUA_TNUMBER:
2569 + if (tt_integer_valued(key,&k)) break;
2570 + default:
2571 + return -1; /* not to be used as array index */
2572 }
2573 - return -1; /* `key' did not match some condition */
2574 + return ((k>0) && (k <= max)) ? cast_int(k) : -1;
2575 }
2576
2577
2578 @@ -137,8 +151,8 @@ static int arrayindex (const TValue *key
2579 static int findindex (lua_State *L, Table *t, StkId key) {
2580 int i;
2581 if (ttisnil(key)) return -1; /* first iteration */
2582 - i = arrayindex(key);
2583 - if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
2584 + i = arrayindex(key, t->sizearray);
2585 + if (i>0) /* inside array part? */
2586 return i-1; /* yes; that's the index (corrected to C) */
2587 else {
2588 Node *n = mainposition(t, key);
2589 @@ -163,7 +177,7 @@ int luaH_next (lua_State *L, Table *t, S
2590 int i = findindex(L, t, key); /* find original element */
2591 for (i++; i < t->sizearray; i++) { /* try first array part */
2592 if (!ttisnil(&t->array[i])) { /* a non-nil value? */
2593 - setnvalue(key, cast_num(i+1));
2594 + setivalue(key, i+1);
2595 setobj2s(L, key+1, &t->array[i]);
2596 return 1;
2597 }
2598 @@ -209,8 +223,8 @@ static int computesizes (int nums[], int
2599
2600
2601 static int countint (const TValue *key, int *nums) {
2602 - int k = arrayindex(key);
2603 - if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
2604 + int k = arrayindex(key,MAXASIZE);
2605 + if (k>0) { /* appropriate array index? */
2606 nums[ceillog2(k)]++; /* count as such */
2607 return 1;
2608 }
2609 @@ -308,7 +322,7 @@ static void resize (lua_State *L, Table
2610 /* re-insert elements from vanishing slice */
2611 for (i=nasize; i<oldasize; i++) {
2612 if (!ttisnil(&t->array[i]))
2613 - setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
2614 + setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]);
2615 }
2616 /* shrink array */
2617 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
2618 @@ -409,7 +423,9 @@ static TValue *newkey (lua_State *L, Tab
2619 othern = mainposition(t, key2tval(mp));
2620 if (othern != mp) { /* is colliding node out of its main position? */
2621 /* yes; move colliding node into free position */
2622 - while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
2623 + while (gnext(othern) != mp) {
2624 + othern = gnext(othern); /* find previous */
2625 + }
2626 gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
2627 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
2628 gnext(mp) = NULL; /* now `mp' is free */
2629 @@ -432,17 +448,18 @@ static TValue *newkey (lua_State *L, Tab
2630 /*
2631 ** search function for integers
2632 */
2633 -const TValue *luaH_getnum (Table *t, int key) {
2634 +const TValue *luaH_getint (Table *t, lua_Integer key) {
2635 /* (1 <= key && key <= t->sizearray) */
2636 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
2637 return &t->array[key-1];
2638 else {
2639 - lua_Number nk = cast_num(key);
2640 - Node *n = hashnum(t, nk);
2641 + Node *n = hashint(t, key);
2642 do { /* check whether `key' is somewhere in the chain */
2643 - if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
2644 + if (ttisint(gkey(n)) && (ivalue(gkey(n)) == key)) {
2645 return gval(n); /* that's it */
2646 - else n = gnext(n);
2647 + } else {
2648 + n = gnext(n);
2649 + }
2650 } while (n);
2651 return luaO_nilobject;
2652 }
2653 @@ -470,14 +487,12 @@ const TValue *luaH_get (Table *t, const
2654 switch (ttype(key)) {
2655 case LUA_TNIL: return luaO_nilobject;
2656 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
2657 + case LUA_TINT: return luaH_getint(t, ivalue(key));
2658 case LUA_TNUMBER: {
2659 - int k;
2660 - lua_Number n = nvalue(key);
2661 - lua_number2int(k, n);
2662 - if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
2663 - return luaH_getnum(t, k); /* use specialized version */
2664 - /* else go through */
2665 - }
2666 + lua_Integer i;
2667 + if (tt_integer_valued(key,&i))
2668 + return luaH_getint(t,i);
2669 + } /* pass through */
2670 default: {
2671 Node *n = mainposition(t, key);
2672 do { /* check whether `key' is somewhere in the chain */
2673 @@ -498,20 +513,25 @@ TValue *luaH_set (lua_State *L, Table *t
2674 return cast(TValue *, p);
2675 else {
2676 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
2677 - else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
2678 - luaG_runerror(L, "table index is NaN");
2679 + else if (ttype(key)==LUA_TNUMBER) {
2680 + lua_Integer k;
2681 + if (luai_numisnan(nvalue_fast(key)))
2682 + luaG_runerror(L, "table index is NaN");
2683 + if (tt_integer_valued(key,&k))
2684 + return luaH_setint(L, t, k);
2685 + }
2686 return newkey(L, t, key);
2687 }
2688 }
2689
2690
2691 -TValue *luaH_setnum (lua_State *L, Table *t, int key) {
2692 - const TValue *p = luaH_getnum(t, key);
2693 +TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key) {
2694 + const TValue *p = luaH_getint(t, key);
2695 if (p != luaO_nilobject)
2696 return cast(TValue *, p);
2697 else {
2698 TValue k;
2699 - setnvalue(&k, cast_num(key));
2700 + setivalue(&k, key);
2701 return newkey(L, t, &k);
2702 }
2703 }
2704 @@ -533,20 +553,21 @@ static int unbound_search (Table *t, uns
2705 unsigned int i = j; /* i is zero or a present index */
2706 j++;
2707 /* find `i' and `j' such that i is present and j is not */
2708 - while (!ttisnil(luaH_getnum(t, j))) {
2709 + while (!ttisnil(luaH_getint(t, j))) {
2710 i = j;
2711 j *= 2;
2712 if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
2713 /* table was built with bad purposes: resort to linear search */
2714 - i = 1;
2715 - while (!ttisnil(luaH_getnum(t, i))) i++;
2716 - return i - 1;
2717 + for( i = 1; i<MAX_INT+1; i++ ) {
2718 + if (ttisnil(luaH_getint(t, i))) break;
2719 + }
2720 + return i - 1; /* up to MAX_INT */
2721 }
2722 }
2723 /* now do a binary search between them */
2724 while (j - i > 1) {
2725 unsigned int m = (i+j)/2;
2726 - if (ttisnil(luaH_getnum(t, m))) j = m;
2727 + if (ttisnil(luaH_getint(t, m))) j = m;
2728 else i = m;
2729 }
2730 return i;
2731 --- a/src/ltable.h
2732 +++ b/src/ltable.h
2733 @@ -18,8 +18,8 @@
2734 #define key2tval(n) (&(n)->i_key.tvk)
2735
2736
2737 -LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
2738 -LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
2739 +LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
2740 +LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key);
2741 LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
2742 LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
2743 LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
2744 --- a/src/ltm.c
2745 +++ b/src/ltm.c
2746 @@ -19,7 +19,6 @@
2747 #include "ltm.h"
2748
2749
2750 -
2751 const char *const luaT_typenames[] = {
2752 "nil", "boolean", "userdata", "number",
2753 "string", "table", "function", "userdata", "thread",
2754 @@ -67,6 +66,9 @@ const TValue *luaT_gettmbyobj (lua_State
2755 case LUA_TUSERDATA:
2756 mt = uvalue(o)->metatable;
2757 break;
2758 + case LUA_TINT:
2759 + mt = G(L)->mt[LUA_TNUMBER];
2760 + break;
2761 default:
2762 mt = G(L)->mt[ttype(o)];
2763 }
2764 --- a/src/lua.c
2765 +++ b/src/lua.c
2766 @@ -16,7 +16,7 @@
2767
2768 #include "lauxlib.h"
2769 #include "lualib.h"
2770 -
2771 +#include "llimits.h"
2772
2773
2774 static lua_State *globalL = NULL;
2775 @@ -382,6 +382,15 @@ int main (int argc, char **argv) {
2776 l_message(argv[0], "cannot create state: not enough memory");
2777 return EXIT_FAILURE;
2778 }
2779 + /* Checking 'sizeof(lua_Integer)' cannot be made in preprocessor on all compilers.
2780 + */
2781 +#ifdef LNUM_INT16
2782 + lua_assert( sizeof(lua_Integer) == 2 );
2783 +#elif defined(LNUM_INT32)
2784 + lua_assert( sizeof(lua_Integer) == 4 );
2785 +#elif defined(LNUM_INT64)
2786 + lua_assert( sizeof(lua_Integer) == 8 );
2787 +#endif
2788 s.argc = argc;
2789 s.argv = argv;
2790 status = lua_cpcall(L, &pmain, &s);
2791 --- a/src/lua.h
2792 +++ b/src/lua.h
2793 @@ -19,7 +19,7 @@
2794 #define LUA_VERSION "Lua 5.1"
2795 #define LUA_RELEASE "Lua 5.1.4"
2796 #define LUA_VERSION_NUM 501
2797 -#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
2798 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" " (" LUA_LNUM ")"
2799 #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
2800
2801
2802 @@ -71,6 +71,16 @@ typedef void * (*lua_Alloc) (void *ud, v
2803 */
2804 #define LUA_TNONE (-1)
2805
2806 +/* LUA_TINT is an internal type, not visible to applications. There are three
2807 + * potential values where it can be tweaked to (code autoadjusts to these):
2808 + *
2809 + * -2: not 'usual' type value; good since 'LUA_TINT' is not part of the API
2810 + * LUA_TNUMBER+1: shifts other type values upwards, breaking binary compatibility
2811 + * not acceptable for 5.1, maybe 5.2 onwards?
2812 + * 9: greater than existing (5.1) type values.
2813 +*/
2814 +#define LUA_TINT (-2)
2815 +
2816 #define LUA_TNIL 0
2817 #define LUA_TBOOLEAN 1
2818 #define LUA_TLIGHTUSERDATA 2
2819 @@ -139,6 +149,8 @@ LUA_API int (lua_isuserdata)
2820 LUA_API int (lua_type) (lua_State *L, int idx);
2821 LUA_API const char *(lua_typename) (lua_State *L, int tp);
2822
2823 +LUA_API int (lua_isinteger) (lua_State *L, int idx);
2824 +
2825 LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
2826 LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
2827 LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
2828 @@ -244,6 +256,19 @@ LUA_API lua_Alloc (lua_getallocf) (lua_S
2829 LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
2830
2831
2832 +/*
2833 +* It is unnecessary to break Lua C API 'lua_tonumber()' compatibility, just
2834 +* because the Lua number type is complex. Most C modules would use scalars
2835 +* only. We'll introduce new 'lua_tocomplex' and 'lua_pushcomplex' for when
2836 +* the module really wants to use them.
2837 +*/
2838 +#ifdef LNUM_COMPLEX
2839 + #include <complex.h>
2840 + typedef LUA_NUMBER complex lua_Complex;
2841 + LUA_API lua_Complex (lua_tocomplex) (lua_State *L, int idx);
2842 + LUA_API void (lua_pushcomplex) (lua_State *L, lua_Complex v);
2843 +#endif
2844 +
2845
2846 /*
2847 ** ===============================================================
2848 @@ -268,7 +293,12 @@ LUA_API void lua_setallocf (lua_State *L
2849 #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
2850 #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
2851 #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
2852 -#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
2853 +
2854 +#if LUA_TINT < 0
2855 +# define lua_isnoneornil(L, n) ( (lua_type(L,(n)) <= 0) && (lua_type(L,(n)) != LUA_TINT) )
2856 +#else
2857 +# define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
2858 +#endif
2859
2860 #define lua_pushliteral(L, s) \
2861 lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
2862 @@ -386,3 +416,4 @@ struct lua_Debug {
2863
2864
2865 #endif
2866 +
2867 --- a/src/luaconf.h
2868 +++ b/src/luaconf.h
2869 @@ -10,7 +10,9 @@
2870
2871 #include <limits.h>
2872 #include <stddef.h>
2873 -
2874 +#ifdef lua_assert
2875 +# include <assert.h>
2876 +#endif
2877
2878 /*
2879 ** ==================================================================
2880 @@ -136,14 +138,38 @@
2881
2882
2883 /*
2884 -@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
2885 -** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
2886 -** machines, ptrdiff_t gives a good choice between int or long.)
2887 +@@ LUAI_BITSINT defines the number of bits in an int.
2888 +** CHANGE here if Lua cannot automatically detect the number of bits of
2889 +** your machine. Probably you do not need to change this.
2890 */
2891 -#define LUA_INTEGER ptrdiff_t
2892 +/* avoid overflows in comparison */
2893 +#if INT_MAX-20 < 32760
2894 +#define LUAI_BITSINT 16
2895 +#elif INT_MAX > 2147483640L
2896 +/* int has at least 32 bits */
2897 +#define LUAI_BITSINT 32
2898 +#else
2899 +#error "you must define LUA_BITSINT with number of bits in an integer"
2900 +#endif
2901
2902
2903 /*
2904 +@@ LNUM_DOUBLE | LNUM_FLOAT | LNUM_LDOUBLE: Generic Lua number mode
2905 +@@ LNUM_INT32 | LNUM_INT64: Integer type
2906 +@@ LNUM_COMPLEX: Define for using 'a+bi' numbers
2907 +@@
2908 +@@ You can combine LNUM_xxx but only one of each group. I.e. '-DLNUM_FLOAT
2909 +@@ -DLNUM_INT32 -DLNUM_COMPLEX' gives float range complex numbers, with
2910 +@@ 32-bit scalar integer range optimized.
2911 +**
2912 +** These are kept in a separate configuration file mainly for ease of patching
2913 +** (can be changed if integerated to Lua proper).
2914 +*/
2915 +/*#define LNUM_DOUBLE*/
2916 +/*#define LNUM_INT32*/
2917 +#include "lnum_config.h"
2918 +
2919 +/*
2920 @@ LUA_API is a mark for all core API functions.
2921 @@ LUALIB_API is a mark for all standard library functions.
2922 ** CHANGE them if you need to define those functions in some special way.
2923 @@ -383,22 +409,6 @@
2924
2925
2926 /*
2927 -@@ LUAI_BITSINT defines the number of bits in an int.
2928 -** CHANGE here if Lua cannot automatically detect the number of bits of
2929 -** your machine. Probably you do not need to change this.
2930 -*/
2931 -/* avoid overflows in comparison */
2932 -#if INT_MAX-20 < 32760
2933 -#define LUAI_BITSINT 16
2934 -#elif INT_MAX > 2147483640L
2935 -/* int has at least 32 bits */
2936 -#define LUAI_BITSINT 32
2937 -#else
2938 -#error "you must define LUA_BITSINT with number of bits in an integer"
2939 -#endif
2940 -
2941 -
2942 -/*
2943 @@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
2944 @@ LUAI_INT32 is an signed integer with at least 32 bits.
2945 @@ LUAI_UMEM is an unsigned integer big enough to count the total
2946 @@ -425,6 +435,15 @@
2947 #define LUAI_MEM long
2948 #endif
2949
2950 +/*
2951 +@@ LUAI_BOOL carries 0 and nonzero (normally 1). It may be defined as 'char'
2952 +** (to save memory), 'int' (for speed), 'bool' (for C++) or '_Bool' (C99)
2953 +*/
2954 +#ifdef __cplusplus
2955 +# define LUAI_BOOL bool
2956 +#else
2957 +# define LUAI_BOOL int
2958 +#endif
2959
2960 /*
2961 @@ LUAI_MAXCALLS limits the number of nested calls.
2962 @@ -490,101 +509,6 @@
2963 /* }================================================================== */
2964
2965
2966 -
2967 -
2968 -/*
2969 -** {==================================================================
2970 -@@ LUA_NUMBER is the type of numbers in Lua.
2971 -** CHANGE the following definitions only if you want to build Lua
2972 -** with a number type different from double. You may also need to
2973 -** change lua_number2int & lua_number2integer.
2974 -** ===================================================================
2975 -*/
2976 -
2977 -#define LUA_NUMBER_DOUBLE
2978 -#define LUA_NUMBER double
2979 -
2980 -/*
2981 -@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
2982 -@* over a number.
2983 -*/
2984 -#define LUAI_UACNUMBER double
2985 -
2986 -
2987 -/*
2988 -@@ LUA_NUMBER_SCAN is the format for reading numbers.
2989 -@@ LUA_NUMBER_FMT is the format for writing numbers.
2990 -@@ lua_number2str converts a number to a string.
2991 -@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
2992 -@@ lua_str2number converts a string to a number.
2993 -*/
2994 -#define LUA_NUMBER_SCAN "%lf"
2995 -#define LUA_NUMBER_FMT "%.14g"
2996 -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
2997 -#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
2998 -#define lua_str2number(s,p) strtod((s), (p))
2999 -
3000 -
3001 -/*
3002 -@@ The luai_num* macros define the primitive operations over numbers.
3003 -*/
3004 -#if defined(LUA_CORE)
3005 -#include <math.h>
3006 -#define luai_numadd(a,b) ((a)+(b))
3007 -#define luai_numsub(a,b) ((a)-(b))
3008 -#define luai_nummul(a,b) ((a)*(b))
3009 -#define luai_numdiv(a,b) ((a)/(b))
3010 -#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
3011 -#define luai_numpow(a,b) (pow(a,b))
3012 -#define luai_numunm(a) (-(a))
3013 -#define luai_numeq(a,b) ((a)==(b))
3014 -#define luai_numlt(a,b) ((a)<(b))
3015 -#define luai_numle(a,b) ((a)<=(b))
3016 -#define luai_numisnan(a) (!luai_numeq((a), (a)))
3017 -#endif
3018 -
3019 -
3020 -/*
3021 -@@ lua_number2int is a macro to convert lua_Number to int.
3022 -@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
3023 -** CHANGE them if you know a faster way to convert a lua_Number to
3024 -** int (with any rounding method and without throwing errors) in your
3025 -** system. In Pentium machines, a naive typecast from double to int
3026 -** in C is extremely slow, so any alternative is worth trying.
3027 -*/
3028 -
3029 -/* On a Pentium, resort to a trick */
3030 -#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
3031 - (defined(__i386) || defined (_M_IX86) || defined(__i386__))
3032 -
3033 -/* On a Microsoft compiler, use assembler */
3034 -#if defined(_MSC_VER)
3035 -
3036 -#define lua_number2int(i,d) __asm fld d __asm fistp i
3037 -#define lua_number2integer(i,n) lua_number2int(i, n)
3038 -
3039 -/* the next trick should work on any Pentium, but sometimes clashes
3040 - with a DirectX idiosyncrasy */
3041 -#else
3042 -
3043 -union luai_Cast { double l_d; long l_l; };
3044 -#define lua_number2int(i,d) \
3045 - { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
3046 -#define lua_number2integer(i,n) lua_number2int(i, n)
3047 -
3048 -#endif
3049 -
3050 -
3051 -/* this option always works, but may be slow */
3052 -#else
3053 -#define lua_number2int(i,d) ((i)=(int)(d))
3054 -#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
3055 -
3056 -#endif
3057 -
3058 -/* }================================================================== */
3059 -
3060 -
3061 /*
3062 @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
3063 ** CHANGE it if your system requires alignments larger than double. (For
3064 @@ -728,28 +652,6 @@ union luai_Cast { double l_d; long l_l;
3065 #define luai_userstateyield(L,n) ((void)L)
3066
3067
3068 -/*
3069 -@@ LUA_INTFRMLEN is the length modifier for integer conversions
3070 -@* in 'string.format'.
3071 -@@ LUA_INTFRM_T is the integer type correspoding to the previous length
3072 -@* modifier.
3073 -** CHANGE them if your system supports long long or does not support long.
3074 -*/
3075 -
3076 -#if defined(LUA_USELONGLONG)
3077 -
3078 -#define LUA_INTFRMLEN "ll"
3079 -#define LUA_INTFRM_T long long
3080 -
3081 -#else
3082 -
3083 -#define LUA_INTFRMLEN "l"
3084 -#define LUA_INTFRM_T long
3085 -
3086 -#endif
3087 -
3088 -
3089 -
3090 /* =================================================================== */
3091
3092 /*
3093 --- a/src/lundump.c
3094 +++ b/src/lundump.c
3095 @@ -73,6 +73,13 @@ static lua_Number LoadNumber(LoadState*
3096 return x;
3097 }
3098
3099 +static lua_Integer LoadInteger(LoadState* S)
3100 +{
3101 + lua_Integer x;
3102 + LoadVar(S,x);
3103 + return x;
3104 +}
3105 +
3106 static TString* LoadString(LoadState* S)
3107 {
3108 size_t size;
3109 @@ -119,6 +126,9 @@ static void LoadConstants(LoadState* S,
3110 case LUA_TNUMBER:
3111 setnvalue(o,LoadNumber(S));
3112 break;
3113 + case LUA_TINT: /* Integer type saved in bytecode (see lcode.c) */
3114 + setivalue(o,LoadInteger(S));
3115 + break;
3116 case LUA_TSTRING:
3117 setsvalue2n(S->L,o,LoadString(S));
3118 break;
3119 @@ -223,5 +233,22 @@ void luaU_header (char* h)
3120 *h++=(char)sizeof(size_t);
3121 *h++=(char)sizeof(Instruction);
3122 *h++=(char)sizeof(lua_Number);
3123 - *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
3124 +
3125 + /*
3126 + * Last byte of header (0/1 in unpatched Lua 5.1.3):
3127 + *
3128 + * 0: lua_Number is float or double, lua_Integer not used. (nonpatched only)
3129 + * 1: lua_Number is integer (nonpatched only)
3130 + *
3131 + * +2: LNUM_INT16: sizeof(lua_Integer)
3132 + * +4: LNUM_INT32: sizeof(lua_Integer)
3133 + * +8: LNUM_INT64: sizeof(lua_Integer)
3134 + *
3135 + * +0x80: LNUM_COMPLEX
3136 + */
3137 + *h++ = (char)(sizeof(lua_Integer)
3138 +#ifdef LNUM_COMPLEX
3139 + | 0x80
3140 +#endif
3141 + );
3142 }
3143 --- a/src/lvm.c
3144 +++ b/src/lvm.c
3145 @@ -25,22 +25,35 @@
3146 #include "ltable.h"
3147 #include "ltm.h"
3148 #include "lvm.h"
3149 -
3150 -
3151 +#include "llex.h"
3152 +#include "lnum.h"
3153
3154 /* limit for table tag-method chains (to avoid loops) */
3155 #define MAXTAGLOOP 100
3156
3157
3158 -const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
3159 - lua_Number num;
3160 +/*
3161 + * If 'obj' is a string, it is tried to be interpreted as a number.
3162 + */
3163 +const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
3164 + lua_Number d;
3165 + lua_Integer i;
3166 +
3167 if (ttisnumber(obj)) return obj;
3168 - if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
3169 - setnvalue(n, num);
3170 - return n;
3171 - }
3172 - else
3173 - return NULL;
3174 +
3175 + if (ttisstring(obj)) {
3176 + switch( luaO_str2d( svalue(obj), &d, &i ) ) {
3177 + case TK_INT:
3178 + setivalue(n,i); return n;
3179 + case TK_NUMBER:
3180 + setnvalue(n,d); return n;
3181 +#ifdef LNUM_COMPLEX
3182 + case TK_NUMBER2: /* "N.NNNi", != 0 */
3183 + setnvalue_complex_fast(n, d*I); return n;
3184 +#endif
3185 + }
3186 + }
3187 + return NULL;
3188 }
3189
3190
3191 @@ -49,8 +62,7 @@ int luaV_tostring (lua_State *L, StkId o
3192 return 0;
3193 else {
3194 char s[LUAI_MAXNUMBER2STR];
3195 - lua_Number n = nvalue(obj);
3196 - lua_number2str(s, n);
3197 + luaO_num2buf(s,obj);
3198 setsvalue2s(L, obj, luaS_new(L, s));
3199 return 1;
3200 }
3201 @@ -218,59 +230,127 @@ static int l_strcmp (const TString *ls,
3202 }
3203
3204
3205 +#ifdef LNUM_COMPLEX
3206 +void error_complex( lua_State *L, const TValue *l, const TValue *r )
3207 +{
3208 + char buf1[ LUAI_MAXNUMBER2STR ];
3209 + char buf2[ LUAI_MAXNUMBER2STR ];
3210 + luaO_num2buf( buf1, l );
3211 + luaO_num2buf( buf2, r );
3212 + luaG_runerror( L, "unable to compare: %s with %s", buf1, buf2 );
3213 + /* no return */
3214 +}
3215 +#endif
3216 +
3217 +
3218 int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
3219 int res;
3220 - if (ttype(l) != ttype(r))
3221 + int tl,tr;
3222 + lua_Integer tmp;
3223 +
3224 + if (!ttype_ext_same(l,r))
3225 return luaG_ordererror(L, l, r);
3226 - else if (ttisnumber(l))
3227 - return luai_numlt(nvalue(l), nvalue(r));
3228 - else if (ttisstring(l))
3229 - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
3230 - else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
3231 +#ifdef LNUM_COMPLEX
3232 + if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
3233 + error_complex( L, l, r );
3234 +#endif
3235 + tl= ttype(l); tr= ttype(r);
3236 + if (tl==tr) { /* clear arithmetics */
3237 + switch(tl) {
3238 + case LUA_TINT: return ivalue(l) < ivalue(r);
3239 + case LUA_TNUMBER: return luai_numlt(nvalue_fast(l), nvalue_fast(r));
3240 + case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
3241 + }
3242 + } else if (tl==LUA_TINT) { /* l:int, r:num */
3243 + /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons
3244 + * in integer realm. Only otherwise cast 'l' to FP (which might change its
3245 + * value).
3246 + */
3247 + if (tt_integer_valued(r,&tmp))
3248 + return ivalue(l) < tmp;
3249 + else
3250 + return luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) );
3251 +
3252 + } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
3253 + if (tt_integer_valued(l,&tmp))
3254 + return tmp < ivalue(r);
3255 + else
3256 + return luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) );
3257 +
3258 + } else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
3259 return res;
3260 +
3261 return luaG_ordererror(L, l, r);
3262 }
3263
3264
3265 static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
3266 int res;
3267 - if (ttype(l) != ttype(r))
3268 + int tl, tr;
3269 + lua_Integer tmp;
3270 +
3271 + if (!ttype_ext_same(l,r))
3272 return luaG_ordererror(L, l, r);
3273 - else if (ttisnumber(l))
3274 - return luai_numle(nvalue(l), nvalue(r));
3275 - else if (ttisstring(l))
3276 - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
3277 - else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
3278 +#ifdef LNUM_COMPLEX
3279 + if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
3280 + error_complex( L, l, r );
3281 +#endif
3282 + tl= ttype(l); tr= ttype(r);
3283 + if (tl==tr) { /* clear arithmetics */
3284 + switch(tl) {
3285 + case LUA_TINT: return ivalue(l) <= ivalue(r);
3286 + case LUA_TNUMBER: return luai_numle(nvalue_fast(l), nvalue_fast(r));
3287 + case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
3288 + }
3289 + }
3290 + if (tl==LUA_TINT) { /* l:int, r:num */
3291 + if (tt_integer_valued(r,&tmp))
3292 + return ivalue(l) <= tmp;
3293 + else
3294 + return luai_numle( cast_num(ivalue(l)), nvalue_fast(r) );
3295 +
3296 + } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
3297 + if (tt_integer_valued(l,&tmp))
3298 + return tmp <= ivalue(r);
3299 + else
3300 + return luai_numle( nvalue_fast(l), cast_num(ivalue(r)) );
3301 +
3302 + } else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
3303 return res;
3304 else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
3305 return !res;
3306 +
3307 return luaG_ordererror(L, l, r);
3308 }
3309
3310
3311 -int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
3312 +/* Note: 'luaV_equalval()' and 'luaO_rawequalObj()' have largely overlapping
3313 + * implementation. LUA_TNIL..LUA_TLIGHTUSERDATA cases could be handled
3314 + * simply by the 'default' case here.
3315 + */
3316 +int luaV_equalval (lua_State *L, const TValue *l, const TValue *r) {
3317 const TValue *tm;
3318 - lua_assert(ttype(t1) == ttype(t2));
3319 - switch (ttype(t1)) {
3320 + lua_assert(ttype_ext_same(l,r));
3321 + switch (ttype(l)) {
3322 case LUA_TNIL: return 1;
3323 - case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
3324 - case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
3325 - case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
3326 + case LUA_TINT:
3327 + case LUA_TNUMBER: return luaO_rawequalObj(l,r);
3328 + case LUA_TBOOLEAN: return bvalue(l) == bvalue(r); /* true must be 1 !! */
3329 + case LUA_TLIGHTUSERDATA: return pvalue(l) == pvalue(r);
3330 case LUA_TUSERDATA: {
3331 - if (uvalue(t1) == uvalue(t2)) return 1;
3332 - tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
3333 - TM_EQ);
3334 + if (uvalue(l) == uvalue(r)) return 1;
3335 + tm = get_compTM(L, uvalue(l)->metatable, uvalue(r)->metatable, TM_EQ);
3336 break; /* will try TM */
3337 }
3338 case LUA_TTABLE: {
3339 - if (hvalue(t1) == hvalue(t2)) return 1;
3340 - tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
3341 + if (hvalue(l) == hvalue(r)) return 1;
3342 + tm = get_compTM(L, hvalue(l)->metatable, hvalue(r)->metatable, TM_EQ);
3343 break; /* will try TM */
3344 }
3345 - default: return gcvalue(t1) == gcvalue(t2);
3346 + default: return gcvalue(l) == gcvalue(r);
3347 }
3348 if (tm == NULL) return 0; /* no TM? */
3349 - callTMres(L, L->top, tm, t1, t2); /* call TM */
3350 + callTMres(L, L->top, tm, l, r); /* call TM */
3351 return !l_isfalse(L->top);
3352 }
3353
3354 @@ -310,30 +390,6 @@ void luaV_concat (lua_State *L, int tota
3355 }
3356
3357
3358 -static void Arith (lua_State *L, StkId ra, const TValue *rb,
3359 - const TValue *rc, TMS op) {
3360 - TValue tempb, tempc;
3361 - const TValue *b, *c;
3362 - if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
3363 - (c = luaV_tonumber(rc, &tempc)) != NULL) {
3364 - lua_Number nb = nvalue(b), nc = nvalue(c);
3365 - switch (op) {
3366 - case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
3367 - case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
3368 - case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
3369 - case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
3370 - case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
3371 - case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
3372 - case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
3373 - default: lua_assert(0); break;
3374 - }
3375 - }
3376 - else if (!call_binTM(L, rb, rc, ra, op))
3377 - luaG_aritherror(L, rb, rc);
3378 -}
3379 -
3380 -
3381 -
3382 /*
3383 ** some macros for common tasks in `luaV_execute'
3384 */
3385 @@ -357,17 +413,154 @@ static void Arith (lua_State *L, StkId r
3386 #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
3387
3388
3389 -#define arith_op(op,tm) { \
3390 - TValue *rb = RKB(i); \
3391 - TValue *rc = RKC(i); \
3392 - if (ttisnumber(rb) && ttisnumber(rc)) { \
3393 - lua_Number nb = nvalue(rb), nc = nvalue(rc); \
3394 - setnvalue(ra, op(nb, nc)); \
3395 - } \
3396 - else \
3397 - Protect(Arith(L, ra, rb, rc, tm)); \
3398 +/* Note: if called for unary operations, 'rc'=='rb'.
3399 + */
3400 +static void Arith (lua_State *L, StkId ra, const TValue *rb,
3401 + const TValue *rc, TMS op) {
3402 + TValue tempb, tempc;
3403 + const TValue *b, *c;
3404 + lua_Number nb,nc;
3405 +
3406 + if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
3407 + (c = luaV_tonumber(rc, &tempc)) != NULL) {
3408 +
3409 + /* Keep integer arithmetics in the integer realm, if possible.
3410 + */
3411 + if (ttisint(b) && ttisint(c)) {
3412 + lua_Integer ib = ivalue(b), ic = ivalue(c);
3413 + lua_Integer *ri = &ra->value.i;
3414 + ra->tt= LUA_TINT; /* part of 'setivalue(ra)' */
3415 + switch (op) {
3416 + case TM_ADD: if (try_addint( ri, ib, ic)) return; break;
3417 + case TM_SUB: if (try_subint( ri, ib, ic)) return; break;
3418 + case TM_MUL: if (try_mulint( ri, ib, ic)) return; break;
3419 + case TM_DIV: if (try_divint( ri, ib, ic)) return; break;
3420 + case TM_MOD: if (try_modint( ri, ib, ic)) return; break;
3421 + case TM_POW: if (try_powint( ri, ib, ic)) return; break;
3422 + case TM_UNM: if (try_unmint( ri, ib)) return; break;
3423 + default: lua_assert(0);
3424 + }
3425 + }
3426 + /* Fallback to floating point, when leaving range. */
3427 +
3428 +#ifdef LNUM_COMPLEX
3429 + if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) {
3430 + lua_Complex r;
3431 + if (op==TM_UNM) {
3432 + r= -nvalue_complex_fast(b); /* never an integer (or scalar) */
3433 + setnvalue_complex_fast( ra, r );
3434 + } else {
3435 + lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c);
3436 + switch (op) {
3437 + case TM_ADD: r= bb + cc; break;
3438 + case TM_SUB: r= bb - cc; break;
3439 + case TM_MUL: r= bb * cc; break;
3440 + case TM_DIV: r= bb / cc; break;
3441 + case TM_MOD:
3442 + luaG_runerror(L, "attempt to use %% on complex numbers"); /* no return */
3443 + case TM_POW: r= luai_vectpow( bb, cc ); break;
3444 + default: lua_assert(0); r=0;
3445 + }
3446 + setnvalue_complex( ra, r );
3447 }
3448 + return;
3449 + }
3450 +#endif
3451 + nb = nvalue(b); nc = nvalue(c);
3452 + switch (op) {
3453 + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return;
3454 + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return;
3455 + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return;
3456 + case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return;
3457 + case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return;
3458 + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return;
3459 + case TM_UNM: setnvalue(ra, luai_numunm(nb)); return;
3460 + default: lua_assert(0);
3461 + }
3462 + }
3463 +
3464 + /* Either operand not a number */
3465 + if (!call_binTM(L, rb, rc, ra, op))
3466 + luaG_aritherror(L, rb, rc);
3467 +}
3468
3469 +/* Helper macro to sort arithmetic operations into four categories:
3470 + * TK_INT: integer - integer operands
3471 + * TK_NUMBER: number - number (non complex, either may be integer)
3472 + * TK_NUMBER2: complex numbers (at least the other)
3473 + * 0: non-numeric (at least the other)
3474 +*/
3475 +#ifdef LNUM_COMPLEX
3476 +static inline int arith_mode( const TValue *rb, const TValue *rc ) {
3477 + if (ttisint(rb) && ttisint(rc)) return TK_INT;
3478 + if (ttiscomplex(rb) || ttiscomplex(rc)) return TK_NUMBER2;
3479 + if (ttisnumber(rb) && ttisnumber(rc)) return TK_NUMBER;
3480 + return 0;
3481 +}
3482 +#else
3483 +# define arith_mode(rb,rc) \
3484 + ( (ttisint(rb) && ttisint(rc)) ? TK_INT : \
3485 + (ttisnumber(rb) && ttisnumber(rc)) ? TK_NUMBER : 0 )
3486 +#endif
3487 +
3488 +/* arith_op macro for two operators:
3489 + * automatically chooses, which function (number, integer, complex) to use
3490 + */
3491 +#define ARITH_OP2_START( op_num, op_int ) \
3492 + int failed= 0; \
3493 + switch( arith_mode(rb,rc) ) { \
3494 + case TK_INT: \
3495 + if (op_int ( &(ra)->value.i, ivalue(rb), ivalue(rc) )) \
3496 + { ra->tt= LUA_TINT; break; } /* else flow through */ \
3497 + case TK_NUMBER: \
3498 + setnvalue(ra, op_num ( nvalue(rb), nvalue(rc) )); break;
3499 +
3500 +#define ARITH_OP2_END \
3501 + default: \
3502 + failed= 1; break; \
3503 + } if (!failed) continue;
3504 +
3505 +#define arith_op_continue_scalar( op_num, op_int ) \
3506 + ARITH_OP2_START( op_num, op_int ) \
3507 + ARITH_OP2_END
3508 +
3509 +#ifdef LNUM_COMPLEX
3510 +# define arith_op_continue( op_num, op_int, op_complex ) \
3511 + ARITH_OP2_START( op_num, op_int ) \
3512 + case TK_NUMBER2: \
3513 + setnvalue_complex( ra, op_complex ( nvalue_complex(rb), nvalue_complex(rc) ) ); break; \
3514 + ARITH_OP2_END
3515 +#else
3516 +# define arith_op_continue(op_num,op_int,_) arith_op_continue_scalar(op_num,op_int)
3517 +#endif
3518 +
3519 +/* arith_op macro for one operator:
3520 + */
3521 +#define ARITH_OP1_START( op_num, op_int ) \
3522 + int failed= 0; \
3523 + switch( arith_mode(rb,rb) ) { \
3524 + case TK_INT: \
3525 + if (op_int ( &(ra)->value.i, ivalue(rb) )) \
3526 + { ra->tt= LUA_TINT; break; } /* else flow through */ \
3527 + case TK_NUMBER: \
3528 + setnvalue(ra, op_num (nvalue(rb))); break; \
3529 +
3530 +#define ARITH_OP1_END \
3531 + default: \
3532 + failed= 1; break; \
3533 + } if (!failed) continue;
3534 +
3535 +#ifdef LNUM_COMPLEX
3536 +# define arith_op1_continue( op_num, op_int, op_complex ) \
3537 + ARITH_OP1_START( op_num, op_int ) \
3538 + case TK_NUMBER2: \
3539 + setnvalue_complex( ra, op_complex ( nvalue_complex_fast(rb) )); break; \
3540 + ARITH_OP1_END
3541 +#else
3542 +# define arith_op1_continue( op_num, op_int, _ ) \
3543 + ARITH_OP1_START( op_num, op_int ) \
3544 + ARITH_OP1_END
3545 +#endif
3546
3547
3548 void luaV_execute (lua_State *L, int nexeccalls) {
3549 @@ -468,38 +661,45 @@ void luaV_execute (lua_State *L, int nex
3550 continue;
3551 }
3552 case OP_ADD: {
3553 - arith_op(luai_numadd, TM_ADD);
3554 + TValue *rb = RKB(i), *rc= RKC(i);
3555 + arith_op_continue( luai_numadd, try_addint, luai_vectadd );
3556 + Protect(Arith(L, ra, rb, rc, TM_ADD)); \
3557 continue;
3558 }
3559 case OP_SUB: {
3560 - arith_op(luai_numsub, TM_SUB);
3561 + TValue *rb = RKB(i), *rc= RKC(i);
3562 + arith_op_continue( luai_numsub, try_subint, luai_vectsub );
3563 + Protect(Arith(L, ra, rb, rc, TM_SUB));
3564 continue;
3565 }
3566 case OP_MUL: {
3567 - arith_op(luai_nummul, TM_MUL);
3568 + TValue *rb = RKB(i), *rc= RKC(i);
3569 + arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
3570 + Protect(Arith(L, ra, rb, rc, TM_MUL));
3571 continue;
3572 }
3573 case OP_DIV: {
3574 - arith_op(luai_numdiv, TM_DIV);
3575 + TValue *rb = RKB(i), *rc= RKC(i);
3576 + arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
3577 + Protect(Arith(L, ra, rb, rc, TM_DIV));
3578 continue;
3579 }
3580 case OP_MOD: {
3581 - arith_op(luai_nummod, TM_MOD);
3582 + TValue *rb = RKB(i), *rc= RKC(i);
3583 + arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
3584 + Protect(Arith(L, ra, rb, rc, TM_MOD));
3585 continue;
3586 }
3587 case OP_POW: {
3588 - arith_op(luai_numpow, TM_POW);
3589 + TValue *rb = RKB(i), *rc= RKC(i);
3590 + arith_op_continue(luai_numpow, try_powint, luai_vectpow);
3591 + Protect(Arith(L, ra, rb, rc, TM_POW));
3592 continue;
3593 }
3594 case OP_UNM: {
3595 TValue *rb = RB(i);
3596 - if (ttisnumber(rb)) {
3597 - lua_Number nb = nvalue(rb);
3598 - setnvalue(ra, luai_numunm(nb));
3599 - }
3600 - else {
3601 - Protect(Arith(L, ra, rb, rb, TM_UNM));
3602 - }
3603 + arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
3604 + Protect(Arith(L, ra, rb, rb, TM_UNM));
3605 continue;
3606 }
3607 case OP_NOT: {
3608 @@ -511,11 +711,11 @@ void luaV_execute (lua_State *L, int nex
3609 const TValue *rb = RB(i);
3610 switch (ttype(rb)) {
3611 case LUA_TTABLE: {
3612 - setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
3613 + setivalue(ra, luaH_getn(hvalue(rb)));
3614 break;
3615 }
3616 case LUA_TSTRING: {
3617 - setnvalue(ra, cast_num(tsvalue(rb)->len));
3618 + setivalue(ra, tsvalue(rb)->len);
3619 break;
3620 }
3621 default: { /* try metamethod */
3622 @@ -648,14 +848,30 @@ void luaV_execute (lua_State *L, int nex
3623 }
3624 }
3625 case OP_FORLOOP: {
3626 - lua_Number step = nvalue(ra+2);
3627 - lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
3628 - lua_Number limit = nvalue(ra+1);
3629 - if (luai_numlt(0, step) ? luai_numle(idx, limit)
3630 - : luai_numle(limit, idx)) {
3631 - dojump(L, pc, GETARG_sBx(i)); /* jump back */
3632 - setnvalue(ra, idx); /* update internal index... */
3633 - setnvalue(ra+3, idx); /* ...and external index */
3634 + /* If start,step and limit are all integers, we don't need to check
3635 + * against overflow in the looping.
3636 + */
3637 + if (ttisint(ra) && ttisint(ra+1) && ttisint(ra+2)) {
3638 + lua_Integer step = ivalue(ra+2);
3639 + lua_Integer idx = ivalue(ra) + step; /* increment index */
3640 + lua_Integer limit = ivalue(ra+1);
3641 + if (step > 0 ? (idx <= limit) : (limit <= idx)) {
3642 + dojump(L, pc, GETARG_sBx(i)); /* jump back */
3643 + setivalue(ra, idx); /* update internal index... */
3644 + setivalue(ra+3, idx); /* ...and external index */
3645 + }
3646 + } else {
3647 + /* non-integer looping (don't use 'nvalue_fast', some may be integer!)
3648 + */
3649 + lua_Number step = nvalue(ra+2);
3650 + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
3651 + lua_Number limit = nvalue(ra+1);
3652 + if (luai_numlt(0, step) ? luai_numle(idx, limit)
3653 + : luai_numle(limit, idx)) {
3654 + dojump(L, pc, GETARG_sBx(i)); /* jump back */
3655 + setnvalue(ra, idx); /* update internal index... */
3656 + setnvalue(ra+3, idx); /* ...and external index */
3657 + }
3658 }
3659 continue;
3660 }
3661 @@ -664,13 +880,21 @@ void luaV_execute (lua_State *L, int nex
3662 const TValue *plimit = ra+1;
3663 const TValue *pstep = ra+2;
3664 L->savedpc = pc; /* next steps may throw errors */
3665 + /* Using same location for tonumber's both arguments, effectively does
3666 + * in-place modification (string->number). */
3667 if (!tonumber(init, ra))
3668 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
3669 else if (!tonumber(plimit, ra+1))
3670 luaG_runerror(L, LUA_QL("for") " limit must be a number");
3671 else if (!tonumber(pstep, ra+2))
3672 luaG_runerror(L, LUA_QL("for") " step must be a number");
3673 - setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
3674 + /* Step back one value (keep within integers if we can)
3675 + */
3676 + if (!( ttisint(ra) && ttisint(pstep) &&
3677 + try_subint( &ra->value.i, ivalue(ra), ivalue(pstep) ) )) {
3678 + /* don't use 'nvalue_fast()', values may be integer */
3679 + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
3680 + }
3681 dojump(L, pc, GETARG_sBx(i));
3682 continue;
3683 }
3684 @@ -707,7 +931,7 @@ void luaV_execute (lua_State *L, int nex
3685 luaH_resizearray(L, h, last); /* pre-alloc it at once */
3686 for (; n > 0; n--) {
3687 TValue *val = ra+n;
3688 - setobj2t(L, luaH_setnum(L, h, last--), val);
3689 + setobj2t(L, luaH_setint(L, h, last--), val);
3690 luaC_barriert(L, h, val);
3691 }
3692 continue;
3693 --- a/src/lvm.h
3694 +++ b/src/lvm.h
3695 @@ -15,11 +15,9 @@
3696
3697 #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
3698
3699 -#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
3700 - (((o) = luaV_tonumber(o,n)) != NULL))
3701 +#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
3702
3703 -#define equalobj(L,o1,o2) \
3704 - (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
3705 +#define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
3706
3707
3708 LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
3709 --- a/src/print.c
3710 +++ b/src/print.c
3711 @@ -14,6 +14,7 @@
3712 #include "lobject.h"
3713 #include "lopcodes.h"
3714 #include "lundump.h"
3715 +#include "lnum.h"
3716
3717 #define PrintFunction luaU_print
3718
3719 @@ -59,8 +60,16 @@ static void PrintConstant(const Proto* f
3720 case LUA_TBOOLEAN:
3721 printf(bvalue(o) ? "true" : "false");
3722 break;
3723 + case LUA_TINT:
3724 + printf(LUA_INTEGER_FMT,ivalue(o));
3725 + break;
3726 case LUA_TNUMBER:
3727 - printf(LUA_NUMBER_FMT,nvalue(o));
3728 +#ifdef LNUM_COMPLEX
3729 + // TBD: Do we get complex values here?
3730 + { lua_Number b= nvalue_img_fast(o);
3731 + printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); }
3732 +#endif
3733 + printf(LUA_NUMBER_FMT,nvalue_fast(o));
3734 break;
3735 case LUA_TSTRING:
3736 PrintString(rawtsvalue(o));
This page took 0.265863 seconds and 5 git commands to generate.