@@ -122,6 +122,9 @@ typedef enum {
122
122
123
123
// loop
124
124
ISN_FOR, // get next item from a list, uses isn_arg.forloop
125
+ ISN_WHILE, // jump if condition false, store funcref count, uses
126
+ // isn_arg.whileloop
127
+ ISN_ENDLOOP, // handle variables for closures, uses isn_arg.endloop
125
128
126
129
ISN_TRY, // add entry to ec_trystack, uses isn_arg.tryref
127
130
ISN_THROW, // pop value of stack, store in v:exception
@@ -240,6 +243,7 @@ typedef enum {
240
243
JUMP_ALWAYS,
241
244
JUMP_NEVER,
242
245
JUMP_IF_FALSE, // pop and jump if false
246
+ JUMP_WHILE_FALSE, // pop and jump if false for :while
243
247
JUMP_AND_KEEP_IF_TRUE, // jump if top of stack is truthy, drop if not
244
248
JUMP_IF_COND_TRUE, // jump if top of stack is true, drop if not
245
249
JUMP_IF_COND_FALSE, // jump if top of stack is false, drop if not
@@ -263,6 +267,19 @@ typedef struct {
263
267
int for_end; // position to jump to after done
264
268
} forloop_T;
265
269
270
+ // arguments to ISN_WHILE
271
+ typedef struct {
272
+ int while_funcref_idx; // variable index for funcref count
273
+ int while_end; // position to jump to after done
274
+ } whileloop_T;
275
+
276
+ // arguments to ISN_ENDLOOP
277
+ typedef struct {
278
+ short end_funcref_idx; // variable index of funcrefs.ga_len
279
+ short end_var_idx; // first variable declared in the loop
280
+ short end_var_count; // number of variables declared in the loop
281
+ } endloop_T;
282
+
266
283
// indirect arguments to ISN_TRY
267
284
typedef struct {
268
285
int try_catch; // position to jump to on throw
@@ -446,6 +463,8 @@ struct isn_S {
446
463
jump_T jump;
447
464
jumparg_T jumparg;
448
465
forloop_T forloop;
466
+ whileloop_T whileloop;
467
+ endloop_T endloop;
449
468
try_T tryref;
450
469
trycont_T trycont;
451
470
cbfunc_T bfunc;
@@ -597,6 +616,9 @@ typedef struct {
597
616
typedef struct {
598
617
int ws_top_label; // instruction idx at WHILE
599
618
endlabel_T *ws_end_label; // instructions to set end
619
+ int ws_funcref_idx; // index of var that holds funcref count
620
+ int ws_local_count; // ctx_locals.ga_len at :while
621
+ int ws_closure_count; // ctx_closure_count at :while
600
622
} whilescope_T;
601
623
602
624
/*
@@ -605,6 +627,9 @@ typedef struct {
605
627
typedef struct {
606
628
int fs_top_label; // instruction idx at FOR
607
629
endlabel_T *fs_end_label; // break instructions
630
+ int fs_funcref_idx; // index of var that holds funcref count
631
+ int fs_local_count; // ctx_locals.ga_len at :for
632
+ int fs_closure_count; // ctx_closure_count at :for
608
633
} forscope_T;
609
634
610
635
/*
@@ -726,8 +751,10 @@ struct cctx_S {
726
751
727
752
garray_T ctx_locals; // currently visible local variables
728
753
729
- int ctx_has_closure; // set to one if a closure was created in
730
- // the function
754
+ int ctx_has_closure; // set to one if a FUNCREF was used in the
755
+ // function
756
+ int ctx_closure_count; // incremented for each closure created in
757
+ // the function.
731
758
732
759
skip_T ctx_skip;
733
760
scope_T *ctx_scope; // current scope, NULL at toplevel
0 commit comments