PRIMITIVE VALUE vm_get_const(VALUE outer, void *cache_p, ID path, int flags) { struct ccache *cache = (struct ccache *)cache_p; rb_vm_outer_t *outer_stack = rb_vm_get_outer_stack(); GC_RETAIN(outer_stack); const bool lexical_lookup = (flags & CONST_LOOKUP_LEXICAL); const bool dynamic_class = (flags & CONST_LOOKUP_DYNAMIC_CLASS); if (dynamic_class && lexical_lookup) { outer = rb_vm_get_const_base(); } VALUE val; if (cache->outer == outer && cache->outer_stack == outer_stack && cache->val != Qundef) { val = cache->val; } else { val = rb_vm_const_lookup_level(outer, path, lexical_lookup, false, outer_stack); cache->outer = outer; GC_RELEASE(cache->outer_stack); cache->outer_stack = outer_stack; GC_RETAIN(cache->outer_stack); cache->val = val; } GC_RELEASE(outer_stack); return val; }
static VALUE rb_block_release_eval(VALUE data) { GC_RELEASE(data); rb_vm_block_t *b = (rb_vm_block_t *)data; return rb_vm_block_eval(b, 0, NULL); }
force_inline rb_vm_block_t * RoxorVM::uncache_or_create_block(void *key, bool *cached, int dvars_size) { std::map<void *, rb_vm_block_t *>::iterator iter = blocks.find(key); rb_vm_block_t *b; const int create_block_mask = VM_BLOCK_ACTIVE | VM_BLOCK_PROC | VM_BLOCK_IFUNC; if ((iter == blocks.end()) || (iter->second->flags & create_block_mask)) { const bool is_ifunc = (iter != blocks.end()) && ((iter->second->flags & VM_BLOCK_IFUNC) == VM_BLOCK_IFUNC); b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t) + (sizeof(VALUE *) * dvars_size)); if (!is_ifunc) { if (iter != blocks.end()) { GC_RELEASE(iter->second); } GC_RETAIN(b); blocks[key] = b; } *cached = false; } else { b = iter->second; *cached = true; } return b; }
void rb_jump_tag(int state) { assert(state > 0); VALUE exc = protect_exc; assert(exc != Qnil); protect_exc = Qnil; GC_RELEASE(exc); rb_exc_raise(exc); }
static VALUE rb_queue_apply(VALUE self, SEL sel, VALUE n) { rb_vm_block_t *block = get_prepared_block(); dispatch_apply_f(NUM2SIZET(n), RQueue(self)->queue, (void *)block, rb_block_applier); GC_RELEASE(block); return Qnil; }
rb_vm_block_t * RoxorVM::uncache_or_dup_block(rb_vm_block_t *b) { void *key = (void *)b->imp; std::map<void *, rb_vm_block_t *>::iterator iter = blocks.find(key); if (iter == blocks.end() || iter->second->self != b->self) { if (iter != blocks.end()) { GC_RELEASE(iter->second); } b = dup_block(b); GC_RETAIN(b); blocks[key] = b; } else { b = iter->second; } return b; }
static void release_cb(CFAllocatorRef allocator, const void *v) { GC_RELEASE(v); }
void rb_node_release(NODE *node) { if (node == NULL || node == (NODE *)-1) { return; } // static int c = 0; // printf("%d RELEASE %s %p\n", ++c, ruby_node_name(nd_type(node)), node); switch (nd_type(node)) { case NODE_IF: /* 1,2,3 */ case NODE_FOR: case NODE_ITER: case NODE_WHEN: case NODE_MASGN: case NODE_RESCUE: case NODE_RESBODY: case NODE_CLASS: case NODE_BLOCK_PASS: rb_node_release(node->u2.node); /* fall through */ case NODE_BLOCK: /* 1,3 */ case NODE_OPTBLOCK: case NODE_ARRAY: case NODE_ENSURE: case NODE_CALL: case NODE_DEFS: case NODE_OP_ASGN1: case NODE_ARGS: rb_node_release(node->u1.node); /* fall through */ case NODE_SUPER: /* 3 */ case NODE_FCALL: case NODE_DEFN: case NODE_ARGS_AUX: rb_node_release(node->u3.node); break; case NODE_WHILE: /* 1,2 */ case NODE_UNTIL: case NODE_AND: case NODE_OR: case NODE_CASE: case NODE_SCLASS: case NODE_DOT2: case NODE_DOT3: case NODE_FLIP2: case NODE_FLIP3: case NODE_MATCH2: case NODE_MATCH3: case NODE_OP_ASGN_OR: case NODE_OP_ASGN_AND: case NODE_MODULE: case NODE_ARGSCAT: rb_node_release(node->u1.node); /* fall through */ case NODE_FBODY: /* 2 */ case NODE_GASGN: case NODE_LASGN: case NODE_DASGN: case NODE_DASGN_CURR: case NODE_IASGN: case NODE_IASGN2: case NODE_CVASGN: case NODE_OPT_N: case NODE_EVSTR: case NODE_UNDEF: case NODE_POSTEXE: rb_node_release(node->u2.node); break; case NODE_HASH: /* 1 */ case NODE_DEFINED: case NODE_RETURN: case NODE_BREAK: case NODE_NEXT: case NODE_YIELD: case NODE_COLON2: case NODE_SPLAT: case NODE_TO_ARY: rb_node_release(node->u1.node); break; case NODE_SCOPE: /* 2,3 */ case NODE_CDECL: case NODE_OPT_ARG: rb_node_release(node->u3.node); rb_node_release(node->u2.node); break; } // c--; // Some NODE structures are apparently reused somewhere in parserland. const int count = auto_zone_retain_count(__auto_zone, node); if (count > 0) { node->u1.node = node->u2.node = node->u3.node = NULL; GC_RELEASE(node); } }