diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-09-23 17:33:05 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-09-23 17:33:05 -0300 |
commit | fcc46467fa92c8e9951e63baf2c3e1b22bf20a1f (patch) | |
tree | 54e6ab8b2b6d720911251e6863ddca1e54a75cd0 | |
parent | f8e354e2404cbd0a91b4299598d4de9757e73fd7 (diff) | |
download | lua-fcc46467fa92c8e9951e63baf2c3e1b22bf20a1f.tar.gz lua-fcc46467fa92c8e9951e63baf2c3e1b22bf20a1f.tar.bz2 lua-fcc46467fa92c8e9951e63baf2c3e1b22bf20a1f.zip |
limit of constants per function changed to 2^26 using extra arguments
to opcodes LOADK, GETGLOBAL, and SETGLOBAL
-rw-r--r-- | lcode.c | 103 | ||||
-rw-r--r-- | lcode.h | 6 | ||||
-rw-r--r-- | ldebug.c | 6 | ||||
-rw-r--r-- | lopcodes.h | 15 | ||||
-rw-r--r-- | lvm.c | 22 |
5 files changed, 86 insertions, 66 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.40 2009/06/18 16:35:05 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.41 2009/08/10 15:31:44 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -191,6 +191,55 @@ void luaK_concat (FuncState *fs, int *l1, int l2) { | |||
191 | } | 191 | } |
192 | 192 | ||
193 | 193 | ||
194 | static int luaK_code (FuncState *fs, Instruction i) { | ||
195 | Proto *f = fs->f; | ||
196 | dischargejpc(fs); /* `pc' will change */ | ||
197 | /* put new instruction in code array */ | ||
198 | luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, | ||
199 | MAX_INT, "opcodes"); | ||
200 | f->code[fs->pc] = i; | ||
201 | /* save corresponding line information */ | ||
202 | luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, | ||
203 | MAX_INT, "opcodes"); | ||
204 | f->lineinfo[fs->pc] = fs->ls->lastline; | ||
205 | return fs->pc++; | ||
206 | } | ||
207 | |||
208 | |||
209 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { | ||
210 | lua_assert(getOpMode(o) == iABC); | ||
211 | lua_assert(getBMode(o) != OpArgN || b == 0); | ||
212 | lua_assert(getCMode(o) != OpArgN || c == 0); | ||
213 | lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); | ||
214 | return luaK_code(fs, CREATE_ABC(o, a, b, c)); | ||
215 | } | ||
216 | |||
217 | |||
218 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | ||
219 | lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); | ||
220 | lua_assert(getCMode(o) == OpArgN); | ||
221 | lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); | ||
222 | return luaK_code(fs, CREATE_ABx(o, a, bc)); | ||
223 | } | ||
224 | |||
225 | |||
226 | static int codeextraarg (FuncState *fs, int a) { | ||
227 | lua_assert(a <= MAXARG_Ax); | ||
228 | return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); | ||
229 | } | ||
230 | |||
231 | |||
232 | int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k) { | ||
233 | if (k < MAXARG_Bx) | ||
234 | return luaK_codeABx(fs, o, reg, k + 1); | ||
235 | else { | ||
236 | int p = luaK_codeABx(fs, o, reg, 0); | ||
237 | codeextraarg(fs, k); | ||
238 | return p; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | |||
194 | void luaK_checkstack (FuncState *fs, int n) { | 243 | void luaK_checkstack (FuncState *fs, int n) { |
195 | int newstack = fs->freereg + n; | 244 | int newstack = fs->freereg + n; |
196 | if (newstack > fs->f->maxstacksize) { | 245 | if (newstack > fs->f->maxstacksize) { |
@@ -238,7 +287,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { | |||
238 | oldsize = f->sizek; | 287 | oldsize = f->sizek; |
239 | k = fs->nk; | 288 | k = fs->nk; |
240 | setnvalue(idx, cast_num(k)); | 289 | setnvalue(idx, cast_num(k)); |
241 | luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Bx, "constants"); | 290 | luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); |
242 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); | 291 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); |
243 | setobj(L, &f->k[k], v); | 292 | setobj(L, &f->k[k], v); |
244 | fs->nk++; | 293 | fs->nk++; |
@@ -324,7 +373,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { | |||
324 | break; | 373 | break; |
325 | } | 374 | } |
326 | case VGLOBAL: { | 375 | case VGLOBAL: { |
327 | e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); | 376 | e->u.s.info = luaK_codeABxX(fs, OP_GETGLOBAL, 0, e->u.s.info); |
328 | e->k = VRELOCABLE; | 377 | e->k = VRELOCABLE; |
329 | break; | 378 | break; |
330 | } | 379 | } |
@@ -496,7 +545,7 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { | |||
496 | } | 545 | } |
497 | case VGLOBAL: { | 546 | case VGLOBAL: { |
498 | int e = luaK_exp2anyreg(fs, ex); | 547 | int e = luaK_exp2anyreg(fs, ex); |
499 | luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); | 548 | luaK_codeABxX(fs, OP_SETGLOBAL, e, var->u.s.info); |
500 | break; | 549 | break; |
501 | } | 550 | } |
502 | case VINDEXED: { | 551 | case VINDEXED: { |
@@ -802,50 +851,6 @@ void luaK_fixline (FuncState *fs, int line) { | |||
802 | } | 851 | } |
803 | 852 | ||
804 | 853 | ||
805 | static int luaK_code (FuncState *fs, Instruction i) { | ||
806 | Proto *f = fs->f; | ||
807 | dischargejpc(fs); /* `pc' will change */ | ||
808 | /* put new instruction in code array */ | ||
809 | luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, | ||
810 | MAX_INT, "opcodes"); | ||
811 | f->code[fs->pc] = i; | ||
812 | /* save corresponding line information */ | ||
813 | luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, | ||
814 | MAX_INT, "opcodes"); | ||
815 | f->lineinfo[fs->pc] = fs->ls->lastline; | ||
816 | return fs->pc++; | ||
817 | } | ||
818 | |||
819 | |||
820 | int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { | ||
821 | lua_assert(getOpMode(o) == iABC); | ||
822 | lua_assert(getBMode(o) != OpArgN || b == 0); | ||
823 | lua_assert(getCMode(o) != OpArgN || c == 0); | ||
824 | lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); | ||
825 | return luaK_code(fs, CREATE_ABC(o, a, b, c)); | ||
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 | lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); | ||
833 | return luaK_code(fs, CREATE_ABx(o, a, bc)); | ||
834 | } | ||
835 | |||
836 | |||
837 | static int luaK_codeAx (FuncState *fs, OpCode o, int a) { | ||
838 | lua_assert(getOpMode(o) == iAx); | ||
839 | lua_assert(a <= MAXARG_Ax); | ||
840 | return luaK_code(fs, CREATE_Ax(o, a)); | ||
841 | } | ||
842 | |||
843 | |||
844 | void luaK_codek (FuncState *fs, int reg, int k) { | ||
845 | luaK_codeABx(fs, OP_LOADK, reg, k); | ||
846 | } | ||
847 | |||
848 | |||
849 | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { | 854 | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { |
850 | int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; | 855 | int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; |
851 | int b = (tostore == LUA_MULTRET) ? 0 : tostore; | 856 | int b = (tostore == LUA_MULTRET) ? 0 : tostore; |
@@ -854,7 +859,7 @@ void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { | |||
854 | luaK_codeABC(fs, OP_SETLIST, base, b, c); | 859 | luaK_codeABC(fs, OP_SETLIST, base, b, c); |
855 | else if (c <= MAXARG_Ax) { | 860 | else if (c <= MAXARG_Ax) { |
856 | luaK_codeABC(fs, OP_SETLIST, base, b, 0); | 861 | luaK_codeABC(fs, OP_SETLIST, base, b, 0); |
857 | luaK_codeAx(fs, OP_EXTRAARG, c); | 862 | codeextraarg(fs, c); |
858 | } | 863 | } |
859 | else | 864 | else |
860 | luaX_syntaxerror(fs->ls, "constructor too long"); | 865 | luaX_syntaxerror(fs->ls, "constructor too long"); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.h,v 1.50 2009/06/10 16:52:03 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.51 2009/06/18 16:35:05 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -44,9 +44,11 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | |||
44 | 44 | ||
45 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) | 45 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) |
46 | 46 | ||
47 | LUAI_FUNC void luaK_codek (FuncState *fs, int reg, int k); | 47 | #define luaK_codek(fs,reg,k) luaK_codeABxX(fs, OP_LOADK, reg, k) |
48 | |||
48 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); | 49 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
49 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); | 50 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); |
51 | LUAI_FUNC int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k); | ||
50 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); | 52 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); |
51 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); | 53 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); |
52 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); | 54 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.52 2009/06/10 16:57:53 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.53 2009/08/07 16:17:41 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -299,7 +299,9 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, | |||
299 | switch (op) { | 299 | switch (op) { |
300 | case OP_GETGLOBAL: { | 300 | case OP_GETGLOBAL: { |
301 | if (reg == a) { | 301 | if (reg == a) { |
302 | int g = GETARG_Bx(i); /* global index */ | 302 | int g = GETARG_Bx(i); |
303 | if (g != 0) g--; | ||
304 | else g = GETARG_Ax(p->code[++pc]); | ||
303 | lua_assert(ttisstring(&p->k[g])); | 305 | lua_assert(ttisstring(&p->k[g])); |
304 | *name = svalue(&p->k[g]); | 306 | *name = svalue(&p->k[g]); |
305 | what = "global"; | 307 | what = "global"; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.128 2008/10/30 15:39:30 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.129 2009/03/09 15:27:56 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -166,15 +166,15 @@ typedef enum { | |||
166 | name args description | 166 | name args description |
167 | ------------------------------------------------------------------------*/ | 167 | ------------------------------------------------------------------------*/ |
168 | OP_MOVE,/* A B R(A) := R(B) */ | 168 | OP_MOVE,/* A B R(A) := R(B) */ |
169 | OP_LOADK,/* A Bx R(A) := Kst(Bx) */ | 169 | OP_LOADK,/* A Bx R(A) := Kst(Bx - 1) */ |
170 | OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ | 170 | OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ |
171 | OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ | 171 | OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ |
172 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ | 172 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ |
173 | 173 | ||
174 | OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */ | 174 | OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx - 1)] */ |
175 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ | 175 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ |
176 | 176 | ||
177 | OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */ | 177 | OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx - 1)] := R(A) */ |
178 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ | 178 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ |
179 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ | 179 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ |
180 | 180 | ||
@@ -221,7 +221,7 @@ OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ | |||
221 | 221 | ||
222 | OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ | 222 | OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ |
223 | 223 | ||
224 | OP_EXTRAARG/* Ax extra argument for previous opcode */ | 224 | OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ |
225 | } OpCode; | 225 | } OpCode; |
226 | 226 | ||
227 | 227 | ||
@@ -241,7 +241,10 @@ OP_EXTRAARG/* Ax extra argument for previous opcode */ | |||
241 | (*) In OP_RETURN, if (B == 0) then return up to `top'. | 241 | (*) In OP_RETURN, if (B == 0) then return up to `top'. |
242 | 242 | ||
243 | (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next | 243 | (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next |
244 | `instruction' is EXTRAARG(real C). | 244 | 'instruction' is EXTRAARG(real C). |
245 | |||
246 | (*) In OP_LOADK, OP_GETGLOBAL, and OP_SETGLOBAL, if (Bx == 0) then next | ||
247 | 'instruction' is EXTRAARG(real Bx). | ||
245 | 248 | ||
246 | (*) For comparisons, A specifies what condition the test should accept | 249 | (*) For comparisons, A specifies what condition the test should accept |
247 | (true or false). | 250 | (true or false). |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.95 2009/07/15 18:38:16 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.96 2009/08/07 16:17:41 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 | */ |
@@ -353,7 +353,12 @@ void luaV_finishOp (lua_State *L) { | |||
353 | CallInfo *ci = L->ci; | 353 | CallInfo *ci = L->ci; |
354 | StkId base = ci->u.l.base; | 354 | StkId base = ci->u.l.base; |
355 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | 355 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
356 | switch (GET_OPCODE(inst)) { /* finish its execution */ | 356 | OpCode op = GET_OPCODE(inst); |
357 | if (op == OP_EXTRAARG) { /* extra argument? */ | ||
358 | inst = *(ci->u.l.savedpc - 2); /* get its 'main' instruction */ | ||
359 | op = GET_OPCODE(inst); | ||
360 | } | ||
361 | switch (op) { /* finish its execution */ | ||
357 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: | 362 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: |
358 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 363 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: |
359 | case OP_GETGLOBAL: case OP_GETTABLE: case OP_SELF: { | 364 | case OP_GETGLOBAL: case OP_GETTABLE: case OP_SELF: { |
@@ -365,7 +370,7 @@ void luaV_finishOp (lua_State *L) { | |||
365 | L->top--; | 370 | L->top--; |
366 | /* metamethod should not be called when operand is K */ | 371 | /* metamethod should not be called when operand is K */ |
367 | lua_assert(!ISK(GETARG_B(inst))); | 372 | lua_assert(!ISK(GETARG_B(inst))); |
368 | if (GET_OPCODE(inst) == OP_LE && /* "<=" using "<" instead? */ | 373 | if (op == OP_LE && /* "<=" using "<" instead? */ |
369 | ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) | 374 | ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) |
370 | res = !res; /* invert result */ | 375 | res = !res; /* invert result */ |
371 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); | 376 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
@@ -417,7 +422,8 @@ void luaV_finishOp (lua_State *L) { | |||
417 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) | 422 | ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) |
418 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ | 423 | #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ |
419 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) | 424 | ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) |
420 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) | 425 | #define KBx(i) \ |
426 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) | ||
421 | 427 | ||
422 | 428 | ||
423 | #define dojump(i) { ci->u.l.savedpc += (i); luai_threadyield(L);} | 429 | #define dojump(i) { ci->u.l.savedpc += (i); luai_threadyield(L);} |
@@ -468,7 +474,8 @@ void luaV_execute (lua_State *L) { | |||
468 | continue; | 474 | continue; |
469 | } | 475 | } |
470 | case OP_LOADK: { | 476 | case OP_LOADK: { |
471 | setobj2s(L, ra, KBx(i)); | 477 | TValue *rb = KBx(i); |
478 | setobj2s(L, ra, rb); | ||
472 | continue; | 479 | continue; |
473 | } | 480 | } |
474 | case OP_LOADBOOL: { | 481 | case OP_LOADBOOL: { |
@@ -502,9 +509,10 @@ void luaV_execute (lua_State *L) { | |||
502 | } | 509 | } |
503 | case OP_SETGLOBAL: { | 510 | case OP_SETGLOBAL: { |
504 | TValue g; | 511 | TValue g; |
512 | TValue *rb = KBx(i); | ||
505 | sethvalue(L, &g, cl->env); | 513 | sethvalue(L, &g, cl->env); |
506 | lua_assert(ttisstring(KBx(i))); | 514 | lua_assert(ttisstring(rb)); |
507 | Protect(luaV_settable(L, &g, KBx(i), ra)); | 515 | Protect(luaV_settable(L, &g, rb, ra)); |
508 | continue; | 516 | continue; |
509 | } | 517 | } |
510 | case OP_SETUPVAL: { | 518 | case OP_SETUPVAL: { |