@@ -2406,3 +2406,111 @@ FUNC_FASTCALL(rb_vm_opt_struct_aset)(rb_thread_t *th, rb_control_frame_t *reg_cf
24062406 rb_struct_aset (GET_SELF (), TOPN (0 ), TOPN (1 ));
24072407 return reg_cfp ;
24082408}
2409+
2410+ /* defined insn */
2411+
2412+ static VALUE
2413+ vm_defined (rb_thread_t * th , rb_control_frame_t * reg_cfp , rb_num_t op_type , VALUE obj , VALUE needstr , VALUE v )
2414+ {
2415+ VALUE klass ;
2416+ enum defined_type expr_type = 0 ;
2417+ enum defined_type type = (enum defined_type )op_type ;
2418+
2419+ switch (type ) {
2420+ case DEFINED_IVAR :
2421+ if (rb_ivar_defined (GET_SELF (), SYM2ID (obj ))) {
2422+ expr_type = DEFINED_IVAR ;
2423+ }
2424+ break ;
2425+ case DEFINED_IVAR2 :
2426+ klass = vm_get_cbase (GET_EP ());
2427+ break ;
2428+ case DEFINED_GVAR :
2429+ if (rb_gvar_defined (rb_global_entry (SYM2ID (obj )))) {
2430+ expr_type = DEFINED_GVAR ;
2431+ }
2432+ break ;
2433+ case DEFINED_CVAR : {
2434+ const rb_cref_t * cref = rb_vm_get_cref (GET_EP ());
2435+ klass = vm_get_cvar_base (cref , GET_CFP ());
2436+ if (rb_cvar_defined (klass , SYM2ID (obj ))) {
2437+ expr_type = DEFINED_CVAR ;
2438+ }
2439+ break ;
2440+ }
2441+ case DEFINED_CONST :
2442+ klass = v ;
2443+ if (vm_get_ev_const (th , klass , SYM2ID (obj ), 1 )) {
2444+ expr_type = DEFINED_CONST ;
2445+ }
2446+ break ;
2447+ case DEFINED_FUNC :
2448+ klass = CLASS_OF (v );
2449+ if (rb_method_boundp (klass , SYM2ID (obj ), 0 )) {
2450+ expr_type = DEFINED_METHOD ;
2451+ }
2452+ break ;
2453+ case DEFINED_METHOD :{
2454+ VALUE klass = CLASS_OF (v );
2455+ const rb_method_entry_t * me = rb_method_entry (klass , SYM2ID (obj ), 0 );
2456+
2457+ if (me ) {
2458+ const rb_method_definition_t * def = me -> def ;
2459+ if (!(def -> flag & NOEX_PRIVATE )) {
2460+ if (!((def -> flag & NOEX_PROTECTED ) &&
2461+ !rb_obj_is_kind_of (GET_SELF (),
2462+ rb_class_real (klass )))) {
2463+ expr_type = DEFINED_METHOD ;
2464+ }
2465+ }
2466+ }
2467+ {
2468+ VALUE args [2 ];
2469+ VALUE r ;
2470+
2471+ args [0 ] = obj ; args [1 ] = Qfalse ;
2472+ r = rb_check_funcall (v , idRespond_to_missing , 2 , args );
2473+ if (r != Qundef && RTEST (r ))
2474+ expr_type = DEFINED_METHOD ;
2475+ }
2476+ break ;
2477+ }
2478+ case DEFINED_YIELD :
2479+ if (GET_BLOCK_PTR ()) {
2480+ expr_type = DEFINED_YIELD ;
2481+ }
2482+ break ;
2483+ case DEFINED_ZSUPER :{
2484+ rb_call_info_t cit ;
2485+ if (vm_search_superclass (GET_CFP (), GET_ISEQ (), Qnil , & cit ) == 0 ) {
2486+ VALUE klass = cit .klass ;
2487+ ID id = cit .mid ;
2488+ if (rb_method_boundp (klass , id , 0 )) {
2489+ expr_type = DEFINED_ZSUPER ;
2490+ }
2491+ }
2492+ break ;
2493+ }
2494+ case DEFINED_REF :{
2495+ if (vm_getspecial (th , GET_LEP (), Qfalse , FIX2INT (obj )) != Qnil ) {
2496+ expr_type = DEFINED_GVAR ;
2497+ }
2498+ break ;
2499+ }
2500+ default :
2501+ rb_bug ("unimplemented defined? type (VM)" );
2502+ break ;
2503+ }
2504+
2505+ if (expr_type != 0 ) {
2506+ if (needstr != Qfalse ) {
2507+ return rb_iseq_defined_string (expr_type );
2508+ }
2509+ else {
2510+ return Qtrue ;
2511+ }
2512+ }
2513+ else {
2514+ return Qnil ;
2515+ }
2516+ }
0 commit comments