Mercurial > vim
comparison src/vim9compile.c @ 19726:ad37a198a708 v8.2.0419
patch 8.2.0419: various memory leaks in Vim9 script code
Commit: https://github.com/vim/vim/commit/20431c9dbb592ebe0666bf042af7d2b373107372
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Mar 20 18:39:46 2020 +0100
patch 8.2.0419: various memory leaks in Vim9 script code
Problem: Various memory leaks in Vim9 script code.
Solution: Fix the leaks. (Ozaki Kiichi, closes https://github.com/vim/vim/issues/5814)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 20 Mar 2020 18:45:04 +0100 |
parents | 2fee087c94cb |
children | 9daed26b788b |
comparison
equal
deleted
inserted
replaced
19725:700b7d225e02 | 19726:ad37a198a708 |
---|---|
127 static char e_syntax_at[] = N_("E1002: Syntax error at %s"); | 127 static char e_syntax_at[] = N_("E1002: Syntax error at %s"); |
128 | 128 |
129 static int compile_expr1(char_u **arg, cctx_T *cctx); | 129 static int compile_expr1(char_u **arg, cctx_T *cctx); |
130 static int compile_expr2(char_u **arg, cctx_T *cctx); | 130 static int compile_expr2(char_u **arg, cctx_T *cctx); |
131 static int compile_expr3(char_u **arg, cctx_T *cctx); | 131 static int compile_expr3(char_u **arg, cctx_T *cctx); |
132 static void delete_def_function_contents(dfunc_T *dfunc); | |
132 | 133 |
133 /* | 134 /* |
134 * Lookup variable "name" in the local scope and return the index. | 135 * Lookup variable "name" in the local scope and return the index. |
135 */ | 136 */ |
136 static int | 137 static int |
1301 lvar->lv_name = vim_strnsave(name, (int)(len == 0 ? STRLEN(name) : len)); | 1302 lvar->lv_name = vim_strnsave(name, (int)(len == 0 ? STRLEN(name) : len)); |
1302 lvar->lv_const = isConst; | 1303 lvar->lv_const = isConst; |
1303 lvar->lv_type = type; | 1304 lvar->lv_type = type; |
1304 | 1305 |
1305 return idx; | 1306 return idx; |
1307 } | |
1308 | |
1309 /* | |
1310 * Remove local variables above "new_top". | |
1311 */ | |
1312 static void | |
1313 unwind_locals(cctx_T *cctx, int new_top) | |
1314 { | |
1315 if (cctx->ctx_locals.ga_len > new_top) | |
1316 { | |
1317 int idx; | |
1318 lvar_T *lvar; | |
1319 | |
1320 for (idx = new_top; idx < cctx->ctx_locals.ga_len; ++idx) | |
1321 { | |
1322 lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx; | |
1323 vim_free(lvar->lv_name); | |
1324 } | |
1325 } | |
1326 cctx->ctx_locals.ga_len = new_top; | |
1327 } | |
1328 | |
1329 /* | |
1330 * Free all local variables. | |
1331 */ | |
1332 static void | |
1333 free_local(cctx_T *cctx) | |
1334 { | |
1335 unwind_locals(cctx, 0); | |
1336 ga_clear(&cctx->ctx_locals); | |
1306 } | 1337 } |
1307 | 1338 |
1308 /* | 1339 /* |
1309 * Skip over a type definition and return a pointer to just after it. | 1340 * Skip over a type definition and return a pointer to just after it. |
1310 */ | 1341 */ |
1670 } | 1701 } |
1671 return NULL; | 1702 return NULL; |
1672 } | 1703 } |
1673 | 1704 |
1674 /* | 1705 /* |
1706 * Free all imported variables. | |
1707 */ | |
1708 static void | |
1709 free_imported(cctx_T *cctx) | |
1710 { | |
1711 int idx; | |
1712 | |
1713 for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx) | |
1714 { | |
1715 imported_T *import = ((imported_T *)cctx->ctx_imports.ga_data) + idx; | |
1716 | |
1717 vim_free(import->imp_name); | |
1718 } | |
1719 ga_clear(&cctx->ctx_imports); | |
1720 } | |
1721 | |
1722 /* | |
1675 * Generate an instruction to load script-local variable "name". | 1723 * Generate an instruction to load script-local variable "name". |
1676 */ | 1724 */ |
1677 static int | 1725 static int |
1678 compile_load_scriptvar( | 1726 compile_load_scriptvar( |
1679 cctx_T *cctx, | 1727 cctx_T *cctx, |
2125 ufunc_T *ufunc; | 2173 ufunc_T *ufunc; |
2126 | 2174 |
2127 // Get the funcref in "rettv". | 2175 // Get the funcref in "rettv". |
2128 if (get_lambda_tv(arg, &rettv, TRUE) == FAIL) | 2176 if (get_lambda_tv(arg, &rettv, TRUE) == FAIL) |
2129 return FAIL; | 2177 return FAIL; |
2178 | |
2130 ufunc = rettv.vval.v_partial->pt_func; | 2179 ufunc = rettv.vval.v_partial->pt_func; |
2180 ++ufunc->uf_refcount; | |
2181 clear_tv(&rettv); | |
2131 | 2182 |
2132 // The function will have one line: "return {expr}". | 2183 // The function will have one line: "return {expr}". |
2133 // Compile it into instructions. | 2184 // Compile it into instructions. |
2134 compile_def_function(ufunc, TRUE); | 2185 compile_def_function(ufunc, TRUE); |
2135 | 2186 |
2167 semsg(_(e_missing_paren), "lambda"); | 2218 semsg(_(e_missing_paren), "lambda"); |
2168 clear_tv(&rettv); | 2219 clear_tv(&rettv); |
2169 return FAIL; | 2220 return FAIL; |
2170 } | 2221 } |
2171 | 2222 |
2223 ufunc = rettv.vval.v_partial->pt_func; | |
2224 ++ufunc->uf_refcount; | |
2225 clear_tv(&rettv); | |
2226 | |
2172 // The function will have one line: "return {expr}". | 2227 // The function will have one line: "return {expr}". |
2173 // Compile it into instructions. | 2228 // Compile it into instructions. |
2174 ufunc = rettv.vval.v_partial->pt_func; | |
2175 ++ufunc->uf_refcount; | |
2176 compile_def_function(ufunc, TRUE); | 2229 compile_def_function(ufunc, TRUE); |
2177 | 2230 |
2178 // compile the arguments | 2231 // compile the arguments |
2179 *arg = skipwhite(*arg + 1); | 2232 *arg = skipwhite(*arg + 1); |
2180 if (compile_arguments(arg, cctx, &argcount) == OK) | 2233 if (compile_arguments(arg, cctx, &argcount) == OK) |
2181 // call the compiled function | 2234 // call the compiled function |
2182 ret = generate_CALL(cctx, ufunc, argcount); | 2235 ret = generate_CALL(cctx, ufunc, argcount); |
2183 | 2236 |
2184 clear_tv(&rettv); | |
2185 return ret; | 2237 return ret; |
2186 } | 2238 } |
2187 | 2239 |
2188 /* | 2240 /* |
2189 * parse a dict: {'key': val} or #{key: val} | 2241 * parse a dict: {'key': val} or #{key: val} |
3396 { | 3448 { |
3397 if (*arg == '&') | 3449 if (*arg == '&') |
3398 { | 3450 { |
3399 int cc; | 3451 int cc; |
3400 long numval; | 3452 long numval; |
3401 char_u *stringval = NULL; | |
3402 | 3453 |
3403 dest = dest_option; | 3454 dest = dest_option; |
3404 if (cmdidx == CMD_const) | 3455 if (cmdidx == CMD_const) |
3405 { | 3456 { |
3406 emsg(_(e_const_option)); | 3457 emsg(_(e_const_option)); |
3418 emsg(_(e_letunexp)); | 3469 emsg(_(e_letunexp)); |
3419 return NULL; | 3470 return NULL; |
3420 } | 3471 } |
3421 cc = *p; | 3472 cc = *p; |
3422 *p = NUL; | 3473 *p = NUL; |
3423 opt_type = get_option_value(arg + 1, &numval, &stringval, opt_flags); | 3474 opt_type = get_option_value(arg + 1, &numval, NULL, opt_flags); |
3424 *p = cc; | 3475 *p = cc; |
3425 if (opt_type == -3) | 3476 if (opt_type == -3) |
3426 { | 3477 { |
3427 semsg(_(e_unknown_option), *arg); | 3478 semsg(_(e_unknown_option), *arg); |
3428 return NULL; | 3479 return NULL; |
4215 if (scope == NULL || scope->se_type != IF_SCOPE) | 4266 if (scope == NULL || scope->se_type != IF_SCOPE) |
4216 { | 4267 { |
4217 emsg(_(e_elseif_without_if)); | 4268 emsg(_(e_elseif_without_if)); |
4218 return NULL; | 4269 return NULL; |
4219 } | 4270 } |
4220 cctx->ctx_locals.ga_len = scope->se_local_count; | 4271 unwind_locals(cctx, scope->se_local_count); |
4221 | 4272 |
4222 if (cctx->ctx_skip == MAYBE) | 4273 if (cctx->ctx_skip == MAYBE) |
4223 { | 4274 { |
4224 if (compile_jump_to_end(&scope->se_u.se_if.is_end_label, | 4275 if (compile_jump_to_end(&scope->se_u.se_if.is_end_label, |
4225 JUMP_ALWAYS, cctx) == FAIL) | 4276 JUMP_ALWAYS, cctx) == FAIL) |
4263 if (scope == NULL || scope->se_type != IF_SCOPE) | 4314 if (scope == NULL || scope->se_type != IF_SCOPE) |
4264 { | 4315 { |
4265 emsg(_(e_else_without_if)); | 4316 emsg(_(e_else_without_if)); |
4266 return NULL; | 4317 return NULL; |
4267 } | 4318 } |
4268 cctx->ctx_locals.ga_len = scope->se_local_count; | 4319 unwind_locals(cctx, scope->se_local_count); |
4269 | 4320 |
4270 // jump from previous block to the end, unless the else block is empty | 4321 // jump from previous block to the end, unless the else block is empty |
4271 if (cctx->ctx_skip == MAYBE) | 4322 if (cctx->ctx_skip == MAYBE) |
4272 { | 4323 { |
4273 if (compile_jump_to_end(&scope->se_u.se_if.is_end_label, | 4324 if (compile_jump_to_end(&scope->se_u.se_if.is_end_label, |
4305 emsg(_(e_endif_without_if)); | 4356 emsg(_(e_endif_without_if)); |
4306 return NULL; | 4357 return NULL; |
4307 } | 4358 } |
4308 ifscope = &scope->se_u.se_if; | 4359 ifscope = &scope->se_u.se_if; |
4309 cctx->ctx_scope = scope->se_outer; | 4360 cctx->ctx_scope = scope->se_outer; |
4310 cctx->ctx_locals.ga_len = scope->se_local_count; | 4361 unwind_locals(cctx, scope->se_local_count); |
4311 | 4362 |
4312 if (scope->se_u.se_if.is_if_label >= 0) | 4363 if (scope->se_u.se_if.is_if_label >= 0) |
4313 { | 4364 { |
4314 // previous "if" or "elseif" jumps here | 4365 // previous "if" or "elseif" jumps here |
4315 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label; | 4366 isn = ((isn_T *)instr->ga_data) + scope->se_u.se_if.is_if_label; |
4433 emsg(_(e_for)); | 4484 emsg(_(e_for)); |
4434 return NULL; | 4485 return NULL; |
4435 } | 4486 } |
4436 forscope = &scope->se_u.se_for; | 4487 forscope = &scope->se_u.se_for; |
4437 cctx->ctx_scope = scope->se_outer; | 4488 cctx->ctx_scope = scope->se_outer; |
4438 cctx->ctx_locals.ga_len = scope->se_local_count; | 4489 unwind_locals(cctx, scope->se_local_count); |
4439 | 4490 |
4440 // At end of ":for" scope jump back to the FOR instruction. | 4491 // At end of ":for" scope jump back to the FOR instruction. |
4441 generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label); | 4492 generate_JUMP(cctx, JUMP_ALWAYS, forscope->fs_top_label); |
4442 | 4493 |
4443 // Fill in the "end" label in the FOR statement so it can jump here | 4494 // Fill in the "end" label in the FOR statement so it can jump here |
4504 { | 4555 { |
4505 emsg(_(e_while)); | 4556 emsg(_(e_while)); |
4506 return NULL; | 4557 return NULL; |
4507 } | 4558 } |
4508 cctx->ctx_scope = scope->se_outer; | 4559 cctx->ctx_scope = scope->se_outer; |
4509 cctx->ctx_locals.ga_len = scope->se_local_count; | 4560 unwind_locals(cctx, scope->se_local_count); |
4510 | 4561 |
4511 // At end of ":for" scope jump back to the FOR instruction. | 4562 // At end of ":for" scope jump back to the FOR instruction. |
4512 generate_JUMP(cctx, JUMP_ALWAYS, scope->se_u.se_while.ws_top_label); | 4563 generate_JUMP(cctx, JUMP_ALWAYS, scope->se_u.se_while.ws_top_label); |
4513 | 4564 |
4514 // Fill in the "end" label in the WHILE statement so it can jump here. | 4565 // Fill in the "end" label in the WHILE statement so it can jump here. |
4597 compile_endblock(cctx_T *cctx) | 4648 compile_endblock(cctx_T *cctx) |
4598 { | 4649 { |
4599 scope_T *scope = cctx->ctx_scope; | 4650 scope_T *scope = cctx->ctx_scope; |
4600 | 4651 |
4601 cctx->ctx_scope = scope->se_outer; | 4652 cctx->ctx_scope = scope->se_outer; |
4602 cctx->ctx_locals.ga_len = scope->se_local_count; | 4653 unwind_locals(cctx, scope->se_local_count); |
4603 vim_free(scope); | 4654 vim_free(scope); |
4604 } | 4655 } |
4605 | 4656 |
4606 /* | 4657 /* |
4607 * compile "try" | 4658 * compile "try" |
4940 sctx_T save_current_sctx = current_sctx; | 4991 sctx_T save_current_sctx = current_sctx; |
4941 int emsg_before = called_emsg; | 4992 int emsg_before = called_emsg; |
4942 | 4993 |
4943 if (ufunc->uf_dfunc_idx >= 0) | 4994 if (ufunc->uf_dfunc_idx >= 0) |
4944 { | 4995 { |
4945 // redefining a function that was compiled before | 4996 // Redefining a function that was compiled before. |
4946 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; | 4997 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; |
4947 dfunc->df_deleted = FALSE; | 4998 |
4999 // Free old instructions. | |
5000 delete_def_function_contents(dfunc); | |
4948 } | 5001 } |
4949 else | 5002 else |
4950 { | 5003 { |
4951 // Add the function to "def_functions". | 5004 // Add the function to "def_functions". |
4952 if (ga_grow(&def_functions, 1) == FAIL) | 5005 if (ga_grow(&def_functions, 1) == FAIL) |
5303 // Return zero if there is no return at the end. | 5356 // Return zero if there is no return at the end. |
5304 generate_PUSHNR(&cctx, 0); | 5357 generate_PUSHNR(&cctx, 0); |
5305 generate_instr(&cctx, ISN_RETURN); | 5358 generate_instr(&cctx, ISN_RETURN); |
5306 } | 5359 } |
5307 | 5360 |
5361 dfunc->df_deleted = FALSE; | |
5308 dfunc->df_instr = instr->ga_data; | 5362 dfunc->df_instr = instr->ga_data; |
5309 dfunc->df_instr_count = instr->ga_len; | 5363 dfunc->df_instr_count = instr->ga_len; |
5310 dfunc->df_varcount = cctx.ctx_max_local; | 5364 dfunc->df_varcount = cctx.ctx_max_local; |
5311 | 5365 |
5312 ret = OK; | 5366 ret = OK; |
5313 | 5367 |
5314 erret: | 5368 erret: |
5315 if (ret == FAIL) | 5369 if (ret == FAIL) |
5316 { | 5370 { |
5371 int idx; | |
5372 | |
5373 for (idx = 0; idx < instr->ga_len; ++idx) | |
5374 delete_instr(((isn_T *)instr->ga_data) + idx); | |
5317 ga_clear(instr); | 5375 ga_clear(instr); |
5376 | |
5318 ufunc->uf_dfunc_idx = -1; | 5377 ufunc->uf_dfunc_idx = -1; |
5319 --def_functions.ga_len; | 5378 if (!dfunc->df_deleted) |
5379 --def_functions.ga_len; | |
5380 | |
5381 // Don't execute this function body. | |
5382 ga_clear_strings(&ufunc->uf_lines); | |
5383 | |
5320 if (errormsg != NULL) | 5384 if (errormsg != NULL) |
5321 emsg(errormsg); | 5385 emsg(errormsg); |
5322 else if (called_emsg == called_emsg_before) | 5386 else if (called_emsg == called_emsg_before) |
5323 emsg(_("E1028: compile_def_function failed")); | 5387 emsg(_("E1028: compile_def_function failed")); |
5324 | |
5325 // don't execute this function body | |
5326 ufunc->uf_lines.ga_len = 0; | |
5327 } | 5388 } |
5328 | 5389 |
5329 current_sctx = save_current_sctx; | 5390 current_sctx = save_current_sctx; |
5391 free_imported(&cctx); | |
5392 free_local(&cctx); | |
5330 ga_clear(&cctx.ctx_type_stack); | 5393 ga_clear(&cctx.ctx_type_stack); |
5331 ga_clear(&cctx.ctx_locals); | |
5332 } | 5394 } |
5333 | 5395 |
5334 /* | 5396 /* |
5335 * Delete an instruction, free what it contains. | 5397 * Delete an instruction, free what it contains. |
5336 */ | 5398 */ |
5337 static void | 5399 void |
5338 delete_instr(isn_T *isn) | 5400 delete_instr(isn_T *isn) |
5339 { | 5401 { |
5340 switch (isn->isn_type) | 5402 switch (isn->isn_type) |
5341 { | 5403 { |
5342 case ISN_EXEC: | 5404 case ISN_EXEC: |
5441 break; | 5503 break; |
5442 } | 5504 } |
5443 } | 5505 } |
5444 | 5506 |
5445 /* | 5507 /* |
5446 * When a user function is deleted, delete any associated def function. | 5508 * Free all instructions for "dfunc". |
5447 */ | 5509 */ |
5448 void | 5510 static void |
5449 delete_def_function(ufunc_T *ufunc) | 5511 delete_def_function_contents(dfunc_T *dfunc) |
5450 { | 5512 { |
5451 int idx; | 5513 int idx; |
5452 | 5514 |
5453 if (ufunc->uf_dfunc_idx >= 0) | 5515 ga_clear(&dfunc->df_def_args_isn); |
5454 { | 5516 |
5455 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) | 5517 if (dfunc->df_instr != NULL) |
5456 + ufunc->uf_dfunc_idx; | 5518 { |
5457 ga_clear(&dfunc->df_def_args_isn); | |
5458 | |
5459 for (idx = 0; idx < dfunc->df_instr_count; ++idx) | 5519 for (idx = 0; idx < dfunc->df_instr_count; ++idx) |
5460 delete_instr(dfunc->df_instr + idx); | 5520 delete_instr(dfunc->df_instr + idx); |
5461 VIM_CLEAR(dfunc->df_instr); | 5521 VIM_CLEAR(dfunc->df_instr); |
5462 | 5522 } |
5463 dfunc->df_deleted = TRUE; | 5523 |
5524 dfunc->df_deleted = TRUE; | |
5525 } | |
5526 | |
5527 /* | |
5528 * When a user function is deleted, delete any associated def function. | |
5529 */ | |
5530 void | |
5531 delete_def_function(ufunc_T *ufunc) | |
5532 { | |
5533 if (ufunc->uf_dfunc_idx >= 0) | |
5534 { | |
5535 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) | |
5536 + ufunc->uf_dfunc_idx; | |
5537 | |
5538 delete_def_function_contents(dfunc); | |
5464 } | 5539 } |
5465 } | 5540 } |
5466 | 5541 |
5467 #if defined(EXITFREE) || defined(PROTO) | 5542 #if defined(EXITFREE) || defined(PROTO) |
5543 /* | |
5544 * Free all functions defined with ":def". | |
5545 */ | |
5468 void | 5546 void |
5469 free_def_functions(void) | 5547 free_def_functions(void) |
5470 { | 5548 { |
5471 vim_free(def_functions.ga_data); | 5549 int idx; |
5550 | |
5551 for (idx = 0; idx < def_functions.ga_len; ++idx) | |
5552 { | |
5553 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + idx; | |
5554 | |
5555 delete_def_function_contents(dfunc); | |
5556 } | |
5557 | |
5558 ga_clear(&def_functions); | |
5472 } | 5559 } |
5473 #endif | 5560 #endif |
5474 | 5561 |
5475 | 5562 |
5476 #endif // FEAT_EVAL | 5563 #endif // FEAT_EVAL |