diff options
Diffstat (limited to 'insns.def')
-rw-r--r-- | insns.def | 267 |
1 files changed, 150 insertions, 117 deletions
@@ -253,6 +253,16 @@ setclassvariable vm_setclassvariable(GET_ISEQ(), GET_CFP(), id, val, ic); } +DEFINE_INSN +opt_getconstant_path +(IC ic) +() +(VALUE val) +// attr bool leaf = false; /* may autoload or raise */ +{ + val = rb_vm_opt_getconstant_path(ec, GET_CFP(), ic); +} + /* Get constant variable id. If klass is Qnil and allow_nil is Qtrue, constants are searched in the current scope. Otherwise, get constant under klass class or module. @@ -365,7 +375,17 @@ putstring () (VALUE val) { - val = rb_ec_str_resurrect(ec, str); + val = rb_ec_str_resurrect(ec, str, false); +} + +/* put chilled string val. string will be copied but frozen in the future. */ +DEFINE_INSN +putchilledstring +(VALUE str) +() +(VALUE val) +{ + val = rb_ec_str_resurrect(ec, str, true); } /* put concatenate strings */ @@ -452,6 +472,20 @@ newarraykwsplat } } +/* push hash onto array unless the hash is empty (as empty keyword + splats should be ignored). + */ +DEFINE_INSN +pushtoarraykwsplat +() +(VALUE ary, VALUE hash) +(VALUE ary) +{ + if (!RHASH_EMPTY_P(hash)) { + rb_ary_push(ary, hash); + } +} + /* dup array */ DEFINE_INSN duparray @@ -488,13 +522,16 @@ expandarray (rb_num_t num, rb_num_t flag) (..., VALUE ary) (...) +// attr bool handles_sp = true; // attr bool leaf = false; /* has rb_check_array_type() */ // attr rb_snum_t sp_inc = (rb_snum_t)num - 1 + (flag & 1 ? 1 : 0); { - vm_expandarray(GET_SP(), ary, num, (int)flag); + vm_expandarray(GET_CFP(), ary, num, (int)flag); } -/* concat two arrays */ +/* concat two arrays, without modifying first array. + * attempts to convert both objects to arrays using to_a. + */ DEFINE_INSN concatarray () @@ -505,6 +542,32 @@ concatarray ary = vm_concat_array(ary1, ary2); } +/* concat second array to first array. + * first argument must already be an array. + * attempts to convert second object to array using to_a. + */ +DEFINE_INSN +concattoarray +() +(VALUE ary1, VALUE ary2) +(VALUE ary) +// attr bool leaf = false; /* has rb_check_array_type() */ +{ + ary = vm_concat_to_array(ary1, ary2); +} + +/* push given number of objects to array directly before. */ +DEFINE_INSN +pushtoarray +(rb_num_t num) +(...) +(VALUE val) +// attr rb_snum_t sp_inc = -(rb_snum_t)num; +{ + const VALUE *objp = STACK_ADDR_FROM_TOP(num); + val = rb_ary_cat(*(objp-1), objp, num); +} + /* call to_a on array ary to splat */ DEFINE_INSN splatarray @@ -516,6 +579,22 @@ splatarray obj = vm_splat_array(flag, ary); } +/* call to_hash on hash to keyword splat before converting block */ +DEFINE_INSN +splatkw +() +(VALUE hash, VALUE block) +(VALUE obj, VALUE block) +// attr bool leaf = false; /* has rb_to_hash_type() */ +{ + if (NIL_P(hash)) { + obj = Qnil; + } + else { + obj = rb_to_hash_type(hash); + } +} + /* put new Hash from n elements. n must be an even number. */ DEFINE_INSN newhash @@ -674,7 +753,21 @@ defined { val = Qnil; if (vm_defined(ec, GET_CFP(), op_type, obj, v)) { - val = pushval; + val = pushval; + } +} + +/* defined?(@foo) */ +DEFINE_INSN +definedivar +(ID id, IVC ic, VALUE pushval) +() +(VALUE val) +// attr bool leaf = false; +{ + val = Qnil; + if (!UNDEF_P(vm_getivar(GET_SELF(), id, GET_ISEQ(), ic, NULL, FALSE, Qundef))) { + val = pushval; } } @@ -776,8 +869,9 @@ send { VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); + JIT_EXEC(ec, val); - if (val == Qundef) { + if (UNDEF_P(val)) { RESTORE_REGS(); NEXT_INSN(); } @@ -795,8 +889,9 @@ opt_send_without_block { VALUE bh = VM_BLOCK_HANDLER_NONE; val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); + JIT_EXEC(ec, val); - if (val == Qundef) { + if (UNDEF_P(val)) { RESTORE_REGS(); NEXT_INSN(); } @@ -812,7 +907,7 @@ objtostring { val = vm_objtostring(GET_ISEQ(), recv, cd); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -825,7 +920,7 @@ opt_str_freeze { val = vm_opt_str_freeze(str, BOP_FREEZE, idFreeze); - if (val == Qundef) { + if (UNDEF_P(val)) { PUSH(rb_str_resurrect(str)); CALL_SIMPLE_METHOD(); } @@ -840,7 +935,7 @@ opt_nil_p { val = vm_opt_nil_p(GET_ISEQ(), cd, recv); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -853,15 +948,15 @@ opt_str_uminus { val = vm_opt_str_freeze(str, BOP_UMINUS, idUMinus); - if (val == Qundef) { + if (UNDEF_P(val)) { PUSH(rb_str_resurrect(str)); CALL_SIMPLE_METHOD(); } } DEFINE_INSN -opt_newarray_max -(rb_num_t num) +opt_newarray_send +(rb_num_t num, ID method) (...) (VALUE val) /* This instruction typically has no funcalls. But it compares array @@ -870,20 +965,21 @@ opt_newarray_max * cannot but mark it being not leaf. */ // attr bool leaf = false; /* has rb_funcall() */ // attr rb_snum_t sp_inc = 1 - (rb_snum_t)num; -{ - val = vm_opt_newarray_max(ec, num, STACK_ADDR_FROM_TOP(num)); -} - -DEFINE_INSN -opt_newarray_min -(rb_num_t num) -(...) -(VALUE val) -/* Same discussion as opt_newarray_max. */ -// attr bool leaf = false; /* has rb_funcall() */ -// attr rb_snum_t sp_inc = 1 - (rb_snum_t)num; -{ - val = vm_opt_newarray_min(ec, num, STACK_ADDR_FROM_TOP(num)); +// attr rb_snum_t comptime_sp_inc = 1 - (rb_snum_t)num; +{ + switch(method) { + case idHash: + val = vm_opt_newarray_hash(ec, num, STACK_ADDR_FROM_TOP(num)); + break; + case idMin: + val = vm_opt_newarray_min(ec, num, STACK_ADDR_FROM_TOP(num)); + break; + case idMax: + val = vm_opt_newarray_max(ec, num, STACK_ADDR_FROM_TOP(num)); + break; + default: + rb_bug("unreachable"); + } } /* super(args) # args.size => num */ @@ -897,8 +993,9 @@ invokesuper { VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true); val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super); + JIT_EXEC(ec, val); - if (val == Qundef) { + if (UNDEF_P(val)) { RESTORE_REGS(); NEXT_INSN(); } @@ -916,8 +1013,9 @@ invokeblock { VALUE bh = VM_BLOCK_HANDLER_NONE; val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_invokeblock); + JIT_EXEC(ec, val); - if (val == Qundef) { + if (UNDEF_P(val)) { RESTORE_REGS(); NEXT_INSN(); } @@ -1039,46 +1137,6 @@ branchnil /* for optimize */ /**********************************************************/ -/* push inline-cached value and go to dst if it is valid */ -DEFINE_INSN -opt_getinlinecache -(OFFSET dst, IC ic) -() -(VALUE val) -{ - struct iseq_inline_constant_cache_entry *ice = ic->entry; - - // If there isn't an entry, then we're going to walk through the ISEQ - // starting at this instruction until we get to the associated - // opt_setinlinecache and associate this inline cache with every getconstant - // listed in between. We're doing this here instead of when the instructions - // are first compiled because it's possible to turn off inline caches and we - // want this to work in either case. - if (!ice) { - vm_ic_compile(GET_CFP(), ic); - } - - if (ice && vm_ic_hit_p(ice, GET_EP())) { - val = ice->value; - JUMP(dst); - } - else { - ruby_vm_constant_cache_misses++; - val = Qnil; - } -} - -/* set inline cache */ -DEFINE_INSN -opt_setinlinecache -(IC ic) -(VALUE val) -(VALUE val) -// attr bool leaf = false; -{ - vm_ic_update(GET_ISEQ(), ic, val, GET_EP()); -} - /* run iseq only once */ DEFINE_INSN once @@ -1115,7 +1173,7 @@ opt_plus { val = vm_opt_plus(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1129,7 +1187,7 @@ opt_minus { val = vm_opt_minus(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1143,7 +1201,7 @@ opt_mult { val = vm_opt_mult(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1160,7 +1218,7 @@ opt_div { val = vm_opt_div(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1176,7 +1234,7 @@ opt_mod { val = vm_opt_mod(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1190,7 +1248,7 @@ opt_eq { val = opt_equality(GET_ISEQ(), recv, obj, cd); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1204,7 +1262,7 @@ opt_neq { val = vm_opt_neq(GET_ISEQ(), cd, cd_eq, recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1218,7 +1276,7 @@ opt_lt { val = vm_opt_lt(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1232,7 +1290,7 @@ opt_le { val = vm_opt_le(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1246,7 +1304,7 @@ opt_gt { val = vm_opt_gt(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1260,7 +1318,7 @@ opt_ge { val = vm_opt_ge(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1278,7 +1336,7 @@ opt_ltlt { val = vm_opt_ltlt(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1292,7 +1350,7 @@ opt_and { val = vm_opt_and(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1306,7 +1364,7 @@ opt_or { val = vm_opt_or(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1325,7 +1383,7 @@ opt_aref { val = vm_opt_aref(recv, obj); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1342,7 +1400,7 @@ opt_aset { val = vm_opt_aset(recv, obj, set); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1358,14 +1416,12 @@ opt_aset_with { VALUE tmp = vm_opt_aset_with(recv, key, val); - if (tmp != Qundef) { + if (!UNDEF_P(tmp)) { val = tmp; } else { -#ifndef MJIT_HEADER TOPN(0) = rb_str_resurrect(key); PUSH(val); -#endif CALL_SIMPLE_METHOD(); } } @@ -1381,10 +1437,8 @@ opt_aref_with { val = vm_opt_aref_with(recv, key); - if (val == Qundef) { -#ifndef MJIT_HEADER + if (UNDEF_P(val)) { PUSH(rb_str_resurrect(key)); -#endif CALL_SIMPLE_METHOD(); } } @@ -1398,7 +1452,7 @@ opt_length { val = vm_opt_length(recv, BOP_LENGTH); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1412,7 +1466,7 @@ opt_size { val = vm_opt_length(recv, BOP_SIZE); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1426,7 +1480,7 @@ opt_empty_p { val = vm_opt_empty_p(recv); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1440,7 +1494,7 @@ opt_succ { val = vm_opt_succ(recv); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1454,7 +1508,7 @@ opt_not { val = vm_opt_not(GET_ISEQ(), cd, recv); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } @@ -1469,32 +1523,11 @@ opt_regexpmatch2 { val = vm_opt_regexpmatch2(obj2, obj1); - if (val == Qundef) { + if (UNDEF_P(val)) { CALL_SIMPLE_METHOD(); } } -/* call native compiled method */ -DEFINE_INSN_IF(SUPPORT_CALL_C_FUNCTION) -opt_call_c_function -(rb_insn_func_t funcptr) -() -() -// attr bool leaf = false; /* anything can happen inside */ -// attr bool handles_sp = true; -{ - reg_cfp = (funcptr)(ec, reg_cfp); - - if (reg_cfp == 0) { - VALUE err = ec->errinfo; - ec->errinfo = Qnil; - THROW_EXCEPTION(err); - } - - RESTORE_REGS(); - NEXT_INSN(); -} - /* call specific function with args */ DEFINE_INSN invokebuiltin |