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); }
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); } }
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; }
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; }
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; }
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; }