~ilya-yanok/ubuntu/precise/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to script/lua/lcode.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Millan
  • Date: 2009-07-25 19:00:53 UTC
  • mfrom: (1.6.3 upstream)
  • mto: (17.4.13 sid)
  • mto: This revision was merged to the branch mainline in revision 53.
  • Revision ID: james.westby@ubuntu.com-20090725190053-uv3lm6ya3zxs77ep
ImportĀ upstreamĀ versionĀ 1.96+20090725

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
 
3
** Code generator for Lua
 
4
** See Copyright Notice in lua.h
 
5
*/
 
6
 
 
7
#if 0
 
8
#include <stdlib.h>
 
9
#endif
 
10
 
 
11
#define lcode_c
 
12
#define LUA_CORE
 
13
 
 
14
#include "lua.h"
 
15
 
 
16
#include "lcode.h"
 
17
#include "ldebug.h"
 
18
#include "ldo.h"
 
19
#include "lgc.h"
 
20
#include "llex.h"
 
21
#include "lmem.h"
 
22
#include "lobject.h"
 
23
#include "lopcodes.h"
 
24
#include "lparser.h"
 
25
#include "ltable.h"
 
26
 
 
27
 
 
28
#define hasjumps(e)     ((e)->t != (e)->f)
 
29
 
 
30
 
 
31
static int isnumeral(expdesc *e) {
 
32
  return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
 
33
}
 
34
 
 
35
 
 
36
void luaK_nil (FuncState *fs, int from, int n) {
 
37
  Instruction *previous;
 
38
  if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
 
39
    if (fs->pc == 0) {  /* function start? */
 
40
      if (from >= fs->nactvar)
 
41
        return;  /* positions are already clean */
 
42
    }
 
43
    else {
 
44
      previous = &fs->f->code[fs->pc-1];
 
45
      if (GET_OPCODE(*previous) == OP_LOADNIL) {
 
46
        int pfrom = GETARG_A(*previous);
 
47
        int pto = GETARG_B(*previous);
 
48
        if (pfrom <= from && from <= pto+1) {  /* can connect both? */
 
49
          if (from+n-1 > pto)
 
50
            SETARG_B(*previous, from+n-1);
 
51
          return;
 
52
        }
 
53
      }
 
54
    }
 
55
  }
 
56
  luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0);  /* else no optimization */
 
57
}
 
58
 
 
59
 
 
60
int luaK_jump (FuncState *fs) {
 
61
  int jpc = fs->jpc;  /* save list of jumps to here */
 
62
  int j;
 
63
  fs->jpc = NO_JUMP;
 
64
  j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
 
65
  luaK_concat(fs, &j, jpc);  /* keep them on hold */
 
66
  return j;
 
67
}
 
68
 
 
69
 
 
70
void luaK_ret (FuncState *fs, int first, int nret) {
 
71
  luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
 
72
}
 
73
 
 
74
 
 
75
static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
 
76
  luaK_codeABC(fs, op, A, B, C);
 
77
  return luaK_jump(fs);
 
78
}
 
79
 
 
80
 
 
81
static void fixjump (FuncState *fs, int pc, int dest) {
 
82
  Instruction *jmp = &fs->f->code[pc];
 
83
  int offset = dest-(pc+1);
 
84
  lua_assert(dest != NO_JUMP);
 
85
  if (abs(offset) > MAXARG_sBx)
 
86
    luaX_syntaxerror(fs->ls, "control structure too long");
 
87
  SETARG_sBx(*jmp, offset);
 
88
}
 
89
 
 
90
 
 
91
/*
 
92
** returns current `pc' and marks it as a jump target (to avoid wrong
 
93
** optimizations with consecutive instructions not in the same basic block).
 
94
*/
 
95
int luaK_getlabel (FuncState *fs) {
 
96
  fs->lasttarget = fs->pc;
 
97
  return fs->pc;
 
98
}
 
