** Convert expression 'e' into 'func(e,'. */
| 1165 | ** Convert expression 'e' into 'func(e,'. |
| 1166 | */ |
| 1167 | void luaK_prepcallfirstarg (FuncState *fs, expdesc *e, expdesc *func) { |
| 1168 | luaK_dischargevars(fs, e); |
| 1169 | luaK_dischargevars(fs, func); |
| 1170 | |
| 1171 | freeexps(fs, e, func); |
| 1172 | const int basereg = fs->freereg; /* base register for call */ |
| 1173 | luaK_reserveregs(fs, 2); /* function and first arg */ |
| 1174 | |
| 1175 | int freg = func->k == VNONRELOC ? func->u.reg : -1; |
| 1176 | int ereg = e->k == VNONRELOC ? e->u.reg : -1; |
| 1177 | |
| 1178 | bool fcanreloc = true; |
| 1179 | if (ereg == basereg) { /* argument is in the register where the function should be? */ |
| 1180 | if (freg == basereg + 1) { /* function is in the register where the argument should be? */ |
| 1181 | /* oh dear. we have to swap them around. move function into a temporary register. */ |
| 1182 | luaK_checkstack(fs, 1); |
| 1183 | int tmpreg = basereg + 2; |
| 1184 | luaK_codeABC(fs, OP_MOVE, tmpreg, freg, 0); |
| 1185 | freg = tmpreg; |
| 1186 | } |
| 1187 | luaK_codeABC(fs, OP_MOVE, basereg + 1, ereg, 0); /* move it where it should be */ |
| 1188 | ereg = basereg + 1; /* and don't do it again */ |
| 1189 | fcanreloc = false; /* if function is VRELOC, that would be before this MOVE instruction, so we have to use a different register for it. */ |
| 1190 | } |
| 1191 | if (freg == basereg + 1) { /* function is in the register where the argument should be? */ |
| 1192 | luaK_codeABC(fs, OP_MOVE, basereg, freg, 0); /* move it where it should be */ |
| 1193 | freg = basereg; /* and don't do it again */ |
| 1194 | } |
| 1195 | |
| 1196 | /* if function is yet to be loaded into a register, load it into the correct one. */ |
| 1197 | if (freg == -1) { |
| 1198 | lua_assert(func->k == VRELOC); |
| 1199 | if (!fcanreloc) { |
| 1200 | luaK_checkstack(fs, 1); |
| 1201 | exp2reg(fs, func, basereg + 2); |
| 1202 | freg = basereg; |
| 1203 | luaK_codeABC(fs, OP_MOVE, freg, basereg + 2, 0); |
| 1204 | } |
| 1205 | else { |
| 1206 | freg = basereg; |
| 1207 | exp2reg(fs, func, freg); |
| 1208 | } |
| 1209 | } |
| 1210 | |
| 1211 | /* if argument is yet to be loaded into a register, load it into the correct one. */ |
| 1212 | if (ereg == -1) { |
| 1213 | lua_assert(e->k == VNIL || e->k == VFALSE || e->k == VTRUE || e->k == VKSTR || e->k == VK || e->k == VKFLT || e->k == VKINT || e->k == VRELOC); |
| 1214 | ereg = basereg + 1; |
| 1215 | exp2reg(fs, e, ereg); |
| 1216 | } |
| 1217 | |
| 1218 | /* ensure function is in correct register */ |
| 1219 | if (basereg != freg) { |
| 1220 | luaK_codeABC(fs, OP_MOVE, basereg, freg, 0); |
| 1221 | } |
| 1222 | |
| 1223 | /* ensure argument is in correct register */ |
| 1224 | if (basereg + 1 != ereg) { |
no test coverage detected