Ejemplo n.º 1
0
static void bind_lob_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
{
    oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
    const oci8_handle_data_type_t *bind_data_type = obind->base.data_type;
    const oci8_handle_data_type_t *lob_data_type = bind_data_type->rb_data_type.data;
    oci8_base_t *h = oci8_check_typeddata(val, lob_data_type, 1);
    oho->hp = h->hp.ptr;
    RB_OBJ_WRITE(obind->base.self, &oho->obj, val);
}
Ejemplo n.º 2
0
static void
clone_method(VALUE klass, ID mid, const rb_method_entry_t *me)
{
    VALUE newiseqval;
    if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) {
	rb_iseq_t *iseq;
	NODE *new_cref;
	newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass);
	GetISeqPtr(newiseqval, iseq);
	rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass, &new_cref);
	RB_OBJ_WRITE(iseq->self, &iseq->cref_stack, new_cref);
	rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
	RB_GC_GUARD(newiseqval);
    }
    else {
	rb_method_entry_set(klass, mid, me, me->flag);
    }
}
Ejemplo n.º 3
0
static void
rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass, NODE **new_cref_ptr)
{
    NODE *new_node;
    while (node) {
	if (node->nd_clss == old_klass) {
	    new_node = NEW_CREF(new_klass);
	    RB_OBJ_WRITE(new_node, &new_node->nd_next, node->nd_next);
	    *new_cref_ptr = new_node;
	    return;
	}
	new_node = NEW_CREF(node->nd_clss);
	node = node->nd_next;
	*new_cref_ptr = new_node;
	new_cref_ptr = &new_node->nd_next;
    }
    *new_cref_ptr = NULL;
}
Ejemplo n.º 4
0
static VALUE protected_call(VALUE data)
{
    struct protected_call_arg *parg = (struct protected_call_arg*)data;
    VALUE rv;

    if (!NIL_P(parg->svcctx->executing_thread)) {
        rb_raise(rb_eRuntimeError, "executing in another thread");
    }
    RB_OBJ_WRITE(parg->svcctx->base.self, &parg->svcctx->executing_thread, rb_thread_current());
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
    rv = (VALUE)rb_thread_call_without_gvl(parg->func, parg->data, oci8_unblock_func, parg->svcctx);
#else
    rv = rb_thread_blocking_region((VALUE(*)(void*))parg->func, parg->data, oci8_unblock_func, parg->svcctx);
#endif
    if ((sword)rv == OCI_ERROR) {
        if (oci8_get_error_code(oci8_errhp) == 1013) {
            rb_raise(eOCIBreak, "Canceled by user request.");
        }
    }
    return rv;
}
Ejemplo n.º 5
0
rb_method_entry_t *
rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
{
    rb_thread_t *th;
    rb_control_frame_t *cfp;
    int line;
    rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, 0, noex, klass);
    rb_method_definition_t *def = ALLOC(rb_method_definition_t);
    if (me->def && me->def->type == VM_METHOD_TYPE_REFINED) {
	me->def->body.orig_me->def = def;
    }
    else {
	me->def = def;
    }
    def->type = type;
    def->original_id = mid;
    def->alias_count = 0;
    switch (type) {
      case VM_METHOD_TYPE_ISEQ: {
	  rb_iseq_t *iseq = (rb_iseq_t *)opts;
	  *(rb_iseq_t **)&def->body.iseq = iseq;
	  RB_OBJ_WRITTEN(klass, Qundef, iseq->self);
	  break;
      }
      case VM_METHOD_TYPE_CFUNC:
	{
	    rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
	    setup_method_cfunc_struct(&def->body.cfunc, cfunc->func, cfunc->argc);
	}
	break;
      case VM_METHOD_TYPE_ATTRSET:
      case VM_METHOD_TYPE_IVAR:
	def->body.attr.id = (ID)(VALUE)opts;
	RB_OBJ_WRITE(klass, &def->body.attr.location, Qfalse);
	th = GET_THREAD();
	cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
	if (cfp && (line = rb_vm_get_sourceline(cfp))) {
	    VALUE location = rb_ary_new3(2, cfp->iseq->location.path, INT2FIX(line));
	    RB_OBJ_WRITE(klass, &def->body.attr.location, rb_ary_freeze(location));
	}
	break;
      case VM_METHOD_TYPE_BMETHOD:
	RB_OBJ_WRITE(klass, &def->body.proc, (VALUE)opts);
	break;
      case VM_METHOD_TYPE_NOTIMPLEMENTED:
	setup_method_cfunc_struct(&def->body.cfunc, rb_f_notimplement, -1);
	break;
      case VM_METHOD_TYPE_OPTIMIZED:
	def->body.optimize_type = (enum method_optimized_type)opts;
	break;
      case VM_METHOD_TYPE_ZSUPER:
      case VM_METHOD_TYPE_UNDEF:
	break;
      case VM_METHOD_TYPE_REFINED:
	def->body.orig_me = (rb_method_entry_t *) opts;
	break;
      default:
	rb_bug("rb_add_method: unsupported method type (%d)\n", type);
    }
    if (type != VM_METHOD_TYPE_UNDEF && type != VM_METHOD_TYPE_REFINED) {
	method_added(klass, mid);
    }
    return me;
}
Ejemplo n.º 6
0
static rb_method_entry_t *
rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type,
		     rb_method_definition_t *def, rb_method_flag_t noex,
		     VALUE defined_class)
{
    rb_method_entry_t *me;
#if NOEX_NOREDEF
    VALUE rklass;
#endif
    st_table *mtbl;
    st_data_t data;
    int make_refined = 0;

    if (NIL_P(klass)) {
	klass = rb_cObject;
    }
    if (!FL_TEST(klass, FL_SINGLETON) &&
	type != VM_METHOD_TYPE_NOTIMPLEMENTED &&
	type != VM_METHOD_TYPE_ZSUPER) {
	switch (mid) {
	  case idInitialize:
	  case idInitialize_copy:
	  case idInitialize_clone:
	  case idInitialize_dup:
	  case idRespond_to_missing:
	    noex |= NOEX_PRIVATE;
	}
    }

    rb_frozen_class_p(klass);
#if NOEX_NOREDEF
    rklass = klass;
#endif
    if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
	VALUE refined_class =
	    rb_refinement_module_get_refined_class(klass);

	rb_add_refined_method_entry(refined_class, mid);
    }
    if (type == VM_METHOD_TYPE_REFINED) {
	rb_method_entry_t *old_me =
	    lookup_method_table(RCLASS_ORIGIN(klass), mid);
	if (old_me) rb_vm_check_redefinition_opt_method(old_me, klass);
    }
    else {
	klass = RCLASS_ORIGIN(klass);
    }
    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;
