예제 #1
0
spidermonkey_vm *sm_initialize(long thread_stack, long heap_size) {
  spidermonkey_vm *vm = ejs_alloc(sizeof(spidermonkey_vm));
  spidermonkey_state *state = ejs_alloc(sizeof(spidermonkey_state));
  state->branch_count = 0;
  state->error = NULL;
  state->terminate = 0;
  int gc_size = (int) heap_size * 0.25;
  vm->runtime = JS_NewRuntime(MAX_GC_SIZE);
  JS_SetGCParameter(vm->runtime, JSGC_MAX_BYTES, heap_size);
  JS_SetGCParameter(vm->runtime, JSGC_MAX_MALLOC_BYTES, gc_size);
  vm->context = JS_NewContext(vm->runtime, 8192);
  JS_SetScriptStackQuota(vm->context, thread_stack);

  begin_request(vm);
  JS_SetOptions(vm->context, JSOPTION_VAROBJFIX);
  JS_SetOptions(vm->context, JSOPTION_STRICT);
  JS_SetOptions(vm->context, JSOPTION_COMPILE_N_GO);
  JS_SetOptions(vm->context, JSVERSION_LATEST);
  vm->global = JS_NewCompartmentAndGlobalObject(vm->context, &global_class, NULL);
  JS_InitStandardClasses(vm->context, vm->global);
  JS_SetErrorReporter(vm->context, on_error);
  JS_SetOperationCallback(vm->context, on_branch);
  JS_SetContextPrivate(vm->context, state);
  JSNative funptr = (JSNative) &js_log;
  JS_DefineFunction(vm->context, JS_GetGlobalObject(vm->context), "ejsLog", funptr,
                    0, 0);
  end_request(vm);

  return vm;
}
예제 #2
0
char *copy_string(const char *source) {
  size_t size = strlen(source);
  char *retval = ejs_alloc(size + 1);
  strncpy(retval, source, size);
  retval[size] = '\0';
  return retval;
}
예제 #3
0
static void process(ErlDrvData handle, ErlIOVec *ev) {
  spidermonkey_drv_t *dd = (spidermonkey_drv_t *) handle;

  char *data = ev->binv[1]->orig_bytes;
  char *command = read_command(&data);
  if (strncmp(command, "ij", 2) == 0) {
    char *call_id = read_string(&data);
    int thread_stack = read_int32(&data);
    if (thread_stack < 8) {
      thread_stack = 8;
    }
    thread_stack = thread_stack * (1024 * 1024);
    int heap_size = read_int32(&data) * (1024 * 1024);
    dd->vm = sm_initialize(thread_stack, heap_size);
    send_immediate_ok_response(dd, call_id);
    driver_free(call_id);
  }
  else {
    js_call *call_data = ejs_alloc(sizeof(js_call));
    call_data->driver_data = dd;
    call_data->args = ev->binv[1];
    call_data->return_terms[0] = 0;
    call_data->return_term_count = 0;
    call_data->return_string = NULL;
    driver_binary_inc_refc(call_data->args);
    ErlDrvPort port = dd->port;
    intptr_t port_ptr = (intptr_t) port;
    unsigned int thread_key = port_ptr;
    driver_async(dd->port, &thread_key, (asyncfun) run_js, (void *) call_data, NULL);
  }
  driver_free(command);
}
예제 #4
0
static ErlDrvData start(ErlDrvPort port, char *cmd) {
  spidermonkey_drv_t *retval = ejs_alloc(sizeof(spidermonkey_drv_t));
  retval->port = port;
  retval->shutdown = 0;
  retval->atom_ok = driver_mk_atom((char *) "ok");
  retval->atom_error = driver_mk_atom((char *) "error");
  retval->atom_unknown_cmd = driver_mk_atom((char *) "unknown_command");
  return (ErlDrvData) retval;
}
예제 #5
0
char *error_to_json(const spidermonkey_error *error) {
  char *escaped_source = escape_quotes(error->offending_source);
  /* size = length(escaped source) + length(error msg) + JSON formatting */
  size_t size = strlen(escaped_source) + strlen(error->msg) + 80;
  char *retval = ejs_alloc(size);

  snprintf(retval, size, "{\"error\": {\"lineno\": %d, \"message\": \"%s\", \"source\": \"%s\"}}",
           error->lineno, error->msg, escaped_source);
  driver_free(escaped_source);
  return retval;
}
예제 #6
0
char *escape_quotes(char *text) {
  size_t bufsize = strlen(text) * 2;
  char *buf = ejs_alloc(bufsize);
  memset(buf, 0, bufsize);
  int i = 0;
  int x = 0;
  int escaped = 0;
  for (i = 0; i < strlen(text); i++) {
    if (text[i] == '"') {
      if(!escaped) {
        memcpy(&buf[x], (char *) "\\\"", 2);
        x += 2;
      }
      else {
        memcpy(&buf[x], &text[i], 1);
        x++;
      }
    }
    else {
      if(text[i] =='\\') {
        escaped = 1;
      }
      else {
        escaped = 0;
      }
      memcpy(&buf[x], &text[i], 1);
      x++;
    }
  }
  size_t buf_size = strlen(buf);
  char *retval = ejs_alloc(buf_size + 1);
  strncpy(retval, buf, buf_size);
  retval[buf_size] = '\0';
  driver_free(buf);
  return retval;
}
예제 #7
0
void on_error(JSContext *context, const char *message, JSErrorReport *report) {
  if (report->flags & JSREPORT_EXCEPTION) {
    spidermonkey_error *sm_error = ejs_alloc(sizeof(spidermonkey_error));
    if (message != NULL) {
      sm_error->msg = copy_string(message);
    }
    else {
      sm_error->msg = copy_string("undefined error");
    }
    sm_error->lineno = report->lineno;
    if (report->linebuf != NULL) {
      sm_error->offending_source = copy_string(report->linebuf);
    }
    else {
      sm_error->offending_source = copy_string("unknown");
    }
    spidermonkey_state *state = (spidermonkey_state *) JS_GetContextPrivate(context);
    state->error = sm_error;
    JS_SetContextPrivate(context, state);
  }
}