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