1 /*
2 ** apiprint.c
3 **
4 */
5 
6 #include <string.h>
7 #include "mrdb.h"
8 #include <mruby/value.h>
9 #include <mruby/class.h>
10 #include <mruby/compile.h>
11 #include <mruby/error.h>
12 #include <mruby/numeric.h>
13 #include <mruby/string.h>
14 #include "apiprint.h"
15 
16 static void
mrdb_check_syntax(mrb_state * mrb,mrb_debug_context * dbg,const char * expr,size_t len)17 mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len)
18 {
19   mrbc_context *c;
20 
21   c = mrbc_context_new(mrb);
22   c->no_exec = TRUE;
23   c->capture_errors = TRUE;
24   mrbc_filename(mrb, c, (const char*)dbg->prvfile);
25   c->lineno = dbg->prvline;
26 
27   /* Load program */
28   mrb_load_nstring_cxt(mrb, expr, len, c);
29 
30   mrbc_context_free(mrb, c);
31 }
32 
33 mrb_value
mrb_debug_eval(mrb_state * mrb,mrb_debug_context * dbg,const char * expr,size_t len,mrb_bool * exc,int direct_eval)34 mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval)
35 {
36   void (*tmp)(struct mrb_state *, struct mrb_irep *, const mrb_code *, mrb_value *);
37   mrb_value ruby_code;
38   mrb_value s;
39   mrb_value v;
40   mrb_value recv;
41 
42   /* disable code_fetch_hook */
43   tmp = mrb->code_fetch_hook;
44   mrb->code_fetch_hook = NULL;
45 
46   mrdb_check_syntax(mrb, dbg, expr, len);
47   if (mrb->exc) {
48     v = mrb_obj_value(mrb->exc);
49     mrb->exc = 0;
50   }
51   else if (direct_eval) {
52     recv = dbg->regs[0];
53 
54     v = mrb_funcall(mrb, recv, expr, 0);
55   }
56   else {
57     /*
58      * begin
59      *   expr
60      * rescue => e
61      *   e
62      * end
63      */
64     ruby_code = mrb_str_new_lit(mrb, "begin\n");
65     ruby_code = mrb_str_cat(mrb, ruby_code, expr, len);
66     ruby_code = mrb_str_cat_lit(mrb, ruby_code, "\nrescue => e\ne\nend");
67 
68     recv = dbg->regs[0];
69 
70     v =  mrb_funcall(mrb, recv, "instance_eval", 1, ruby_code);
71   }
72 
73   if (exc) {
74     *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class);
75   }
76 
77   s = mrb_inspect(mrb, v);
78 
79   /* enable code_fetch_hook */
80   mrb->code_fetch_hook = tmp;
81 
82   return s;
83 }
84