99
 
 
100
 
 
101
static int getjump (FuncState *fs, int pc) {
 
102
  int offset = GETARG_sBx(fs->f->code[pc]);
 
103
  if (offset == NO_JUMP)  /* point to itself represents end of list */
 
104
    return NO_JUMP;  /* end of list */
 
105
  else
 
106
    return (pc+1)+offset;  /* turn offset into absolute position */
 
107
}
 
108
 
 
109
 
 
110
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
 
111
  Instruction *pi = &fs->f->code[pc];
 
112
  if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
 
113
    return pi-1;
 
114
  else
 
115
    return pi;
 
116
}
 
117
 
 
118
 
 
119
/*
 
120
** check whether list has any jump that do not produce a value
 
121
** (or produce an inverted value)
 
122
*/
 
123
static int need_value (FuncState *fs, int list) {
 
124
  for (; list != NO_JUMP; list = getjump(fs, list)) {
 
125
    Instruction i = *getjumpcontrol(fs, list);
 
126
    if (GET_OPCODE(i) != OP_TESTSET) return 1;
 
127
  }
 
128
  return 0;  /* not found */
 
129
}
 
130
 
 
131
 
 
132
static int patchtestreg (FuncState *fs, int node, int reg) {
 
133
  Instruction *i = getjumpcontrol(fs, node);
 
134
  if (GET_OPCODE(*i) != OP_TESTSET)
 
135
    return 0;  /* cannot patch other instructions */
 
136
  if (reg != NO_REG && reg != GETARG_B(*i))
 
137
    SETARG_A(*i, reg);
 
138
  else  /* no register to put value or register already has the value */
 
139
    *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
 
140
 
 
141
  return 1;
 
142
}
 
143
 
 
144
 
 
145
static void removevalues (FuncState *fs, int list) {
 
146
  for (; list != NO_JUMP; list = getjump(fs, list))
 
147
      patchtestreg(fs, list, NO_REG);
 
148
}
 
149
 
 
150
 
 
151
static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
 
152
                          int dtarget) {
 
153
  while (list != NO_JUMP) {
 
154
    int next = getjump(fs, list);
 
155
    if (patchtestreg(fs, list, reg))
 
156
      fixjump(fs, list, vtarget);
 
157
    else
 
158
      fixjump(fs, list, dtarget);  /* jump to default target */
 
159
    list = next;
 
160
  }
 
161
}
 
162
 
 
163
 
 
164
static void dischargejpc (FuncState *fs) {
 
165
  patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
 
166
  fs->jpc = NO_JUMP;
 
167
}
 
168
 
 
169
 
 
170
void luaK_patchlist (FuncState *fs, int list, int target) {
 
171
  if (target == fs->pc)
 
172
    luaK_patchtohere(fs, list);
 
173
  else {
 
174
    lua_assert(target < fs->pc);
 
175
    patchlistaux(fs, list, target, NO_REG, target);
 
176
  }
 
177
}
 
178
 
 
179
 
 
180
void luaK_patchtohere (FuncState *fs, int list) {
 
181
  luaK_getlabel(fs);
 
182
  luaK_concat(fs, &fs->jpc, list);
 
183
}
 
184
 
 
185
 
 
186
void luaK_concat (FuncState *fs, int *l1, int l2) {
 
187
  if (l2 == NO_JUMP) return;
 
188
  else if (*l1 == NO_JUMP)
 
189
    *l1 = l2;
 
190
  else {
 
191
    int list = *l1;
 
192
    int next;
 
193
    while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
 
194
      list = next;
 
195
    fixjump(fs, list, l2);
 
196
  }
 
197
}
 
198
 
 
199
 
 
200
void luaK_checkstack (FuncState *fs, int n) {
 
201
  int newstack = fs->freereg + n;
 
202
  if (newstack > fs->f->maxstacksize) {
 
203
    if (newstack >= MAXSTACK)
 
204
      luaX_syntaxerror(fs->ls, "function or expression too complex");
 
205
    fs->f->maxstacksize = cast_byte(newstack);
 
206
  }
 
207
}
 
