Exemple #1
0
void httpIdle() {
  if (networkState != NETWORKSTATE_ONLINE) return;
  JsVar *arr = httpGetArray(HTTP_ARRAY_HTTP_SERVERS,false);
  if (arr) {
    JsArrayIterator it;
    jsvArrayIteratorNew(&it, arr);
    while (jsvArrayIteratorHasElement(&it)) {
      JsVar *server = jsvArrayIteratorGetElement(&it);
      SOCKET socket = (SOCKET)jsvGetIntegerAndUnLock(jsvObjectGetChild(server,HTTP_NAME_SOCKET,0))-1; // so -1 if undefined
  #ifndef USE_CC3000
      // TODO: look for unreffed servers?
      fd_set s;
      FD_ZERO(&s);
      FD_SET(socket,&s);
      // check for waiting clients
      struct timeval timeout;
      timeout.tv_sec = 0;
      timeout.tv_usec = 0;
      int n = select(socket+1,&s,NULL,NULL,&timeout);
  #else
      /* CC3000 works a different way - we set accept as nonblocking,
       * and then we just call it and see if it works or not...
       */
      int n=1;
  #endif
      while (n-->0) {
        // we have a client waiting to connect...
        int theClient = accept(socket,NULL,NULL); // try and connect
        if (theClient > -1) {
          JsVar *req = jspNewObject(jsiGetParser(), 0, "httpSRq");
          JsVar *res = jspNewObject(jsiGetParser(), 0, "httpSRs");
          if (res && req) { // out of memory?
            JsVar *arr = httpGetArray(HTTP_ARRAY_HTTP_SERVER_CONNECTIONS, true);
            if (arr) {
              jsvArrayPush(arr, req);
              jsvUnLock(arr);
            }
            jsvObjectSetChild(req, HTTP_NAME_RESPONSE_VAR, res);
            jsvObjectSetChild(req, HTTP_NAME_SERVER_VAR, server);
            jsvUnLock(jsvObjectSetChild(req, HTTP_NAME_SOCKET, jsvNewFromInteger(theClient+1)));
            // on response
            jsvUnLock(jsvObjectSetChild(res, HTTP_NAME_CODE, jsvNewFromInteger(200)));
            jsvUnLock(jsvObjectSetChild(res, HTTP_NAME_HEADERS, jsvNewWithFlags(JSV_OBJECT)));
          }
          jsvUnLock(req);
          jsvUnLock(res);
          //add(new CNetworkConnect(theClient, this));
          // add to service queue
        }
      }
      jsvUnLock(server);
      jsvArrayIteratorNext(&it);
    }
    jsvArrayIteratorFree(&it);
    jsvUnLock(arr);
  }

  httpServerConnectionsIdle();
  httpClientConnectionsIdle();
}
/*JSON{ "type":"function", "name" : "eval",
         "description" : "Evaluate a string containing JavaScript code",
         "generate" : "jswrap_eval",
         "params" : [ [ "code", "JsVar", ""] ],
         "return" : ["JsVar", "The result of evaluating the string"]
}*/
JsVar *jswrap_eval(JsVar *v) {
  if (!v) return 0;
  JsVar *s = jsvAsString(v, false); // get as a string
  JsVar *result = jspEvaluateVar(jsiGetParser(), s, 0);
  jsvUnLock(s);
  return result;
}
Exemple #3
0
JsVar *httpClientRequestNew(JsVar *options, JsVar *callback) {
  JsVar *arr = httpGetArray(HTTP_ARRAY_HTTP_CLIENT_CONNECTIONS,true);
  if (!arr) return 0;
  JsVar *req = jspNewObject(jsiGetParser(), 0, "httpCRq");
  JsVar *res = jspNewObject(jsiGetParser(), 0, "httpCRs");
  if (res && req) { // out of memory?
   jsvUnLock(jsvAddNamedChild(req, callback, HTTP_NAME_ON_CONNECT));

   jsvArrayPush(arr, req);
   jsvObjectSetChild(req, HTTP_NAME_RESPONSE_VAR, res);
   jsvObjectSetChild(req, HTTP_NAME_OPTIONS_VAR, options);
  }
  jsvUnLock(res);
  jsvUnLock(arr);
  return req;
}
/*JSON{ "type":"function", "name" : "trace", "ifndef" : "SAVE_ON_FLASH",
         "description" : "Output debugging information",
         "generate" : "jswrap_interface_trace",
         "params" : [ [ "root", "JsVarName", "The symbol to output (optional). If nothing is specified, everything will be output"] ]
}*/
void jswrap_interface_trace(JsVar *root) {
  if (jsvIsUndefined(root)) {
    jsvTrace(jsvGetRef(jsiGetParser()->root), 0);
  } else {
    jsvTrace(jsvGetRef(root), 0);
  }
}
Exemple #5
0
JsVar *jswrap_interface_memory() {
  jsvGarbageCollect();
  JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
  if (obj) {
    unsigned int history = 0;
    JsVar *historyVar = jsvObjectGetChild(jsiGetParser()->root, JSI_HISTORY_NAME, 0);
    if (historyVar) {
      history = (unsigned int)jsvCountJsVarsUsed(historyVar); // vars used to store history
      jsvUnLock(historyVar);
    }
    unsigned int usage = jsvGetMemoryUsage() - history;
    unsigned int total = jsvGetMemoryTotal();
    JsVar *v;
    v = jsvNewFromInteger(total-usage);
    jsvUnLock(jsvAddNamedChild(obj, v, "free"));
    jsvUnLock(v);
    v = jsvNewFromInteger(usage);
    jsvUnLock(jsvAddNamedChild(obj, v, "usage"));
    jsvUnLock(v);
    v = jsvNewFromInteger(total);
    jsvUnLock(jsvAddNamedChild(obj, v, "total"));
    jsvUnLock(v);
    v = jsvNewFromInteger(history);
    jsvUnLock(jsvAddNamedChild(obj, v, "history"));
    jsvUnLock(v);

#ifdef ARM
    v = jsvNewFromInteger((JsVarInt)(unsigned int)&_end);
    jsvUnLock(jsvAddNamedChild(obj, v, "stackEndAddress"));
    jsvUnLock(v);
#endif
  }
  return obj;
}
Exemple #6
0
/*JSON{ "type":"function", "name" : "require",
         "description" : "Load the given module, and return the exported functions",
         "generate" : "jswrap_require",
         "params" : [ [ "moduleName", "JsVar", "A String containing the name of the given module"] ],
         "return" : ["JsVar", "The result of evaluating the string"]
}*/
JsVar *jswrap_require(JsVar *moduleName) {
  if (!jsvIsString(moduleName)) {
    jsWarn("Expecting a module name as a string, but got %t", moduleName);
    return 0;
  }
  // Search to see if we have already loaded this module

  JsVar *moduleList = jswrap_modules_getModuleList();
  if (!moduleList) return 0; // out of memory
  JsVar *moduleExportName = jsvFindChildFromVar(moduleList, moduleName, true);
  jsvUnLock(moduleList);
  if (!moduleExportName) return 0; // out of memory
  JsVar *moduleExport = jsvSkipName(moduleExportName);
  if (moduleExport) {
    // Found the module!
    jsvUnLock(moduleExportName);
    return moduleExport;
  }

  // Now check if it is built-in
  char moduleNameBuf[32];
  jsvGetString(moduleName, moduleNameBuf, sizeof(moduleNameBuf));
  if (jswIsBuiltInLibrary(moduleNameBuf)) {
    // create a 'fake' module that Espruino can use to map its built-in functions against
    moduleExport = jspNewBuiltin(moduleNameBuf);
  } else {
    // Now try and load it
    JsVar *fileContents = 0;
    //if (jsvIsStringEqual(moduleName,"http")) {}
    //if (jsvIsStringEqual(moduleName,"fs")) {}
  #ifdef USE_FILESYSTEM
    JsVar *modulePath = jsvNewFromString(
  #ifdef LINUX
        "node_modules/"
  #else
        "NODE_M~1/"
  #endif
        );
    if (!modulePath) { jsvUnLock(moduleExportName); return 0; } // out of memory
    jsvAppendStringVarComplete(modulePath, moduleName);
    jsvAppendString(modulePath,".js");
    fileContents = wrap_fat_readFile(modulePath);
    jsvUnLock(modulePath);
  #endif
    if (!fileContents || jsvIsStringEqual(fileContents,"")) {
      jsvUnLock(moduleExportName);
      jsvUnLock(fileContents);
      jsWarn("Module not found");
      return 0;
    }
    moduleExport = jspEvaluateModule(jsiGetParser(), fileContents);
    jsvUnLock(fileContents);
  }

  assert(moduleExport);
  jsvSetValueOfName(moduleExportName, moduleExport); // save in cache
  jsvUnLock(moduleExportName);
  return moduleExport;
}
Exemple #7
0
static void cc3000_state_change(const char *data) {
  JsVar *wlanObj = jsvObjectGetChild(jsiGetParser()->root, CC3000_OBJ_NAME, 0);
  JsVar *dataVar = jsvNewFromString(data);
  if (wlanObj)
    jsiQueueObjectCallbacks(wlanObj, CC3000_ON_STATE_CHANGE, dataVar, 0);
  jsvUnLock(dataVar);
  jsvUnLock(wlanObj);
bool run_test(const char *filename) {
  printf("----------------------------------\r\n");
  printf("----------------------------- TEST %s \r\n", filename);
  char *buffer = (char *)read_file(filename);
  if (!buffer) return (false);

  jshInit();
  jsiInit(false /* do not autoload!!! */);

  jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
  jspAddNativeFunction(jsiGetParser(), "function interrupt()", nativeInterrupt);

  jsvUnLock(jspEvaluate(jsiGetParser(), buffer ));

  isRunning = true;
  while (isRunning && jsiHasTimers()) jsiLoop();

  JsVar *result = jsvObjectGetChild(jsiGetParser()->root, "result", 0/*no create*/);
  bool pass = jsvGetBool(result);
  jsvUnLock(result);

  if (pass)
    printf("----------------------------- PASS %s\r\n", filename);
  else {
    printf("----------------------------------\r\n");
    printf("----------------------------- FAIL %s <-------\r\n", filename);
    jsvTrace(jsvGetRef(jsiGetParser()->root), 0);
    printf("----------------------------- FAIL %s <-------\r\n", filename);
    printf("----------------------------------\r\n");
  }
  printf("BEFORE: %d Memory Records Used\r\n", jsvGetMemoryUsage());
 // jsvTrace(jsiGetParser()->root, 0);
  jsiKill();
  printf("AFTER: %d Memory Records Used\r\n", jsvGetMemoryUsage());
  jsvGarbageCollect();
  printf("AFTER GC: %d Memory Records Used (should be 0!)\r\n", jsvGetMemoryUsage());
  jsvShowAllocated();
  jshKill();

  //jsvDottyOutput();
  printf("\r\n");

  free(buffer);
  return pass;
}
Exemple #9
0
static JsVar *httpGetArray(const char *name, bool create) {
  JsVar *arrayName = jsvFindChildFromString(jsiGetParser()->root, name, create);
  JsVar *arr = jsvSkipName(arrayName);
  if (!arr && create) {
    arr = jsvNewWithFlags(JSV_ARRAY);
    jsvSetValueOfName(arrayName, arr);
  }
  jsvUnLock(arrayName);
  return arr;
}
Exemple #10
0
static JsVar *jswrap_modules_getModuleList() {
  JsVar *moduleListName = jsvFindChildFromString(jsiGetParser()->root, JSPARSE_MODULE_CACHE_NAME, true);
  if (!moduleListName) return 0; // out of memory
  JsVar *moduleList = jsvSkipName(moduleListName);
  if (!moduleList) {
    moduleList = jsvNewWithFlags(JSV_OBJECT);
    if (!moduleList) { jsvUnLock(moduleListName); return 0; } // out of memory
    jsvSetValueOfName(moduleListName, moduleList); // no need to unlock
  }
  jsvUnLock(moduleListName);
  return moduleList;
}
Exemple #11
0
void lcdSetPixel_JS(JsGraphics *gfx, short x, short y, unsigned int col) {
  // look up setPixel and execute it!
//  JsVar *lcdProto = jsvSkipNameAndUnLock(jsvFindChildFromString(gfx->graphicsVar, JSPARSE_PROTOTYPE_VAR, false));
 // if (lcdProto) {
    JsVar *setPixel = jsvSkipNameAndUnLock(jsvFindChildFromString(gfx->graphicsVar/*lcdProto*/, "setPixel", false));
    if (setPixel) {
      JsVar *args[3];
      args[0] = jsvNewFromInteger(x);
      args[1] = jsvNewFromInteger(y);
      args[2] = jsvNewFromInteger(col);
      jspExecuteFunction(jsiGetParser(), setPixel, gfx->graphicsVar, 3, args);
      jsvUnLock(args[0]);
      jsvUnLock(args[1]);
      jsvUnLock(args[2]);
      jsvUnLock(setPixel);
    }
//    jsvUnLock(lcdProto);
//  }
}
Exemple #12
0
void cc3000_initialise(JsVar *wlanObj) {
  jsvObjectSetChild(jsiGetParser()->root, CC3000_OBJ_NAME, wlanObj);

  cc3000_spi_open();
  wlan_init(cc3000_usynch_callback,
            sendNoPatch/*sendWLFWPatch*/,
            sendNoPatch/*sendDriverPatch*/,
            sendNoPatch/*sendBootLoaderPatch*/,
            cc3000_read_irq_pin, cc3000_irq_enable, cc3000_irq_disable, cc3000_write_en_pin);
  wlan_start(0/* No patches */);
  // Mask out all non-required events from CC3000
  wlan_set_event_mask(
      HCI_EVNT_WLAN_KEEPALIVE |
      HCI_EVNT_WLAN_UNSOL_INIT);

  // TODO: check return value !=0
  wlan_ioctl_set_connection_policy(0, 0, 0); // don't auto-connect
  wlan_ioctl_del_profile(255); // delete stored eeprom data
Exemple #13
0
/*JSON{ "type":"staticmethod",
         "class" : "Modules", "name" : "addCached",
         "description" : "Add the given module to the cache",
         "generate" : "jswrap_modules_addCached",
         "params" : [ [ "id", "JsVar", "The module name to add" ],
                      [  "sourcecode", "JsVar", "The module's sourcecode" ] ]
}*/
void jswrap_modules_addCached(JsVar *id, JsVar *sourceCode) {
  if (!jsvIsString(id) || !jsvIsString(sourceCode)) {
    jsError("Both arguments to addCached must be strings");
    return;
  }

  JsVar *moduleList = jswrap_modules_getModuleList();
  if (!moduleList) return; // out of memory

  JsVar *moduleExport = jspEvaluateModule(jsiGetParser(), sourceCode);
  if (!moduleExport) {
    jsWarn("Unable to load module");
  } else {
    JsVar *moduleName = jsvFindChildFromVar(moduleList, id, true);
    if (moduleName) jsvSetValueOfName(moduleName, moduleExport);
    jsvUnLock(moduleExport);
  }
  jsvUnLock(moduleList);

}
/*JSON{ "type":"function", "name" : "edit",
        "description" : ["Fill the console with the contents of the given function, so you can edit it.",
                         "NOTE: This is a convenience function - it will not edit 'inner functions'. For that, you must edit the 'outer function' and re-execute it."],
        "generate" : "jswrap_interface_edit",
        "params" : [ [ "funcName", "JsVarName", "The name of the function to edit (either a string or just the unquoted name)"] ]
}*/
void jswrap_interface_edit(JsVar *funcName) {
  if (jsvIsString(funcName)) {
    JsVar *func = 0;
    if (jsvIsName(funcName))
      func = jsvSkipName(funcName);
    else
      func = jsvSkipNameAndUnLock(jsvFindChildFromVar(jsiGetParser()->root, funcName, 0));
    if (jsvIsFunction(func)) {
      JsVar *scopeVar = jsvFindChildFromString(func, JSPARSE_FUNCTION_SCOPE_NAME, false);
      JsVarRef scope = jsvGetRef(scopeVar);
      jsvUnLock(scopeVar);
      JsVar *newLine = jsvNewFromEmptyString();
      if (newLine) { // could be out of memory
        jsvAppendStringVarComplete(newLine, funcName);
        if (scope) {
          // If we have a scope, it's an internal function so we will need to write different code
          jsvAppendString(newLine, ".replaceWith(");
        } else {
          jsvAppendString(newLine, " = ");
        }
        JsVar *funcData = jsvAsString(func, false);
        if (funcData)
          jsvAppendStringVarComplete(newLine, funcData);
        jsvUnLock(funcData);
        if (scope) {
          jsvAppendString(newLine, ");");
        } else {
          jsvAppendString(newLine, ";");
        }
        jsiReplaceInputLine(newLine);
        jsvUnLock(newLine);
      }
    } else {
      jsError("Edit should be called with the name of a function");
    }
    jsvUnLock(func);
  } else {
    jsError("Edit should be called with edit(funcName) or edit('funcName')");
  }
}
Exemple #15
0
JsVar *httpServerNew(JsVar *callback) {
  SOCKET sckt = socket(AF_INET,           // Go over TCP/IP
                       SOCK_STREAM,       // This is a stream-oriented socket
                       IPPROTO_TCP);      // Use TCP rather than UDP
  if (sckt == INVALID_SOCKET) {
    httpError("socket creation failed");
    return 0;
  }

  JsVar *arr = httpGetArray(HTTP_ARRAY_HTTP_SERVERS, true);
  if (!arr) return 0; // out of memory

  JsVar *server = jspNewObject(jsiGetParser(),0,"httpSrv");
  if (!server) {
    jsvUnLock(arr);
    return 0; // out of memory
  }

  jsvObjectSetChild(server, HTTP_NAME_ON_CONNECT, callback); // no unlock needed
  jsvUnLock(jsvObjectSetChild(server, HTTP_NAME_SOCKET, jsvNewFromInteger(sckt+1)));

#ifndef USE_CC3000
  int optval = 1;
  if (setsockopt(sckt,SOL_SOCKET,SO_REUSEADDR,(const char *)&optval,sizeof(optval)) < 0)
#else
  int optval = SOCK_ON;
  if (setsockopt(sckt,SOL_SOCKET,SOCKOPT_ACCEPT_NONBLOCK,(const char *)&optval,sizeof(optval)) < 0)
#endif
    jsWarn("setsockopt failed\n");

  // add to list of servers
  jsvArrayPush(arr, server);
  jsvUnLock(arr);

  return server;
}
int espruino(int argc, char **argv) {
  int i;
  for (i=1;i<argc;i++) {
    if (argv[i][0]=='-') {
      // option
      char *a = argv[i];
      if (!strcmp(a,"-h") || !strcmp(a,"--help")) {
        show_help();
        return (1);
      } else if (!strcmp(a,"-e") || !strcmp(a,"--eval")) {
        if (i+1>=argc) die("Expecting an extra argument\n");
        jshInit();
        jsiInit(true);
        jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
        jsvUnLock(jspEvaluate(jsiGetParser(), argv[i+1]));
        isRunning = true;
        //while (isRunning && jsiHasTimers()) jsiLoop();
        jsiKill();
        jshKill();
        return (0);
      } else if (!strcmp(a,"--test")) {
        if (i+1>=argc) die("Expecting an extra argument\n");
        bool ok = run_test(argv[i+1]);
        return (ok ? 0 : 1);
      } else if (!strcmp(a,"--test-all")) {
        bool ok = run_all_tests();
        return (ok ? 0 : 1);
      } else if (!strcmp(a,"--test-mem-all")) {
        bool ok = run_memory_tests(0);
        return (ok ? 0 : 1);
      } else if (!strcmp(a,"--test-mem")) {
        if (i+1>=argc) die("Expecting an extra argument\n");
        bool ok = run_memory_test(argv[i+1], 0);
        return (ok ? 0 : 1);
      } else if (!strcmp(a,"--test-mem-n")) {
        if (i+2>=argc) die("Expecting an extra 2 arguments\n");
        bool ok = run_memory_test(argv[i+1], atoi(argv[i+2]));
        return (ok ? 0 : 1);
      } else {
        printf("Unknown Argument %s\n", a);
        show_help();
        return -1;
      }
    }
  }

  if (argc==1) {
    printf("Interactive mode.\n");
  } else if (argc==2) {
    // single file - just run it
    char *buffer = (char *)read_file(argv[1]);
    if (!buffer) return (1);
    // check for '#' as the first char, and if so, skip the first line
    char *cmd = buffer;
    if (cmd[0]=='#') {
      while (cmd[0] && cmd[0]!='\n') cmd++;
      if (cmd[0]=='\n') cmd++;
    }
    jshInit();
    jsiInit(false /* do not autoload!!! */);
    jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
    jsvUnLock(jspEvaluate(jsiGetParser(), cmd ));
    free(buffer);
    //isRunning = true;
    //while (isRunning && jsiHasTimers()) jsiLoop();
    jsiKill();
    jshKill();
    return -1;
  } else {
    printf("Unknown arguments!\n");
    show_help();
    return -1;
  }

  printf("Size of JsVar is now %d bytes\n", (int)sizeof(JsVar));
  printf("Size of JsVarRef is now %d bytes\n", (int)sizeof(JsVarRef));

  jshInit();
  jsiInit(true);

  jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
  jspAddNativeFunction(jsiGetParser(), "function interrupt()", nativeInterrupt);

  while (isRunning) {
    jsiLoop();
  }
  jsiConsolePrint("\n");
  jsiKill();

  jsvShowAllocated();
  jshKill();

  return 0;
}
Exemple #17
0
int main(int argc, char **argv) {
  int i;
  for (i=1;i<argc;i++) {
    if (argv[i][0]=='-') {
      // option
      char *a = argv[i];
      if (!strcmp(a,"-h") || !strcmp(a,"--help")) {
        show_help();
        exit(1);
      } else if (!strcmp(a,"-e") || !strcmp(a,"--eval")) {
        if (i+1>=argc) die("Expecting an extra argument");
        jshInit();
        jsiInit(true);
        jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
        jsvUnLock(jspEvaluate(jsiGetParser(), argv[i+1]));
        isRunning = true;
        while (isRunning && jsiHasTimers()) jsiLoop();
        jsiKill();
        jshKill();
        exit(0);
      } else if (!strcmp(a,"--test-all")) {
        bool ok = run_all_tests();
        exit(ok ? 0 : 1);
      } else if (!strcmp(a,"--test-mem-all")) {
        bool ok = run_memory_tests(0);
        exit(ok ? 0 : 1);
      } else if (!strcmp(a,"--test-mem")) {
        if (i+1>=argc) die("Expecting an extra argument");
        bool ok = run_memory_test(argv[i+1], 0);
        exit(ok ? 0 : 1);
      } else if (!strcmp(a,"--test-mem-n")) {
        if (i+2>=argc) die("Expecting an extra 2 arguments");
        bool ok = run_memory_test(argv[i+1], atoi(argv[i+2]));
        exit(ok ? 0 : 1);
      } else {
        printf("Unknown Argument %s\n", a);
        show_help();
        exit(1);
      }
    }
  }

  if (argc==1) {
    printf("Interactive mode.\n");
  } else if (argc==2) {
    char *buffer = read_file(argv[1]);
    jshInit();
    jsiInit(false /* do not autoload!!! */);
    jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
    jsvUnLock(jspEvaluate(jsiGetParser(), buffer ));
    free(buffer);
    isRunning = true;
    while (isRunning && jsiHasTimers()) jsiLoop();
    jsiKill();
    jshKill();
    exit(0);
  } else {
    printf("Unknown arguments!\n");
    show_help();
    exit(1);
  }

  printf("Size of JsVar is now %d bytes\n", (int)sizeof(JsVar));
  printf("Size of JsVarRef is now %d bytes\n", (int)sizeof(JsVarRef));

  struct sigaction sa;
  sa.sa_handler = sig_handler;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);
  if (sigaction(SIGINT, &sa, NULL) == -1)
    printf("Adding SIGINT hook failed\n");
  else
    printf("Added SIGINT hook\n");
  if (sigaction(SIGHUP, &sa, NULL) == -1)
    printf("Adding SIGHUP hook failed\n");
  else
    printf("Added SIGHUP hook\n");
  if (sigaction(SIGTERM, &sa, NULL) == -1)
    printf("Adding SIGTERM hook failed\n");
  else
    printf("Added SIGTERM hook\n");

  jshInit();
  jsiInit(true);

  jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
  jspAddNativeFunction(jsiGetParser(), "function interrupt()", nativeInterrupt);

  while (isRunning) {
    jsiLoop();
  }
  jsiConsolePrint("\n");
  jsiKill();

  jsvShowAllocated();
  jshKill();

  return 0;
}