Exemplo n.º 1
0
static NODE *
new_assign(NODE * lnode, NODE * rhs)
{
    switch (nd_type(lnode)) {
      case NODE_LASGN:{
	  return NEW_NODE(NODE_LASGN, lnode->nd_vid, rhs, lnode->nd_cnt);
	  /* NEW_LASGN(lnode->nd_vid, rhs); */
      }
      case NODE_GASGN:{
	  return NEW_GASGN(lnode->nd_vid, rhs);
      }
      case NODE_DASGN:{
	  return NEW_DASGN(lnode->nd_vid, rhs);
      }
      case NODE_ATTRASGN:{
	  NODE *args = 0;
	  if (lnode->nd_args) {
	      args = NEW_ARRAY(lnode->nd_args->nd_head);
	      args->nd_next = NEW_ARRAY(rhs);
	      args->nd_alen = 2;
	  }
	  else {
	      args = NEW_ARRAY(rhs);
	  }

	  return NEW_ATTRASGN(lnode->nd_recv,
			      lnode->nd_mid,
			      args);
      }
      default:
	rb_bug("unimplemented (block inlining): %s", ruby_node_name(nd_type(lnode)));
    }
    return 0;
}
Exemplo n.º 2
0
int
rb_node_arity(NODE* body)
{
    switch (nd_type(body)) {
      case NODE_CFUNC:
	if (body->nd_argc < 0)
	    return -1;
	return body->nd_argc;
      case NODE_ZSUPER:
	return -1;
      case NODE_ATTRSET:
	return 1;
      case NODE_IVAR:
	return 0;
      case NODE_BMETHOD:
	return rb_proc_arity(body->nd_cval);
      case RUBY_VM_METHOD_NODE:
	{
	    rb_iseq_t *iseq;
	    GetISeqPtr((VALUE)body->nd_body, iseq);
	    if (iseq->arg_rest == -1 && iseq->arg_opts == 0) {
		return iseq->argc;
	    }
	    else {
		return -(iseq->argc + 1 + iseq->arg_post_len);
	    }
	}
      default:
	rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body));
    }
}
Exemplo n.º 3
0
rb_alloc_func_t
rb_get_alloc_func(VALUE klass)
{
    NODE *n;
    Check_Type(klass, T_CLASS);
    n = rb_method_node(CLASS_OF(klass), ID_ALLOCATOR);
    if (!n) return 0;
    if (nd_type(n) != NODE_METHOD) return 0;
    n = n->nd_body;
    if (nd_type(n) != NODE_CFUNC) return 0;
    return (rb_alloc_func_t)n->nd_cfnc;
}
Exemplo n.º 4
0
static inline void
vm_send_optimize(rb_control_frame_t * const reg_cfp, NODE ** const mn,
		 rb_num_t * const flag, rb_num_t * const num,
		 ID * const id, const VALUE klass)
{
    if (*mn && nd_type((*mn)->nd_body) == NODE_CFUNC) {
	NODE *node = (*mn)->nd_body;
	extern VALUE rb_f_send(int argc, VALUE *argv, VALUE recv);

	if (node->nd_cfnc == rb_f_send) {
	    int i = *num - 1;
	    VALUE sym = TOPN(i);
	    *id = SYMBOL_P(sym) ? SYM2ID(sym) : rb_to_id(sym);

	    /* shift arguments */
	    if (i > 0) {
		MEMMOVE(&TOPN(i), &TOPN(i-1), VALUE, i);
	    }

	    *mn = rb_method_node(klass, *id);
	    *num -= 1;
	    DEC_SP(1);
	    *flag |= VM_CALL_FCALL_BIT;
	}
    }
}
Exemplo n.º 5
0
static VALUE
f_hijack(VALUE self)
{
  VALUE proc, ary;
  struct BLOCK* blk;
  NODE* nd;
  NODE* block;
  NODE* args;
  NODE* body;
  int argc;
  ID mid;
  if (!rb_block_given_p()) return Qnil;
  proc = rb_block_proc();
  Data_Get_Struct(proc, struct BLOCK, blk);
  nd = find_def_node(blk->body);
  if (!nd->nd_defn) return Qnil;
  if (nd_type(nd->nd_defn) != NODE_SCOPE) return Qnil;
  /*
   * nd_mid: an id of the name of the method
   * nd_defn: scope node for the method
   */
  mid = nd->nd_mid;
  block = nd->nd_defn->nd_next;
  proc = Data_Wrap_Struct(rb_cProc, blk_mark, blk_free, block);
  return proc;
}
Exemplo n.º 6
0
static void
rb_export_method(VALUE klass, ID name, ID noex)
{
    NODE *fbody;
    VALUE origin;

    if (klass == rb_cObject) {
	rb_secure(4);
    }
    fbody = search_method(klass, name, &origin);
    if (!fbody && TYPE(klass) == T_MODULE) {
	fbody = search_method(rb_cObject, name, &origin);
    }
    if (!fbody || !fbody->nd_body) {
	rb_print_undef(klass, name, 0);
    }
    if (fbody->nd_body->nd_noex != noex) {
	if (nd_type(fbody->nd_body->nd_body) == NODE_CFUNC) {
	    rb_vm_check_redefinition_opt_method(fbody);
	}
	if (klass == origin) {
	    fbody->nd_body->nd_noex = noex;
	}
	else {
	    rb_add_method(klass, name, NEW_ZSUPER(), noex);
	}
    }
}
Exemplo n.º 7
0
static int
clone_method(ID mid, NODE *body, VALUE nklass)
{
    NODE *fbody = body->nd_body;

    if (fbody) {
	VALUE nbody;

	switch (nd_type(fbody)) {
	  case NODE_SCOPE:
	    fbody = rb_copy_node_scope(fbody, ruby_cref);
    	    break;
	  case NODE_BMETHOD:
	    nbody = rb_block_dup(fbody->nd_cval, nklass, (VALUE)ruby_cref);
	    fbody = NEW_BMETHOD(nbody);
	    break;
	  case NODE_DMETHOD:
	    nbody = rb_method_dup(fbody->nd_cval, nklass, (VALUE)ruby_cref);
	    fbody = NEW_DMETHOD(nbody);
	    break;
	}
    }
    st_insert(RCLASS(nklass)->m_tbl, mid, (st_data_t)NEW_METHOD(fbody, body->nd_noex));
    return ST_CONTINUE;
}
Exemplo n.º 8
0
/*
The name of the ruby source file where the code associated with the node are defined
*/
VALUE rb_node_file(VALUE self) {
    NODE* _node;
    Data_Get_Struct(self,NODE,_node);

	#ifdef RUBY1_8
    if (nd_file(_node)  == NULL ) {
	    return rb_str_new2("");
    }
    return rb_str_new2(nd_file(_node) );
    #endif

    #ifdef RUBY1_9

	if (nd_type(_node) == RUBY_VM_METHOD_NODE) {
		VALUE iseqval = (VALUE)(_node->nd_body);
		rb_iseq_t__* ptr;
		Data_Get_Struct(iseqval, rb_iseq_t__, ptr);

		return ptr->filename;
	}

	return rb_str_new2("");

	#endif

}
Exemplo n.º 9
0
static VALUE
proc_arity(VALUE self)
{
    rb_proc_t *proc;
    rb_iseq_t *iseq;
    GetProcPtr(self, proc);
    iseq = proc->block.iseq;
    if (iseq) {
	if (BUILTIN_TYPE(iseq) != T_NODE) {
	    if (iseq->arg_rest < 0) {
		return INT2FIX(iseq->argc);
	    }
	    else {
		return INT2FIX(-(iseq->argc + 1 + iseq->arg_post_len));
	    }
	}
	else {
	    NODE *node = (NODE *)iseq;
	    if (nd_type(node) == NODE_IFUNC && node->nd_cfnc == bmcall) {
		/* method(:foo).to_proc.arity */
		return INT2FIX(method_arity(node->nd_tval));
	    }
	}
    }
    return INT2FIX(-1);
}
Exemplo n.º 10
0
NODE *
ruby_debug_print_node(int level, int debug_level, const char *header, const NODE *node)
{
    if (level < debug_level) {
	fprintf(stderr, "DBG> %s: %s (%lu)\n", header,
		ruby_node_name(nd_type(node)), nd_line(node));
    }
    return (NODE *)node;
}
Exemplo n.º 11
0
void
rb_alias(VALUE klass, ID name, ID def)
{
    NODE *orig_fbody, *node, *method;
    VALUE singleton = 0;
    st_data_t data;

    rb_frozen_class_p(klass);
    if (klass == rb_cObject) {
	rb_secure(4);
    }
    orig_fbody = search_method(klass, def, 0);
    if (!orig_fbody || !orig_fbody->nd_body) {
	if (TYPE(klass) == T_MODULE) {
	    orig_fbody = search_method(rb_cObject, def, 0);
	}
    }
    if (!orig_fbody || !orig_fbody->nd_body) {
	rb_print_undef(klass, def, 0);
    }
    if (FL_TEST(klass, FL_SINGLETON)) {
	singleton = rb_iv_get(klass, "__attached__");
    }

    orig_fbody->nd_cnt++;

    if (st_lookup(RCLASS_M_TBL(klass), name, &data)) {
	node = (NODE *)data;
	if (node) {
	    if (RTEST(ruby_verbose) && node->nd_cnt == 0 && node->nd_body) {
		rb_warning("discarding old %s", rb_id2name(name));
	    }
	    if (nd_type(node->nd_body->nd_body) == NODE_CFUNC) {
		rb_vm_check_redefinition_opt_method(node);
	    }
	}
    }

    st_insert(RCLASS_M_TBL(klass), name,
	      (st_data_t) NEW_FBODY(
		  method = NEW_METHOD(orig_fbody->nd_body->nd_body,
			     orig_fbody->nd_body->nd_clss,
			     NOEX_WITH_SAFE(orig_fbody->nd_body->nd_noex)), def));
    method->nd_file = (void *)def;

    rb_clear_cache_by_id(name);

    if (!ruby_running) return;

    if (singleton) {
	rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
    }
    else {
	rb_funcall(klass, added, 1, ID2SYM(name));
    }
}
Exemplo n.º 12
0
int
rb_node_arity(NODE* body)
{
    int n;

    switch (nd_type(body)) {
    case NODE_CFUNC:
	if (body->nd_argc < 0)
	    return -1;
	return body->nd_argc;
    case NODE_ZSUPER:
	return -1;
    case NODE_ATTRSET:
	return 1;
    case NODE_IVAR:
	return 0;
    case NODE_BMETHOD:
	return rb_proc_arity(body->nd_cval);
    case NODE_SCOPE:
	body = body->nd_next;	/* skip NODE_SCOPE */
	if (nd_type(body) == NODE_BLOCK)
	    body = body->nd_head;
	if (!body)
	    return 0;
	n = body->nd_frml ? RARRAY_LEN(body->nd_frml) : 0;
	if (body->nd_opt || body->nd_rest)
	    n = -n - 1;
	return n;
    case RUBY_VM_METHOD_NODE:{
	    rb_iseq_t *iseq;
	    GetISeqPtr((VALUE)body->nd_body, iseq);
	    if (iseq->arg_rest == 0 && iseq->arg_opts == 0) {
		return iseq->argc;
	    }
	    else {
		return -iseq->argc - 1;
	    }
	}
    default:
	rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body));
    }
}
Exemplo n.º 13
0
static struct RNode*
find_def_node(struct RNode* nd)
{
  while (nd) {
    switch (nd_type(nd)) {
    case NODE_DEFN: case NODE_DEFS:
      return nd;
    case NODE_BEGIN:
      nd = nd->nd_body;
      break;
    case NODE_NEWLINE:
      nd = nd->nd_next;
      break;
    default:
      print_node_name(nd_type(nd));
      return NULL;
    }
  }
  return NULL;
}
Exemplo n.º 14
0
static VALUE compiled_location(VALUE self)
{
    struct METHOD *data;
    VALUE name = rb_funcall(self, rb_intern("name"), 0);

    Data_Get_Struct(self, struct METHOD, data);

    if (nd_type(data->body) != NODE_CFUNC) {
        return Qnil;
    }

    return file_and_offset(*data->body->nd_cfnc, StringValueCStr(name));
}
Exemplo n.º 15
0
Arquivo: proc.c Projeto: MSch/MacRuby
int
rb_node_arity(NODE* body)
{
    // TODO should be replaced by the roxor.cpp's stuff
    switch (nd_type(body)) {
	case NODE_CFUNC:
	    if (body->nd_argc < 0) {
		return -1;
	    }
	    return body->nd_argc;
	case NODE_ZSUPER:
	    return -1;
	case NODE_ATTRSET:
	    return 1;
	case NODE_IVAR:
	    return 0;
	case NODE_BMETHOD:
	    return rb_proc_arity(body->nd_cval);
	default:
	    rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body));
    }
}
Exemplo n.º 16
0
static int
cn_i(void *vstart, void *vend, size_t stride, void *n)
{
    size_t *nodes = (size_t *)n;
    VALUE v = (VALUE)vstart;

    for (; v != (VALUE)vend; v += stride) {
	if (RBASIC(v)->flags && BUILTIN_TYPE(v) == T_NODE) {
	    size_t s = nd_type((NODE *)v);
	    nodes[s]++;
	}
    }

    return 0;
}
Exemplo n.º 17
0
static VALUE
mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)
{
    VALUE method;
    NODE *body;
    struct METHOD *data;
    VALUE rclass = klass;
    ID oid = id;

  again:
    if ((body = rb_get_method_body(klass, id, 0)) == 0) {
	rb_print_undef(rclass, oid, 0);
    }
    if (scope && (body->nd_noex & NOEX_MASK) != NOEX_PUBLIC) {
	rb_print_undef(rclass, oid, (body->nd_noex & NOEX_MASK));
    }

    klass = body->nd_clss;
    body = body->nd_body;

    if (nd_type(body) == NODE_ZSUPER) {
	klass = RCLASS_SUPER(klass);
	goto again;
    }

    while (rclass != klass &&
	   (RCLASS_SINGLETON(rclass) || TYPE(rclass) == T_ICLASS)) {
	rclass = RCLASS_SUPER(rclass);
    }
    if (TYPE(klass) == T_ICLASS)
	klass = RBASIC(klass)->klass;
    method = Data_Make_Struct(mclass, struct METHOD, bm_mark, -1, data);
    data->oclass = klass;
    GC_WB(&data->recv, obj);

    data->id = id;
    data->body = body;
    data->rclass = rclass;
    data->oid = oid;
#if !WITH_OBJC
    OBJ_INFECT(method, klass);
#endif

    return method;
}
Exemplo n.º 18
0
static rb_iseq_t *
get_method_iseq(VALUE method)
{
    struct METHOD *data;
    NODE *body;
    rb_iseq_t *iseq;

    Data_Get_Struct(method, struct METHOD, data);
    body = data->body;
    switch (nd_type(body)) {
      case RUBY_VM_METHOD_NODE:
	GetISeqPtr((VALUE)body->nd_body, iseq);
	if (RUBY_VM_NORMAL_ISEQ_P(iseq)) break;
      default:
	return 0;
    }
    return iseq;
}
Exemplo n.º 19
0
static VALUE
rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
{
    int i;
    ID id;
    NODE *fbody;

    if (TYPE(module) != T_MODULE) {
	rb_raise(rb_eTypeError, "module_function must be called for modules");
    }

    secure_visibility(module);
    if (argc == 0) {
	SCOPE_SET(NOEX_MODFUNC);
	return module;
    }

    set_method_visibility(module, argc, argv, NOEX_PRIVATE);

    for (i = 0; i < argc; i++) {
	VALUE m = module;

	id = rb_to_id(argv[i]);
	for (;;) {
	    fbody = search_method(m, id, &m);
	    if (fbody == 0) {
		fbody = search_method(rb_cObject, id, &m);
	    }
	    if (fbody == 0 || fbody->nd_body == 0) {
		rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
	    }
	    if (nd_type(fbody->nd_body->nd_body) != NODE_ZSUPER) {
		break;		/* normal case: need not to follow 'super' link */
	    }
	    m = RCLASS_SUPER(m);
	    if (!m)
		break;
	}
	rb_add_method(rb_singleton_class(module), id, fbody->nd_body->nd_body,
		      NOEX_PUBLIC);
    }
    return module;
}
Exemplo n.º 20
0
static void
remove_method(VALUE klass, ID mid)
{
    st_data_t data;
    NODE *body = 0;

    if (klass == rb_cObject) {
	rb_secure(4);
    }
    if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
	rb_raise(rb_eSecurityError, "Insecure: can't remove method");
    }
    if (OBJ_FROZEN(klass))
	rb_error_frozen("class/module");
    if (mid == object_id || mid == __send__ || mid == idInitialize) {
	rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
    }
    if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
	body = (NODE *)data;
	if (!body || !body->nd_body) body = 0;
	else {
	    st_delete(RCLASS_M_TBL(klass), &mid, &data);
	}
    }
    if (!body) {
	rb_name_error(mid, "method `%s' not defined in %s",
		      rb_id2name(mid), rb_class2name(klass));
    }

    if (nd_type(body->nd_body->nd_body) == NODE_CFUNC) {
	rb_vm_check_redefinition_opt_method(body);
    }

    rb_clear_cache_for_undef(klass, mid);
    if (FL_TEST(klass, FL_SINGLETON)) {
	rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1,
		   ID2SYM(mid));
    }
    else {
	rb_funcall(klass, removed, 1, ID2SYM(mid));
    }
}
Exemplo n.º 21
0
Arquivo: mri.c Projeto: hkraji/looksee
/*
 * Return the source file and line number of the given object and method.
 */
