35
35
#include <stdio.h>
36
36
#include "sys-state.h"
37
37
38
- REBNATIVE (do ); // Forward declaration for detection and special cases
39
- #define IS_DO (v ) (IS_NATIVE(v) && (VAL_FUNC_CODE(v) == &N_do))
40
-
41
38
enum Eval_Types {
42
39
ET_INVALID , // not valid to evaluate
43
40
ET_WORD ,
@@ -607,13 +604,13 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
607
604
608
605
/***********************************************************************
609
606
**
610
- */ static REBINT Do_Args (REBVAL * func , REBVAL * path , REBSER * block , REBCNT index )
607
+ */ static REBINT Do_Args (REBCNT func_offset , REBVAL * path , REBSER * block , REBCNT index )
611
608
/*
612
609
** Evaluate code block according to the function arg spec.
613
610
** Args are pushed onto the data stack in the same order
614
611
** as the function frame.
615
612
**
616
- ** func : function or path value
613
+ ** func_offset : offset of the function or path value, relative to DS_Base
617
614
** path: refinements or object/function path
618
615
** block: current evaluation block
619
616
** index: current evaluation index
@@ -627,11 +624,15 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
627
624
REBINT dsp = DSP + 1 ; // stack base
628
625
REBINT dsf = dsp - DSF_BIAS ;
629
626
REBVAL * tos ;
627
+ REBVAL * func ;
630
628
631
- if (IS_OP (func )) dsf -- ; // adjust for extra arg
629
+ if ((dsp + 100 ) > (REBINT )SERIES_REST (DS_Series )) {
630
+ Expand_Stack (STACK_MIN );
631
+ }
632
632
633
- if ((dsp + 100 ) > (REBINT )SERIES_REST (DS_Series ))
634
- Trap0 (RE_STACK_OVERFLOW ); //Expand_Stack();
633
+ func = & DS_Base [func_offset ];
634
+
635
+ if (IS_OP (func )) dsf -- ; // adjust for extra arg
635
636
636
637
// Get list of words:
637
638
words = VAL_FUNC_WORDS (func );
@@ -656,6 +657,8 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
656
657
ds = dsp ;
657
658
for (; NOT_END (args ); args ++ , ds ++ ) {
658
659
660
+ func = & DS_Base [func_offset ]; //DS_Base could be changed
661
+
659
662
//if (Trace_Flags) Trace_Arg(ds - dsp, args, path);
660
663
661
664
// Process each formal argument:
@@ -841,6 +844,7 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
841
844
if (IS_UNSET (value )) Trap1 (RE_NO_VALUE , word );
842
845
if (VAL_TYPE (value ) >= REB_NATIVE && VAL_TYPE (value ) <= REB_FUNCTION ) goto reval ; // || IS_LIT_PATH(value)
843
846
DS_PUSH (value );
847
+ if (IS_LIT_WORD (value )) VAL_SET (DS_TOP , REB_WORD );
844
848
if (IS_FRAME (value )) Init_Obj_Value (DS_TOP , VAL_WORD_FRAME (word ));
845
849
index ++ ;
846
850
break ;
@@ -872,7 +876,8 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
872
876
Debug_Value (word , 4 , 0 );
873
877
Dump_Values (value , 4 );
874
878
}
875
- index = Do_Args (value , 0 , block , index + 1 ); // uses old DSF, updates DSP
879
+ index = Do_Args (dsf + 3 , 0 , block , index + 1 ); // uses old DSF, updates DSP
880
+ value = DSF_FUNC (dsf ); //reevaluate value, because stack could be expanded in Do_Args
876
881
eval_func2 :
877
882
// Evaluate the function:
878
883
DSF = dsf ; // Set new DSF
@@ -927,12 +932,15 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
927
932
//Debug_Fmt("v: %r", value);
928
933
// Value returned only for functions that need evaluation (but not GET_PATH):
929
934
if (value && ANY_FUNC (value )) {
935
+ REBCNT offset = 0 ;
930
936
if (IS_OP (value )) Trap_Type (value ); // (because prior value is wiped out above)
931
937
// Can be object/func or func/refinements or object/func/refinement:
932
938
dsf = Push_Func (TRUE, block , index , VAL_WORD_SYM (word ), value ); // Do not unset TOS1 (it is the value)
933
939
value = DS_TOP ;
934
- index = Do_Args ( value , word + 1 , block , index + 1 ) ;
940
+ offset = value - DS_Base ;
935
941
ftype = VAL_TYPE (value )- REB_NATIVE ;
942
+ index = Do_Args (offset , word + 1 , block , index + 1 );
943
+ value = & DS_Base [offset ]; //restore in case the stack is expanded
936
944
goto eval_func2 ;
937
945
} else
938
946
index ++ ;
@@ -1323,9 +1331,9 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
1323
1331
**
1324
1332
***********************************************************************/
1325
1333
{
1334
+ REBINT ftype = VAL_TYPE (func ) - REB_NATIVE ; // function type
1326
1335
REBSER * block = VAL_SERIES (args );
1327
1336
REBCNT index = VAL_INDEX (args );
1328
- REBCNT dsp ;
1329
1337
REBCNT dsf ;
1330
1338
1331
1339
REBSER * words ;
@@ -1334,10 +1342,6 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
1334
1342
REBINT start ;
1335
1343
REBVAL * val ;
1336
1344
1337
- dsp = DSP ; // in case we have to reset it later
1338
-
1339
- reapply : // Go back here to start over with a new func
1340
-
1341
1345
if (index > SERIES_TAIL (block )) index = SERIES_TAIL (block );
1342
1346
1343
1347
// Push function frame:
@@ -1353,17 +1357,6 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
1353
1357
if (reduce ) {
1354
1358
// Reduce block contents to stack:
1355
1359
n = 0 ;
1356
- // Check for DO any-function
1357
- if (index < BLK_LEN (block )) {
1358
- index = Do_Next (block , index , 0 );
1359
- val = DS_TOP ;
1360
- if (IS_DO (func ) && ANY_FUNC (val )) {
1361
- func = val ; // apply this func directly (volatile reference!)
1362
- DSP = dsp ; // reset the stack
1363
- goto reapply ; // go back to the beginning
1364
- }
1365
- n ++ ;
1366
- }
1367
1360
while (index < BLK_LEN (block )) {
1368
1361
index = Do_Next (block , index , 0 );
1369
1362
if (THROWN (DS_TOP )) return ;
@@ -1372,18 +1365,11 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
1372
1365
if (n > len ) DSP = start + len ;
1373
1366
}
1374
1367
else {
1375
- // Get args block and check for DO any-function
1376
- n = BLK_LEN (block ) - index ;
1377
- val = BLK_SKIP (block , index );
1378
- if (n > 0 && IS_DO (func ) && ANY_FUNC (val )) {
1379
- func = val ; // apply this func directly
1380
- index ++ ; // skip past the func value in the args
1381
- DSP = dsp ; // reset the stack
1382
- goto reapply ; // go back to the beginning
1383
- }
1384
1368
// Copy block contents to stack:
1369
+ n = VAL_BLK_LEN (args );
1385
1370
if (len < n ) n = len ;
1386
- memcpy (& DS_Base [start ], val , n * sizeof (REBVAL ));
1371
+ if (start + n + 100 > SERIES_REST (DS_Series )) Expand_Stack (STACK_MIN );
1372
+ memcpy (& DS_Base [start ], BLK_SKIP (block , index ), n * sizeof (REBVAL ));
1387
1373
DSP = start + n - 1 ;
1388
1374
}
1389
1375
@@ -1418,7 +1404,8 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
1418
1404
1419
1405
// Evaluate the function:
1420
1406
DSF = dsf ;
1421
- Func_Dispatch [VAL_TYPE (func ) - REB_NATIVE ](func );
1407
+ func = DSF_FUNC (dsf ); //stack could be expanded
1408
+ Func_Dispatch [ftype ](func );
1422
1409
DSP = dsf ;
1423
1410
DSF = PRIOR_DSF (dsf );
1424
1411
}
@@ -1447,6 +1434,10 @@ x*/ static REBINT Do_Args_Light(REBVAL *func, REBVAL *path, REBSER *block, REBCN
1447
1434
func = DSF_FUNC (dsf ); // for safety
1448
1435
words = VAL_FUNC_WORDS (func );
1449
1436
ds = SERIES_TAIL (words )- 1 ; // length of stack fill below
1437
+ if (DSP + ds + 100 > SERIES_REST (DS_Series )) {//unlikely
1438
+ Expand_Stack (STACK_MIN );
1439
+ func = DSF_FUNC (dsf ); //reevaluate func
1440
+ }
1450
1441
1451
1442
// Gather arguments from C stack:
1452
1443
for (; ds > 0 ; ds -- ) {
0 commit comments