208
 
 
209
 
 
210
void luaK_reserveregs (FuncState *fs, int n) {
 
211
  luaK_checkstack(fs, n);
 
212
  fs->freereg += n;
 
213
}
 
214
 
 
215
 
 
216
static void freereg (FuncState *fs, int reg) {
 
217
  if (!ISK(reg) && reg >= fs->nactvar) {
 
218
    fs->freereg--;
 
219
    lua_assert(reg == fs->freereg);
 
220
  }
 
221
}
 
222
 
 
223
 
 
224
static void freeexp (FuncState *fs, expdesc *e) {
 
225
  if (e->k == VNONRELOC)
 
226
    freereg(fs, e->u.s.info);
 
227
}
 
228
 
 
229
 
 
230
static int addk (FuncState *fs, TValue *k, TValue *v) {
 
231
  lua_State *L = fs->L;
 
232
  TValue *idx = luaH_set(L, fs->h, k);
 
233
  Proto *f = fs->f;
 
234
  int oldsize = f->sizek;
 
235
  if (ttisnumber(idx)) {
 
236
    lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
 
237
    return cast_int(nvalue(idx));
 
238
  }
 
239
  else {  /* constant not found; create a new entry */
 
240
    setnvalue(idx, cast_num(fs->nk));
 
241
    luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
 
242
                    MAXARG_Bx, "constant table overflow");
 
243
    while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
 
244
    setobj(L, &f->k[fs->nk], v);
 
245
    luaC_barrier(L, f, v);
 
246
    return fs->nk++;
 
247
  }
 
248
}
 
249
 
 
250
 
 
251
int luaK_stringK (FuncState *fs, TString *s) {
 
252
  TValue o;
 
253
  setsvalue(fs->L, &o, s);
 
254
  return addk(fs, &o, &o);
 
255
}
 
256
 
 
257
 
 
258
int luaK_numberK (FuncState *fs, lua_Number r) {
 
259
  TValue o;
 
260
  setnvalue(&o, r);
 
261
  return addk(fs, &o, &o);
 
262
}
 
263
 
 
264
 
 
265
static int boolK (FuncState *fs, int b) {
 
266
  TValue o;
 
267
  setbvalue(&o, b);
 
268
  return addk(fs, &o, &o);
 
269
}
 
270
 
 
271
 
 
272
static int nilK (FuncState *fs) {
 
273
  TValue k, v;
 
274
  setnilvalue(&v);
 
275
  /* cannot use nil as key; instead use table itself to represent nil */
 
276
  sethvalue(fs->L, &k, fs->h);
 
277
  return addk(fs, &k, &v);
 
278
}
 
279
 
 
280
 
 
281
void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
 
282
  if (e->k == VCALL) {  /* expression is an open function call? */
 
283
    SETARG_C(getcode(fs, e), nresults+1);
 
284
  }
 
285
  else if (e->k == VVARARG) {
 
286
    SETARG_B(getcode(fs, e), nresults+1);
 
287
    SETARG_A(getcode(fs, e), fs->freereg);
 
288
    luaK_reserveregs(fs, 1);
 
289
  }
 
290
}
 
291
 
 
292
 
 
293
void luaK_setoneret (FuncState *fs, expdesc *e) {
 
294
  if (e->k == VCALL) {  /* expression is an open function call? */
 
295
    e->k = VNONRELOC;
 
296
    e->u.s.info = GETARG_A(getcode(fs, e));
 
297
  }
 
298
  else if (e->k == VVARARG) {
 
299
    SETARG_B(getcode(fs, e), 2);
 
300
    e->k = VRELOCABLE;  /* can relocate its simple result */
 
301
  }
 
302
}
 
