예제 #1
0
static void
replace_stop_with_return(mrb_state *mrb, mrb_irep *irep)
{
  if (irep->iseq[irep->ilen - 1] == MKOP_A(OP_STOP, 0)) {
    irep->iseq = mrb_realloc(mrb, irep->iseq, (irep->ilen + 1) * sizeof(mrb_code));
    irep->iseq[irep->ilen - 1] = MKOP_A(OP_LOADNIL, 0);
    irep->iseq[irep->ilen] = MKOP_AB(OP_RETURN, 0, OP_R_NORMAL);
    irep->ilen++;
  }
}
예제 #2
0
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);
}
예제 #3
0
static void
replace_stop_with_return(mrb_state *mrb, mrb_irep *irep)
{
  if (irep->iseq[irep->ilen - 1] == MKOP_A(OP_STOP, 0)) {
    if (irep->flags == MRB_ISEQ_NO_FREE) {
      mrb_code* iseq = (mrb_code *)mrb_malloc(mrb, (irep->ilen + 1) * sizeof(mrb_code));
      memcpy(iseq, irep->iseq, irep->ilen * sizeof(mrb_code));
      irep->iseq = iseq;
      irep->flags &= ~MRB_ISEQ_NO_FREE;
    } else {
      irep->iseq = (mrb_code *)mrb_realloc(mrb, irep->iseq, (irep->ilen + 1) * sizeof(mrb_code));
    }
    irep->iseq[irep->ilen - 1] = MKOP_A(OP_LOADNIL, 0);
    irep->iseq[irep->ilen] = MKOP_AB(OP_RETURN, 0, OP_R_NORMAL);
    irep->ilen++;
  }
}
예제 #4
0
파일: eval.c 프로젝트: devnexen/h2o
static void
patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top)
{
  int i;
  mrb_code c;
  int argc = irep_argc(irep);

  for (i = 0; i < irep->ilen; i++) {
    c = irep->iseq[i];
    switch(GET_OPCODE(c)){
    case OP_EPUSH:
      patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1, top);
      break;

    case OP_LAMBDA:
      {
        int arg_c = GETARG_c(c);
        if (arg_c & OP_L_CAPTURE) {
          patch_irep(mrb, irep->reps[GETARG_b(c)], bnest + 1, top);
        }
      }
      break;

    case OP_SEND:
      if (GETARG_C(c) != 0) {
        break;
      }
      else {
        mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest);
        if (arg != 0) {
          /* must replace */
          irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
        }
      }
      break;

    case OP_MOVE:
      /* src part */
      if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) {
        mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest);
        if (arg != 0) {
          /* must replace */
          irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
        }
      }
      /* dst part */
      if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) {
        mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest);
        if (arg != 0) {
          /* must replace */
          irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg;
        }
      }
      break;

    case OP_GETUPVAR:
      {
        int lev = GETARG_C(c)+1;
        mrb_irep *tmp = search_irep(top, bnest, lev, irep);
        if (potential_upvar_p(tmp->lv, GETARG_B(c), irep_argc(tmp), tmp->nlocals)) {
          mrb_code arg = search_variable(mrb, tmp->lv[GETARG_B(c)-1].name, bnest);
          if (arg != 0) {
            /* must replace */
            irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
          }
        }
      }
      break;

    case OP_SETUPVAR:
      {
        int lev = GETARG_C(c)+1;
        mrb_irep *tmp = search_irep(top, bnest, lev, irep);
        if (potential_upvar_p(tmp->lv, GETARG_B(c), irep_argc(tmp), tmp->nlocals)) {
          mrb_code arg = search_variable(mrb, tmp->lv[GETARG_B(c)-1].name, bnest);
          if (arg != 0) {
            /* must replace */
            irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
          }
        }
      }
      break;

    case OP_STOP:
      if (mrb->c->ci->acc >= 0) {
        irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL);
      }
      break;
    }
  }
}