VALUE Looksee_source_location(VALUE self, VALUE unbound_method) {
  if (!rb_obj_is_kind_of(unbound_method, rb_cUnboundMethod))
    rb_raise(rb_eTypeError, "expected UnboundMethod, got %s", rb_obj_classname(unbound_method));

  struct METHOD *method;
  Data_Get_Struct(unbound_method, struct METHOD, method);

  NODE *node;
  switch (nd_type(method->body)) {
    // Can't be a FBODY or ZSUPER.
  case NODE_SCOPE:
    node = method->body->nd_defn;
    break;
  case NODE_BMETHOD:
    {
      struct BLOCK *block;
      Data_Get_Struct(method->body->nd_orig, struct BLOCK, block);
      (node = block->frame.node) || (node = block->body);
      // Proc#to_s suggests this may be NULL sometimes.
      if (!node)
        return Qnil;
    }
    break;
  case NODE_DMETHOD:
    {
      struct METHOD *original_method;
      NODE *body = method->body;
      Data_Get_Struct(body->nd_orig, struct METHOD, original_method);
      node = original_method->body->nd_defn;
    }
    break;
  default:
    return Qnil;
  }
  VALUE file = rb_str_new2(node->nd_file);
  VALUE line = INT2NUM(nd_line(node));
  VALUE location = rb_ary_new2(2);
  rb_ary_store(location, 0, file);
  rb_ary_store(location, 1, line);
  return location;
}
Exemplo n.º 22
0
static VALUE
mnew(VALUE klass, VALUE obj, ID id, VALUE mklass)
{
    VALUE method;
    NODE *body;
    struct METHOD *data;
    VALUE rklass = klass;
    ID oid = id;

  again:
    if ((body = rb_get_method_body(klass, id, 0)) == 0) {
	print_undef(rklass, oid);
    }

    klass = body->nd_clss;
    body = body->nd_body;

    if (nd_type(body) == NODE_ZSUPER) {
	klass = RCLASS(klass)->super;
	goto again;
    }

    while (rklass != klass &&
	   (FL_TEST(rklass, FL_SINGLETON) || TYPE(rklass) == T_ICLASS)) {
	rklass = RCLASS(rklass)->super;
    }
    if (TYPE(klass) == T_ICLASS)
	klass = RBASIC(klass)->klass;
    method = Data_Make_Struct(mklass, struct METHOD, bm_mark, -1, data);
    data->klass = klass;
    data->recv = obj;

    data->id = id;
    data->body = body;
    data->rklass = rklass;
    data->oid = oid;
    OBJ_INFECT(method, klass);

    return method;
}
Exemplo n.º 23
0
static char *
load_lock(const char *ftptr)
{
    st_data_t data;
    st_table *loading_tbl = get_loading_table();

    if (!loading_tbl || !st_lookup(loading_tbl, (st_data_t)ftptr, &data)) {
	/* loading ruby library should be serialized. */
	if (!loading_tbl) {
	    GET_VM()->loading_table = loading_tbl = st_init_strtable();
	}
	/* partial state */
	ftptr = ruby_strdup(ftptr);
	data = (st_data_t)rb_thread_shield_new();
	st_insert(loading_tbl, (st_data_t)ftptr, data);
	return (char *)ftptr;
    }
    else if (RB_TYPE_P((VALUE)data, T_NODE) && nd_type((VALUE)data) == NODE_MEMO) {
	NODE *memo = RNODE(data);
	void (*init)(void) = (void (*)(void))memo->nd_cfnc;
	data = (st_data_t)rb_thread_shield_new();
	st_insert(loading_tbl, (st_data_t)ftptr, data);
	(*init)();
	return (char *)"";
    }
    if (RTEST(ruby_verbose)) {
	rb_warning("loading in progress, circular require considered harmful - %s", ftptr);
	rb_backtrace_print_to(rb_stderr);
    }
    switch (rb_thread_shield_wait((VALUE)data)) {
      case Qfalse:
	data = (st_data_t)ftptr;
	st_insert(loading_tbl, data, (st_data_t)rb_thread_shield_new());
	return 0;
      case Qnil:
	return 0;
    }
    return (char *)ftptr;
}
Exemplo n.º 24
0
char *
nd_type_str(VALUE obj)
{
  switch(nd_type(obj)) {
    #define ND(type) case NODE_##type: return #type;
    ND(METHOD);     ND(FBODY);      ND(CFUNC);    ND(SCOPE);
    ND(BLOCK);      ND(IF);         ND(CASE);     ND(WHEN);
    ND(OPT_N);      ND(WHILE);      ND(UNTIL);    ND(ITER);
    ND(FOR);        ND(BREAK);      ND(NEXT);     ND(REDO);
    ND(RETRY);      ND(BEGIN);      ND(RESCUE);   ND(RESBODY);
    ND(ENSURE);     ND(AND);        ND(OR);       ND(NOT);
    ND(MASGN);      ND(LASGN);      ND(DASGN);    ND(DASGN_CURR);
    ND(GASGN);      ND(IASGN);      ND(CDECL);    ND(CVASGN);
    ND(CVDECL);     ND(OP_ASGN1);   ND(OP_ASGN2); ND(OP_ASGN_AND);
    ND(OP_ASGN_OR); ND(CALL);       ND(FCALL);    ND(VCALL);
    ND(SUPER);      ND(ZSUPER);     ND(ARRAY);    ND(ZARRAY);
    ND(HASH);       ND(RETURN);     ND(YIELD);    ND(LVAR);
    ND(DVAR);       ND(GVAR);       ND(IVAR);     ND(CONST);
    ND(CVAR);       ND(NTH_REF);    ND(BACK_REF); ND(MATCH);
    ND(MATCH2);     ND(MATCH3);     ND(LIT);      ND(STR);
    ND(DSTR);       ND(XSTR);       ND(DXSTR);    ND(EVSTR);
    ND(DREGX);      ND(DREGX_ONCE); ND(ARGS);     ND(ARGSCAT);
    ND(ARGSPUSH);   ND(SPLAT);      ND(TO_ARY);   ND(SVALUE);
    ND(BLOCK_ARG);  ND(BLOCK_PASS); ND(DEFN);     ND(DEFS);
    ND(ALIAS);      ND(VALIAS);     ND(UNDEF);    ND(CLASS);
    ND(MODULE);     ND(SCLASS);     ND(COLON2);   ND(COLON3)
    ND(CREF);       ND(DOT2);       ND(DOT3);     ND(FLIP2);
    ND(FLIP3);      ND(ATTRSET);    ND(SELF);     ND(NIL);
    ND(TRUE);       ND(FALSE);      ND(DEFINED);  ND(NEWLINE);
    ND(POSTEXE);    ND(ALLOCA);     ND(DMETHOD);  ND(BMETHOD);
    ND(MEMO);       ND(IFUNC);      ND(DSYM);     ND(ATTRASGN);
    ND(LAST);
    default:
      return "unknown";
  }
}
Exemplo n.º 25
0
static bool attribute_p(VALUE self, char* name)
{
  if (!method_p(self, name))
    return false;

  VALUE rb_id = rb_intern(name);
  VALUE rb_method = rb_funcall(self, rb_intern("method"), 1, ID2SYM(rb_id));

  if (TYPE(rb_method) == T_DATA)
  {
    VALUE klass = CLASS_OF(rb_method);
    if (klass == rb_cMethod)
    {
      METHOD* method;
      Data_Get_Struct(rb_method, METHOD, method);

      if (method && nd_type(method->body) == NODE_IVAR)
        return true;
    }
  }

  return RTEST(rb_funcall(Johnson_SpiderMonkey_JSLandProxy(),
    rb_intern("js_property?"), 2, self, ID2SYM(rb_id)));
}
Exemplo n.º 26
0
static NODE *
build_Array_each_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
		      VALUE param_vars, VALUE local_vars)
{
    /* Special block for Array#each
       ary.each{|e|
       BODY
       }
       =>
       {|e, _self|
       _i = 0
       while _i < _self.length
       e = _self[_i]
       redo_point:
       BODY
       next_point:
       _i = _i.succ
       end
       }

       ary.each{
       BODY
       }
       =>
       {|_i, _self|
       _i = 0
       while _i < _self.length
       redo_point:
       BODY
       next_point:
       _i = _i.succ
       end
       }
     */

    ID _self = rb_intern("#_self");
    ID _i = rb_intern("#_i");

    if (iseq->argc == 0) {
	ID _e = rb_intern("#_e");
	rb_ary_push(param_vars, ID2SYM(_e));
	rb_ary_push(param_vars, ID2SYM(_self));
	iseq->argc += 2;
	rb_ary_push(local_vars, ID2SYM(_i));

	node =
	    new_block(NEW_DASGN(_i, NEW_LIT(INT2FIX(0))),
		      NEW_WHILE(NEW_CALL(NEW_DVAR(_i), idLT,
					 new_ary(NEW_CALL
						 (NEW_DVAR(_self), idLength,
						  0), 0)),
				new_block(NEW_OPTBLOCK(node),
					  NEW_DASGN(_i,
						    NEW_CALL(NEW_DVAR(_i),
							     idSucc, 0))),
				Qundef));
    }
    else {
	ID e = SYM2ID(rb_ary_entry(param_vars, 0));
	NODE *assign;

	rb_ary_push(param_vars, ID2SYM(_self));
	iseq->argc++;
	rb_ary_push(local_vars, ID2SYM(_i));

	if (nd_type(lnode) == NODE_DASGN_CURR) {
	    assign = NEW_DASGN(e,
			       NEW_CALL(NEW_DVAR(_self), idAREF,
					new_ary(NEW_DVAR(_i), 0)));
	}
	else {
	    assign = new_assign(lnode,
				NEW_CALL(NEW_DVAR(_self), idAREF,
					 new_ary(NEW_DVAR(_i), 0)));
	}

	node =
	    new_block(NEW_DASGN(_i, NEW_LIT(INT2FIX(0))),
		      NEW_WHILE(NEW_CALL(NEW_DVAR(_i), idLT,
					 new_ary(NEW_CALL
						 (NEW_DVAR(_self), idLength,
						  0), 0)), new_block(assign,
								     new_block
								     (NEW_OPTBLOCK
								      (node),
								      NEW_DASGN
								      (_i,
								       NEW_CALL
								       (NEW_DVAR
									(_i),
									idSucc,
									0)))),
				Qundef));
    }
    return node;
}
Exemplo n.º 27
0
static NODE *
build_Range_each_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
		      VALUE param_vars, VALUE local_vars, ID mid)
{
    /* Special Block for Range#each
       {|e, _last|
       _e = e
       while _e < _last
       e = _e
       next_point:
       BODY
       redo_point:
       _e = _e.succ
       end
       }
       {|e, _last|
       while e < _last
       BODY
       redo_point:
       e = e.succ
       end
       }
     */
    ID _last = rb_intern("#_last");
    if (iseq->argc == 0) {
	ID e = rb_intern("#e");
	rb_ary_push(param_vars, ID2SYM(e));
	rb_ary_push(param_vars, ID2SYM(_last));
	iseq->argc += 2;

	node =
	    NEW_WHILE(NEW_CALL(NEW_DVAR(e), mid, new_ary(NEW_DVAR(_last), 0)),
		      new_block(NEW_OPTBLOCK(node),
				NEW_DASGN(e,
					  NEW_CALL(NEW_DVAR(e), idSucc, 0))),
		      Qundef);
    }
    else {
	ID _e = rb_intern("#_e");
	ID e = SYM2ID(rb_ary_entry(param_vars, 0));
	NODE *assign;

	rb_ary_push(param_vars, ID2SYM(_last));
	rb_ary_push(local_vars, ID2SYM(_e));
	iseq->argc++;

	if (nd_type(lnode) == NODE_DASGN_CURR) {
	    assign = NEW_DASGN(e, NEW_DVAR(_e));
	}
	else {
	    assign = new_assign(lnode, NEW_DVAR(_e));
	}

	node =
	    new_block(NEW_DASGN(_e, NEW_DVAR(e)),
		      NEW_WHILE(NEW_CALL
				(NEW_DVAR(_e), mid,
				 new_ary(NEW_DVAR(_last), 0)),
				new_block(assign,
					  new_block(NEW_OPTBLOCK(node),
						    NEW_DASGN(_e,
							      NEW_CALL
							      (NEW_DVAR(_e),
							       idSucc, 0)))),
				Qundef));
    }
    return node;
}
Exemplo n.º 28
0
static NODE *
build_Integer_times_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
			 VALUE param_vars, VALUE local_vars)
{
    /* Special Block for Integer#times
       {|e, _self|
       _e = e
       while(e < _self)
       e = _e
       redo_point:
       BODY
       next_point:
       _e = _e.succ
       end
       }

       {|e, _self|
       while(e < _self)
       BODY
       next_point:
       e = e.succ
       end
       }
     */
    ID _self = rb_intern("#_self");
    if (iseq->argc == 0) {
	ID e = rb_intern("#e");
	rb_ary_push(param_vars, ID2SYM(e));
	rb_ary_push(param_vars, ID2SYM(_self));
	iseq->argc += 2;

	node =
	    NEW_WHILE(NEW_CALL
		      (NEW_DVAR(e), idLT, new_ary(NEW_DVAR(_self), 0)),
		      new_block(NEW_OPTBLOCK(node),
				NEW_DASGN(e,
					  NEW_CALL(NEW_DVAR(e), idSucc, 0))),
		      Qundef);
    }
    else {
	ID _e = rb_intern("#_e");
	ID e = SYM2ID(rb_ary_entry(param_vars, 0));
	NODE *assign;

	rb_ary_push(param_vars, ID2SYM(_self));
	rb_ary_push(local_vars, ID2SYM(_e));
	iseq->argc++;

	if (nd_type(lnode) == NODE_DASGN_CURR) {
	    assign = NEW_DASGN(e, NEW_DVAR(_e));
	}
	else {
	    assign = new_assign(lnode, NEW_DVAR(_e));
	}

	node =
	    new_block(NEW_DASGN(_e, NEW_DVAR(e)),
		      NEW_WHILE(NEW_CALL
				(NEW_DVAR(_e), idLT,
				 new_ary(NEW_DVAR(_self), 0)),
				new_block(assign,
					  new_block(NEW_OPTBLOCK(node),
						    NEW_DASGN(_e,
							      NEW_CALL
							      (NEW_DVAR(_e),
							       idSucc, 0)))),
				Qundef));
    }
    return node;
}
Exemplo n.º 29
0
Arquivo: gc.c Projeto: 1nueve/MacRuby
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);
    }
}
Exemplo n.º 30
0
static inline VALUE
vm_call0(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid,
	 int argc, const VALUE *argv, const NODE *body, int nosuper)
{
    VALUE val;
    rb_block_t *blockptr = 0;

    if (0) printf("id: %s, nd: %s, argc: %d, passed: %p\n",
		  rb_id2name(id), ruby_node_name(nd_type(body)),
		  argc, (void *)th->passed_block);

    if (th->passed_block) {
	blockptr = th->passed_block;
	th->passed_block = 0;
    }
  again:
    switch (nd_type(body)) {
      case RUBY_VM_METHOD_NODE:{
	rb_control_frame_t *reg_cfp;
	VALUE iseqval = (VALUE)body->nd_body;
	int i;

	rb_vm_set_finish_env(th);
	reg_cfp = th->cfp;

	CHECK_STACK_OVERFLOW(reg_cfp, argc + 1);

	*reg_cfp->sp++ = recv;
	for (i = 0; i < argc; i++) {
	    *reg_cfp->sp++ = argv[i];
	}

	vm_setup_method(th, reg_cfp, argc, blockptr, 0, iseqval, recv);
	val = vm_exec(th);
	break;
      }
      case NODE_CFUNC: {
	EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
	{
	    rb_control_frame_t *reg_cfp = th->cfp;
	    rb_control_frame_t *cfp =
		vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
			      recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);

	    cfp->method_id = oid;
	    cfp->method_class = klass;

	    val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv);

	    if (reg_cfp != th->cfp + 1) {
		SDR2(reg_cfp);
		SDR2(th->cfp-5);
		rb_bug("cfp consistency error - call0");
		th->cfp = reg_cfp;
	    }
	    vm_pop_frame(th);
	}
	EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
	break;
      }
      case NODE_ATTRSET:{
	if (argc != 1) {
	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
	}
	val = rb_ivar_set(recv, body->nd_vid, argv[0]);
	break;
      }
      case NODE_IVAR: {
	if (argc != 0) {
	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)",
		     argc);
	}
	val = rb_attr_get(recv, body->nd_vid);
	break;
      }
      case NODE_BMETHOD:{
	val = vm_call_bmethod(th, oid, body->nd_cval,
			      recv, klass, argc, (VALUE *)argv, blockptr);
	break;
      }
      case NODE_ZSUPER:{
	klass = RCLASS_SUPER(klass);
	if (!klass || !(body = rb_method_node(klass, id))) {
	    return method_missing(recv, id, argc, argv, 0);
	}
	RUBY_VM_CHECK_INTS();
	nosuper = CALL_SUPER;
	body = body->nd_body;
	goto again;
      }
      default:
	rb_bug("unsupported: vm_call0(%s)", ruby_node_name(nd_type(body)));
    }
    RUBY_VM_CHECK_INTS();
    return val;
}