summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-10-23 13:27:21 +0900
committerKoichi Sasada <ko1@atdot.net>2020-10-29 23:42:55 +0900
commit07c03bc30984a496558d9e830bc4fb2f8cfb1854 (patch)
tree961a2eaa656943974221bbdf8cae28a9116e5f37 /iseq.c
parentbf951c763d00a4aee8f8c896d1a97c387fa8f30e (diff)
check isolated Proc more strictly
Isolated Proc prohibit to access outer local variables, but it was violated by binding and so on, so they should be error.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3721
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/iseq.c b/iseq.c
index 85ced1212c..449d3385cc 100644
--- a/iseq.c
+++ b/iseq.c
@@ -130,6 +130,7 @@ rb_iseq_free(const rb_iseq_t *iseq)
ruby_xfree((void *)body->param.keyword);
}
compile_data_free(ISEQ_COMPILE_DATA(iseq));
+ if (body->outer_variables) rb_id_table_free(body->outer_variables);
ruby_xfree(body);
}
@@ -575,8 +576,7 @@ new_arena(void)
static VALUE
prepare_iseq_build(rb_iseq_t *iseq,
VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_code_location_t *code_location, const int node_id,
- const rb_iseq_t *parent, enum iseq_type type,
- const rb_compile_option_t *option)
+ const rb_iseq_t *parent, int isolated_depth, enum iseq_type type, const rb_compile_option_t *option)
{
VALUE coverage = Qfalse;
VALUE err_info = Qnil;
@@ -603,11 +603,11 @@ prepare_iseq_build(rb_iseq_t *iseq,
ISEQ_COMPILE_DATA(iseq)->node.storage_head = ISEQ_COMPILE_DATA(iseq)->node.storage_current = new_arena();
ISEQ_COMPILE_DATA(iseq)->insn.storage_head = ISEQ_COMPILE_DATA(iseq)->insn.storage_current = new_arena();
+ ISEQ_COMPILE_DATA(iseq)->isolated_depth = isolated_depth;
ISEQ_COMPILE_DATA(iseq)->option = option;
-
ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = NULL;
-
ISEQ_COMPILE_DATA(iseq)->builtin_function_table = GET_VM()->builtin_function_table;
+
if (option->coverage_enabled) {
VALUE coverages = rb_get_coverages();
@@ -794,8 +794,8 @@ rb_iseq_t *
rb_iseq_new(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath,
const rb_iseq_t *parent, enum iseq_type type)
{
- return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, type,
- &COMPILE_OPTION_DEFAULT);
+ return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent,
+ 0, type, &COMPILE_OPTION_DEFAULT);
}
rb_iseq_t *
@@ -810,8 +810,8 @@ rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath
}
}
- return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, ISEQ_TYPE_TOP,
- &COMPILE_OPTION_DEFAULT);
+ return rb_iseq_new_with_opt(ast, name, path, realpath, INT2FIX(0), parent, 0,
+ ISEQ_TYPE_TOP, &COMPILE_OPTION_DEFAULT);
}
rb_iseq_t *
@@ -819,7 +819,14 @@ rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_
{
return rb_iseq_new_with_opt(ast, rb_fstring_lit("<main>"),
path, realpath, INT2FIX(0),
- parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
+ parent, 0, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
+}
+
+rb_iseq_t *
+rb_iseq_new_eval(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth)
+{
+ return rb_iseq_new_with_opt(ast, name, path, realpath, first_lineno,
+ parent, isolated_depth, ISEQ_TYPE_EVAL, &COMPILE_OPTION_DEFAULT);
}
static inline rb_iseq_t *
@@ -838,8 +845,8 @@ iseq_translate(rb_iseq_t *iseq)
rb_iseq_t *
rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath,
- VALUE first_lineno, const rb_iseq_t *parent,
- enum iseq_type type, const rb_compile_option_t *option)
+ VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth,
+ enum iseq_type type, const rb_compile_option_t *option)
{
const NODE *node = ast ? ast->root : 0;
/* TODO: argument check */
@@ -854,7 +861,7 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea
}
if (ast && ast->compile_option) rb_iseq_make_compile_option(&new_opt, ast->compile_option);
- prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, node ? nd_node_id(node) : -1, parent, type, &new_opt);
+ prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, node ? nd_node_id(node) : -1, parent, isolated_depth, type, &new_opt);
rb_iseq_compile_node(iseq, node);
finish_iseq_build(iseq);
@@ -873,7 +880,7 @@ rb_iseq_new_with_callback(
rb_iseq_t *iseq = iseq_alloc();
if (!option) option = &COMPILE_OPTION_DEFAULT;
- prepare_iseq_build(iseq, name, path, realpath, first_lineno, NULL, -1, parent, type, option);
+ prepare_iseq_build(iseq, name, path, realpath, first_lineno, NULL, -1, parent, 0, type, option);
rb_iseq_compile_callback(iseq, ifunc);
finish_iseq_build(iseq);
@@ -986,7 +993,7 @@ iseq_load(VALUE data, const rb_iseq_t *parent, VALUE opt)
make_compile_option(&option, opt);
option.peephole_optimization = FALSE; /* because peephole optimization can modify original iseq */
prepare_iseq_build(iseq, name, path, realpath, first_lineno, &tmp_loc, NUM2INT(node_id),
- parent, (enum iseq_type)iseq_type, &option);
+ parent, 0, (enum iseq_type)iseq_type, &option);
rb_iseq_build_from_ary(iseq, misc, locals, params, exception, body);
@@ -1054,7 +1061,7 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE realpath, VALUE line, V
else {
INITIALIZED VALUE label = rb_fstring_lit("<compiled>");
iseq = rb_iseq_new_with_opt(&ast->body, label, file, realpath, line,
- 0, ISEQ_TYPE_TOP, &option);
+ NULL, 0, ISEQ_TYPE_TOP, &option);
rb_ast_dispose(ast);
}
@@ -1310,7 +1317,7 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
ret = iseqw_new(rb_iseq_new_with_opt(&ast->body, rb_fstring_lit("<main>"),
file,
rb_realpath_internal(Qnil, file, 1),
- line, NULL, ISEQ_TYPE_TOP, &option));
+ line, NULL, 0, ISEQ_TYPE_TOP, &option));
rb_ast_dispose(ast);
return ret;
}