summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-24 14:15:14 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-24 14:15:14 +0000
commit89b3281668f2e63ab091659165c0cf46fc5db927 (patch)
tree3be8b03dfcdb27004c809e770cb87098a65cd93f /iseq.c
parent5715bee4a598bea7dcfe293a7be364b62cc0f3f4 (diff)
iseq.c: narrow down protected region
* iseq.c (rb_iseq_compile_with_option): narrow down protected region, and check/convert/prepare arguments before setting base_block which needs to roll back. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53282 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c61
1 files changed, 31 insertions, 30 deletions
diff --git a/iseq.c b/iseq.c
index 3dfc390..3c68264 100644
--- a/iseq.c
+++ b/iseq.c
@@ -603,46 +603,47 @@ rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE li
rb_thread_t *th = GET_THREAD();
rb_block_t *prev_base_block = th->base_block;
rb_iseq_t *iseq = NULL;
+ const rb_iseq_t *parent = NULL;
+ rb_compile_option_t option;
+ VALUE label;
+ enum iseq_type type;
+ NODE *(*parse)(VALUE vparser, VALUE fname, VALUE file, int start);
+ int ln = NUM2INT(line);
- th->base_block = base_block;
-
- TH_PUSH_TAG(th);
- if ((state = EXEC_TAG()) == 0) {
- VALUE parser;
- int ln = NUM2INT(line);
- NODE *node;
- rb_compile_option_t option;
-
- StringValueCStr(file);
- make_compile_option(&option, opt);
-
- parser = rb_parser_new();
+ StringValueCStr(file);
+ if (RB_TYPE_P(src, T_FILE)) {
+ parse = rb_parser_compile_file_path;
+ }
+ else {
+ StringValue(src);
+ parse = rb_parser_compile_string_path;
+ }
- if (RB_TYPE_P((src), T_FILE))
- node = rb_parser_compile_file_path(parser, file, src, ln);
- else {
- StringValue(src);
- node = rb_parser_compile_string_path(parser, file, src, ln);
+ make_compile_option(&option, opt);
- if (!node) {
- rb_exc_raise(th->errinfo); /* TODO: check err */
- }
- }
+ if (base_block && (parent = base_block->iseq) != NULL) {
+ label = parent->body->location.label;
+ type = ISEQ_TYPE_EVAL;
+ }
+ else {
+ label = rb_fstring_cstr("<compiled>");
+ type = ISEQ_TYPE_TOP;
+ }
- if (base_block && base_block->iseq) {
- iseq = rb_iseq_new_with_opt(node, base_block->iseq->body->location.label,
- file, absolute_path, line, base_block->iseq,
- ISEQ_TYPE_EVAL, &option);
- }
- else {
- iseq = rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, absolute_path, line,
- NULL, ISEQ_TYPE_TOP, &option);
+ th->base_block = base_block;
+ TH_PUSH_TAG(th);
+ if ((state = EXEC_TAG()) == 0) {
+ NODE *node = (*parse)(rb_parser_new(), file, src, ln);
+ if (node) { /* TODO: check err */
+ iseq = rb_iseq_new_with_opt(node, label, file, absolute_path, line,
+ parent, type, &option);
}
}
TH_POP_TAG();
th->base_block = prev_base_block;
+ if (!iseq) rb_exc_raise(th->errinfo);
if (state) {
JUMP_TAG(state);
}