diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-05-02 09:37:24 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-05-02 09:37:24 -0300 |
| commit | 67532d5a10f9bdc8ed58c6babbce49788ae3be4d (patch) | |
| tree | 21d3d9aa16c7406245d670977bde294a38ac92d1 /lobject.c | |
| parent | 6920a7f2e3f8cbdb9c9d43fca720b9dd459be733 (diff) | |
| download | lua-67532d5a10f9bdc8ed58c6babbce49788ae3be4d.tar.gz lua-67532d5a10f9bdc8ed58c6babbce49788ae3be4d.tar.bz2 lua-67532d5a10f9bdc8ed58c6babbce49788ae3be4d.zip | |
constant folding and API arithmetic with integers
Diffstat (limited to 'lobject.c')
| -rw-r--r-- | lobject.c | 47 |
1 files changed, 45 insertions, 2 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.60 2013/04/25 13:53:13 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.61 2013/04/29 16:57:28 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -70,7 +70,21 @@ int luaO_ceillog2 (unsigned int x) { | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | 72 | ||
| 73 | lua_Number luaO_numarith (int op, lua_Number v1, lua_Number v2) { | 73 | static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, |
| 74 | lua_Integer v2) { | ||
| 75 | switch (op) { | ||
| 76 | case LUA_OPADD: return intop(+, v1, v2); | ||
| 77 | case LUA_OPSUB:return intop(-, v1, v2); | ||
| 78 | case LUA_OPMUL:return intop(*, v1, v2); | ||
| 79 | case LUA_OPMOD: return luaV_mod(L, v1, v2); | ||
| 80 | case LUA_OPPOW: return luaV_pow(v1, v2); | ||
| 81 | case LUA_OPUNM: return -v1; | ||
| 82 | default: lua_assert(0); return 0; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | static lua_Number numarith (int op, lua_Number v1, lua_Number v2) { | ||
| 74 | switch (op) { | 88 | switch (op) { |
| 75 | case LUA_OPADD: return luai_numadd(NULL, v1, v2); | 89 | case LUA_OPADD: return luai_numadd(NULL, v1, v2); |
| 76 | case LUA_OPSUB: return luai_numsub(NULL, v1, v2); | 90 | case LUA_OPSUB: return luai_numsub(NULL, v1, v2); |
| @@ -84,6 +98,35 @@ lua_Number luaO_numarith (int op, lua_Number v1, lua_Number v2) { | |||
| 84 | } | 98 | } |
| 85 | 99 | ||
| 86 | 100 | ||
| 101 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | ||
| 102 | TValue *res) { | ||
| 103 | if (op == LUA_OPIDIV) { /* operates only on integers */ | ||
| 104 | lua_Integer i1; lua_Integer i2; | ||
| 105 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | ||
| 106 | setivalue(res, luaV_div(L, i1, i2)); | ||
| 107 | return; | ||
| 108 | } | ||
| 109 | /* else go to the end */ | ||
| 110 | } | ||
| 111 | else { /* other operations */ | ||
| 112 | lua_Number n1; lua_Number n2; | ||
| 113 | if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV && | ||
| 114 | (op != LUA_OPPOW || ivalue(p2) >= 0)) { | ||
| 115 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); | ||
| 116 | return; | ||
| 117 | } | ||
| 118 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | ||
| 119 | setnvalue(res, numarith(op, n1, n2)); | ||
| 120 | return; | ||
| 121 | } | ||
| 122 | /* else go to the end */ | ||
| 123 | } | ||
| 124 | /* could not perform raw operation; try metmethod */ | ||
| 125 | lua_assert(L != NULL); /* cannot fail when folding (compile time) */ | ||
| 126 | luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD)); | ||
| 127 | } | ||
| 128 | |||
| 129 | |||
| 87 | int luaO_hexavalue (int c) { | 130 | int luaO_hexavalue (int c) { |
| 88 | if (lisdigit(c)) return c - '0'; | 131 | if (lisdigit(c)) return c - '0'; |
| 89 | else return ltolower(c) - 'a' + 10; | 132 | else return ltolower(c) - 'a' + 10; |