303
 
 
304
 
 
305
void luaK_dischargevars (FuncState *fs, expdesc *e) {
 
306
  switch (e->k) {
 
307
    case VLOCAL: {
 
308
      e->k = VNONRELOC;
 
309
      break;
 
310
    }
 
311
    case VUPVAL: {
 
312
      e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
 
313
      e->k = VRELOCABLE;
 
314
      break;
 
315
    }
 
316
    case VGLOBAL: {
 
317
      e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
 
318
      e->k = VRELOCABLE;
 
319
      break;
 
320
    }
 
321
    case VINDEXED: {
 
322
      freereg(fs, e->u.s.aux);
 
323
      freereg(fs, e->u.s.info);
 
324
      e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
 
325
      e->k = VRELOCABLE;
 
326
      break;
 
327
    }
 
328
    case VVARARG:
 
329
    case VCALL: {
 
330
      luaK_setoneret(fs, e);
 
331
      break;
 
332
    }
 
333
    default: break;  /* there is one value available (somewhere) */
 
334
  }
 
335
}
 
336
 
 
337
 
 
338
static int code_label (FuncState *fs, int A, int b, int jump) {
 
339
  luaK_getlabel(fs);  /* those instructions may be jump targets */
 
340
  return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
 
341
}
 
342
 
 
343
 
 
344
static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
 
345
  luaK_dischargevars(fs, e);
 
346
  switch (e->k) {
 
347
    case VNIL: {
 
348
      luaK_nil(fs, reg, 1);
 
349
      break;
 
350
    }
 
351
    case VFALSE:  case VTRUE: {
 
352
      luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
 
353
      break;
 
354
    }
 
355
    case VK: {
 
356
      luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
 
357
      break;
 
358
    }
 
359
    case VKNUM: {
 
360
      luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
 
361
      break;
 
362
    }
 
363
    case VRELOCABLE: {
 
364
      Instruction *pc = &getcode(fs, e);
 
365
      SETARG_A(*pc, reg);
 
366
      break;
 
367
    }
 
368
    case VNONRELOC: {
 
369
      if (reg != e->u.s.info)
 
370
        luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
 
371
      break;
 
372
    }
 
373
    default: {
 
374
      lua_assert(e->k == VVOID || e->k == VJMP);
 
375
      return;  /* nothing to do... */
 
376
    }
 
377
  }
 
378
  e->u.s.info = reg;
 
379
  e->k = VNONRELOC;
 
380
}
 
381
 
 
382
 
 
383
static void discharge2anyreg (FuncState *fs, expdesc *e) {
 
384
  if (e->k != VNONRELOC) {
 
385
    luaK_reserveregs(fs, 1);
 
386
    discharge2reg(fs, e, fs->freereg-1);
 
387
  }
 
388
}
 
389
 
 
390
 
 
391
static void exp2reg (FuncState *fs, expdesc *e, int reg) {
 
392
  discharge2reg(fs, e, reg);
 
393
  if (e->k == VJMP)
 
394
    luaK_concat(fs, &e->t, e->u.s.info);  /* put this jump in `t' list */
 
395
  if (hasjumps(e)) {
 
396
    int final;  /* position after whole expression */
 
397
    int p_f = NO_JUMP;  /* position of an eventual LOAD false */
 
398
    int p_t = NO_JUMP;  /* position of an eventual LOAD true */
 
399
    if (need_value(fs, e->t) || need_value(fs, e->f)) {
 
400
      int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
 
401
      p_f = code_label(fs, reg, 0, 1);
 
402
      p_t = code_label(fs, reg, 1, 0);
 
403
      luaK_patchtohere(fs, fj);
 
404
    }
 
405
    final = luaK_getlabel(fs);
 
406
    patchlistaux(fs, e->f, final, reg, p_f);
 
407
    patchlistaux(fs, e->t, final, reg, p_t);
 
408
  }
 
409
  e->f = e->t = NO_JUMP;
 
410
  e->u.s.info = reg;
 
411
  e->k = VNONRELOC;
 
412
}
 