#if NOEX_NOREDEF
	if (old_me->flag & NOEX_NOREDEF) {
	    rb_raise(rb_eTypeError, "cannot redefine %"PRIsVALUE"#%"PRIsVALUE,
		     rb_class_name(rklass), rb_id2str(mid));
	}
#endif
	rb_vm_check_redefinition_opt_method(old_me, klass);
	if (old_def->type == VM_METHOD_TYPE_REFINED)
	    make_refined = 1;

	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) {
	    rb_iseq_t *iseq = 0;

	    rb_warning("method redefined; discarding old %"PRIsVALUE, rb_id2str(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->location.path)) {
		int line = iseq->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq->self)) : 0;
		rb_compile_warning(RSTRING_PTR(iseq->location.path), line,
				   "previous definition of %"PRIsVALUE" was here",
				   rb_id2str(old_def->original_id));
	    }
	}

	rb_unlink_method_entry(old_me);
    }

    me = ALLOC(rb_method_entry_t);

    rb_clear_method_cache_by_class(klass);

    me->flag = NOEX_WITH_SAFE(noex);
    me->mark = 0;
    me->called_id = mid;
    RB_OBJ_WRITE(klass, &me->klass, defined_class);
    me->def = def;

    if (def) {
	def->alias_count++;

	switch(def->type) {
	  case VM_METHOD_TYPE_ISEQ:
	    RB_OBJ_WRITTEN(klass, Qundef, def->body.iseq->self);
	    break;
	  case VM_METHOD_TYPE_IVAR:
	    RB_OBJ_WRITTEN(klass, Qundef, def->body.attr.location);
	    break;
	  case VM_METHOD_TYPE_BMETHOD:
	    RB_OBJ_WRITTEN(klass, Qundef, def->body.proc);
	    break;
	  default:;
	    /* ignore */
	}
    }

    /* 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 && search_method(klass, mid, 0)) {
	    rb_warn("redefining `%s' may cause serious problems", rb_id2name(mid));
	}
    }

    if (make_refined) {
	make_method_entry_refined(me);
    }

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

    return me;
}