コード例 #1
0
rb_control_frame_t* RPRuby_internal_framePriorTo( rb_control_frame_t* c_control_frame )  {
  
  rb_thread_t*      c_thread          = (rb_thread_t *)RTYPEDDATA_DATA(rb_thread_current());
  rb_control_frame_t*    c_prior_control_frame    = NULL;
  //  get the current frame pointer
  if ( c_control_frame == NULL )  {
    c_control_frame  = c_thread->cfp;
  }
  
    if ( ( c_prior_control_frame = rb_vm_get_ruby_level_next_cfp( c_thread, c_control_frame ) ) != 0) {
    
    //  not sure why we have to call this a second time after it was called at the end of rb_vm_get_ruby_level_next_cfp,
    //  but for some reason it seems to be necessary
    c_prior_control_frame = RUBY_VM_PREVIOUS_CONTROL_FRAME( c_prior_control_frame );

    }
  else {
    c_prior_control_frame = NULL;
  }
  
  //  if we have a nil object we've passed main, we're done
  if ( c_prior_control_frame->self == Qnil )  {
    return NULL;
  }

  return c_prior_control_frame;
  
}
コード例 #2
0
ファイル: vm.c プロジェクト: qnighy/ruby-1.9.2p0
NODE *
rb_vm_cref(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
    return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
}
コード例 #3
0
ファイル: vm.c プロジェクト: qnighy/ruby-1.9.2p0
void
rb_vm_stack_to_heap(rb_thread_t * const th)
{
    rb_control_frame_t *cfp = th->cfp;
    while ((cfp = rb_vm_get_ruby_level_next_cfp(th, cfp)) != 0) {
	rb_vm_make_env_object(th, cfp);
	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
    }
}
コード例 #4
0
ファイル: vm.c プロジェクト: qnighy/ruby-1.9.2p0
int
rb_sourceline(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);

    if (cfp) {
	return rb_vm_get_sourceline(cfp);
    }
    else {
	return 0;
    }
}
コード例 #5
0
ファイル: vm.c プロジェクト: qnighy/ruby-1.9.2p0
const char *
rb_sourcefile(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);

    if (cfp) {
	return RSTRING_PTR(cfp->iseq->filename);
    }
    else {
	return 0;
    }
}
コード例 #6
0
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);
    rb_method_definition_t *def = ALLOC(rb_method_definition_t);
    me->def = def;
    def->type = type;
    def->original_id = mid;
    def->alias_count = 0;
    switch (type) {
      case VM_METHOD_TYPE_ISEQ:
	def->body.iseq = (rb_iseq_t *)opts;
	break;
      case VM_METHOD_TYPE_CFUNC:
	def->body.cfunc = *(rb_method_cfunc_t *)opts;
	break;
      case VM_METHOD_TYPE_ATTRSET:
      case VM_METHOD_TYPE_IVAR:
	def->body.attr.id = (ID)opts;
	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->filename, INT2FIX(line));
	    def->body.attr.location = rb_ary_freeze(location);
	}
	break;
      case VM_METHOD_TYPE_BMETHOD:
	def->body.proc = (VALUE)opts;
	break;
      case VM_METHOD_TYPE_NOTIMPLEMENTED:
	def->body.cfunc.func = rb_f_notimplement;
	def->body.cfunc.argc = -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;
      default:
	rb_bug("rb_add_method: unsupported method type (%d)\n", type);
    }
    if (type != VM_METHOD_TYPE_UNDEF) {
	method_added(klass, mid);
    }
    return me;
}
コード例 #7
0
ファイル: vm_trace.c プロジェクト: Chatto/VGdesk
static void
fill_path_and_lineno(rb_trace_arg_t *trace_arg)
{
    if (trace_arg->path == Qundef) {
	rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(trace_arg->th, trace_arg->cfp);

	if (cfp) {
	    trace_arg->path = cfp->iseq->location.path;
	    trace_arg->lineno = rb_vm_get_sourceline(cfp);
	}
	else {
	    trace_arg->path = Qnil;
	    trace_arg->lineno = 0;
	}
    }
}
コード例 #8
0
ファイル: proc.c プロジェクト: srirammca53/update_status
VALUE
rb_binding_new(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
    VALUE bindval = binding_alloc(rb_cBinding);
    rb_binding_t *bind;

    if (cfp == 0) {
	rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
    }

    GetBindingPtr(bindval, bind);
    bind->env = rb_vm_make_env_object(th, cfp);
    return bindval;
}
コード例 #9
0
ファイル: vm_eval.c プロジェクト: 3runo5ouza/rhodes
/*RHO static*/ VALUE
eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *file, int line)
{
    int state;
    VALUE result = Qundef;
    VALUE envval;
    rb_binding_t *bind = 0;
    rb_thread_t *th = GET_THREAD();
    rb_env_t *env = NULL;
    rb_block_t block;
    volatile int parse_in_eval;
    volatile int mild_compile_error;

    if (file == 0) {
	file = rb_sourcefile();
	line = rb_sourceline();
    }

    parse_in_eval = th->parse_in_eval;
    mild_compile_error = th->mild_compile_error;
    PUSH_TAG();
    if ((state = EXEC_TAG()) == 0) {
	rb_iseq_t *iseq;
	volatile VALUE iseqval;

	if (scope != Qnil) {
	    if (rb_obj_is_kind_of(scope, rb_cBinding)) {
		GetBindingPtr(scope, bind);
		envval = bind->env;
	    }
	    else {
		rb_raise(rb_eTypeError,
			 "wrong argument type %s (expected Binding)",
			 rb_obj_classname(scope));
	    }
	    GetEnvPtr(envval, env);
	    th->base_block = &env->block;
	}
	else {
	    rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);

	    if (cfp != 0) {
		block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
		th->base_block = █
		th->base_block->self = self;
		th->base_block->iseq = cfp->iseq;	/* TODO */
	    }
	    else {
		rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
	    }
	}

    //RHO
    if ( TYPE(src) != T_STRING ){
        iseqval = src;
    }else
    //RHO
    {
	    /* make eval iseq */
	    th->parse_in_eval++;
	    th->mild_compile_error++;
	    iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
	    th->mild_compile_error--;
	    th->parse_in_eval--;
    }

	vm_set_eval_stack(th, iseqval, cref);
	th->base_block = 0;

	if (0) {		/* for debug */
	    printf("%s\n", RSTRING_PTR(rb_iseq_disasm(iseqval)));
	}

	/* save new env */
	GetISeqPtr(iseqval, iseq);
	if (bind && iseq->local_size > 0) {
	    bind->env = rb_vm_make_env_object(th, th->cfp);
	}

	/* kick */
	CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
	result = vm_exec(th);
    }
    POP_TAG();
    th->mild_compile_error = mild_compile_error;
    th->parse_in_eval = parse_in_eval;

    if (state) {
	if (state == TAG_RAISE) {
	    VALUE errinfo = th->errinfo;
	    if (strcmp(file, "(eval)") == 0) {
		VALUE mesg, errat, bt2;
		extern VALUE rb_get_backtrace(VALUE info);
		ID id_mesg;

		CONST_ID(id_mesg, "mesg");
		errat = rb_get_backtrace(errinfo);
		mesg = rb_attr_get(errinfo, id_mesg);
		if (!NIL_P(errat) && TYPE(errat) == T_ARRAY &&
		    (bt2 = vm_backtrace(th, -2), RARRAY_LEN(bt2) > 0)) {
		    if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_LEN(mesg)) {
			if (OBJ_FROZEN(mesg)) {
			    VALUE m = rb_str_cat(rb_str_dup(RARRAY_PTR(errat)[0]), ": ", 2);
			    rb_ivar_set(errinfo, id_mesg, rb_str_append(m, mesg));
			}
			else {
			    rb_str_update(mesg, 0, 0, rb_str_new2(": "));
			    rb_str_update(mesg, 0, 0, RARRAY_PTR(errat)[0]);
			}
		    }
		    RARRAY_PTR(errat)[0] = RARRAY_PTR(bt2)[0];
		}
	    }
	    rb_exc_raise(errinfo);
	}
	JUMP_TAG(state);
    }
    return result;
}
コード例 #10
0
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;
}