aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-08 12:50:23 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-08 12:50:23 -0200
commit26679ea35bf261f2b5edc2fb2f5cc4df483fd50d (patch)
tree94c99ed74251cdf3e10a7e52560c3a7a78053ad1 /lvm.c
parentc3e5946fb2b7b5781d9bca9d303967abe6263482 (diff)
downloadlua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.tar.gz
lua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.tar.bz2
lua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.zip
new function 'luaV_flttointeger' to convert floats to integers (without
string coercions) + string operands to bitwise operations handled by string metamethods
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/lvm.c b/lvm.c
index 009dfc57..24208cdd 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.306 2017/11/07 13:25:26 roberto Exp roberto $ 2** $Id: lvm.c,v 2.307 2017/11/07 17:20:42 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -74,7 +74,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
74 *n = cast_num(ivalue(obj)); 74 *n = cast_num(ivalue(obj));
75 return 1; 75 return 1;
76 } 76 }
77 else if (cvt2num(obj) && /* string convertible to number? */ 77 else if (cvt2num(obj) && /* string coercible to number? */
78 luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { 78 luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
79 *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ 79 *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
80 return 1; 80 return 1;
@@ -85,15 +85,15 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
85 85
86 86
87/* 87/*
88** try to convert a value to an integer, rounding according to 'mode': 88** try to convert a float to an integer, rounding according to 'mode':
89** mode == 0: accepts only integral values 89** mode == 0: accepts only integral values
90** mode == 1: takes the floor of the number 90** mode == 1: takes the floor of the number
91** mode == 2: takes the ceil of the number 91** mode == 2: takes the ceil of the number
92*/ 92*/
93int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { 93int luaV_flttointeger (const TValue *obj, lua_Integer *p, int mode) {
94 TValue v; 94 if (!ttisfloat(obj))
95 again: 95 return 0;
96 if (ttisfloat(obj)) { 96 else {
97 lua_Number n = fltvalue(obj); 97 lua_Number n = fltvalue(obj);
98 lua_Number f = l_floor(n); 98 lua_Number f = l_floor(n);
99 if (n != f) { /* not an integral value? */ 99 if (n != f) { /* not an integral value? */
@@ -103,16 +103,23 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
103 } 103 }
104 return lua_numbertointeger(f, p); 104 return lua_numbertointeger(f, p);
105 } 105 }
106 else if (ttisinteger(obj)) { 106}
107
108
109/*
110** try to convert a value to an integer. ("Fast track" is handled
111** by macro 'tointeger'.)
112*/
113int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
114 TValue v;
115 if (cvt2num(obj) && luaO_str2num(svalue(obj), &v) == vslen(obj) + 1)
116 obj = &v; /* change string to its corresponding number */
117 if (ttisinteger(obj)) {
107 *p = ivalue(obj); 118 *p = ivalue(obj);
108 return 1; 119 return 1;
109 } 120 }
110 else if (cvt2num(obj) && 121 else
111 luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) { 122 return luaV_flttointeger(obj, p, mode);
112 obj = &v;
113 goto again; /* convert result from 'luaO_str2num' to an integer */
114 }
115 return 0; /* conversion failed */
116} 123}
117 124
118 125
@@ -120,9 +127,9 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
120** Try to convert a 'for' limit to an integer, preserving the semantics 127** Try to convert a 'for' limit to an integer, preserving the semantics
121** of the loop. (The following explanation assumes a non-negative step; 128** of the loop. (The following explanation assumes a non-negative step;
122** it is valid for negative steps mutatis mutandis.) 129** it is valid for negative steps mutatis mutandis.)
123** If the limit can be converted to an integer, rounding down, that is 130** If the limit is an integer or can be converted to an integer,
124** it. 131** rounding down, that is it.
125** Otherwise, check whether the limit can be converted to a number. If 132** Otherwise, check whether the limit can be converted to a float. If
126** the number is too large, it is OK to set the limit as LUA_MAXINTEGER, 133** the number is too large, it is OK to set the limit as LUA_MAXINTEGER,
127** which means no limit. If the number is too negative, the loop 134** which means no limit. If the number is too negative, the loop
128** should not run, because any initial integer value is larger than the 135** should not run, because any initial integer value is larger than the
@@ -133,7 +140,10 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
133static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, 140static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
134 int *stopnow) { 141 int *stopnow) {
135 *stopnow = 0; /* usually, let loops run */ 142 *stopnow = 0; /* usually, let loops run */
136 if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */ 143 if (ttisinteger(obj))
144 *p = ivalue(obj);
145 else if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) {
146 /* not coercible to in integer */
137 lua_Number n; /* try to convert to float */ 147 lua_Number n; /* try to convert to float */
138 if (!tonumber(obj, &n)) /* cannot convert to float? */ 148 if (!tonumber(obj, &n)) /* cannot convert to float? */
139 return 0; /* not a number */ 149 return 0; /* not a number */
@@ -411,7 +421,7 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
411 return 0; /* only numbers can be equal with different variants */ 421 return 0; /* only numbers can be equal with different variants */
412 else { /* two numbers with different variants */ 422 else { /* two numbers with different variants */
413 lua_Integer i1, i2; /* compare them as integers */ 423 lua_Integer i1, i2; /* compare them as integers */
414 return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2); 424 return (tointegerns(t1, &i1) && tointegerns(t2, &i2) && i1 == i2);
415 } 425 }
416 } 426 }
417 /* values have same type and same variant */ 427 /* values have same type and same variant */
@@ -1144,7 +1154,7 @@ void luaV_execute (lua_State *L) {
1144 TValue *rb = vRB(i); 1154 TValue *rb = vRB(i);
1145 TValue *rc = vRC(i); 1155 TValue *rc = vRC(i);
1146 lua_Integer ib; lua_Integer ic; 1156 lua_Integer ib; lua_Integer ic;
1147 if (tointeger(rb, &ib) && tointeger(rc, &ic)) { 1157 if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) {
1148 setivalue(s2v(ra), intop(&, ib, ic)); 1158 setivalue(s2v(ra), intop(&, ib, ic));
1149 } 1159 }
1150 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } 1160 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); }
@@ -1154,7 +1164,7 @@ void luaV_execute (lua_State *L) {
1154 TValue *rb = vRB(i); 1164 TValue *rb = vRB(i);
1155 TValue *rc = vRC(i); 1165 TValue *rc = vRC(i);
1156 lua_Integer ib; lua_Integer ic; 1166 lua_Integer ib; lua_Integer ic;
1157 if (tointeger(rb, &ib) && tointeger(rc, &ic)) { 1167 if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) {
1158 setivalue(s2v(ra), intop(|, ib, ic)); 1168 setivalue(s2v(ra), intop(|, ib, ic));
1159 } 1169 }
1160 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } 1170 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); }
@@ -1164,7 +1174,7 @@ void luaV_execute (lua_State *L) {
1164 TValue *rb = vRB(i); 1174 TValue *rb = vRB(i);
1165 TValue *rc = vRC(i); 1175 TValue *rc = vRC(i);
1166 lua_Integer ib; lua_Integer ic; 1176 lua_Integer ib; lua_Integer ic;
1167 if (tointeger(rb, &ib) && tointeger(rc, &ic)) { 1177 if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) {
1168 setivalue(s2v(ra), intop(^, ib, ic)); 1178 setivalue(s2v(ra), intop(^, ib, ic));
1169 } 1179 }
1170 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } 1180 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); }
@@ -1174,7 +1184,7 @@ void luaV_execute (lua_State *L) {
1174 TValue *rb = vRB(i); 1184 TValue *rb = vRB(i);
1175 TValue *rc = vRC(i); 1185 TValue *rc = vRC(i);
1176 lua_Integer ib; lua_Integer ic; 1186 lua_Integer ib; lua_Integer ic;
1177 if (tointeger(rb, &ib) && tointeger(rc, &ic)) { 1187 if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) {
1178 setivalue(s2v(ra), luaV_shiftl(ib, ic)); 1188 setivalue(s2v(ra), luaV_shiftl(ib, ic));
1179 } 1189 }
1180 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } 1190 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); }
@@ -1184,7 +1194,7 @@ void luaV_execute (lua_State *L) {
1184 TValue *rb = vRB(i); 1194 TValue *rb = vRB(i);
1185 TValue *rc = vRC(i); 1195 TValue *rc = vRC(i);
1186 lua_Integer ib; lua_Integer ic; 1196 lua_Integer ib; lua_Integer ic;
1187 if (tointeger(rb, &ib) && tointeger(rc, &ic)) { 1197 if (tointegerns(rb, &ib) && tointegerns(rc, &ic)) {
1188 setivalue(s2v(ra), luaV_shiftl(ib, -ic)); 1198 setivalue(s2v(ra), luaV_shiftl(ib, -ic));
1189 } 1199 }
1190 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } 1200 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); }
@@ -1248,7 +1258,7 @@ void luaV_execute (lua_State *L) {
1248 vmcase(OP_BNOT) { 1258 vmcase(OP_BNOT) {
1249 TValue *rb = vRB(i); 1259 TValue *rb = vRB(i);
1250 lua_Integer ib; 1260 lua_Integer ib;
1251 if (tointeger(rb, &ib)) { 1261 if (tointegerns(rb, &ib)) {
1252 setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); 1262 setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib));
1253 } 1263 }
1254 else { 1264 else {