예제 #1
0
static VALUE
binding_dup(VALUE self)
{
    VALUE bindval = binding_alloc(rb_cBinding);
    rb_binding_t *src, *dst;
    GetBindingPtr(self, src);
    GetBindingPtr(bindval, dst);
    dst->env = src->env;
    return bindval;
}
예제 #2
0
파일: proc.c 프로젝트: MSch/MacRuby
static VALUE
binding_dup(VALUE self, SEL sel)
{
    VALUE bindval = binding_alloc(rb_cBinding);
    rb_vm_binding_t *src, *dst;
    GetBindingPtr(self, src);
    GetBindingPtr(bindval, dst);
    GC_WB(&dst->self, src->self);
    GC_WB(&dst->next, src->next);
    GC_WB(&dst->locals, src->locals);
    GC_WB(&dst->outer_stack, src->outer_stack);
    GC_WB(&dst->block, src->block);
    return bindval;
}
예제 #3
0
VALUE
rb_binding_new(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
    VALUE bindval = binding_alloc(rb_cBinding);
    rb_binding_t *bind;

    GetBindingPtr(bindval, bind);
    GC_WB(&bind->env, vm_make_env_object(th, cfp));
    return bindval;
}
예제 #4
0
VALUE
rb_binding_new(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
    VALUE bindval = binding_alloc(rb_cBinding);
    rb_binding_t *bind;

    GetBindingPtr(bindval, bind);
    bind->env = th_make_env_object(th, cfp);
    bind->cref_stack = ruby_cref();
    return bindval;
}
예제 #5
0
VALUE
rb_f_eval(VALUE self, SEL sel, int argc, VALUE *argv)
{
    VALUE src, scope, vfile, vline;
    const char *file = "(eval)";
    int line = 1;

    rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
    if (rb_safe_level() >= 4) {
	StringValue(src);
	if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
	    rb_raise(rb_eSecurityError,
		     "Insecure: can't modify trusted binding");
	}
    }
    else {
	SafeStringValue(src);
    }
    if (argc >= 3) {
	StringValue(vfile);
    }
    if (argc >= 4) {
	line = NUM2INT(vline);
    }
    if (!NIL_P(vfile)) {
	file = RSTRING_PTR(vfile);
    }
    VALUE klass;
    switch (TYPE(self)) {
	case T_CLASS:
	case T_MODULE:
	    klass = self;
	    break;
	default:
	    klass = 0;
	    break;
    }
#if 0
    if (!NIL_P(scope)) {
	rb_vm_binding_t *t = rb_vm_current_binding();
	assert(t != NULL);
	rb_vm_binding_t *tmp = rb_vm_create_binding(t->self,
		t->block, GetBindingPtr(scope), 0, NULL, false);
	GC_WB(&tmp->locals, t->locals);
	scope = rb_binding_new_from_binding(tmp);
    }
#endif
    return eval_string(self, klass, src, scope, file, line);
}
예제 #6
0
static VALUE
eval_string_with_should_push_outer(VALUE self, VALUE klass, VALUE src,
	VALUE scope, const char *file, const int line,
	bool should_push_outer)
{
    rb_vm_binding_t *binding = NULL;
    if (scope != Qnil) {
	if (!rb_obj_is_kind_of(scope, rb_cBinding)) {
	    rb_raise(rb_eTypeError, "wrong argument type %s (expected Binding)",
		     rb_obj_classname(scope));
	}
	binding = GetBindingPtr(scope);
    }
    return rb_vm_eval_string(self, klass, src, binding, file, line,
	    should_push_outer);
}
예제 #7
0
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;
}
예제 #8
0
/*
 *  call-seq:
 *     prc.binding    => binding
 *  
 *  Returns the binding associated with <i>prc</i>. Note that
 *  <code>Kernel#eval</code> accepts either a <code>Proc</code> or a
 *  <code>Binding</code> object as its second parameter.
 *     
 *     def fred(param)
 *       proc {}
 *     end
 *     
 *     b = fred(99)
 *     eval("param", b.binding)   #=> 99
 */
static VALUE
proc_binding(VALUE self)
{
    rb_proc_t *proc;
    VALUE bindval = binding_alloc(rb_cBinding);
    rb_binding_t *bind;

    GetProcPtr(self, proc);
    GetBindingPtr(bindval, bind);

    if (TYPE(proc->block.iseq) == T_NODE) {
	rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
    }

    bind->env = proc->envval;
    return bindval;
}
예제 #9
0
파일: vm.c 프로젝트: qnighy/ruby-1.9.2p0
static void
vm_set_main_stack(rb_thread_t *th, VALUE iseqval)
{
    VALUE toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING"));
    rb_binding_t *bind;
    rb_iseq_t *iseq;
    rb_env_t *env;

    GetBindingPtr(toplevel_binding, bind);
    GetEnvPtr(bind->env, env);
    th->base_block = &env->block;
    vm_set_eval_stack(th, iseqval, 0);
    th->base_block = 0;

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

    CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
}
예제 #10
0
static VALUE binding_of_caller(VALUE self, VALUE rb_level)
{
  rb_thread_t *th;
  GetThreadPtr(rb_thread_current(), th);

  rb_control_frame_t *cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
  rb_control_frame_t *limit_cfp = (void *)(th->stack + th->stack_size);
  int level = FIX2INT(rb_level);

  // attempt to locate the nth parent control frame
  for (int i = 0; i < level; i++) {
    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);

    if (cfp >= limit_cfp)
      rb_raise(rb_eRuntimeError, "Invalid frame, gone beyond end of stack!");

    // skip invalid frames
    if (!valid_frame_p(cfp, limit_cfp))
      cfp = find_valid_frame(cfp, limit_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);
  bind->filename = cfp->iseq->filename;
  bind->line_no = rb_vm_get_sourceline(cfp);
  
  rb_iv_set(bindval, "@frame_type", frametype_name(cfp->flag));
  rb_iv_set(bindval, "@frame_description", cfp->iseq->name);

  return bindval;
}
예제 #11
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 = &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;
}