static struct RProc* create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, char *file, mrb_int line) { mrbc_context *cxt; struct mrb_parser_state *p; struct RProc *proc; struct REnv *e; if (!mrb_nil_p(binding)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil."); } cxt = mrbc_context_new(mrb); cxt->lineno = line; if (file) { mrbc_filename(mrb, cxt, file); } cxt->capture_errors = TRUE; p = mrb_parse_nstring(mrb, s, len, cxt); /* only occur when memory ran out */ if (!p) { mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state."); } if (0 < p->nerr) { /* parse error */ char buf[256]; int n; n = snprintf(buf, sizeof(buf), "line %d: %s\n", p->error_buffer[0].lineno, p->error_buffer[0].message); mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_exc_raise(mrb, mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n)); } proc = mrb_generate_code(mrb, p); if (proc == NULL) { /* codegen error */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error"); } if (mrb->c->ci[-1].proc->target_class) { proc->target_class = mrb->c->ci[-1].proc->target_class; } e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci[-1].proc->env); e->mid = mrb->c->ci[-1].mid; e->cioff = mrb->c->ci - mrb->c->cibase - 1; e->stack = mrb->c->ci->stackent; mrb->c->ci->env = e; proc->env = e; patch_irep(mrb, proc->body.irep, 0); mrb_parser_free(p); mrbc_context_free(mrb, cxt); return proc; }
static mrb_value eval_context_compile(mrb_state *mrb, mrb_value self) { char *script; mrb_int script_length; mrbc_context* compile_ctx; struct mrb_parser_state *parser; struct RProc *proc; mrb_get_args(mrb, "s", &script, &script_length); compile_ctx = mrbc_context_new(mrb); if (!compile_ctx) { mrb_raise(mrb, E_RUNTIME_ERROR, "[mruby][eval][compile] failed to allocate context"); } compile_ctx->capture_errors = TRUE; parser = mrb_parse_nstring(mrb, script, script_length, compile_ctx); if (!parser) { mrbc_context_free(mrb, compile_ctx); mrb_raise(mrb, E_RUNTIME_ERROR, "[mruby][eval][compile] failed to allocate parser"); } if (parser->nerr > 0) { struct mrb_parser_message *error = &(parser->error_buffer[0]); mrb_value new_args[1]; mrb_value exception; new_args[0] = mrb_format(mrb, "line %S:%S: %S", mrb_fixnum_value(error->lineno), mrb_fixnum_value(error->column), mrb_str_new_cstr(mrb, error->message)); exception = mrb_obj_new(mrb, E_SYNTAX_ERROR, 1, new_args); mrb_parser_free(parser); mrbc_context_free(mrb, compile_ctx); mrb_exc_raise(mrb, exception); } proc = mrb_generate_code(mrb, parser); { mrb_code *iseq = proc->body.irep->iseq; while (GET_OPCODE(*iseq) != OP_STOP) { iseq++; } *iseq = MKOP_AB(OP_RETURN, 1, OP_R_NORMAL); } mrb_parser_free(parser); mrbc_context_free(mrb, compile_ctx); return mrb_obj_value(proc); }
bool TRI_ExecuteRubyString (mrb_state* mrb, char const* script, char const* name, bool printResult, mrb_value* result) { struct mrb_parser_state* parser; mrb_value r; int n; parser = mrb_parse_nstring(mrb, script, strlen(script), NULL); if (parser == 0 || parser->tree == 0 || 0 < parser->nerr) { LOG_DEBUG("failed to parse ruby script"); if (parser != 0 && parser->pool != 0) { mrb_pool_close(parser->pool); } return false; } n = mrb_generate_code(mrb, parser); mrb_pool_close(parser->pool); if (n < 0) { LOG_DEBUG("failed to generate ruby code: %d", n); return false; } r = mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); if (mrb->exc) { if (printResult) { mrb_p(mrb, mrb_obj_value(mrb->exc)); } mrb->exc = 0; } else if (printResult && ! mrb_nil_p(r)) { mrb_p(mrb, r); } if (result != NULL) { *result = r; } return true; }
bool TRI_ExecuteRubyString (mrb_state* mrb, char const* script, char const* name, bool printResult, mrb_value* result) { struct mrb_parser_state* p; mrb_value r; int n; p = mrb_parse_nstring(mrb, script, strlen(script)); if (p == 0 || p->tree == 0 || 0 < p->nerr) { printf("failed to parse script\n"); return false; } n = mrb_generate_code(mrb, p->tree); if (n < 0) { printf("failed to generate code: %d\n", n); return false; } r = mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb)); if (mrb->exc) { if (printResult) { mrb_p(mrb, mrb_obj_value(mrb->exc)); } mrb->exc = 0; } else if (printResult && ! mrb_nil_p(r)) { mrb_p(mrb, r); } if (result != NULL) { *result = r; } return true; }
static struct RProc* create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) { mrbc_context *cxt; struct mrb_parser_state *p; struct RProc *proc; struct REnv *e; mrb_callinfo *ci = &mrb->c->ci[-1]; /* callinfo of eval caller */ struct RClass *target_class = NULL; int bidx; if (!mrb_nil_p(binding)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil."); } cxt = mrbc_context_new(mrb); cxt->lineno = (short)line; mrbc_filename(mrb, cxt, file ? file : "(eval)"); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; p = mrb_parse_nstring(mrb, s, len, cxt); /* only occur when memory ran out */ if (!p) { mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state."); } if (0 < p->nerr) { /* parse error */ mrb_value str; if (file) { str = mrb_format(mrb, " file %S line %S: %S", mrb_str_new_cstr(mrb, file), mrb_fixnum_value(p->error_buffer[0].lineno), mrb_str_new_cstr(mrb, p->error_buffer[0].message)); } else { str = mrb_format(mrb, " line %S: %S", mrb_fixnum_value(p->error_buffer[0].lineno), mrb_str_new_cstr(mrb, p->error_buffer[0].message)); } mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); } proc = mrb_generate_code(mrb, p); if (proc == NULL) { /* codegen error */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error"); } target_class = MRB_PROC_TARGET_CLASS(ci->proc); if (!MRB_PROC_CFUNC_P(ci->proc)) { if (ci->env) { e = ci->env; } else { e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)target_class); e->mid = ci->mid; e->stack = ci[1].stackent; e->cxt = mrb->c; MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals); bidx = ci->argc; if (ci->argc < 0) bidx = 2; else bidx += 1; MRB_ENV_SET_BIDX(e, bidx); ci->env = e; } proc->e.env = e; proc->flags |= MRB_PROC_ENVSET; mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); } proc->upper = ci->proc; mrb->c->ci->target_class = target_class; patch_irep(mrb, proc->body.irep, 0, proc->body.irep); /* mrb_codedump_all(mrb, proc); */ mrb_parser_free(p); mrbc_context_free(mrb, cxt); return proc; }
mrb_parser_state* mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c) { return mrb_parse_nstring(mrb, s, c); }
mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const std::string & s, mrbc_context *c) { return load_exec(mrb, mrb_parse_nstring(mrb, s, c), c); }