Пример #1
0
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;
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
static void
release_cb(CFAllocatorRef allocator, const void *v)
{
    GC_RELEASE(v);
}
Пример #8
0
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);
    }
}