summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-eval/src/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-eval/src/eval.c')
-rw-r--r--mrbgems/mruby-eval/src/eval.c102
1 files changed, 51 insertions, 51 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index 508f5ffcb..13dd3ea4c 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -9,10 +9,10 @@
#include <mruby/variable.h>
struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc);
-mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook);
+mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p);
mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
+mrb_value mrb_mod_module_eval(mrb_state*, mrb_value);
void mrb_codedump_all(mrb_state*, struct RProc*);
-void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack);
static struct RProc*
create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line)
@@ -52,10 +52,19 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
e = NULL;
}
+ if (file) {
+ if (strlen(file) >= UINT16_MAX) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "filename too long");
+ }
+ }
+ else {
+ file = "(eval)";
+ }
+
cxt = mrbc_context_new(mrb);
cxt->lineno = (uint16_t)line;
- mrbc_filename(mrb, cxt, file ? file : "(eval)");
+ mrbc_filename(mrb, cxt, file);
cxt->capture_errors = TRUE;
cxt->no_optimize = TRUE;
cxt->upper = scope && MRB_PROC_CFUNC_P(scope) ? NULL : scope;
@@ -64,6 +73,7 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
/* only occur when memory ran out */
if (!p) {
+ mrbc_context_free(mrb, cxt);
mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state (out of memory)");
}
@@ -71,6 +81,11 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
/* parse error */
mrb_value str;
+ mrbc_context_free(mrb, cxt);
+ if (!p->error_buffer[0].message) {
+ mrb_parser_free(p);
+ mrb_raise(mrb, E_SYNTAX_ERROR, "compile error");
+ }
if (file) {
str = mrb_format(mrb, "file %s line %d: %s",
file,
@@ -83,7 +98,6 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
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));
}
@@ -127,44 +141,14 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi
}
static mrb_value
-exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc, mrb_func_t posthook)
+exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
{
/* no argument passed from eval() */
- mrb->c->ci->argc = 0;
+ mrb->c->ci->n = 0;
+ mrb->c->ci->nk = 0;
/* clear block */
mrb->c->ci->stack[1] = mrb_nil_value();
- return mrb_exec_irep(mrb, self, proc, posthook);
-}
-
-static void
-eval_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack)
-{
- mrb_assert(mrb->c->stend >= stack + num);
- mrb_proc_merge_lvar(mrb, irep, env, num, lv, stack);
-}
-
-static mrb_value
-eval_merge_lvar_hook(mrb_state *mrb, mrb_value dummy_self)
-{
- const mrb_callinfo *orig_ci = &mrb->c->ci[1];
- const struct RProc *orig_proc = orig_ci->proc;
- const mrb_irep *orig_irep = orig_proc->body.irep;
- int orig_nlocals = orig_irep->nlocals;
-
- if (orig_nlocals > 1) {
- struct RProc *proc = (struct RProc *)orig_proc->upper;
- struct REnv *env = MRB_PROC_ENV(orig_proc);
- eval_merge_lvar(mrb, (mrb_irep *)proc->body.irep, env,
- orig_nlocals - 1, orig_irep->lv,
- mrb->c->ci->stack + 3 /* hook proc + exc + ret val */);
- }
-
- mrb_value exc = mrb->c->ci->stack[1];
- if (!mrb_nil_p(exc)) {
- mrb_exc_raise(mrb, exc);
- }
-
- return mrb->c->ci->stack[2];
+ return mrb_exec_irep(mrb, self, proc);
}
static mrb_value
@@ -176,30 +160,21 @@ f_eval(mrb_state *mrb, mrb_value self)
const char *file = NULL;
mrb_int line = 1;
struct RProc *proc;
- mrb_func_t posthook = NULL;
mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line);
proc = create_proc_from_string(mrb, s, len, binding, file, line);
if (!mrb_nil_p(binding)) {
self = mrb_iv_get(mrb, binding, MRB_SYM(recv));
- if (mrb_env_p(mrb_iv_get(mrb, binding, MRB_SYM(env)))) {
- posthook = eval_merge_lvar_hook;
- }
}
mrb_assert(!MRB_PROC_CFUNC_P(proc));
- return exec_irep(mrb, self, proc, posthook);
+ return exec_irep(mrb, self, proc);
}
static mrb_value
f_instance_eval(mrb_state *mrb, mrb_value self)
{
- mrb_value b;
- mrb_int argc; const mrb_value *argv;
-
- mrb_get_args(mrb, "*!&", &argv, &argc, &b);
-
- if (mrb_nil_p(b)) {
+ if (!mrb_block_given_p(mrb)) {
const char *s;
mrb_int len;
const char *file = NULL;
@@ -213,19 +188,44 @@ f_instance_eval(mrb_state *mrb, mrb_value self)
MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv));
mrb_assert(!MRB_PROC_CFUNC_P(proc));
mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(cv));
- return exec_irep(mrb, self, proc, NULL);
+ return exec_irep(mrb, self, proc);
}
else {
- mrb_get_args(mrb, "&", &b);
+ mrb_get_args(mrb, "");
return mrb_obj_instance_eval(mrb, self);
}
}
+static mrb_value
+f_class_eval(mrb_state *mrb, mrb_value self)
+{
+ if (!mrb_block_given_p(mrb)) {
+ const char *s;
+ mrb_int len;
+ const char *file = NULL;
+ mrb_int line = 1;
+ struct RProc *proc;
+
+ mrb_get_args(mrb, "s|zi", &s, &len, &file, &line);
+ proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
+ MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(self));
+ mrb_assert(!MRB_PROC_CFUNC_P(proc));
+ mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(self));
+ return exec_irep(mrb, self, proc);
+ }
+ else {
+ mrb_get_args(mrb, "");
+ return mrb_mod_module_eval(mrb, self);
+ }
+}
+
void
mrb_mruby_eval_gem_init(mrb_state* mrb)
{
mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), MRB_SYM(instance_eval), f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
+ mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(module_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
+ mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(class_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
}
void