blob: d82efe94e53aa20f098e6a26ac2907745ece59a1 [file] [log] [blame]
Bram Moolenaardc7c3662021-12-20 15:04:29 +00001/* vi:set ts=8 sts=4 sw=4 noet:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * vim9instr.c: Dealing with instructions of a compiled function
12 */
13
14#define USING_FLOAT_STUFF
15#include "vim.h"
16
17#if defined(FEAT_EVAL) || defined(PROTO)
18
19// When not generating protos this is included in proto.h
20#ifdef PROTO
21# include "vim9.h"
22#endif
23
24
25/////////////////////////////////////////////////////////////////////
26// Following generate_ functions expect the caller to call ga_grow().
27
28#define RETURN_NULL_IF_SKIP(cctx) if (cctx->ctx_skip == SKIP_YES) return NULL
29#define RETURN_OK_IF_SKIP(cctx) if (cctx->ctx_skip == SKIP_YES) return OK
30
31/*
32 * Generate an instruction without arguments.
33 * Returns a pointer to the new instruction, NULL if failed.
34 */
35 isn_T *
36generate_instr(cctx_T *cctx, isntype_T isn_type)
37{
38 garray_T *instr = &cctx->ctx_instr;
39 isn_T *isn;
40
41 RETURN_NULL_IF_SKIP(cctx);
42 if (GA_GROW_FAILS(instr, 1))
43 return NULL;
44 isn = ((isn_T *)instr->ga_data) + instr->ga_len;
45 isn->isn_type = isn_type;
46 isn->isn_lnum = cctx->ctx_lnum + 1;
47 ++instr->ga_len;
48
49 return isn;
50}
51
52/*
53 * Generate an instruction without arguments.
54 * "drop" will be removed from the stack.
55 * Returns a pointer to the new instruction, NULL if failed.
56 */
57 isn_T *
58generate_instr_drop(cctx_T *cctx, isntype_T isn_type, int drop)
59{
60 garray_T *stack = &cctx->ctx_type_stack;
61
62 RETURN_NULL_IF_SKIP(cctx);
63 stack->ga_len -= drop;
64 return generate_instr(cctx, isn_type);
65}
66
67/*
68 * Generate instruction "isn_type" and put "type" on the type stack.
69 */
70 isn_T *
71generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type)
72{
73 isn_T *isn;
74 garray_T *stack = &cctx->ctx_type_stack;
75
76 if ((isn = generate_instr(cctx, isn_type)) == NULL)
77 return NULL;
78
79 if (GA_GROW_FAILS(stack, 1))
80 return NULL;
81 ((type_T **)stack->ga_data)[stack->ga_len] = type == NULL ? &t_any : type;
82 ++stack->ga_len;
83
84 return isn;
85}
86
87/*
88 * Generate an ISN_DEBUG instruction.
89 */
90 isn_T *
91generate_instr_debug(cctx_T *cctx)
92{
93 isn_T *isn;
94 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
95 + cctx->ctx_ufunc->uf_dfunc_idx;
96
97 if ((isn = generate_instr(cctx, ISN_DEBUG)) == NULL)
98 return NULL;
99 isn->isn_arg.debug.dbg_var_names_len = dfunc->df_var_names.ga_len;
100 isn->isn_arg.debug.dbg_break_lnum = cctx->ctx_prev_lnum;
101 return isn;
102}
103
104/*
105 * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING.
106 * But only for simple types.
107 * When "tolerant" is TRUE convert most types to string, e.g. a List.
108 */
109 int
110may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
111{
112 isn_T *isn;
113 isntype_T isntype = ISN_2STRING;
114 garray_T *stack = &cctx->ctx_type_stack;
115 type_T **type;
116
117 RETURN_OK_IF_SKIP(cctx);
118 type = ((type_T **)stack->ga_data) + stack->ga_len + offset;
119 switch ((*type)->tt_type)
120 {
121 // nothing to be done
122 case VAR_STRING: return OK;
123
124 // conversion possible
125 case VAR_SPECIAL:
126 case VAR_BOOL:
127 case VAR_NUMBER:
128 case VAR_FLOAT:
129 break;
130
131 // conversion possible (with runtime check)
132 case VAR_ANY:
133 case VAR_UNKNOWN:
134 isntype = ISN_2STRING_ANY;
135 break;
136
137 // conversion possible when tolerant
138 case VAR_LIST:
139 if (tolerant)
140 {
141 isntype = ISN_2STRING_ANY;
142 break;
143 }
144 // FALLTHROUGH
145
146 // conversion not possible
147 case VAR_VOID:
148 case VAR_BLOB:
149 case VAR_FUNC:
150 case VAR_PARTIAL:
151 case VAR_DICT:
152 case VAR_JOB:
153 case VAR_CHANNEL:
154 case VAR_INSTR:
155 to_string_error((*type)->tt_type);
156 return FAIL;
157 }
158
159 *type = &t_string;
160 if ((isn = generate_instr(cctx, isntype)) == NULL)
161 return FAIL;
162 isn->isn_arg.tostring.offset = offset;
163 isn->isn_arg.tostring.tolerant = tolerant;
164
165 return OK;
166}
167
168 static int
169check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
170{
171 if (!((type1 == VAR_NUMBER || type1 == VAR_FLOAT || type1 == VAR_ANY)
172 && (type2 == VAR_NUMBER || type2 == VAR_FLOAT
173 || type2 == VAR_ANY)))
174 {
175 if (*op == '+')
176 emsg(_(e_wrong_argument_type_for_plus));
177 else
178 semsg(_(e_char_requires_number_or_float_arguments), *op);
179 return FAIL;
180 }
181 return OK;
182}
183
184/*
185 * Generate instruction for "+". For a list this creates a new list.
186 */
187 int
188generate_add_instr(
189 cctx_T *cctx,
190 vartype_T vartype,
191 type_T *type1,
192 type_T *type2,
193 exprtype_T expr_type)
194{
195 garray_T *stack = &cctx->ctx_type_stack;
196 isn_T *isn = generate_instr_drop(cctx,
197 vartype == VAR_NUMBER ? ISN_OPNR
198 : vartype == VAR_LIST ? ISN_ADDLIST
199 : vartype == VAR_BLOB ? ISN_ADDBLOB
200#ifdef FEAT_FLOAT
201 : vartype == VAR_FLOAT ? ISN_OPFLOAT
202#endif
203 : ISN_OPANY, 1);
204
205 if (vartype != VAR_LIST && vartype != VAR_BLOB
206 && type1->tt_type != VAR_ANY
207 && type2->tt_type != VAR_ANY
208 && check_number_or_float(
209 type1->tt_type, type2->tt_type, (char_u *)"+") == FAIL)
210 return FAIL;
211
212 if (isn != NULL)
213 {
214 if (isn->isn_type == ISN_ADDLIST)
215 isn->isn_arg.op.op_type = expr_type;
216 else
217 isn->isn_arg.op.op_type = EXPR_ADD;
218 }
219
220 // When concatenating two lists with different member types the member type
221 // becomes "any".
222 if (vartype == VAR_LIST
223 && type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST
224 && type1->tt_member != type2->tt_member)
225 (((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any;
226
227 return isn == NULL ? FAIL : OK;
228}
229
230/*
231 * Get the type to use for an instruction for an operation on "type1" and
232 * "type2". If they are matching use a type-specific instruction. Otherwise
233 * fall back to runtime type checking.
234 */
235 vartype_T
236operator_type(type_T *type1, type_T *type2)
237{
238 if (type1->tt_type == type2->tt_type
239 && (type1->tt_type == VAR_NUMBER
240 || type1->tt_type == VAR_LIST
241#ifdef FEAT_FLOAT
242 || type1->tt_type == VAR_FLOAT
243#endif
244 || type1->tt_type == VAR_BLOB))
245 return type1->tt_type;
246 return VAR_ANY;
247}
248
249/*
250 * Generate an instruction with two arguments. The instruction depends on the
251 * type of the arguments.
252 */
253 int
254generate_two_op(cctx_T *cctx, char_u *op)
255{
256 garray_T *stack = &cctx->ctx_type_stack;
257 type_T *type1;
258 type_T *type2;
259 vartype_T vartype;
260 isn_T *isn;
261
262 RETURN_OK_IF_SKIP(cctx);
263
264 // Get the known type of the two items on the stack.
265 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2];
266 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1];
267 vartype = operator_type(type1, type2);
268
269 switch (*op)
270 {
271 case '+':
272 if (generate_add_instr(cctx, vartype, type1, type2,
273 EXPR_COPY) == FAIL)
274 return FAIL;
275 break;
276
277 case '-':
278 case '*':
279 case '/': if (check_number_or_float(type1->tt_type, type2->tt_type,
280 op) == FAIL)
281 return FAIL;
282 if (vartype == VAR_NUMBER)
283 isn = generate_instr_drop(cctx, ISN_OPNR, 1);
284#ifdef FEAT_FLOAT
285 else if (vartype == VAR_FLOAT)
286 isn = generate_instr_drop(cctx, ISN_OPFLOAT, 1);
287#endif
288 else
289 isn = generate_instr_drop(cctx, ISN_OPANY, 1);
290 if (isn != NULL)
291 isn->isn_arg.op.op_type = *op == '*'
292 ? EXPR_MULT : *op == '/'? EXPR_DIV : EXPR_SUB;
293 break;
294
295 case '%': if ((type1->tt_type != VAR_ANY
296 && type1->tt_type != VAR_NUMBER)
297 || (type2->tt_type != VAR_ANY
298 && type2->tt_type != VAR_NUMBER))
299 {
300 emsg(_(e_percent_requires_number_arguments));
301 return FAIL;
302 }
303 isn = generate_instr_drop(cctx,
304 vartype == VAR_NUMBER ? ISN_OPNR : ISN_OPANY, 1);
305 if (isn != NULL)
306 isn->isn_arg.op.op_type = EXPR_REM;
307 break;
308 }
309
310 // correct type of result
311 if (vartype == VAR_ANY)
312 {
313 type_T *type = &t_any;
314
315#ifdef FEAT_FLOAT
316 // float+number and number+float results in float
317 if ((type1->tt_type == VAR_NUMBER || type1->tt_type == VAR_FLOAT)
318 && (type2->tt_type == VAR_NUMBER || type2->tt_type == VAR_FLOAT))
319 type = &t_float;
320#endif
321 ((type_T **)stack->ga_data)[stack->ga_len - 1] = type;
322 }
323
324 return OK;
325}
326
327/*
328 * Get the instruction to use for comparing "type1" with "type2"
329 * Return ISN_DROP when failed.
330 */
331 static isntype_T
332get_compare_isn(exprtype_T exprtype, vartype_T type1, vartype_T type2)
333{
334 isntype_T isntype = ISN_DROP;
335
336 if (type1 == VAR_UNKNOWN)
337 type1 = VAR_ANY;
338 if (type2 == VAR_UNKNOWN)
339 type2 = VAR_ANY;
340
341 if (type1 == type2)
342 {
343 switch (type1)
344 {
345 case VAR_BOOL: isntype = ISN_COMPAREBOOL; break;
346 case VAR_SPECIAL: isntype = ISN_COMPARESPECIAL; break;
347 case VAR_NUMBER: isntype = ISN_COMPARENR; break;
348 case VAR_FLOAT: isntype = ISN_COMPAREFLOAT; break;
349 case VAR_STRING: isntype = ISN_COMPARESTRING; break;
350 case VAR_BLOB: isntype = ISN_COMPAREBLOB; break;
351 case VAR_LIST: isntype = ISN_COMPARELIST; break;
352 case VAR_DICT: isntype = ISN_COMPAREDICT; break;
353 case VAR_FUNC: isntype = ISN_COMPAREFUNC; break;
354 default: isntype = ISN_COMPAREANY; break;
355 }
356 }
357 else if (type1 == VAR_ANY || type2 == VAR_ANY
358 || ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
359 && (type2 == VAR_NUMBER || type2 == VAR_FLOAT)))
360 isntype = ISN_COMPAREANY;
361
362 if ((exprtype == EXPR_IS || exprtype == EXPR_ISNOT)
363 && (isntype == ISN_COMPAREBOOL
364 || isntype == ISN_COMPARESPECIAL
365 || isntype == ISN_COMPARENR
366 || isntype == ISN_COMPAREFLOAT))
367 {
368 semsg(_(e_cannot_use_str_with_str),
369 exprtype == EXPR_IS ? "is" : "isnot" , vartype_name(type1));
370 return ISN_DROP;
371 }
372 if (isntype == ISN_DROP
373 || ((exprtype != EXPR_EQUAL && exprtype != EXPR_NEQUAL
374 && (type1 == VAR_BOOL || type1 == VAR_SPECIAL
375 || type2 == VAR_BOOL || type2 == VAR_SPECIAL)))
376 || ((exprtype != EXPR_EQUAL && exprtype != EXPR_NEQUAL
377 && exprtype != EXPR_IS && exprtype != EXPR_ISNOT
378 && (type1 == VAR_BLOB || type2 == VAR_BLOB
379 || type1 == VAR_LIST || type2 == VAR_LIST))))
380 {
381 semsg(_(e_cannot_compare_str_with_str),
382 vartype_name(type1), vartype_name(type2));
383 return ISN_DROP;
384 }
385 return isntype;
386}
387
388 int
389check_compare_types(exprtype_T type, typval_T *tv1, typval_T *tv2)
390{
391 if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP)
392 return FAIL;
393 return OK;
394}
395
396/*
397 * Generate an ISN_COMPARE* instruction with a boolean result.
398 */
399 int
400generate_COMPARE(cctx_T *cctx, exprtype_T exprtype, int ic)
401{
402 isntype_T isntype;
403 isn_T *isn;
404 garray_T *stack = &cctx->ctx_type_stack;
405 vartype_T type1;
406 vartype_T type2;
407
408 RETURN_OK_IF_SKIP(cctx);
409
410 // Get the known type of the two items on the stack. If they are matching
411 // use a type-specific instruction. Otherwise fall back to runtime type
412 // checking.
413 type1 = ((type_T **)stack->ga_data)[stack->ga_len - 2]->tt_type;
414 type2 = ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type;
415 isntype = get_compare_isn(exprtype, type1, type2);
416 if (isntype == ISN_DROP)
417 return FAIL;
418
419 if ((isn = generate_instr(cctx, isntype)) == NULL)
420 return FAIL;
421 isn->isn_arg.op.op_type = exprtype;
422 isn->isn_arg.op.op_ic = ic;
423
424 // takes two arguments, puts one bool back
425 if (stack->ga_len >= 2)
426 {
427 --stack->ga_len;
428 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
429 }
430
431 return OK;
432}
433
434/*
435 * Generate an ISN_2BOOL instruction.
436 * "offset" is the offset in the type stack.
437 */
438 int
439generate_2BOOL(cctx_T *cctx, int invert, int offset)
440{
441 isn_T *isn;
442 garray_T *stack = &cctx->ctx_type_stack;
443
444 RETURN_OK_IF_SKIP(cctx);
445 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL)
446 return FAIL;
447 isn->isn_arg.tobool.invert = invert;
448 isn->isn_arg.tobool.offset = offset;
449
450 // type becomes bool
451 ((type_T **)stack->ga_data)[stack->ga_len + offset] = &t_bool;
452
453 return OK;
454}
455
456/*
457 * Generate an ISN_COND2BOOL instruction.
458 */
459 int
460generate_COND2BOOL(cctx_T *cctx)
461{
462 isn_T *isn;
463 garray_T *stack = &cctx->ctx_type_stack;
464
465 RETURN_OK_IF_SKIP(cctx);
466 if ((isn = generate_instr(cctx, ISN_COND2BOOL)) == NULL)
467 return FAIL;
468
469 // type becomes bool
470 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool;
471
472 return OK;
473}
474
475 int
476generate_TYPECHECK(
477 cctx_T *cctx,
478 type_T *expected,
479 int offset,
480 int argidx)
481{
482 isn_T *isn;
483 garray_T *stack = &cctx->ctx_type_stack;
484
485 RETURN_OK_IF_SKIP(cctx);
486 if ((isn = generate_instr(cctx, ISN_CHECKTYPE)) == NULL)
487 return FAIL;
488 isn->isn_arg.type.ct_type = alloc_type(expected);
489 isn->isn_arg.type.ct_off = (int8_T)offset;
490 isn->isn_arg.type.ct_arg_idx = (int8_T)argidx;
491
492 // type becomes expected
493 ((type_T **)stack->ga_data)[stack->ga_len + offset] = expected;
494
495 return OK;
496}
497
498 int
499generate_SETTYPE(
500 cctx_T *cctx,
501 type_T *expected)
502{
503 isn_T *isn;
504
505 RETURN_OK_IF_SKIP(cctx);
506 if ((isn = generate_instr(cctx, ISN_SETTYPE)) == NULL)
507 return FAIL;
508 isn->isn_arg.type.ct_type = alloc_type(expected);
509 return OK;
510}
511
512/*
513 * Generate a PUSH instruction for "tv".
514 * "tv" will be consumed or cleared.
515 * Nothing happens if "tv" is NULL or of type VAR_UNKNOWN;
516 */
517 int
518generate_tv_PUSH(cctx_T *cctx, typval_T *tv)
519{
520 if (tv != NULL)
521 {
522 switch (tv->v_type)
523 {
524 case VAR_UNKNOWN:
525 break;
526 case VAR_BOOL:
527 generate_PUSHBOOL(cctx, tv->vval.v_number);
528 break;
529 case VAR_SPECIAL:
530 generate_PUSHSPEC(cctx, tv->vval.v_number);
531 break;
532 case VAR_NUMBER:
533 generate_PUSHNR(cctx, tv->vval.v_number);
534 break;
535#ifdef FEAT_FLOAT
536 case VAR_FLOAT:
537 generate_PUSHF(cctx, tv->vval.v_float);
538 break;
539#endif
540 case VAR_BLOB:
541 generate_PUSHBLOB(cctx, tv->vval.v_blob);
542 tv->vval.v_blob = NULL;
543 break;
544 case VAR_STRING:
545 generate_PUSHS(cctx, &tv->vval.v_string);
546 tv->vval.v_string = NULL;
547 break;
548 default:
549 iemsg("constant type not supported");
550 clear_tv(tv);
551 return FAIL;
552 }
553 tv->v_type = VAR_UNKNOWN;
554 }
555 return OK;
556}
557
558/*
559 * Generate an ISN_PUSHNR instruction.
560 */
561 int
562generate_PUSHNR(cctx_T *cctx, varnumber_T number)
563{
564 isn_T *isn;
565 garray_T *stack = &cctx->ctx_type_stack;
566
567 RETURN_OK_IF_SKIP(cctx);
568 if ((isn = generate_instr_type(cctx, ISN_PUSHNR, &t_number)) == NULL)
569 return FAIL;
570 isn->isn_arg.number = number;
571
572 if (number == 0 || number == 1)
573 // A 0 or 1 number can also be used as a bool.
574 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_number_bool;
575 return OK;
576}
577
578/*
579 * Generate an ISN_PUSHBOOL instruction.
580 */
581 int
582generate_PUSHBOOL(cctx_T *cctx, varnumber_T number)
583{
584 isn_T *isn;
585
586 RETURN_OK_IF_SKIP(cctx);
587 if ((isn = generate_instr_type(cctx, ISN_PUSHBOOL, &t_bool)) == NULL)
588 return FAIL;
589 isn->isn_arg.number = number;
590
591 return OK;
592}
593
594/*
595 * Generate an ISN_PUSHSPEC instruction.
596 */
597 int
598generate_PUSHSPEC(cctx_T *cctx, varnumber_T number)
599{
600 isn_T *isn;
601
602 RETURN_OK_IF_SKIP(cctx);
603 if ((isn = generate_instr_type(cctx, ISN_PUSHSPEC, &t_special)) == NULL)
604 return FAIL;
605 isn->isn_arg.number = number;
606
607 return OK;
608}
609
610#if defined(FEAT_FLOAT) || defined(PROTO)
611/*
612 * Generate an ISN_PUSHF instruction.
613 */
614 int
615generate_PUSHF(cctx_T *cctx, float_T fnumber)
616{
617 isn_T *isn;
618
619 RETURN_OK_IF_SKIP(cctx);
620 if ((isn = generate_instr_type(cctx, ISN_PUSHF, &t_float)) == NULL)
621 return FAIL;
622 isn->isn_arg.fnumber = fnumber;
623
624 return OK;
625}
626#endif
627
628/*
629 * Generate an ISN_PUSHS instruction.
630 * Consumes "*str". When freed *str is set to NULL, unless "str" is NULL.
631 */
632 int
633generate_PUSHS(cctx_T *cctx, char_u **str)
634{
635 isn_T *isn;
636
637 if (cctx->ctx_skip == SKIP_YES)
638 {
639 if (str != NULL)
640 VIM_CLEAR(*str);
641 return OK;
642 }
643 if ((isn = generate_instr_type(cctx, ISN_PUSHS, &t_string)) == NULL)
644 {
645 if (str != NULL)
646 VIM_CLEAR(*str);
647 return FAIL;
648 }
649 isn->isn_arg.string = str == NULL ? NULL : *str;
650
651 return OK;
652}
653
654/*
655 * Generate an ISN_PUSHCHANNEL instruction.
656 * Consumes "channel".
657 */
658 int
659generate_PUSHCHANNEL(cctx_T *cctx, channel_T *channel)
660{
661 isn_T *isn;
662
663 RETURN_OK_IF_SKIP(cctx);
664 if ((isn = generate_instr_type(cctx, ISN_PUSHCHANNEL, &t_channel)) == NULL)
665 return FAIL;
666 isn->isn_arg.channel = channel;
667
668 return OK;
669}
670
671/*
672 * Generate an ISN_PUSHJOB instruction.
673 * Consumes "job".
674 */
675 int
676generate_PUSHJOB(cctx_T *cctx, job_T *job)
677{
678 isn_T *isn;
679
680 RETURN_OK_IF_SKIP(cctx);
681 if ((isn = generate_instr_type(cctx, ISN_PUSHJOB, &t_channel)) == NULL)
682 return FAIL;
683 isn->isn_arg.job = job;
684
685 return OK;
686}
687
688/*
689 * Generate an ISN_PUSHBLOB instruction.
690 * Consumes "blob".
691 */
692 int
693generate_PUSHBLOB(cctx_T *cctx, blob_T *blob)
694{
695 isn_T *isn;
696
697 RETURN_OK_IF_SKIP(cctx);
698 if ((isn = generate_instr_type(cctx, ISN_PUSHBLOB, &t_blob)) == NULL)
699 return FAIL;
700 isn->isn_arg.blob = blob;
701
702 return OK;
703}
704
705/*
706 * Generate an ISN_PUSHFUNC instruction with name "name".
707 * Consumes "name".
708 */
709 int
710generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type)
711{
712 isn_T *isn;
713 char_u *funcname;
714
715 RETURN_OK_IF_SKIP(cctx);
716 if ((isn = generate_instr_type(cctx, ISN_PUSHFUNC, type)) == NULL)
717 return FAIL;
718 if (name == NULL)
719 funcname = NULL;
720 else if (*name == K_SPECIAL) // script-local
721 funcname = vim_strsave(name);
722 else
723 {
724 funcname = alloc(STRLEN(name) + 3);
725 if (funcname != NULL)
726 {
727 STRCPY(funcname, "g:");
728 STRCPY(funcname + 2, name);
729 }
730 }
731
732 isn->isn_arg.string = funcname;
733 return OK;
734}
735
736/*
737 * Generate an ISN_GETITEM instruction with "index".
738 * "with_op" is TRUE for "+=" and other operators, the stack has the current
739 * value below the list with values.
740 */
741 int
742generate_GETITEM(cctx_T *cctx, int index, int with_op)
743{
744 isn_T *isn;
745 garray_T *stack = &cctx->ctx_type_stack;
746 type_T *type = ((type_T **)stack->ga_data)[stack->ga_len
747 - (with_op ? 2 : 1)];
748 type_T *item_type = &t_any;
749
750 RETURN_OK_IF_SKIP(cctx);
751
752 if (type->tt_type != VAR_LIST)
753 {
754 // cannot happen, caller has checked the type
755 emsg(_(e_listreq));
756 return FAIL;
757 }
758 item_type = type->tt_member;
759 if ((isn = generate_instr(cctx, ISN_GETITEM)) == NULL)
760 return FAIL;
761 isn->isn_arg.getitem.gi_index = index;
762 isn->isn_arg.getitem.gi_with_op = with_op;
763
764 // add the item type to the type stack
765 if (GA_GROW_FAILS(stack, 1))
766 return FAIL;
767 ((type_T **)stack->ga_data)[stack->ga_len] = item_type;
768 ++stack->ga_len;
769 return OK;
770}
771
772/*
773 * Generate an ISN_SLICE instruction with "count".
774 */
775 int
776generate_SLICE(cctx_T *cctx, int count)
777{
778 isn_T *isn;
779
780 RETURN_OK_IF_SKIP(cctx);
781 if ((isn = generate_instr(cctx, ISN_SLICE)) == NULL)
782 return FAIL;
783 isn->isn_arg.number = count;
784 return OK;
785}
786
787/*
788 * Generate an ISN_CHECKLEN instruction with "min_len".
789 */
790 int
791generate_CHECKLEN(cctx_T *cctx, int min_len, int more_OK)
792{
793 isn_T *isn;
794
795 RETURN_OK_IF_SKIP(cctx);
796
797 if ((isn = generate_instr(cctx, ISN_CHECKLEN)) == NULL)
798 return FAIL;
799 isn->isn_arg.checklen.cl_min_len = min_len;
800 isn->isn_arg.checklen.cl_more_OK = more_OK;
801
802 return OK;
803}
804
805/*
806 * Generate an ISN_STORE instruction.
807 */
808 int
809generate_STORE(cctx_T *cctx, isntype_T isn_type, int idx, char_u *name)
810{
811 isn_T *isn;
812
813 RETURN_OK_IF_SKIP(cctx);
814 if ((isn = generate_instr_drop(cctx, isn_type, 1)) == NULL)
815 return FAIL;
816 if (name != NULL)
817 isn->isn_arg.string = vim_strsave(name);
818 else
819 isn->isn_arg.number = idx;
820
821 return OK;
822}
823
824/*
825 * Generate an ISN_STOREOUTER instruction.
826 */
827 int
828generate_STOREOUTER(cctx_T *cctx, int idx, int level)
829{
830 isn_T *isn;
831
832 RETURN_OK_IF_SKIP(cctx);
833 if ((isn = generate_instr_drop(cctx, ISN_STOREOUTER, 1)) == NULL)
834 return FAIL;
835 isn->isn_arg.outer.outer_idx = idx;
836 isn->isn_arg.outer.outer_depth = level;
837
838 return OK;
839}
840
841/*
842 * Generate an ISN_STORENR instruction (short for ISN_PUSHNR + ISN_STORE)
843 */
844 int
845generate_STORENR(cctx_T *cctx, int idx, varnumber_T value)
846{
847 isn_T *isn;
848
849 RETURN_OK_IF_SKIP(cctx);
850 if ((isn = generate_instr(cctx, ISN_STORENR)) == NULL)
851 return FAIL;
852 isn->isn_arg.storenr.stnr_idx = idx;
853 isn->isn_arg.storenr.stnr_val = value;
854
855 return OK;
856}
857
858/*
859 * Generate an ISN_STOREOPT or ISN_STOREFUNCOPT instruction
860 */
861 int
862generate_STOREOPT(
863 cctx_T *cctx,
864 isntype_T isn_type,
865 char_u *name,
866 int opt_flags)
867{
868 isn_T *isn;
869
870 RETURN_OK_IF_SKIP(cctx);
871 if ((isn = generate_instr_drop(cctx, isn_type, 1)) == NULL)
872 return FAIL;
873 isn->isn_arg.storeopt.so_name = vim_strsave(name);
874 isn->isn_arg.storeopt.so_flags = opt_flags;
875
876 return OK;
877}
878
879/*
880 * Generate an ISN_LOAD or similar instruction.
881 */
882 int
883generate_LOAD(
884 cctx_T *cctx,
885 isntype_T isn_type,
886 int idx,
887 char_u *name,
888 type_T *type)
889{
890 isn_T *isn;
891
892 RETURN_OK_IF_SKIP(cctx);
893 if ((isn = generate_instr_type(cctx, isn_type, type)) == NULL)
894 return FAIL;
895 if (name != NULL)
896 isn->isn_arg.string = vim_strsave(name);
897 else
898 isn->isn_arg.number = idx;
899
900 return OK;
901}
902
903/*
904 * Generate an ISN_LOADOUTER instruction
905 */
906 int
907generate_LOADOUTER(
908 cctx_T *cctx,
909 int idx,
910 int nesting,
911 type_T *type)
912{
913 isn_T *isn;
914
915 RETURN_OK_IF_SKIP(cctx);
916 if ((isn = generate_instr_type(cctx, ISN_LOADOUTER, type)) == NULL)
917 return FAIL;
918 isn->isn_arg.outer.outer_idx = idx;
919 isn->isn_arg.outer.outer_depth = nesting;
920
921 return OK;
922}
923
924/*
925 * Generate an ISN_LOADV instruction for v:var.
926 */
927 int
928generate_LOADV(
929 cctx_T *cctx,
930 char_u *name,
931 int error)
932{
933 int di_flags;
934 int vidx = find_vim_var(name, &di_flags);
935 type_T *type;
936
937 RETURN_OK_IF_SKIP(cctx);
938 if (vidx < 0)
939 {
940 if (error)
941 semsg(_(e_variable_not_found_str), name);
942 return FAIL;
943 }
944 type = typval2type_vimvar(get_vim_var_tv(vidx), cctx->ctx_type_list);
945
946 return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, type);
947}
948
949/*
950 * Generate an ISN_UNLET instruction.
951 */
952 int
953generate_UNLET(cctx_T *cctx, isntype_T isn_type, char_u *name, int forceit)
954{
955 isn_T *isn;
956
957 RETURN_OK_IF_SKIP(cctx);
958 if ((isn = generate_instr(cctx, isn_type)) == NULL)
959 return FAIL;
960 isn->isn_arg.unlet.ul_name = vim_strsave(name);
961 isn->isn_arg.unlet.ul_forceit = forceit;
962
963 return OK;
964}
965
966/*
967 * Generate an ISN_LOCKCONST instruction.
968 */
969 int
970generate_LOCKCONST(cctx_T *cctx)
971{
972 isn_T *isn;
973
974 RETURN_OK_IF_SKIP(cctx);
975 if ((isn = generate_instr(cctx, ISN_LOCKCONST)) == NULL)
976 return FAIL;
977 return OK;
978}
979
980/*
981 * Generate an ISN_LOADS instruction.
982 */
983 int
984generate_OLDSCRIPT(
985 cctx_T *cctx,
986 isntype_T isn_type,
987 char_u *name,
988 int sid,
989 type_T *type)
990{
991 isn_T *isn;
992
993 RETURN_OK_IF_SKIP(cctx);
994 if (isn_type == ISN_LOADS)
995 isn = generate_instr_type(cctx, isn_type, type);
996 else
997 isn = generate_instr_drop(cctx, isn_type, 1);
998 if (isn == NULL)
999 return FAIL;
1000 isn->isn_arg.loadstore.ls_name = vim_strsave(name);
1001 isn->isn_arg.loadstore.ls_sid = sid;
1002
1003 return OK;
1004}
1005
1006/*
1007 * Generate an ISN_LOADSCRIPT or ISN_STORESCRIPT instruction.
1008 */
1009 int
1010generate_VIM9SCRIPT(
1011 cctx_T *cctx,
1012 isntype_T isn_type,
1013 int sid,
1014 int idx,
1015 type_T *type)
1016{
1017 isn_T *isn;
1018 scriptref_T *sref;
1019 scriptitem_T *si = SCRIPT_ITEM(sid);
1020
1021 RETURN_OK_IF_SKIP(cctx);
1022 if (isn_type == ISN_LOADSCRIPT)
1023 isn = generate_instr_type(cctx, isn_type, type);
1024 else
1025 isn = generate_instr_drop(cctx, isn_type, 1);
1026 if (isn == NULL)
1027 return FAIL;
1028
1029 // This requires three arguments, which doesn't fit in an instruction, thus
1030 // we need to allocate a struct for this.
1031 sref = ALLOC_ONE(scriptref_T);
1032 if (sref == NULL)
1033 return FAIL;
1034 isn->isn_arg.script.scriptref = sref;
1035 sref->sref_sid = sid;
1036 sref->sref_idx = idx;
1037 sref->sref_seq = si->sn_script_seq;
1038 sref->sref_type = type;
1039 return OK;
1040}
1041
1042/*
1043 * Generate an ISN_NEWLIST instruction.
1044 */
1045 int
1046generate_NEWLIST(cctx_T *cctx, int count)
1047{
1048 isn_T *isn;
1049 garray_T *stack = &cctx->ctx_type_stack;
1050 type_T *type;
1051 type_T *member;
1052
1053 RETURN_OK_IF_SKIP(cctx);
1054 if ((isn = generate_instr(cctx, ISN_NEWLIST)) == NULL)
1055 return FAIL;
1056 isn->isn_arg.number = count;
1057
1058 // get the member type from all the items on the stack.
1059 if (count == 0)
1060 member = &t_unknown;
1061 else
1062 member = get_member_type_from_stack(
1063 ((type_T **)stack->ga_data) + stack->ga_len, count, 1,
1064 cctx->ctx_type_list);
1065 type = get_list_type(member, cctx->ctx_type_list);
1066
1067 // drop the value types
1068 stack->ga_len -= count;
1069
1070 // add the list type to the type stack
1071 if (GA_GROW_FAILS(stack, 1))
1072 return FAIL;
1073 ((type_T **)stack->ga_data)[stack->ga_len] = type;
1074 ++stack->ga_len;
1075
1076 return OK;
1077}
1078
1079/*
1080 * Generate an ISN_NEWDICT instruction.
1081 */
1082 int
1083generate_NEWDICT(cctx_T *cctx, int count)
1084{
1085 isn_T *isn;
1086 garray_T *stack = &cctx->ctx_type_stack;
1087 type_T *type;
1088 type_T *member;
1089
1090 RETURN_OK_IF_SKIP(cctx);
1091 if ((isn = generate_instr(cctx, ISN_NEWDICT)) == NULL)
1092 return FAIL;
1093 isn->isn_arg.number = count;
1094
1095 if (count == 0)
1096 member = &t_void;
1097 else
1098 member = get_member_type_from_stack(
1099 ((type_T **)stack->ga_data) + stack->ga_len, count, 2,
1100 cctx->ctx_type_list);
1101 type = get_dict_type(member, cctx->ctx_type_list);
1102
1103 // drop the key and value types
1104 stack->ga_len -= 2 * count;
1105
1106 // add the dict type to the type stack
1107 if (GA_GROW_FAILS(stack, 1))
1108 return FAIL;
1109 ((type_T **)stack->ga_data)[stack->ga_len] = type;
1110 ++stack->ga_len;
1111
1112 return OK;
1113}
1114
1115/*
1116 * Generate an ISN_FUNCREF instruction.
1117 */
1118 int
1119generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
1120{
1121 isn_T *isn;
1122 garray_T *stack = &cctx->ctx_type_stack;
1123
1124 RETURN_OK_IF_SKIP(cctx);
1125 if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL)
1126 return FAIL;
1127 if (ufunc->uf_def_status == UF_NOT_COMPILED)
1128 isn->isn_arg.funcref.fr_func_name = vim_strsave(ufunc->uf_name);
1129 else
1130 isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx;
1131 cctx->ctx_has_closure = 1;
1132
1133 // If the referenced function is a closure, it may use items further up in
1134 // the nested context, including this one.
1135 if (ufunc->uf_flags & FC_CLOSURE)
1136 cctx->ctx_ufunc->uf_flags |= FC_CLOSURE;
1137
1138 if (GA_GROW_FAILS(stack, 1))
1139 return FAIL;
1140 ((type_T **)stack->ga_data)[stack->ga_len] =
1141 ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type;
1142 ++stack->ga_len;
1143
1144 return OK;
1145}
1146
1147/*
1148 * Generate an ISN_NEWFUNC instruction.
1149 * "lambda_name" and "func_name" must be in allocated memory and will be
1150 * consumed.
1151 */
1152 int
1153generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name)
1154{
1155 isn_T *isn;
1156
1157 if (cctx->ctx_skip == SKIP_YES)
1158 {
1159 vim_free(lambda_name);
1160 vim_free(func_name);
1161 return OK;
1162 }
1163 if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL)
1164 {
1165 vim_free(lambda_name);
1166 vim_free(func_name);
1167 return FAIL;
1168 }
1169 isn->isn_arg.newfunc.nf_lambda = lambda_name;
1170 isn->isn_arg.newfunc.nf_global = func_name;
1171
1172 return OK;
1173}
1174
1175/*
1176 * Generate an ISN_DEF instruction: list functions
1177 */
1178 int
1179generate_DEF(cctx_T *cctx, char_u *name, size_t len)
1180{
1181 isn_T *isn;
1182
1183 RETURN_OK_IF_SKIP(cctx);
1184 if ((isn = generate_instr(cctx, ISN_DEF)) == NULL)
1185 return FAIL;
1186 if (len > 0)
1187 {
1188 isn->isn_arg.string = vim_strnsave(name, len);
1189 if (isn->isn_arg.string == NULL)
1190 return FAIL;
1191 }
1192 return OK;
1193}
1194
1195/*
1196 * Generate an ISN_JUMP instruction.
1197 */
1198 int
1199generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where)
1200{
1201 isn_T *isn;
1202 garray_T *stack = &cctx->ctx_type_stack;
1203
1204 RETURN_OK_IF_SKIP(cctx);
1205 if ((isn = generate_instr(cctx, ISN_JUMP)) == NULL)
1206 return FAIL;
1207 isn->isn_arg.jump.jump_when = when;
1208 isn->isn_arg.jump.jump_where = where;
1209
1210 if (when != JUMP_ALWAYS && stack->ga_len > 0)
1211 --stack->ga_len;
1212
1213 return OK;
1214}
1215
1216/*
1217 * Generate an ISN_JUMP_IF_ARG_SET instruction.
1218 */
1219 int
1220generate_JUMP_IF_ARG_SET(cctx_T *cctx, int arg_off)
1221{
1222 isn_T *isn;
1223
1224 RETURN_OK_IF_SKIP(cctx);
1225 if ((isn = generate_instr(cctx, ISN_JUMP_IF_ARG_SET)) == NULL)
1226 return FAIL;
1227 isn->isn_arg.jumparg.jump_arg_off = arg_off;
1228 // jump_where is set later
1229 return OK;
1230}
1231
1232 int
1233generate_FOR(cctx_T *cctx, int loop_idx)
1234{
1235 isn_T *isn;
1236 garray_T *stack = &cctx->ctx_type_stack;
1237
1238 RETURN_OK_IF_SKIP(cctx);
1239 if ((isn = generate_instr(cctx, ISN_FOR)) == NULL)
1240 return FAIL;
1241 isn->isn_arg.forloop.for_idx = loop_idx;
1242
1243 if (GA_GROW_FAILS(stack, 1))
1244 return FAIL;
1245 // type doesn't matter, will be stored next
1246 ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
1247 ++stack->ga_len;
1248
1249 return OK;
1250}
1251/*
1252 * Generate an ISN_TRYCONT instruction.
1253 */
1254 int
1255generate_TRYCONT(cctx_T *cctx, int levels, int where)
1256{
1257 isn_T *isn;
1258
1259 RETURN_OK_IF_SKIP(cctx);
1260 if ((isn = generate_instr(cctx, ISN_TRYCONT)) == NULL)
1261 return FAIL;
1262 isn->isn_arg.trycont.tct_levels = levels;
1263 isn->isn_arg.trycont.tct_where = where;
1264
1265 return OK;
1266}
1267
1268
1269/*
1270 * Generate an ISN_BCALL instruction.
1271 * "method_call" is TRUE for "value->method()"
1272 * Return FAIL if the number of arguments is wrong.
1273 */
1274 int
1275generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call)
1276{
1277 isn_T *isn;
1278 garray_T *stack = &cctx->ctx_type_stack;
1279 int argoff;
1280 type_T **argtypes = NULL;
1281 type_T *shuffled_argtypes[MAX_FUNC_ARGS];
1282 type_T *maptype = NULL;
1283
1284 RETURN_OK_IF_SKIP(cctx);
1285 argoff = check_internal_func(func_idx, argcount);
1286 if (argoff < 0)
1287 return FAIL;
1288
1289 if (method_call && argoff > 1)
1290 {
1291 if ((isn = generate_instr(cctx, ISN_SHUFFLE)) == NULL)
1292 return FAIL;
1293 isn->isn_arg.shuffle.shfl_item = argcount;
1294 isn->isn_arg.shuffle.shfl_up = argoff - 1;
1295 }
1296
1297 if (argcount > 0)
1298 {
1299 // Check the types of the arguments.
1300 argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount;
1301 if (method_call && argoff > 1)
1302 {
1303 int i;
1304
1305 for (i = 0; i < argcount; ++i)
1306 shuffled_argtypes[i] = (i < argoff - 1)
1307 ? argtypes[i + 1]
1308 : (i == argoff - 1) ? argtypes[0] : argtypes[i];
1309 argtypes = shuffled_argtypes;
1310 }
1311 if (internal_func_check_arg_types(argtypes, func_idx, argcount,
1312 cctx) == FAIL)
1313 return FAIL;
1314 if (internal_func_is_map(func_idx))
1315 maptype = *argtypes;
1316 }
1317
1318 if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL)
1319 return FAIL;
1320 isn->isn_arg.bfunc.cbf_idx = func_idx;
1321 isn->isn_arg.bfunc.cbf_argcount = argcount;
1322
1323 // Drop the argument types and push the return type.
1324 stack->ga_len -= argcount;
1325 if (GA_GROW_FAILS(stack, 1))
1326 return FAIL;
1327 ((type_T **)stack->ga_data)[stack->ga_len] =
1328 internal_func_ret_type(func_idx, argcount, argtypes);
1329 ++stack->ga_len;
1330
1331 if (maptype != NULL && maptype->tt_member != NULL
1332 && maptype->tt_member != &t_any)
1333 // Check that map() didn't change the item types.
1334 generate_TYPECHECK(cctx, maptype, -1, 1);
1335
1336 return OK;
1337}
1338
1339/*
1340 * Generate an ISN_LISTAPPEND instruction. Works like add().
1341 * Argument count is already checked.
1342 */
1343 int
1344generate_LISTAPPEND(cctx_T *cctx)
1345{
1346 garray_T *stack = &cctx->ctx_type_stack;
1347 type_T *list_type;
1348 type_T *item_type;
1349 type_T *expected;
1350
1351 // Caller already checked that list_type is a list.
1352 list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2];
1353 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1354 expected = list_type->tt_member;
1355 if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL)
1356 return FAIL;
1357
1358 if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
1359 return FAIL;
1360
1361 --stack->ga_len; // drop the argument
1362 return OK;
1363}
1364
1365/*
1366 * Generate an ISN_BLOBAPPEND instruction. Works like add().
1367 * Argument count is already checked.
1368 */
1369 int
1370generate_BLOBAPPEND(cctx_T *cctx)
1371{
1372 garray_T *stack = &cctx->ctx_type_stack;
1373 type_T *item_type;
1374
1375 // Caller already checked that blob_type is a blob.
1376 item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1377 if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
1378 return FAIL;
1379
1380 if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
1381 return FAIL;
1382
1383 --stack->ga_len; // drop the argument
1384 return OK;
1385}
1386
1387/*
1388 * Generate an ISN_DCALL or ISN_UCALL instruction.
1389 * Return FAIL if the number of arguments is wrong.
1390 */
1391 int
1392generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
1393{
1394 isn_T *isn;
1395 garray_T *stack = &cctx->ctx_type_stack;
1396 int regular_args = ufunc->uf_args.ga_len;
1397 int argcount = pushed_argcount;
1398
1399 RETURN_OK_IF_SKIP(cctx);
1400 if (argcount > regular_args && !has_varargs(ufunc))
1401 {
1402 semsg(_(e_too_many_arguments_for_function_str),
1403 printable_func_name(ufunc));
1404 return FAIL;
1405 }
1406 if (argcount < regular_args - ufunc->uf_def_args.ga_len)
1407 {
1408 semsg(_(e_not_enough_arguments_for_function_str),
1409 printable_func_name(ufunc));
1410 return FAIL;
1411 }
1412
1413 if (ufunc->uf_def_status != UF_NOT_COMPILED
1414 && ufunc->uf_def_status != UF_COMPILE_ERROR)
1415 {
1416 int i;
1417
1418 for (i = 0; i < argcount; ++i)
1419 {
1420 type_T *expected;
1421 type_T *actual;
1422
1423 actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
1424 if (actual == &t_special
1425 && i >= regular_args - ufunc->uf_def_args.ga_len)
1426 {
1427 // assume v:none used for default argument value
1428 continue;
1429 }
1430 if (i < regular_args)
1431 {
1432 if (ufunc->uf_arg_types == NULL)
1433 continue;
1434 expected = ufunc->uf_arg_types[i];
1435 }
1436 else if (ufunc->uf_va_type == NULL
1437 || ufunc->uf_va_type == &t_list_any)
1438 // possibly a lambda or "...: any"
1439 expected = &t_any;
1440 else
1441 expected = ufunc->uf_va_type->tt_member;
1442 if (need_type(actual, expected, -argcount + i, i + 1, cctx,
1443 TRUE, FALSE) == FAIL)
1444 {
1445 arg_type_mismatch(expected, actual, i + 1);
1446 return FAIL;
1447 }
1448 }
1449 if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
1450 && compile_def_function(ufunc, ufunc->uf_ret_type == NULL,
1451 COMPILE_TYPE(ufunc), NULL) == FAIL)
1452 return FAIL;
1453 }
1454 if (ufunc->uf_def_status == UF_COMPILE_ERROR)
1455 {
1456 emsg_funcname(_(e_call_to_function_that_failed_to_compile_str),
1457 ufunc->uf_name);
1458 return FAIL;
1459 }
1460
1461 if ((isn = generate_instr(cctx,
1462 ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL
1463 : ISN_UCALL)) == NULL)
1464 return FAIL;
1465 if (isn->isn_type == ISN_DCALL)
1466 {
1467 isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx;
1468 isn->isn_arg.dfunc.cdf_argcount = argcount;
1469 }
1470 else
1471 {
1472 // A user function may be deleted and redefined later, can't use the
1473 // ufunc pointer, need to look it up again at runtime.
1474 isn->isn_arg.ufunc.cuf_name = vim_strsave(ufunc->uf_name);
1475 isn->isn_arg.ufunc.cuf_argcount = argcount;
1476 }
1477
1478 stack->ga_len -= argcount; // drop the arguments
1479 if (GA_GROW_FAILS(stack, 1))
1480 return FAIL;
1481 // add return value
1482 ((type_T **)stack->ga_data)[stack->ga_len] = ufunc->uf_ret_type;
1483 ++stack->ga_len;
1484
1485 return OK;
1486}
1487
1488/*
1489 * Generate an ISN_UCALL instruction when the function isn't defined yet.
1490 */
1491 int
1492generate_UCALL(cctx_T *cctx, char_u *name, int argcount)
1493{
1494 isn_T *isn;
1495 garray_T *stack = &cctx->ctx_type_stack;
1496
1497 RETURN_OK_IF_SKIP(cctx);
1498 if ((isn = generate_instr(cctx, ISN_UCALL)) == NULL)
1499 return FAIL;
1500 isn->isn_arg.ufunc.cuf_name = vim_strsave(name);
1501 isn->isn_arg.ufunc.cuf_argcount = argcount;
1502
1503 stack->ga_len -= argcount; // drop the arguments
1504 if (GA_GROW_FAILS(stack, 1))
1505 return FAIL;
1506 // add return value
1507 ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
1508 ++stack->ga_len;
1509
1510 return OK;
1511}
1512
1513/*
1514 * Generate an ISN_PCALL instruction.
1515 * "type" is the type of the FuncRef.
1516 */
1517 int
1518generate_PCALL(
1519 cctx_T *cctx,
1520 int argcount,
1521 char_u *name,
1522 type_T *type,
1523 int at_top)
1524{
1525 isn_T *isn;
1526 garray_T *stack = &cctx->ctx_type_stack;
1527 type_T *ret_type;
1528
1529 RETURN_OK_IF_SKIP(cctx);
1530
1531 if (type->tt_type == VAR_ANY)
1532 ret_type = &t_any;
1533 else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
1534 {
1535 if (type->tt_argcount != -1)
1536 {
1537 int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
1538
1539 if (argcount < type->tt_min_argcount - varargs)
1540 {
1541 semsg(_(e_not_enough_arguments_for_function_str), name);
1542 return FAIL;
1543 }
1544 if (!varargs && argcount > type->tt_argcount)
1545 {
1546 semsg(_(e_too_many_arguments_for_function_str), name);
1547 return FAIL;
1548 }
1549 if (type->tt_args != NULL)
1550 {
1551 int i;
1552
1553 for (i = 0; i < argcount; ++i)
1554 {
1555 int offset = -argcount + i - (at_top ? 0 : 1);
1556 type_T *actual = ((type_T **)stack->ga_data)[
1557 stack->ga_len + offset];
1558 type_T *expected;
1559
1560 if (varargs && i >= type->tt_argcount - 1)
1561 expected = type->tt_args[
1562 type->tt_argcount - 1]->tt_member;
1563 else if (i >= type->tt_min_argcount
1564 && actual == &t_special)
1565 expected = &t_any;
1566 else
1567 expected = type->tt_args[i];
1568 if (need_type(actual, expected, offset, i + 1,
1569 cctx, TRUE, FALSE) == FAIL)
1570 {
1571 arg_type_mismatch(expected, actual, i + 1);
1572 return FAIL;
1573 }
1574 }
1575 }
1576 }
1577 ret_type = type->tt_member;
1578 if (ret_type == &t_unknown)
1579 // return type not known yet, use a runtime check
1580 ret_type = &t_any;
1581 }
1582 else
1583 {
1584 semsg(_(e_not_callable_type_str), name);
1585 return FAIL;
1586 }
1587
1588 if ((isn = generate_instr(cctx, ISN_PCALL)) == NULL)
1589 return FAIL;
1590 isn->isn_arg.pfunc.cpf_top = at_top;
1591 isn->isn_arg.pfunc.cpf_argcount = argcount;
1592
1593 stack->ga_len -= argcount; // drop the arguments
1594
1595 // drop the funcref/partial, get back the return value
1596 ((type_T **)stack->ga_data)[stack->ga_len - 1] = ret_type;
1597
1598 // If partial is above the arguments it must be cleared and replaced with
1599 // the return value.
1600 if (at_top && generate_instr(cctx, ISN_PCALL_END) == NULL)
1601 return FAIL;
1602
1603 return OK;
1604}
1605
1606/*
1607 * Generate an ISN_STRINGMEMBER instruction.
1608 */
1609 int
1610generate_STRINGMEMBER(cctx_T *cctx, char_u *name, size_t len)
1611{
1612 isn_T *isn;
1613 garray_T *stack = &cctx->ctx_type_stack;
1614 type_T *type;
1615
1616 RETURN_OK_IF_SKIP(cctx);
1617 if ((isn = generate_instr(cctx, ISN_STRINGMEMBER)) == NULL)
1618 return FAIL;
1619 isn->isn_arg.string = vim_strnsave(name, len);
1620
1621 // check for dict type
1622 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1623 if (type->tt_type != VAR_DICT && type != &t_any)
1624 {
1625 char *tofree;
1626
1627 semsg(_(e_expected_dictionary_for_using_key_str_but_got_str),
1628 name, type_name(type, &tofree));
1629 vim_free(tofree);
1630 return FAIL;
1631 }
1632 // change dict type to dict member type
1633 if (type->tt_type == VAR_DICT)
1634 {
1635 ((type_T **)stack->ga_data)[stack->ga_len - 1] =
1636 type->tt_member == &t_unknown ? &t_any : type->tt_member;
1637 }
1638
1639 return OK;
1640}
1641
1642/*
1643 * Generate an ISN_ECHO instruction.
1644 */
1645 int
1646generate_ECHO(cctx_T *cctx, int with_white, int count)
1647{
1648 isn_T *isn;
1649
1650 RETURN_OK_IF_SKIP(cctx);
1651 if ((isn = generate_instr_drop(cctx, ISN_ECHO, count)) == NULL)
1652 return FAIL;
1653 isn->isn_arg.echo.echo_with_white = with_white;
1654 isn->isn_arg.echo.echo_count = count;
1655
1656 return OK;
1657}
1658
1659/*
1660 * Generate an ISN_EXECUTE/ISN_ECHOMSG/ISN_ECHOERR instruction.
1661 */
1662 int
1663generate_MULT_EXPR(cctx_T *cctx, isntype_T isn_type, int count)
1664{
1665 isn_T *isn;
1666
1667 if ((isn = generate_instr_drop(cctx, isn_type, count)) == NULL)
1668 return FAIL;
1669 isn->isn_arg.number = count;
1670
1671 return OK;
1672}
1673
1674/*
1675 * Generate an ISN_PUT instruction.
1676 */
1677 int
1678generate_PUT(cctx_T *cctx, int regname, linenr_T lnum)
1679{
1680 isn_T *isn;
1681
1682 RETURN_OK_IF_SKIP(cctx);
1683 if ((isn = generate_instr(cctx, ISN_PUT)) == NULL)
1684 return FAIL;
1685 isn->isn_arg.put.put_regname = regname;
1686 isn->isn_arg.put.put_lnum = lnum;
1687 return OK;
1688}
1689
1690/*
1691 * Generate an EXEC instruction that takes a string argument.
1692 * A copy is made of "line".
1693 */
1694 int
1695generate_EXEC_copy(cctx_T *cctx, isntype_T isntype, char_u *line)
1696{
1697 isn_T *isn;
1698
1699 RETURN_OK_IF_SKIP(cctx);
1700 if ((isn = generate_instr(cctx, isntype)) == NULL)
1701 return FAIL;
1702 isn->isn_arg.string = vim_strsave(line);
1703 return OK;
1704}
1705
1706/*
1707 * Generate an EXEC instruction that takes a string argument.
1708 * "str" must be allocated, it is consumed.
1709 */
1710 int
1711generate_EXEC(cctx_T *cctx, isntype_T isntype, char_u *str)
1712{
1713 isn_T *isn;
1714
1715 if (cctx->ctx_skip == SKIP_YES)
1716 {
1717 vim_free(str);
1718 return OK;
1719 }
1720 if ((isn = generate_instr(cctx, isntype)) == NULL)
1721 {
1722 vim_free(str);
1723 return FAIL;
1724 }
1725 isn->isn_arg.string = str;
1726 return OK;
1727}
1728
1729 int
1730generate_LEGACY_EVAL(cctx_T *cctx, char_u *line)
1731{
1732 isn_T *isn;
1733 garray_T *stack = &cctx->ctx_type_stack;
1734
1735 RETURN_OK_IF_SKIP(cctx);
1736 if ((isn = generate_instr(cctx, ISN_LEGACY_EVAL)) == NULL)
1737 return FAIL;
1738 isn->isn_arg.string = vim_strsave(line);
1739
1740 if (GA_GROW_FAILS(stack, 1))
1741 return FAIL;
1742 ((type_T **)stack->ga_data)[stack->ga_len] = &t_any;
1743 ++stack->ga_len;
1744
1745 return OK;
1746}
1747
1748 int
1749generate_EXECCONCAT(cctx_T *cctx, int count)
1750{
1751 isn_T *isn;
1752
1753 if ((isn = generate_instr_drop(cctx, ISN_EXECCONCAT, count)) == NULL)
1754 return FAIL;
1755 isn->isn_arg.number = count;
1756 return OK;
1757}
1758
1759/*
1760 * Generate ISN_RANGE. Consumes "range". Return OK/FAIL.
1761 */
1762 int
1763generate_RANGE(cctx_T *cctx, char_u *range)
1764{
1765 isn_T *isn;
1766 garray_T *stack = &cctx->ctx_type_stack;
1767
1768 if ((isn = generate_instr(cctx, ISN_RANGE)) == NULL)
1769 return FAIL;
1770 isn->isn_arg.string = range;
1771
1772 if (GA_GROW_FAILS(stack, 1))
1773 return FAIL;
1774 ((type_T **)stack->ga_data)[stack->ga_len] = &t_number;
1775 ++stack->ga_len;
1776 return OK;
1777}
1778
1779 int
1780generate_UNPACK(cctx_T *cctx, int var_count, int semicolon)
1781{
1782 isn_T *isn;
1783
1784 RETURN_OK_IF_SKIP(cctx);
1785 if ((isn = generate_instr(cctx, ISN_UNPACK)) == NULL)
1786 return FAIL;
1787 isn->isn_arg.unpack.unp_count = var_count;
1788 isn->isn_arg.unpack.unp_semicolon = semicolon;
1789 return OK;
1790}
1791
1792/*
1793 * Generate an instruction for any command modifiers.
1794 */
1795 int
1796generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod)
1797{
1798 isn_T *isn;
1799
1800 if (has_cmdmod(cmod, FALSE))
1801 {
1802 cctx->ctx_has_cmdmod = TRUE;
1803
1804 if ((isn = generate_instr(cctx, ISN_CMDMOD)) == NULL)
1805 return FAIL;
1806 isn->isn_arg.cmdmod.cf_cmdmod = ALLOC_ONE(cmdmod_T);
1807 if (isn->isn_arg.cmdmod.cf_cmdmod == NULL)
1808 return FAIL;
1809 mch_memmove(isn->isn_arg.cmdmod.cf_cmdmod, cmod, sizeof(cmdmod_T));
1810 // filter program now belongs to the instruction
1811 cmod->cmod_filter_regmatch.regprog = NULL;
1812 }
1813
1814 return OK;
1815}
1816
1817 int
1818generate_undo_cmdmods(cctx_T *cctx)
1819{
1820 if (cctx->ctx_has_cmdmod && generate_instr(cctx, ISN_CMDMOD_REV) == NULL)
1821 return FAIL;
1822 cctx->ctx_has_cmdmod = FALSE;
1823 return OK;
1824}
1825
1826/*
1827 * Generate a STORE instruction for "dest", not being "dest_local".
1828 * Return FAIL when out of memory.
1829 */
1830 int
1831generate_store_var(
1832 cctx_T *cctx,
1833 assign_dest_T dest,
1834 int opt_flags,
1835 int vimvaridx,
1836 int scriptvar_idx,
1837 int scriptvar_sid,
1838 type_T *type,
1839 char_u *name)
1840{
1841 switch (dest)
1842 {
1843 case dest_option:
1844 return generate_STOREOPT(cctx, ISN_STOREOPT,
1845 skip_option_env_lead(name), opt_flags);
1846 case dest_func_option:
1847 return generate_STOREOPT(cctx, ISN_STOREFUNCOPT,
1848 skip_option_env_lead(name), opt_flags);
1849 case dest_global:
1850 // include g: with the name, easier to execute that way
1851 return generate_STORE(cctx, vim_strchr(name, AUTOLOAD_CHAR) == NULL
1852 ? ISN_STOREG : ISN_STOREAUTO, 0, name);
1853 case dest_buffer:
1854 // include b: with the name, easier to execute that way
1855 return generate_STORE(cctx, ISN_STOREB, 0, name);
1856 case dest_window:
1857 // include w: with the name, easier to execute that way
1858 return generate_STORE(cctx, ISN_STOREW, 0, name);
1859 case dest_tab:
1860 // include t: with the name, easier to execute that way
1861 return generate_STORE(cctx, ISN_STORET, 0, name);
1862 case dest_env:
1863 return generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
1864 case dest_reg:
1865 return generate_STORE(cctx, ISN_STOREREG,
1866 name[1] == '@' ? '"' : name[1], NULL);
1867 case dest_vimvar:
1868 return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
1869 case dest_script:
1870 if (scriptvar_idx < 0)
1871 // "s:" may be included in the name.
1872 return generate_OLDSCRIPT(cctx, ISN_STORES, name,
1873 scriptvar_sid, type);
1874 return generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
1875 scriptvar_sid, scriptvar_idx, type);
1876 case dest_local:
1877 case dest_expr:
1878 // cannot happen
1879 break;
1880 }
1881 return FAIL;
1882}
1883
1884 int
1885generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count)
1886{
1887 if (lhs->lhs_dest != dest_local)
1888 return generate_store_var(cctx, lhs->lhs_dest,
1889 lhs->lhs_opt_flags, lhs->lhs_vimvaridx,
1890 lhs->lhs_scriptvar_idx, lhs->lhs_scriptvar_sid,
1891 lhs->lhs_type, lhs->lhs_name);
1892
1893 if (lhs->lhs_lvar != NULL)
1894 {
1895 garray_T *instr = &cctx->ctx_instr;
1896 isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
1897
1898 // optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into
1899 // ISN_STORENR
1900 if (lhs->lhs_lvar->lv_from_outer == 0
1901 && instr->ga_len == instr_count + 1
1902 && isn->isn_type == ISN_PUSHNR)
1903 {
1904 varnumber_T val = isn->isn_arg.number;
1905 garray_T *stack = &cctx->ctx_type_stack;
1906
1907 isn->isn_type = ISN_STORENR;
1908 isn->isn_arg.storenr.stnr_idx = lhs->lhs_lvar->lv_idx;
1909 isn->isn_arg.storenr.stnr_val = val;
1910 if (stack->ga_len > 0)
1911 --stack->ga_len;
1912 }
1913 else if (lhs->lhs_lvar->lv_from_outer > 0)
1914 generate_STOREOUTER(cctx, lhs->lhs_lvar->lv_idx,
1915 lhs->lhs_lvar->lv_from_outer);
1916 else
1917 generate_STORE(cctx, ISN_STORE, lhs->lhs_lvar->lv_idx, NULL);
1918 }
1919 return OK;
1920}
1921
1922#if defined(FEAT_PROFILE) || defined(PROTO)
1923 void
1924may_generate_prof_end(cctx_T *cctx, int prof_lnum)
1925{
1926 if (cctx->ctx_compile_type == CT_PROFILE && prof_lnum >= 0)
1927 generate_instr(cctx, ISN_PROF_END);
1928}
1929#endif
1930
1931
1932/*
1933 * Delete an instruction, free what it contains.
1934 */
1935 void
1936delete_instr(isn_T *isn)
1937{
1938 switch (isn->isn_type)
1939 {
1940 case ISN_DEF:
1941 case ISN_EXEC:
1942 case ISN_EXECRANGE:
1943 case ISN_EXEC_SPLIT:
1944 case ISN_LEGACY_EVAL:
1945 case ISN_LOADAUTO:
1946 case ISN_LOADB:
1947 case ISN_LOADENV:
1948 case ISN_LOADG:
1949 case ISN_LOADOPT:
1950 case ISN_LOADT:
1951 case ISN_LOADW:
1952 case ISN_LOCKUNLOCK:
1953 case ISN_PUSHEXC:
1954 case ISN_PUSHFUNC:
1955 case ISN_PUSHS:
1956 case ISN_RANGE:
1957 case ISN_STOREAUTO:
1958 case ISN_STOREB:
1959 case ISN_STOREENV:
1960 case ISN_STOREG:
1961 case ISN_STORET:
1962 case ISN_STOREW:
1963 case ISN_STRINGMEMBER:
1964 vim_free(isn->isn_arg.string);
1965 break;
1966
1967 case ISN_SUBSTITUTE:
1968 {
1969 int idx;
1970 isn_T *list = isn->isn_arg.subs.subs_instr;
1971
1972 vim_free(isn->isn_arg.subs.subs_cmd);
1973 for (idx = 0; list[idx].isn_type != ISN_FINISH; ++idx)
1974 delete_instr(list + idx);
1975 vim_free(list);
1976 }
1977 break;
1978
1979 case ISN_INSTR:
1980 {
1981 int idx;
1982 isn_T *list = isn->isn_arg.instr;
1983
1984 for (idx = 0; list[idx].isn_type != ISN_FINISH; ++idx)
1985 delete_instr(list + idx);
1986 vim_free(list);
1987 }
1988 break;
1989
1990 case ISN_LOADS:
1991 case ISN_STORES:
1992 vim_free(isn->isn_arg.loadstore.ls_name);
1993 break;
1994
1995 case ISN_UNLET:
1996 case ISN_UNLETENV:
1997 vim_free(isn->isn_arg.unlet.ul_name);
1998 break;
1999
2000 case ISN_STOREOPT:
2001 case ISN_STOREFUNCOPT:
2002 vim_free(isn->isn_arg.storeopt.so_name);
2003 break;
2004
2005 case ISN_PUSHBLOB: // push blob isn_arg.blob
2006 blob_unref(isn->isn_arg.blob);
2007 break;
2008
2009 case ISN_PUSHJOB:
2010#ifdef FEAT_JOB_CHANNEL
2011 job_unref(isn->isn_arg.job);
2012#endif
2013 break;
2014
2015 case ISN_PUSHCHANNEL:
2016#ifdef FEAT_JOB_CHANNEL
2017 channel_unref(isn->isn_arg.channel);
2018#endif
2019 break;
2020
2021 case ISN_UCALL:
2022 vim_free(isn->isn_arg.ufunc.cuf_name);
2023 break;
2024
2025 case ISN_FUNCREF:
2026 {
2027 if (isn->isn_arg.funcref.fr_func_name == NULL)
2028 {
2029 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
2030 + isn->isn_arg.funcref.fr_dfunc_idx;
2031 ufunc_T *ufunc = dfunc->df_ufunc;
2032
2033 if (ufunc != NULL && func_name_refcount(ufunc->uf_name))
2034 func_ptr_unref(ufunc);
2035 }
2036 else
2037 {
2038 char_u *name = isn->isn_arg.funcref.fr_func_name;
2039
2040 if (name != NULL)
2041 func_unref(name);
2042 vim_free(isn->isn_arg.funcref.fr_func_name);
2043 }
2044 }
2045 break;
2046
2047 case ISN_DCALL:
2048 {
2049 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
2050 + isn->isn_arg.dfunc.cdf_idx;
2051
2052 if (dfunc->df_ufunc != NULL
2053 && func_name_refcount(dfunc->df_ufunc->uf_name))
2054 func_ptr_unref(dfunc->df_ufunc);
2055 }
2056 break;
2057
2058 case ISN_NEWFUNC:
2059 {
2060 char_u *lambda = isn->isn_arg.newfunc.nf_lambda;
2061 ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL);
2062
2063 if (ufunc != NULL)
2064 {
2065 unlink_def_function(ufunc);
2066 func_ptr_unref(ufunc);
2067 }
2068
2069 vim_free(lambda);
2070 vim_free(isn->isn_arg.newfunc.nf_global);
2071 }
2072 break;
2073
2074 case ISN_CHECKTYPE:
2075 case ISN_SETTYPE:
2076 free_type(isn->isn_arg.type.ct_type);
2077 break;
2078
2079 case ISN_CMDMOD:
2080 vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
2081 ->cmod_filter_regmatch.regprog);
2082 vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
2083 break;
2084
2085 case ISN_LOADSCRIPT:
2086 case ISN_STORESCRIPT:
2087 vim_free(isn->isn_arg.script.scriptref);
2088 break;
2089
2090 case ISN_TRY:
2091 vim_free(isn->isn_arg.try.try_ref);
2092 break;
2093
2094 case ISN_CEXPR_CORE:
2095 vim_free(isn->isn_arg.cexpr.cexpr_ref->cer_cmdline);
2096 vim_free(isn->isn_arg.cexpr.cexpr_ref);
2097 break;
2098
2099 case ISN_2BOOL:
2100 case ISN_2STRING:
2101 case ISN_2STRING_ANY:
2102 case ISN_ADDBLOB:
2103 case ISN_ADDLIST:
2104 case ISN_ANYINDEX:
2105 case ISN_ANYSLICE:
2106 case ISN_BCALL:
2107 case ISN_BLOBAPPEND:
2108 case ISN_BLOBINDEX:
2109 case ISN_BLOBSLICE:
2110 case ISN_CATCH:
2111 case ISN_CEXPR_AUCMD:
2112 case ISN_CHECKLEN:
2113 case ISN_CHECKNR:
2114 case ISN_CLEARDICT:
2115 case ISN_CMDMOD_REV:
2116 case ISN_COMPAREANY:
2117 case ISN_COMPAREBLOB:
2118 case ISN_COMPAREBOOL:
2119 case ISN_COMPAREDICT:
2120 case ISN_COMPAREFLOAT:
2121 case ISN_COMPAREFUNC:
2122 case ISN_COMPARELIST:
2123 case ISN_COMPARENR:
2124 case ISN_COMPARESPECIAL:
2125 case ISN_COMPARESTRING:
2126 case ISN_CONCAT:
2127 case ISN_COND2BOOL:
2128 case ISN_DEBUG:
2129 case ISN_DROP:
2130 case ISN_ECHO:
2131 case ISN_ECHOCONSOLE:
2132 case ISN_ECHOERR:
2133 case ISN_ECHOMSG:
2134 case ISN_ENDTRY:
2135 case ISN_EXECCONCAT:
2136 case ISN_EXECUTE:
2137 case ISN_FINALLY:
2138 case ISN_FINISH:
2139 case ISN_FOR:
2140 case ISN_GETITEM:
2141 case ISN_JUMP:
2142 case ISN_JUMP_IF_ARG_SET:
2143 case ISN_LISTAPPEND:
2144 case ISN_LISTINDEX:
2145 case ISN_LISTSLICE:
2146 case ISN_LOAD:
2147 case ISN_LOADBDICT:
2148 case ISN_LOADGDICT:
2149 case ISN_LOADOUTER:
2150 case ISN_LOADREG:
2151 case ISN_LOADTDICT:
2152 case ISN_LOADV:
2153 case ISN_LOADWDICT:
2154 case ISN_LOCKCONST:
2155 case ISN_MEMBER:
2156 case ISN_NEGATENR:
2157 case ISN_NEWDICT:
2158 case ISN_NEWLIST:
2159 case ISN_OPANY:
2160 case ISN_OPFLOAT:
2161 case ISN_OPNR:
2162 case ISN_PCALL:
2163 case ISN_PCALL_END:
2164 case ISN_PROF_END:
2165 case ISN_PROF_START:
2166 case ISN_PUSHBOOL:
2167 case ISN_PUSHF:
2168 case ISN_PUSHNR:
2169 case ISN_PUSHSPEC:
2170 case ISN_PUT:
2171 case ISN_REDIREND:
2172 case ISN_REDIRSTART:
2173 case ISN_RETURN:
2174 case ISN_RETURN_VOID:
2175 case ISN_SHUFFLE:
2176 case ISN_SLICE:
2177 case ISN_STORE:
2178 case ISN_STOREINDEX:
2179 case ISN_STORENR:
2180 case ISN_STOREOUTER:
2181 case ISN_STORERANGE:
2182 case ISN_STOREREG:
2183 case ISN_STOREV:
2184 case ISN_STRINDEX:
2185 case ISN_STRSLICE:
2186 case ISN_THROW:
2187 case ISN_TRYCONT:
2188 case ISN_UNLETINDEX:
2189 case ISN_UNLETRANGE:
2190 case ISN_UNPACK:
2191 case ISN_USEDICT:
2192 // nothing allocated
2193 break;
2194 }
2195}
2196
2197 void
2198clear_instr_ga(garray_T *gap)
2199{
2200 int idx;
2201
2202 for (idx = 0; idx < gap->ga_len; ++idx)
2203 delete_instr(((isn_T *)gap->ga_data) + idx);
2204 ga_clear(gap);
2205}
2206
2207
2208#endif // defined(FEAT_EVAL)