413
 
 
414
 
 
415
void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
 
416
  luaK_dischargevars(fs, e);
 
417
  freeexp(fs, e);
 
418
  luaK_reserveregs(fs, 1);
 
419
  exp2reg(fs, e, fs->freereg - 1);
 
420
}
 
421
 
 
422
 
 
423
int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
 
424
  luaK_dischargevars(fs, e);
 
425
  if (e->k == VNONRELOC) {
 
426
    if (!hasjumps(e)) return e->u.s.info;  /* exp is already in a register */
 
427
    if (e->u.s.info >= fs->nactvar) {  /* reg. is not a local? */
 
428
      exp2reg(fs, e, e->u.s.info);  /* put value on it */
 
429
      return e->u.s.info;
 
430
    }
 
431
  }
 
432
  luaK_exp2nextreg(fs, e);  /* default */
 
433
  return e->u.s.info;
 
434
}
 
435
 
 
436
 
 
437
void luaK_exp2val (FuncState *fs, expdesc *e) {
 
438
  if (hasjumps(e))
 
439
    luaK_exp2anyreg(fs, e);
 
440
  else
 
441
    luaK_dischargevars(fs, e);
 
442
}
 
443
 
 
444
 
 
445
int luaK_exp2RK (FuncState *fs, expdesc *e) {
 
446
  luaK_exp2val(fs, e);
 
447
  switch (e->k) {
 
448
    case VKNUM:
 
449
    case VTRUE:
 
450
    case VFALSE:
 
451
    case VNIL: {
 
452
      if (fs->nk <= MAXINDEXRK) {  /* constant fit in RK operand? */
 
453
        e->u.s.info = (e->k == VNIL)  ? nilK(fs) :
 
454
                      (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
 
455
                                        boolK(fs, (e->k == VTRUE));
 
456
        e->k = VK;
 
457
        return RKASK(e->u.s.info);
 
458
      }
 
459
      else break;
 
460
    }
 
461
    case VK: {
 
462
      if (e->u.s.info <= MAXINDEXRK)  /* constant fit in argC? */
 
463
        return RKASK(e->u.s.info);
 
464
      else break;
 
465
    }
 
466
    default: break;
 
467
  }
 
468
  /* not a constant in the right range: put it in a register */
 
469
  return luaK_exp2anyreg(fs, e);
 
470
}
 
471
 
 
472
 
 
473
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
 
474
  switch (var->k) {
 
475
    case VLOCAL: {
 
476
      freeexp(fs, ex);
 
477
      exp2reg(fs, ex, var->u.s.info);
 
478
      return;
 
479
    }
 
480
    case VUPVAL: {
 
481
      int e = luaK_exp2anyreg(fs, ex);
 
482
      luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
 
483
      break;
 
484
    }
 
485
    case VGLOBAL: {
 
486
      int e = luaK_exp2anyreg(fs, ex);
 
487
      luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
 
488
      break;
 
489
    }
 
490
    case VINDEXED: {
 
491
      int e = luaK_exp2RK(fs, ex);
 
492
      luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
 
493
      break;
 
494
    }
 
495
    default: {
 
496
      lua_assert(0);  /* invalid var kind to store */
 
497
      break;
 
498
    }
 
499
  }
 
500
  freeexp(fs, ex);
 
501
}
 
502
 
 
503
 
 
504
void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
 
505
  int func;
 
506
  luaK_exp2anyreg(fs, e);
 
507
  freeexp(fs, e);
 
508
  func = fs->freereg;
 
509
  luaK_reserveregs(fs, 2);
 
510
  luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
 
511
  freeexp(fs, key);
 
512
  e->u.s.info = func;
 
513
  e->k = VNONRELOC;
 
514
}
 
515
 
 
516
 
 
517
static void invertjump (FuncState *fs, expdesc *e) {
 
518
  Instruction *pc = getjumpcontrol(fs, e->u.s.info);
 
519
  lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
 
520
                                           GET_OPCODE(*pc) != OP_TEST);
 
