Project

General

Profile

Feature #17753 ยป 0001-Add-Module-namespace.patch

tenderlovemaking (Aaron Patterson), 03/27/2021 09:51 PM

View differences:

gc.c
6383 6383
        }
6384 6384
	if (!RCLASS_EXT(obj)) break;
6385 6385

  
6386
        gc_mark(objspace, RCLASS_EXT(obj)->namespace);
6386 6387
        mark_m_tbl(objspace, RCLASS_M_TBL(obj));
6387 6388
        cc_table_mark(objspace, obj);
6388 6389
        mark_tbl_no_pin(objspace, RCLASS_IV_TBL(obj));
......
9259 9260
            UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
9260 9261
        }
9261 9262
        if (!RCLASS_EXT(obj)) break;
9263
        UPDATE_IF_MOVED(objspace, RCLASS_EXT(obj)->namespace);
9262 9264
        update_m_tbl(objspace, RCLASS_M_TBL(obj));
9263 9265
        update_cc_tbl(objspace, obj);
9264 9266

  
internal/class.h
42 42
    struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
43 43
    struct rb_subclass_entry *subclasses;
44 44
    struct rb_subclass_entry **parent_subclasses;
45
    VALUE namespace;
46

  
45 47
    /**
46 48
     * In the case that this is an `ICLASS`, `module_subclasses` points to the link
47 49
     * in the module's `subclasses` list that indicates that the klass has been
object.c
2882 2882
    UNREACHABLE_RETURN(Qundef);
2883 2883
}
2884 2884

  
2885
static VALUE
2886
rb_mod_namespace(VALUE mod)
2887
{
2888
    VALUE scope = RCLASS_EXT(mod)->namespace;
2889
    if (scope) {
2890
        return scope;
2891
    }
2892
    else {
2893
        return Qnil;
2894
    }
2895
}
2896

  
2885 2897
/*
2886 2898
 *  call-seq:
2887 2899
 *     obj.instance_variable_get(symbol)    -> obj
......
4673 4685
    rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2);
4674 4686
    rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, -1);
4675 4687
    rb_define_method(rb_cModule, "const_source_location", rb_mod_const_source_location, -1);
4688
    rb_define_method(rb_cModule, "namespace", rb_mod_namespace, 0);
4676 4689
    rb_define_private_method(rb_cModule, "remove_const",
4677 4690
			     rb_mod_remove_const, 1); /* in variable.c */
4678 4691
    rb_define_method(rb_cModule, "const_missing",
test/ruby/test_module.rb
2869 2869
  end
2870 2870

  
2871 2871
  ConstLocation = [__FILE__, __LINE__]
2872
  class ConstLocationClass; end
2873
  module ConstLocationModule; end
2872 2874

  
2873 2875
  def test_const_source_location
2874 2876
    assert_equal(ConstLocation, self.class.const_source_location(:ConstLocation))
......
2885 2887
    }
2886 2888
  end
2887 2889

  
2890
  module Inner; end
2891

  
2892
  module Outer
2893
    X = Inner
2894
  end
2895

  
2896
  def test_namespace
2897
    assert_equal ::Object, ::Object.namespace
2898
    assert_equal ::Object, ::Kernel.namespace
2899
    assert_equal self.class, ConstLocationClass.namespace
2900
    assert_equal self.class, Outer::X.namespace
2901
  end
2902

  
2888 2903
  module CloneTestM_simple
2889 2904
    C = 1
2890 2905
    def self.m; C; end
variable.c
2998 2998
void
2999 2999
rb_const_set(VALUE klass, ID id, VALUE val)
3000 3000
{
3001
    rb_const_entry_t *ce;
3002

  
3003 3001
    if (NIL_P(klass)) {
3004 3002
	rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
3005 3003
		 QUOTE_ID(id));
......
3015 3013
    {
3016 3014
        struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
3017 3015
        if (!tbl) {
3018
            RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
3019
            rb_clear_constant_cache();
3020
            ce = ZALLOC(rb_const_entry_t);
3021
            rb_id_table_insert(tbl, id, (VALUE)ce);
3022
            setup_const_entry(ce, klass, val, CONST_PUBLIC);
3023
        }
3024
        else {
3025
            struct autoload_const ac = {
3026
                .mod = klass, .id = id,
3027
                .value = val, .flag = CONST_PUBLIC,
3028
                /* fill the rest with 0 */
3029
            };
3030
            const_tbl_update(&ac);
3016
            RCLASS_CONST_TBL(klass) = rb_id_table_create(0);
3031 3017
        }
3018
        struct autoload_const ac = {
3019
            .mod = klass, .id = id,
3020
            .value = val, .flag = CONST_PUBLIC,
3021
            /* fill the rest with 0 */
3022
        };
3023
        const_tbl_update(&ac);
3032 3024
    }
3033 3025
    RB_VM_LOCK_LEAVE();
3034 3026

  
......
3129 3121

  
3130 3122
	ce = ZALLOC(rb_const_entry_t);
3131 3123
	rb_id_table_insert(tbl, id, (VALUE)ce);
3124
	if (RB_TYPE_P(val, T_MODULE) || RB_TYPE_P(val, T_CLASS)) {
3125
            if (!RCLASS_EXT(val)->namespace) {
3126
                RB_OBJ_WRITE(val, &RCLASS_EXT(val)->namespace, klass);
3127
            }
3128
        }
3132 3129
	setup_const_entry(ce, klass, val, visibility);
3133 3130
    }
3134 3131
}