예제 #1
0
파일: error.c 프로젝트: ferrous26/MacRuby
void
rb_check_frozen(VALUE obj)
{
    if (OBJ_FROZEN(obj)) rb_error_frozen(rb_obj_classname(obj));
}
예제 #2
0
static rb_method_entry_t *
rb_add_method_def(VALUE klass, ID mid, rb_method_type_t type, rb_method_definition_t *def, rb_method_flag_t noex)
{
    rb_method_entry_t *me;
    st_table *mtbl;
    st_data_t data;

    if (NIL_P(klass)) {
	klass = rb_cObject;
    }
    if (rb_safe_level() >= 4 &&
       	(klass == rb_cObject || !OBJ_UNTRUSTED(klass))) {
	rb_raise(rb_eSecurityError, "Insecure: can't define method");
    }
    if (!FL_TEST(klass, FL_SINGLETON) &&
	type != VM_METHOD_TYPE_NOTIMPLEMENTED &&
	type != VM_METHOD_TYPE_ZSUPER &&
	(mid == rb_intern("initialize") || mid == rb_intern("initialize_copy"))) {
	noex = NOEX_PRIVATE | noex;
    }
    else if (FL_TEST(klass, FL_SINGLETON) &&
	     type == VM_METHOD_TYPE_CFUNC &&
	     mid == rb_intern("allocate")) {
	rb_warn("defining %s.allocate is deprecated; use rb_define_alloc_func()",
		rb_class2name(rb_ivar_get(klass, attached)));
	mid = ID_ALLOCATOR;
    }
    if (OBJ_FROZEN(klass)) {
	rb_error_frozen("class/module");
    }

    mtbl = RCLASS_M_TBL(klass);

    /* check re-definition */
    if (st_lookup(mtbl, mid, &data)) {
	rb_method_entry_t *old_me = (rb_method_entry_t *)data;
	rb_method_definition_t *old_def = old_me->def;

	if (rb_method_definition_eq(old_def, def)) return old_me;
	rb_vm_check_redefinition_opt_method(old_me);

	if (RTEST(ruby_verbose) &&
	    type != VM_METHOD_TYPE_UNDEF &&
	    old_def->alias_count == 0 &&
	    old_def->type != VM_METHOD_TYPE_UNDEF &&
	    old_def->type != VM_METHOD_TYPE_ZSUPER) {
	    extern rb_iseq_t *rb_proc_get_iseq(VALUE proc, int *is_proc);
	    rb_iseq_t *iseq = 0;

	    rb_warning("method redefined; discarding old %s", rb_id2name(mid));
	    switch (old_def->type) {
	      case VM_METHOD_TYPE_ISEQ:
		iseq = old_def->body.iseq;
		break;
	      case VM_METHOD_TYPE_BMETHOD:
		iseq = rb_proc_get_iseq(old_def->body.proc, 0);
		break;
	      default:
		break;
	    }
	    if (iseq && !NIL_P(iseq->filename)) {
		int line = iseq->insn_info_table ? rb_iseq_first_lineno(iseq) : 0;
		rb_compile_warning(RSTRING_PTR(iseq->filename), line,
				   "previous definition of %s was here",
				   rb_id2name(old_def->original_id));
	    }
	}
	rb_free_method_entry(old_me);
    }

    rb_clear_cache_by_id(mid);

    me = ALLOC(rb_method_entry_t);
    me->flag = NOEX_WITH_SAFE(noex);
    me->called_id = mid;
    me->klass = klass;
    me->def = def;
    if (def) def->alias_count++;

    /* check mid */
    if (klass == rb_cObject && mid == idInitialize) {
	rb_warn("redefining Object#initialize may cause infinite loop");
    }
    /* check mid */
    if (mid == object_id || mid == id__send__) {
	if (type == VM_METHOD_TYPE_ISEQ) {
	    rb_warn("redefining `%s' may cause serious problems", rb_id2name(mid));
	}
    }

    st_insert(mtbl, mid, (st_data_t) me);

    return me;
}