521
  SETARG_A(*pc, !(GETARG_A(*pc)));
 
522
}
 
523
 
 
524
 
 
525
static int jumponcond (FuncState *fs, expdesc *e, int cond) {
 
526
  if (e->k == VRELOCABLE) {
 
527
    Instruction ie = getcode(fs, e);
 
528
    if (GET_OPCODE(ie) == OP_NOT) {
 
529
      fs->pc--;  /* remove previous OP_NOT */
 
530
      return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
 
531
    }
 
532
    /* else go through */
 
533
  }
 
534
  discharge2anyreg(fs, e);
 
535
  freeexp(fs, e);
 
536
  return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
 
537
}
 
538
 
 
539
 
 
540
void luaK_goiftrue (FuncState *fs, expdesc *e) {
 
541
  int pc;  /* pc of last jump */
 
542
  luaK_dischargevars(fs, e);
 
543
  switch (e->k) {
 
544
    case VK: case VKNUM: case VTRUE: {
 
545
      pc = NO_JUMP;  /* always true; do nothing */
 
546
      break;
 
547
    }
 
548
    case VFALSE: {
 
549
      pc = luaK_jump(fs);  /* always jump */
 
550
      break;
 
551
    }
 
552
    case VJMP: {
 
553
      invertjump(fs, e);
 
554
      pc = e->u.s.info;
 
555
      break;
 
556
    }
 
557
    default: {
 
558
      pc = jumponcond(fs, e, 0);
 
559
      break;
 
560
    }
 
561
  }
 
562
  luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
 
563
  luaK_patchtohere(fs, e->t);
 
564
  e->t = NO_JUMP;
 
565
}
 
566
 
 
567
 
 
568
static void luaK_goiffalse (FuncState *fs, expdesc *e) {
 
569
  int pc;  /* pc of last jump */
 
570
  luaK_dischargevars(fs, e);
 
571
  switch (e->k) {
 
572
    case VNIL: case VFALSE: {
 
573
      pc = NO_JUMP;  /* always false; do nothing */
 
574
      break;
 
575
    }
 
576
    case VTRUE: {
 
577
      pc = luaK_jump(fs);  /* always jump */
 
578
      break;
 
579
    }
 
580
    case VJMP: {
 
581
      pc = e->u.s.info;
 
582
      break;
 
583
    }
 
584
    default: {
 
585
      pc = jumponcond(fs, e, 1);
 
586
      break;
 
587
    }
 
588
  }
 
589
  luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
 
590
  luaK_patchtohere(fs, e->f);
 
591
  e->f = NO_JUMP;
 
592
}
 
593
 
 
594
 
 
595
static void codenot (FuncState *fs, expdesc *e) {
 
596
  luaK_dischargevars(fs, e);
 
597
  switch (e->k) {
 
598
    case VNIL: case VFALSE: {
 
599
      e->k = VTRUE;
 
600
      break;
 
601
    }
 
602
    case VK: case VKNUM: case VTRUE: {
 
603
      e->k = VFALSE;
 
604
      break;
 
605
    }
 
606
    case VJMP: {
 
607
      invertjump(fs, e);
 
608
      break;
 
609
    }
 
610
    case VRELOCABLE:
 
611
    case VNONRELOC: {
 
612
      discharge2anyreg(fs, e);
 
613
      freeexp(fs, e);
 
614
      e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
 
615
      e->k = VRELOCABLE;
 
616
      break;
 
617
    }
 
618
    default: {
 
619
      lua_assert(0);  /* cannot happen */
 
620
      break;
 
621
    }
 
622
  }
 
623
  /* interchange true and false lists */
 
624
  { int temp = e->f; e->f = e->t; e->t = temp; }
 
625
  removevalues(fs, e->f);
 
626
  removevalues(fs, e->t);
 
627
}
 
