void Init_prelude(void) { rb_iseq_eval(rb_iseq_compile( rb_str_new(prelude_code0, sizeof(prelude_code0) - 1), rb_str_new(prelude_name0, sizeof(prelude_name0) - 1), INT2FIX(1))); rb_iseq_eval(rb_iseq_compile( rb_str_new(prelude_code1, sizeof(prelude_code1) - 1), rb_str_new(prelude_name1, sizeof(prelude_name1) - 1), INT2FIX(0))); #if 0 puts(prelude_code0); puts(prelude_code1); #endif }
/* Return a list of trace hook line numbers for the string in Ruby source src*/ static VALUE lnums_for_str(VALUE self, VALUE src) { VALUE result = rb_ary_new(); /* The returned array of line numbers. */ int len; char *token; char *disasm; rb_thread_t *th; VALUE iseqval; VALUE disasm_val; StringValue(src); /* Check that src is a string. */ th = GET_THREAD(); /* First compile to bytecode, using the method in eval_string_with_cref() in vm_eval.c */ th->parse_in_eval++; th->mild_compile_error++; iseqval = rb_iseq_compile(src, rb_str_new_cstr("(numbers_for_str)"), INT2FIX(1)); th->mild_compile_error--; th->parse_in_eval--; /* Disassemble the bytecode into text and parse into lines */ disasm_val = rb_iseq_disasm(iseqval); if (disasm_val == Qnil) return(result); disasm = (char*)malloc(strlen(RSTRING_PTR(disasm_val))+1); strcpy(disasm, RSTRING_PTR(disasm_val)); for (token = strtok(disasm, "\n"); token != NULL; token = strtok(NULL, "\n")) { /* look only for lines tracing RUBY_EVENT_LINE (1) */ if (strstr(token, "trace 1 ") == NULL) continue; len = strlen(token) - 1; if (token[len] != ')') continue; len--; if ((token[len] == '(') || (token[len] == ' ')) continue; for (; len > 0; len--) { if (token[len] == ' ') continue; if ((token[len] >= '0') && (token[len] <= '9')) continue; if (token[len] == '(') rb_ary_push(result, INT2NUM(atoi(token + len + 1))); /* trace found */ break; } } free(disasm); return result; }
static VALUE __rho_compile( VALUE obj, VALUE src) { VALUE result; rb_thread_t *th = GET_THREAD(); rb_secure(1); th->parse_in_eval++; result = rb_iseq_compile(src, rb_str_new2("(eval)"), INT2FIX(1)); th->parse_in_eval--; return result; }
/*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; }