VALUE so_respond_to(VALUE self, VALUE obj, VALUE sym) { return (VALUE)rb_respond_to(obj, SYM2ID(sym)); }
/* * call-seq: * Int32Array.new(100) => Int32Array * Int32Array.new("01234567") => Int32Array * Int32Array.new(buf, 20) => Int32Array * Int32Array.new(buf, 0, 20) => Int32Array * Int32Array.new(buf, 20, 20) => Int32Array * * Creates a new TypeArray instance. ArrayBuffer, data (String) and length constructors are supported. * * === Examples * buf = ArrayBuffer.new(100) => ArrayBuffer * * ary = Int32Array.new(buf, 20) => Int32Array * ary.length => 20 * ary.byte_length => 80 * ary.byte_offset => 20 * * ary = Int32Array.new(buf, 0, 20) => Int32Array * ary.length => 20 * ary.byte_length => 80 * ary.byte_offset => 0 * * ary = Int32Array.new(buf, 20, 20) => Int32Array * ary.length => 20 * ary.byte_length => 80 * ary.byte_offset => 20 * * ary = Int32Array.new("01234567") => Int32Array * ary.byte_length => 8 * ary.to_s => "01234567" * * ary = Int32Array.new(100) => Int32Array * ary.length => 100 * ary.byte_length => 400 */ static VALUE rb_type_array_s_new(int argc, VALUE *argv, VALUE klass) { VALUE type_array; VALUE obj, byte_offset, length; rb_type_array_t *array = NULL; unsigned long buffer_length, offset; if (klass == rb_cTypeArray) rb_raise(rb_eTypeError, "TypeArray cannot be instantiated directly."); rb_scan_args(argc, argv, "12", &obj, &byte_offset, &length); type_array = Data_Make_Struct(klass, rb_type_array_t, rb_mark_type_array, rb_free_type_array, array); if (klass != rb_cStructArray) { array->size = FIX2ULONG(rb_const_get(klass, rb_intern("BYTES_PER_ELEMENT"))); } array->byte_offset = 0; array->length = 0; if (klass == rb_cInt8Array) { array->aref_fn = rb_type_array_aref_int8; array->aset_fn = rb_type_array_aset_int8; array->mul_fn = rb_type_array_mul_int8; array->plus_fn = rb_type_array_plus_int8; array->minus_fn = rb_type_array_minus_int8; array->div_fn = rb_type_array_div_int8; array->eql_fn = rb_type_array_eql_int8; } else if (klass == rb_cUInt8Array) { array->aref_fn = rb_type_array_aref_uint8; array->aset_fn = rb_type_array_aset_uint8; array->mul_fn = rb_type_array_mul_uint8; array->plus_fn = rb_type_array_plus_uint8; array->minus_fn = rb_type_array_minus_uint8; array->div_fn = rb_type_array_div_uint8; array->eql_fn = rb_type_array_eql_uint8; } else if (klass == rb_cInt16Array) { array->aref_fn = rb_type_array_aref_int16; array->aset_fn = rb_type_array_aset_int16; array->mul_fn = rb_type_array_mul_int16; array->plus_fn = rb_type_array_plus_int16; array->minus_fn = rb_type_array_minus_int16; array->div_fn = rb_type_array_div_int16; array->eql_fn = rb_type_array_eql_int16; } else if (klass == rb_cUInt16Array) { array->aref_fn = rb_type_array_aref_uint16; array->aset_fn = rb_type_array_aset_uint16; array->mul_fn = rb_type_array_mul_uint16; array->plus_fn = rb_type_array_plus_uint16; array->minus_fn = rb_type_array_minus_uint16; array->div_fn = rb_type_array_div_uint16; array->eql_fn = rb_type_array_eql_uint16; } else if (klass == rb_cInt32Array) { array->aref_fn = rb_type_array_aref_int32; array->aset_fn = rb_type_array_aset_int32; array->mul_fn = rb_type_array_mul_int32; array->plus_fn = rb_type_array_plus_int32; array->minus_fn = rb_type_array_minus_int32; array->div_fn = rb_type_array_div_int32; array->eql_fn = rb_type_array_eql_int32; } else if (klass == rb_cUInt32Array) { array->aref_fn = rb_type_array_aref_uint32; array->aset_fn = rb_type_array_aset_uint32; array->mul_fn = rb_type_array_mul_uint32; array->plus_fn = rb_type_array_plus_uint32; array->minus_fn = rb_type_array_minus_uint32; array->div_fn = rb_type_array_div_uint32; array->eql_fn = rb_type_array_eql_uint32; } else if (klass == rb_cFloat32Array) { array->aref_fn = rb_type_array_aref_float32; array->aset_fn = rb_type_array_aset_float32; array->mul_fn = rb_type_array_mul_float32; array->plus_fn = rb_type_array_plus_float32; array->minus_fn = rb_type_array_minus_float32; array->div_fn = rb_type_array_div_float32; array->eql_fn = rb_type_array_eql_float32; } else if (klass == rb_cFloat64Array) { array->aref_fn = rb_type_array_aref_float64; array->aset_fn = rb_type_array_aset_float64; array->mul_fn = rb_type_array_mul_float64; array->plus_fn = rb_type_array_plus_float64; array->minus_fn = rb_type_array_minus_float64; array->div_fn = rb_type_array_div_float64; array->eql_fn = rb_type_array_eql_float64; } else if (klass == rb_cStructArray) { array->aref_fn = rb_type_array_aref_struct; array->aset_fn = rb_type_array_aset_struct; } if (FIXNUM_P(obj)) { array->length = FIX2ULONG(obj); array->byte_length = (array->length * array->size); array->buf = rb_alloc_array_buffer(array->byte_length, NULL); } else if (rb_type(obj) == T_STRING) { array->byte_length = (unsigned long)RSTRING_LEN(obj); array->length = (array->byte_length / array->size); ArrayBufferEncode(obj); array->buf = rb_alloc_array_buffer(array->byte_length, (void *)RSTRING_PTR(obj)); } else if (rb_class_of(obj) == rb_cArrayBuffer) { GetArrayBuffer(obj); if (!NIL_P(byte_offset)) { Check_Type(byte_offset, T_FIXNUM); array->byte_offset = FIX2ULONG(byte_offset); if (!rb_type_array_assert_alignment(array->byte_offset, array->size)) rb_raise(rb_eRangeError, "Byte offset is not aligned."); } buffer_length = buf->length; if (!NIL_P(length)) { Check_Type(length, T_FIXNUM); array->length = FIX2ULONG(length); array->byte_length = array->length * array->size; } else { array->byte_length = buffer_length - array->byte_offset; } if ((array->byte_offset + array->byte_length) > buffer_length) rb_raise(rb_eRangeError, "Byte offset / length is not aligned."); if (array->length == 0) array->length = array->byte_length / array->size; if (array->byte_offset > buffer_length || array->byte_offset + array->length > buffer_length || array->byte_offset + array->length * array->size > buffer_length) { rb_raise(rb_eRangeError, "Length is out of range."); } array->buf = obj; } else if (rb_obj_is_kind_of(obj, rb_cTypeArray) == Qtrue) { GetTypeArray(obj); array->length = ary->length; array->byte_length = (array->size * array->length); array->buf = rb_alloc_array_buffer(array->byte_length, NULL); array->byte_offset = 0; for (offset = 0; offset < array->length; ++offset) { VALUE offs = INT2FIX(offset); VALUE val = rb_funcall(obj, rb_type_array_intern_aget, 1, offs); rb_funcall(type_array, rb_type_array_intern_aset, 2, offs, val); } } else if (rb_respond_to(obj, rb_type_array_intern_superclass) && (rb_funcall(obj, rb_type_array_intern_superclass, 0) == rb_cStructType)) { array->struct_type = obj; array->size = FIX2ULONG(rb_const_get(obj, rb_intern("BYTES_PER_ELEMENT"))); if (!NIL_P(byte_offset)) { Check_Type(byte_offset, T_FIXNUM); array->byte_offset = FIX2ULONG(byte_offset); if (!rb_type_array_assert_alignment(array->byte_offset, array->size)) rb_raise(rb_eRangeError, "Byte offset is not aligned."); } if (!NIL_P(length)) { Check_Type(length, T_FIXNUM); array->length = FIX2ULONG(length); } else { array->length = 1; } array->byte_length = (array->size * array->length); array->buf = rb_alloc_array_buffer(array->byte_length, NULL); } else { rb_raise(rb_eTypeError, "TypeArray constructor %s not supported.", RSTRING_PTR(rb_obj_as_string(obj))); } rb_obj_call_init(type_array, 0, NULL); return type_array; }
void check_image(VALUE image) { if(!rb_respond_to(image, rb_intern("gl_tex_info"))) rb_raise(rb_eRuntimeError,"must specify a valid source image"); }
/* * call-seq: * parser.parse(yaml) * * Parse the YAML document contained in +yaml+. Events will be called on * the handler set on the parser instance. * * See Psych::Parser and Psych::Parser#handler */ static VALUE parse(VALUE self, VALUE yaml) { yaml_parser_t * parser; yaml_event_t event; int done = 0; #ifdef HAVE_RUBY_ENCODING_H int encoding = rb_utf8_encindex(); rb_encoding * internal_enc = rb_default_internal_encoding(); #endif VALUE handler = rb_iv_get(self, "@handler"); Data_Get_Struct(self, yaml_parser_t, parser); if(rb_respond_to(yaml, id_read)) { yaml_parser_set_input(parser, io_reader, (void *)yaml); } else { StringValue(yaml); yaml_parser_set_input_string( parser, (const unsigned char *)RSTRING_PTR(yaml), (size_t)RSTRING_LEN(yaml) ); } while(!done) { if(!yaml_parser_parse(parser, &event)) { size_t line = parser->mark.line; size_t column = parser->mark.column; rb_raise(ePsychSyntaxError, "couldn't parse YAML at line %d column %d", (int)line, (int)column); } switch(event.type) { case YAML_STREAM_START_EVENT: rb_funcall(handler, id_start_stream, 1, INT2NUM((long)event.data.stream_start.encoding) ); break; case YAML_DOCUMENT_START_EVENT: { /* Get a list of tag directives (if any) */ VALUE tag_directives = rb_ary_new(); /* Grab the document version */ VALUE version = event.data.document_start.version_directive ? rb_ary_new3( (long)2, INT2NUM((long)event.data.document_start.version_directive->major), INT2NUM((long)event.data.document_start.version_directive->minor) ) : rb_ary_new(); if(event.data.document_start.tag_directives.start) { yaml_tag_directive_t *start = event.data.document_start.tag_directives.start; yaml_tag_directive_t *end = event.data.document_start.tag_directives.end; for(; start != end; start++) { VALUE handle = Qnil; VALUE prefix = Qnil; if(start->handle) { handle = rb_str_new2((const char *)start->handle); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(handle, encoding, internal_enc); #endif } if(start->prefix) { prefix = rb_str_new2((const char *)start->prefix); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(prefix, encoding, internal_enc); #endif } rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix)); } } rb_funcall(handler, id_start_document, 3, version, tag_directives, event.data.document_start.implicit == 1 ? Qtrue : Qfalse ); } break; case YAML_DOCUMENT_END_EVENT: rb_funcall(handler, id_end_document, 1, event.data.document_end.implicit == 1 ? Qtrue : Qfalse ); break; case YAML_ALIAS_EVENT: { VALUE alias = Qnil; if(event.data.alias.anchor) { alias = rb_str_new2((const char *)event.data.alias.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(alias, encoding, internal_enc); #endif } rb_funcall(handler, id_alias, 1, alias); } break; case YAML_SCALAR_EVENT: { VALUE anchor = Qnil; VALUE tag = Qnil; VALUE plain_implicit, quoted_implicit, style; VALUE val = rb_str_new( (const char *)event.data.scalar.value, (long)event.data.scalar.length ); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(val, encoding, internal_enc); #endif if(event.data.scalar.anchor) { anchor = rb_str_new2((const char *)event.data.scalar.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } if(event.data.scalar.tag) { tag = rb_str_new2((const char *)event.data.scalar.tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } plain_implicit = event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue; quoted_implicit = event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.scalar.style); rb_funcall(handler, id_scalar, 6, val, anchor, tag, plain_implicit, quoted_implicit, style); } break; case YAML_SEQUENCE_START_EVENT: { VALUE anchor = Qnil; VALUE tag = Qnil; VALUE implicit, style; if(event.data.sequence_start.anchor) { anchor = rb_str_new2((const char *)event.data.sequence_start.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } tag = Qnil; if(event.data.sequence_start.tag) { tag = rb_str_new2((const char *)event.data.sequence_start.tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } implicit = event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.sequence_start.style); rb_funcall(handler, id_start_sequence, 4, anchor, tag, implicit, style); } break; case YAML_SEQUENCE_END_EVENT: rb_funcall(handler, id_end_sequence, 0); break; case YAML_MAPPING_START_EVENT: { VALUE anchor = Qnil; VALUE tag = Qnil; VALUE implicit, style; if(event.data.mapping_start.anchor) { anchor = rb_str_new2((const char *)event.data.mapping_start.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } if(event.data.mapping_start.tag) { tag = rb_str_new2((const char *)event.data.mapping_start.tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } implicit = event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.mapping_start.style); rb_funcall(handler, id_start_mapping, 4, anchor, tag, implicit, style); } break; case YAML_MAPPING_END_EVENT: rb_funcall(handler, id_end_mapping, 0); break; case YAML_NO_EVENT: rb_funcall(handler, id_empty, 0); break; case YAML_STREAM_END_EVENT: rb_funcall(handler, id_end_stream, 0); done = 1; break; } } return self; }
static void handle_timer_event( void *self ) { if ( rb_respond_to( ( VALUE ) self, rb_intern( "handle_timer_event" ) ) == Qtrue ) { rb_funcall( ( VALUE ) self, rb_intern( "handle_timer_event" ), 0 ); } }
static void handle_controller_connected( void *rbswitch ) { if ( rb_respond_to( ( VALUE ) rbswitch, rb_intern( "controller_connected" ) ) == Qtrue ) { rb_funcall( ( VALUE ) rbswitch, rb_intern( "controller_connected" ), 0 ); } }
void RubyState::update(int elapsed) { if(rb_respond_to(_rubyObject, UpdateMethod)) { rb_funcall(_rubyObject, UpdateMethod, 1, INT2FIX(elapsed)); } }
static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data) { Closure* closure = (Closure *) user_data; Function* fn = (Function *) closure->info; FunctionType *cbInfo = fn->info; VALUE* rbParams; VALUE rbReturnValue; int i; rbParams = ALLOCA_N(VALUE, cbInfo->parameterCount); for (i = 0; i < cbInfo->parameterCount; ++i) { VALUE param; switch (cbInfo->parameterTypes[i]->nativeType) { case NATIVE_INT8: param = INT2NUM(*(int8_t *) parameters[i]); break; case NATIVE_UINT8: param = UINT2NUM(*(uint8_t *) parameters[i]); break; case NATIVE_INT16: param = INT2NUM(*(int16_t *) parameters[i]); break; case NATIVE_UINT16: param = UINT2NUM(*(uint16_t *) parameters[i]); break; case NATIVE_INT32: param = INT2NUM(*(int32_t *) parameters[i]); break; case NATIVE_UINT32: param = UINT2NUM(*(uint32_t *) parameters[i]); break; case NATIVE_INT64: param = LL2NUM(*(int64_t *) parameters[i]); break; case NATIVE_UINT64: param = ULL2NUM(*(uint64_t *) parameters[i]); break; case NATIVE_LONG: param = LONG2NUM(*(long *) parameters[i]); break; case NATIVE_ULONG: param = ULONG2NUM(*(unsigned long *) parameters[i]); break; case NATIVE_FLOAT32: param = rb_float_new(*(float *) parameters[i]); break; case NATIVE_FLOAT64: param = rb_float_new(*(double *) parameters[i]); break; case NATIVE_STRING: param = (*(void **) parameters[i] != NULL) ? rb_tainted_str_new2(*(char **) parameters[i]) : Qnil; break; case NATIVE_POINTER: param = rbffi_Pointer_NewInstance(*(void **) parameters[i]); break; case NATIVE_BOOL: param = (*(void **) parameters[i]) ? Qtrue : Qfalse; break; case NATIVE_FUNCTION: case NATIVE_CALLBACK: param = rbffi_NativeValue_ToRuby(cbInfo->parameterTypes[i], rb_ary_entry(cbInfo->rbParameterTypes, i), parameters[i], Qnil); break; default: param = Qnil; break; } rbParams[i] = param; } rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams); if (rbReturnValue == Qnil || TYPE(rbReturnValue) == T_NIL) { memset(retval, 0, cbInfo->ffiReturnType->size); } else switch (cbInfo->returnType->nativeType) { case NATIVE_INT8: case NATIVE_INT16: case NATIVE_INT32: *((ffi_sarg *) retval) = NUM2INT(rbReturnValue); break; case NATIVE_UINT8: case NATIVE_UINT16: case NATIVE_UINT32: *((ffi_arg *) retval) = NUM2UINT(rbReturnValue); break; case NATIVE_INT64: *((int64_t *) retval) = NUM2LL(rbReturnValue); break; case NATIVE_UINT64: *((uint64_t *) retval) = NUM2ULL(rbReturnValue); break; case NATIVE_LONG: *((ffi_sarg *) retval) = NUM2LONG(rbReturnValue); break; case NATIVE_ULONG: *((ffi_arg *) retval) = NUM2ULONG(rbReturnValue); break; case NATIVE_FLOAT32: *((float *) retval) = (float) NUM2DBL(rbReturnValue); break; case NATIVE_FLOAT64: *((double *) retval) = NUM2DBL(rbReturnValue); break; case NATIVE_POINTER: if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) { *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address; } else { // Default to returning NULL if not a value pointer object. handles nil case as well *((void **) retval) = NULL; } break; case NATIVE_BOOL: *((ffi_sarg *) retval) = TYPE(rbReturnValue) == T_TRUE ? 1 : 0; break; case NATIVE_FUNCTION: case NATIVE_CALLBACK: if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) { *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address; } else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) { VALUE function; function = rbffi_Function_ForProc(cbInfo->rbReturnType, rbReturnValue); *((void **) retval) = ((AbstractMemory *) DATA_PTR(function))->address; } else { *((void **) retval) = NULL; } break; default: *((ffi_arg *) retval) = 0; break; } }
VALUE rb_object_free(VALUE obj) { ID id_destructor = rb_intern("__destruct__"); /* value returned by destructor */ VALUE destruct_value = Qnil; /* prevent freeing of immediates */ switch (TYPE(obj)) { case T_NIL: case T_FIXNUM: case T_TRUE: case T_FALSE: case T_SYMBOL: rb_raise(rb_eTypeError, "obj_free() called for immediate value"); break; } /* prevent freeing of *some* critical objects */ if ((obj == rb_cObject) || (obj == rb_cClass) || (obj == rb_cModule) || (obj == rb_cSymbol) || (obj == rb_cFixnum) || (obj == rb_cFloat) || (obj == rb_cString) || (obj == rb_cRegexp) || (obj == rb_cInteger) || (obj == rb_cArray) || (obj == rb_cNilClass) || (obj == rb_cFalseClass) || (obj == rb_cTrueClass) || (obj == rb_cNumeric) || (obj == rb_cBignum) || (obj == rb_cStruct)) rb_raise(rb_eTypeError, "obj_free() called for critical object"); /* run destructor (if one is defined) */ if (rb_respond_to(obj, id_destructor)) destruct_value = rb_funcall(obj, id_destructor, 0); #ifdef RUBY_19 switch (BUILTIN_TYPE(obj)) { case T_NIL: case T_FIXNUM: case T_TRUE: case T_FALSE: rb_bug("obj_free() called for broken object"); break; } if (FL_TEST(obj, FL_EXIVAR)) { rb_free_generic_ivar((VALUE)obj); FL_UNSET(obj, FL_EXIVAR); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) && RANY(obj)->as.object.as.heap.ivptr) { xfree(RANY(obj)->as.object.as.heap.ivptr); } break; case T_MODULE: case T_CLASS: rb_clear_cache_by_class((VALUE)obj); rb_free_m_table(RCLASS_M_TBL(obj)); if (RCLASS_IV_TBL(obj)) { st_free_table(RCLASS_IV_TBL(obj)); } if (RCLASS_IV_INDEX_TBL(obj)) { st_free_table(RCLASS_IV_INDEX_TBL(obj)); } xfree(RANY(obj)->as.klass.ptr); break; case T_STRING: rb_str_free(obj); break; case T_ARRAY: rb_ary_free(obj); break; case T_HASH: if (RANY(obj)->as.hash.ntbl) { st_free_table(RANY(obj)->as.hash.ntbl); } break; case T_REGEXP: if (RANY(obj)->as.regexp.ptr) { onig_free(RANY(obj)->as.regexp.ptr); } break; case T_DATA: if (DATA_PTR(obj)) { if (RTYPEDDATA_P(obj)) { RDATA(obj)->dfree = RANY(obj)->as.typeddata.type->dfree; } if ((long)RANY(obj)->as.data.dfree == -1) { xfree(DATA_PTR(obj)); } else if (RANY(obj)->as.data.dfree) { make_deferred(RANY(obj)); return 1; } } break; case T_MATCH: if (RANY(obj)->as.match.rmatch) { struct rmatch *rm = RANY(obj)->as.match.rmatch; onig_region_free(&rm->regs, 0); if (rm->char_offset) xfree(rm->char_offset); xfree(rm); } break; case T_FILE: if (RANY(obj)->as.file.fptr) { make_io_deferred(RANY(obj)); return 1; } break; case T_RATIONAL: case T_COMPLEX: break; case T_ICLASS: /* iClass shares table with the module */ xfree(RANY(obj)->as.klass.ptr); break; case T_FLOAT: break; case T_BIGNUM: if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) { xfree(RBIGNUM_DIGITS(obj)); } break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: if (RANY(obj)->as.node.u1.tbl) { xfree(RANY(obj)->as.node.u1.tbl); } break; case NODE_ALLOCA: xfree(RANY(obj)->as.node.u1.node); break; } break; /* no need to free iv_tbl */ case T_STRUCT: if ((RBASIC(obj)->flags & RSTRUCT_EMBED_LEN_MASK) == 0 && RANY(obj)->as.rstruct.as.heap.ptr) { xfree(RANY(obj)->as.rstruct.as.heap.ptr); } break; default: rb_bug("gc_sweep(): unknown data type 0x%x(%p)", BUILTIN_TYPE(obj), (void*)obj); } #else switch (BUILTIN_TYPE(obj)) { case T_NIL: case T_FIXNUM: case T_TRUE: case T_FALSE: rb_bug("obj_free() called for broken object"); break; } if (FL_TEST(obj, FL_EXIVAR)) { rb_free_generic_ivar((VALUE)obj); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); } break; case T_MODULE: case T_CLASS: rb_clear_cache_by_class((VALUE)obj); st_free_table(RANY(obj)->as.klass.m_tbl); if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); } break; case T_STRING: if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); } break; case T_ARRAY: if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); } break; case T_HASH: if (RANY(obj)->as.hash.tbl) { st_free_table(RANY(obj)->as.hash.tbl); } break; case T_REGEXP: if (RANY(obj)->as.regexp.ptr) { re_free_pattern(RANY(obj)->as.regexp.ptr); } if (RANY(obj)->as.regexp.str) { RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); } break; case T_DATA: if (DATA_PTR(obj)) { if ((long)RANY(obj)->as.data.dfree == -1) { RUBY_CRITICAL(free(DATA_PTR(obj))); } else if (RANY(obj)->as.data.dfree) { make_deferred(RANY(obj)); return 1; } } break; case T_MATCH: if (RANY(obj)->as.match.regs) { re_free_registers(RANY(obj)->as.match.regs); RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); } break; case T_FILE: if (RANY(obj)->as.file.fptr) { struct rb_io_t *fptr = RANY(obj)->as.file.fptr; make_deferred(RANY(obj)); RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize; RDATA(obj)->data = fptr; return 1; } break; case T_ICLASS: /* iClass shares table with the module */ break; case T_FLOAT: case T_VARMAP: case T_BLKTAG: break; case T_BIGNUM: if (RANY(obj)->as.bignum.digits) { RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); } break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: if (RANY(obj)->as.node.u1.tbl) { RUBY_CRITICAL(free(RANY(obj)->as.node.u1.tbl)); } break; case NODE_ALLOCA: RUBY_CRITICAL(free(RANY(obj)->as.node.u1.node)); break; } break; /* no need to free iv_tbl */ case T_SCOPE: if (RANY(obj)->as.scope.local_vars && RANY(obj)->as.scope.flags != SCOPE_ALLOCA) { VALUE *vars = RANY(obj)->as.scope.local_vars-1; if (!(RANY(obj)->as.scope.flags & SCOPE_CLONE) && vars[0] == 0) RUBY_CRITICAL(free(RANY(obj)->as.scope.local_tbl)); if ((RANY(obj)->as.scope.flags & (SCOPE_MALLOC|SCOPE_CLONE)) == SCOPE_MALLOC) RUBY_CRITICAL(free(vars)); } break; case T_STRUCT: if (RANY(obj)->as.rstruct.ptr) { RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); } break; default: rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", RANY(obj)->as.basic.flags & T_MASK, obj); } #endif rb_gc_force_recycle(obj); return destruct_value; }
/* * call-seq: * combatible?(obj) * * Return compatibility to CvPoint3D32f. Return true if object have method #x and #y and #z. * * For example. * class MyPoint3D32f * def x * 95.7 * end * def y * 70.2 * end * def z * 10.0 * end * end * mp = MyPoint3D32f.new * CvPoint3D32f.compatible?(mp) #=> true * CvPoint3D32f.new(mp) #=> same as CvPoint3D32f(95.7, 70.2) */ VALUE rb_compatible_q(VALUE klass, VALUE object) { return (rb_respond_to(object, rb_intern("x")) && rb_respond_to(object, rb_intern("y"))) ? Qtrue : Qfalse; }
static VALUE range_step(int argc, VALUE *argv, VALUE range) { VALUE b, e, step, tmp; RETURN_ENUMERATOR(range, argc, argv); b = RANGE_BEG(range); e = RANGE_END(range); if (argc == 0) { step = INT2FIX(1); } else { rb_scan_args(argc, argv, "01", &step); if (!rb_obj_is_kind_of(step, rb_cNumeric)) { step = rb_to_int(step); } if (rb_funcall(step, '<', 1, INT2FIX(0))) { rb_raise(rb_eArgError, "step can't be negative"); } else if (!rb_funcall(step, '>', 1, INT2FIX(0))) { rb_raise(rb_eArgError, "step can't be 0"); } } if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */ long end = FIX2LONG(e); long i, unit = FIX2LONG(step); if (!EXCL(range)) end += 1; i = FIX2LONG(b); while (i < end) { rb_yield(LONG2NUM(i)); if (i + unit < i) break; i += unit; } } else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */ VALUE args[2], iter[2]; args[0] = rb_sym_to_s(e); args[1] = EXCL(range) ? Qtrue : Qfalse; iter[0] = INT2FIX(1); iter[1] = step; rb_block_call(rb_sym_to_s(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter); } else if (ruby_float_step(b, e, step, EXCL(range))) { /* done */ } else if (rb_obj_is_kind_of(b, rb_cNumeric) || !NIL_P(rb_check_to_integer(b, "to_int")) || !NIL_P(rb_check_to_integer(e, "to_int"))) { ID op = EXCL(range) ? '<' : rb_intern("<="); VALUE v = b; int i = 0; while (RTEST(rb_funcall(v, op, 1, e))) { rb_yield(v); i++; v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step)); } } else { tmp = rb_check_string_type(b); if (!NIL_P(tmp)) { VALUE args[2], iter[2]; b = tmp; args[0] = e; args[1] = EXCL(range) ? Qtrue : Qfalse; iter[0] = INT2FIX(1); iter[1] = step; rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter); } else { VALUE args[2]; if (!rb_respond_to(b, id_succ)) { rb_raise(rb_eTypeError, "can't iterate from %s", rb_obj_classname(b)); } args[0] = INT2FIX(1); args[1] = step; range_each_func(range, step_i, args); } } return range; }
static void handle_set_config( uint32_t transaction_id, uint16_t flags, uint16_t miss_send_len, void *rbswitch ) { if ( rb_respond_to( ( VALUE ) rbswitch, rb_intern( "set_config" ) ) == Qtrue ) { rb_funcall( ( VALUE ) rbswitch, rb_intern( "set_config" ), 3, UINT2NUM( transaction_id ), UINT2NUM( flags ), UINT2NUM( miss_send_len ) ); } }
static void handle_features_request( uint32_t transaction_id, void *rbswitch ) { if ( rb_respond_to( ( VALUE ) rbswitch, rb_intern( "features_request" ) ) == Qtrue ) { rb_funcall( ( VALUE ) rbswitch, rb_intern( "features_request" ), 1, UINT2NUM( transaction_id ) ); } }
static void handle_hello( uint32_t transaction_id, uint8_t version, void *rbswitch ) { if ( rb_respond_to( ( VALUE ) rbswitch, rb_intern( "hello" ) ) == Qtrue ) { rb_funcall( ( VALUE ) rbswitch, rb_intern( "hello" ), 2, UINT2NUM( transaction_id ), UINT2NUM( version ) ); } }
static int discrete_object_p(VALUE obj) { if (rb_obj_is_kind_of(obj, rb_cTime)) return FALSE; /* until Time#succ removed */ return rb_respond_to(obj, id_succ); }
void RubyState::draw() { if(rb_respond_to(_rubyObject, DrawMethod)) { rb_funcall(_rubyObject, DrawMethod, 0); } }
bool Rice::Object:: respond_to(Identifier id) const { return bool(rb_respond_to(*this, id)); }
void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) { VALUE str, outBuff, otherObj; yajl_encoder_wrapper * w = wrapper; yajl_gen_status status; int idx = 0; const unsigned char * buffer; const char * cptr; unsigned int len; if (io != Qnil || w->on_progress_callback != Qnil) { status = yajl_gen_get_buf(w->encoder, &buffer, &len); if (len >= WRITE_BUFSIZE) { outBuff = rb_str_new((const char *)buffer, len); if (io != Qnil) { rb_io_write(io, outBuff); } else if (w->on_progress_callback != Qnil) { rb_funcall(w->on_progress_callback, intern_call, 1, outBuff); } yajl_gen_clear(w->encoder); } } switch (TYPE(obj)) { case T_HASH: status = yajl_gen_map_open(w->encoder); /* TODO: itterate through keys in the hash */ VALUE keys = rb_funcall(obj, intern_keys, 0); VALUE entry, keyStr; for(idx=0; idx<RARRAY_LEN(keys); idx++) { entry = rb_ary_entry(keys, idx); keyStr = rb_funcall(entry, intern_to_s, 0); /* key must be a string */ /* the key */ yajl_encode_part(w, keyStr, io); /* the value */ yajl_encode_part(w, rb_hash_aref(obj, entry), io); } status = yajl_gen_map_close(w->encoder); break; case T_ARRAY: status = yajl_gen_array_open(w->encoder); for(idx=0; idx<RARRAY_LEN(obj); idx++) { otherObj = rb_ary_entry(obj, idx); yajl_encode_part(w, otherObj, io); } status = yajl_gen_array_close(w->encoder); break; case T_NIL: status = yajl_gen_null(w->encoder); break; case T_TRUE: status = yajl_gen_bool(w->encoder, 1); break; case T_FALSE: status = yajl_gen_bool(w->encoder, 0); break; case T_FIXNUM: case T_FLOAT: case T_BIGNUM: str = rb_funcall(obj, intern_to_s, 0); cptr = RSTRING_PTR(str); len = RSTRING_LEN(str); if (memcmp(cptr, "NaN", 3) == 0 || memcmp(cptr, "Infinity", 8) == 0 || memcmp(cptr, "-Infinity", 9) == 0) { rb_raise(cEncodeError, "'%s' is an invalid number", cptr); } status = yajl_gen_number(w->encoder, cptr, len); break; default: if (rb_respond_to(obj, intern_to_json)) { str = rb_funcall(obj, intern_to_json, 0); cptr = RSTRING_PTR(str); len = RSTRING_LEN(str); status = yajl_gen_number(w->encoder, cptr, len); } else { if (TYPE(obj) != T_STRING) { str = rb_funcall(obj, intern_to_s, 0); }else { str = obj; } cptr = RSTRING_PTR(str); len = RSTRING_LEN(str); status = yajl_gen_string(w->encoder, (const unsigned char *)cptr, len); } break; } }