diff options
Diffstat (limited to 'vm_eval.c')
| -rw-r--r-- | vm_eval.c | 104 |
1 files changed, 59 insertions, 45 deletions
@@ -1,6 +1,6 @@ /********************************************************************** - vm_eval.c - + vm_eval.c - Included into vm.c. $Author$ created at: Sat May 24 16:02:32 JST 2008 @@ -57,7 +57,7 @@ static inline VALUE vm_call0_cc(rb_execution_context_t *ec, VALUE recv, ID id, i VALUE rb_vm_call0(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *cme, int kw_splat) { - const struct rb_callcache cc = VM_CC_ON_STACK(Qfalse, vm_call_general, {{ 0 }}, cme); + const struct rb_callcache cc = VM_CC_ON_STACK(Qundef, vm_call_general, {{ 0 }}, cme); return vm_call0_cc(ec, recv, id, argc, argv, &cc, kw_splat); } @@ -104,7 +104,7 @@ vm_call0_cc(rb_execution_context_t *ec, VALUE recv, ID id, int argc, const VALUE static VALUE vm_call0_cme(rb_execution_context_t *ec, struct rb_calling_info *calling, const VALUE *argv, const rb_callable_method_entry_t *cme) { - calling->cc = &VM_CC_ON_STACK(Qfalse, vm_call_general, {{ 0 }}, cme); + calling->cc = &VM_CC_ON_STACK(Qundef, vm_call_general, {{ 0 }}, cme); return vm_call0_body(ec, calling, argv); } @@ -400,9 +400,9 @@ static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE rec static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self); static VALUE -gccct_hash(VALUE klass, VALUE namespace, ID mid) +gccct_hash(VALUE klass, VALUE box_value, ID mid) { - return ((klass ^ namespace) >> 3) ^ (VALUE)mid; + return ((klass ^ box_value) >> 3) ^ (VALUE)mid; } NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, unsigned int index, const struct rb_callinfo * ci)); @@ -447,8 +447,8 @@ scope_to_ci(call_type scope, ID mid, int argc, struct rb_callinfo *ci) static inline const struct rb_callcache * gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct rb_callinfo *ci) { - VALUE klass, ns_value; - const rb_namespace_t *ns = rb_current_namespace(); + VALUE klass, box_value; + const rb_box_t *box = rb_current_box(); if (!SPECIAL_CONST_P(recv)) { klass = RBASIC_CLASS(recv); @@ -458,14 +458,14 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct klass = CLASS_OF(recv); } - if (NAMESPACE_USER_P(ns)) { - ns_value = ns->ns_object; + if (BOX_USER_P(box)) { + box_value = box->box_object; } else { - ns_value = 0; + box_value = 0; } // search global method cache - unsigned int index = (unsigned int)(gccct_hash(klass, ns_value, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE); + unsigned int index = (unsigned int)(gccct_hash(klass, box_value, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE); rb_vm_t *vm = rb_ec_vm_ptr(ec); const struct rb_callcache *cc = vm->global_cc_cache_table[index]; @@ -1379,6 +1379,17 @@ rb_yield(VALUE val) } } +VALUE +rb_ec_yield(rb_execution_context_t *ec, VALUE val) +{ + if (UNDEF_P(val)) { + return vm_yield(ec, 0, NULL, RB_NO_KEYWORDS); + } + else { + return vm_yield(ec, 1, &val, RB_NO_KEYWORDS); + } +} + #undef rb_yield_values VALUE rb_yield_values(int n, ...) @@ -1522,13 +1533,6 @@ rb_iterate_internal(VALUE (* it_proc)(VALUE), VALUE data1, GET_EC()); } -VALUE -rb_iterate(VALUE (* it_proc)(VALUE), VALUE data1, - rb_block_call_func_t bl_proc, VALUE data2) -{ - return rb_iterate_internal(it_proc, data1, bl_proc, data2); -} - struct iter_method_arg { VALUE obj; ID mid; @@ -1669,6 +1673,24 @@ get_eval_default_path(void) return eval_default_path; } +static inline int +compute_isolated_depth_from_ep(const VALUE *ep) +{ + int depth = 1; + while (1) { + if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ISOLATED)) return depth; + if (VM_ENV_LOCAL_P(ep)) return 0; + ep = VM_ENV_PREV_EP(ep); + depth++; + } +} + +static inline int +compute_isolated_depth_from_block(const struct rb_block *blk) +{ + return compute_isolated_depth_from_ep(vm_block_ep(blk)); +} + static const rb_iseq_t * pm_eval_make_iseq(VALUE src, VALUE fname, int line, const struct rb_block *base_block) @@ -1677,8 +1699,8 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line, const rb_iseq_t *iseq = parent; VALUE name = rb_fstring_lit("<compiled>"); - // Conditionally enable coverage depending on the current mode: int coverage_enabled = ((rb_get_coverage_mode() & COVERAGE_TARGET_EVAL) != 0) ? 1 : 0; + int isolated_depth = compute_isolated_depth_from_block(base_block); if (!fname) { fname = rb_source_location(&line); @@ -1872,7 +1894,7 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line, #undef FORWARDING_ALL_STR int error_state; - iseq = pm_iseq_new_eval(&result.node, name, fname, Qnil, line, parent, 0, &error_state); + iseq = pm_iseq_new_eval(&result.node, name, fname, Qnil, line, parent, isolated_depth, &error_state); pm_scope_node_t *prev = result.node.previous; while (prev) { @@ -1908,27 +1930,9 @@ eval_make_iseq(VALUE src, VALUE fname, int line, rb_iseq_t *iseq = NULL; VALUE ast_value; rb_ast_t *ast; - int isolated_depth = 0; - // Conditionally enable coverage depending on the current mode: int coverage_enabled = (rb_get_coverage_mode() & COVERAGE_TARGET_EVAL) != 0; - - { - int depth = 1; - const VALUE *ep = vm_block_ep(base_block); - - while (1) { - if (VM_ENV_FLAGS(ep, VM_ENV_FLAG_ISOLATED)) { - isolated_depth = depth; - break; - } - else if (VM_ENV_LOCAL_P(ep)) { - break; - } - ep = VM_ENV_PREV_EP(ep); - depth++; - } - } + int isolated_depth = compute_isolated_depth_from_block(base_block); if (!fname) { fname = rb_source_location(&line); @@ -1985,6 +1989,10 @@ eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int li block.as.captured.code.iseq = cfp->iseq; block.type = block_type_iseq; + // EP is not escaped to the heap here, but captured and reused by another frame. + // ZJIT's locals are incompatible with it unlike YJIT's, so invalidate the ISEQ for ZJIT. + rb_zjit_invalidate_no_ep_escape(cfp->iseq); + iseq = eval_make_iseq(src, file, line, &block); if (!iseq) { rb_exc_raise(ec->errinfo); @@ -1996,7 +2004,6 @@ eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int li cref = vm_cref_dup(orig_cref); } vm_set_eval_stack(ec, iseq, cref, &block); - // TODO: set the namespace frame /* kick */ return vm_exec(ec); @@ -2019,8 +2026,6 @@ eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line) vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp)); } - // TODO: set the namespace frame - /* kick */ return vm_exec(ec); } @@ -2147,6 +2152,17 @@ rb_eval_string_wrap(const char *str, int *pstate) VALUE rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat) { + Check_Type(arg, T_ARRAY); + int argc = RARRAY_LENINT(arg); + const VALUE *argv = RARRAY_CONST_PTR(arg); + VALUE val = rb_eval_cmd_call_kw(cmd, argc, argv, kw_splat); + RB_GC_GUARD(arg); + return val; +} + +VALUE +rb_eval_cmd_call_kw(VALUE cmd, int argc, const VALUE *argv, int kw_splat) +{ enum ruby_tag_type state; volatile VALUE val = Qnil; /* OK */ rb_execution_context_t * volatile ec = GET_EC(); @@ -2154,8 +2170,7 @@ rb_eval_cmd_kw(VALUE cmd, VALUE arg, int kw_splat) EC_PUSH_TAG(ec); if ((state = EC_EXEC_TAG()) == TAG_NONE) { if (!RB_TYPE_P(cmd, T_STRING)) { - val = rb_funcallv_kw(cmd, idCall, RARRAY_LENINT(arg), - RARRAY_CONST_PTR(arg), kw_splat); + val = rb_funcallv_kw(cmd, idCall, argc, argv, kw_splat); } else { val = eval_string_with_cref(rb_vm_top_self(), cmd, NULL, 0, 0); @@ -2886,7 +2901,6 @@ Init_vm_eval(void) rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0); rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0); - rb_define_singleton_method(rb_cModule, "gccct_clear_table", rb_gccct_clear_table, 0); id_result = rb_intern_const("result"); id_tag = rb_intern_const("tag"); id_value = rb_intern_const("value"); |