628
 
 
629
 
 
630
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
 
631
  t->u.s.aux = luaK_exp2RK(fs, k);
 
632
  t->k = VINDEXED;
 
633
}
 
634
 
 
635
 
 
636
static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
 
637
  lua_Number v1, v2, r;
 
638
  if (!isnumeral(e1) || !isnumeral(e2)) return 0;
 
639
  v1 = e1->u.nval;
 
640
  v2 = e2->u.nval;
 
641
  switch (op) {
 
642
    case OP_ADD: r = luai_numadd(v1, v2); break;
 
643
    case OP_SUB: r = luai_numsub(v1, v2); break;
 
644
    case OP_MUL: r = luai_nummul(v1, v2); break;
 
645
    case OP_DIV:
 
646
      if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
 
647
      r = luai_numdiv(v1, v2); break;
 
648
    case OP_MOD:
 
649
      if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
 
650
      r = luai_nummod(v1, v2); break;
 
651
    case OP_POW: r = luai_numpow(v1, v2); break;
 
652
    case OP_UNM: r = luai_numunm(v1); break;
 
653
    case OP_LEN: return 0;  /* no constant folding for 'len' */
 
654
    default: lua_assert(0); r = 0; break;
 
655
  }
 
656
  if (luai_numisnan(r)) return 0;  /* do not attempt to produce NaN */
 
657
  e1->u.nval = r;
 
658
  return 1;
 
659
}
 
660
 
 
661
 
 
662
static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
 
663
  if (constfolding(op, e1, e2))
 
664
    return;
 
665
  else {
 
666
    int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
 
667
    int o1 = luaK_exp2RK(fs, e1);
 
668
    if (o1 > o2) {
 
669
      freeexp(fs, e1);
 
670
      freeexp(fs, e2);
 
671
    }
 
672
    else {
 
673
      freeexp(fs, e2);
 
674
      freeexp(fs, e1);
 
675
    }
 
676
    e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
 
677
    e1->k = VRELOCABLE;
 
678
  }
 
679
}
 
680
 
 
681
 
 
682
static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
 
683
                                                          expdesc *e2) {
 
684
  int o1 = luaK_exp2RK(fs, e1);
 
685
  int o2 = luaK_exp2RK(fs, e2);
 
686
  freeexp(fs, e2);
 
687
  freeexp(fs, e1);
 
688
  if (cond == 0 && op != OP_EQ) {
 
689
    int temp;  /* exchange args to replace by `<' or `<=' */
 
690
    temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
 
691
    cond = 1;
 
692
  }
 
693
  e1->u.s.info = condjump(fs, op, cond, o1, o2);
 
694
  e1->k = VJMP;
 
695
}
 
696
 
 
697
 
 
698
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
 
699
  expdesc e2;
 
700
  e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
 
701
  switch (op) {
 
702
    case OPR_MINUS: {
 
703
      if (!isnumeral(e))
 
704
        luaK_exp2anyreg(fs, e);  /* cannot operate on non-numeric constants */
 
705
      codearith(fs, OP_UNM, e, &e2);
 
706
      break;
 
707
    }
 
708
    case OPR_NOT: codenot(fs, e); break;
 
709
    case OPR_LEN: {
 
710
      luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
 
711
      codearith(fs, OP_LEN, e, &e2);
 
712
      break;
 
713
    }
 
714
    default: lua_assert(0);
 
715
  }
 
716
}
 
717
 
 
718
 
 
719
void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
 
720
  switch (op) {
 
721
    case OPR_AND: {
 
722
      luaK_goiftrue(fs, v);
 
723
      break;
 
724
    }
 
725
    case OPR_OR: {
 
726
      luaK_goiffalse(fs, v);
 
727
      break;
 
728
    }
 
729
    case OPR_CONCAT: {
 
730
      luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
 
731
      break;
 
732
    }
 
733
    case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
 
734
    case OPR_MOD: case OPR_POW: {
 
735
      if (!isnumeral(v)) luaK_exp2RK(fs, v);
 
736
      break;
 
737
    }
 
738
    default: {
 
739
      luaK_exp2RK(fs, v);
 
740
      break;
 
741
    }
 
742
  }
 
743
}
 
744
 
 
745
 
 
746
void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
 
747
  switch (op) {
 
748
    case OPR_AND: {
 
749
      lua_assert(e1->t == NO_JUMP);  /* list must be closed */
 
750
      luaK_dischargevars(fs, e2);
 
751
      luaK_concat(fs, &e2->f, e1->f);
 
752
#if 0
 
753
      *e1 = *e2;
 
754
#else
 
755
      memcpy (e1, e2, sizeof (*e1));
 
756
#endif
 
757
      break;
 
758
    }
 
759
    case OPR_OR: {
 
760
      lua_assert(e1->f == NO_JUMP);  /* list must be closed */
 
761
      luaK_dischargevars(fs, e2);
 
762
      luaK_concat(fs, &e2->t, e1->t);
 
763
#if 0
 
764
      *e1 = *e2;
 
765
#else
 
766
      memcpy (e1, e2, sizeof (*e1));
 
767
#endif
 
768
      break;
 
769
    }
 
770
    case OPR_CONCAT: {
 
771
      luaK_exp2val(fs, e2);
 
772
      if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
 
773
        lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
 
774
        freeexp(fs, e1);
 
775
        SETARG_B(getcode(fs, e2), e1->u.s.info);
 
776
        e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
 
777
      }
 
778
      else {
 
779
        luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
 
780
        codearith(fs, OP_CONCAT, e1, e2);
 
781
      }
 
782
      break;
 
783
    }
 
784
    case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
 
785
    case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
 
786
    case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
 
787
    case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
 
788
    case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
 
789
    case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
 
790
    case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
 
791
    case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
 
792
    case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
 
793
    case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
 
794
    case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
 
795
    case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
 
796
    default: lua_assert(0);
 
797
  }
 
798
}
 
799
 
 
800
 
 
801
void luaK_fixline (FuncState *fs, int line) {
 
802
  fs->f->lineinfo[fs->pc - 1] = line;
 
803
}
 
804
 
 
805
 
 
806
static int luaK_code (FuncState *fs, Instruction i, int line) {
 
807
  Proto *f = fs->f;
 
808
  dischargejpc(fs);  /* `pc' will change */
 
809
  /* put new instruction in code array */
 
810
  luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
 
811
                  MAX_INT, "code size overflow");
 
812
  f->code[fs->pc] = i;
 
813
  /* save corresponding line information */
 
814
  luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
 
815
                  MAX_INT, "code size overflow");
 
816
  f->lineinfo[fs->pc] = line;
 
817
  return fs->pc++;
 
818
}
 
819
 
 
820
 
 
821
int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
 
822
  lua_assert(getOpMode(o) == iABC);
 
823
  lua_assert(getBMode(o) != OpArgN || b == 0);
 
824
  lua_assert(getCMode(o) != OpArgN || c == 0);
 
825
  return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
 
826
}
 
827
 
 
828
 
 
829
int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
 
830
  lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
 
831
  lua_assert(getCMode(o) == OpArgN);
 
832
  return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
 
833
}
 
834
 
 
835
 
 
836
void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
 
837
  int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
 
838
  int b = (tostore == LUA_MULTRET) ? 0 : tostore;
 
839
  lua_assert(tostore != 0);
 
840
  if (c <= MAXARG_C)
 
841
    luaK_codeABC(fs, OP_SETLIST, base, b, c);
 
842
  else {
 
843
    luaK_codeABC(fs, OP_SETLIST, base, b, 0);
 
844
    luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
 
845
  }
 
846
  fs->freereg = base + 1;  /* free registers with list values */
 
847
}
 
848