static int handle_eval(duk_context *ctx, const char *code) { int rc; int retval = -1; duk_push_pointer(ctx, (void *) code); duk_push_uint(ctx, (duk_uint_t) strlen(code)); duk_push_string(ctx, "eval"); interactive_mode = 0; /* global */ rc = duk_safe_call(ctx, wrapped_compile_execute, 3 /*nargs*/, 1 /*nret*/); #if defined(DUK_CMDLINE_AJSHEAP) ajsheap_clear_exec_timeout(); #endif if (rc != DUK_EXEC_SUCCESS) { print_pop_error(ctx, stderr); } else { duk_pop(ctx); retval = 0; } return retval; }
/* in interactive mode, write to stdout */ print_pop_error(ctx, stdout); retval = -1; /* an error 'taints' the execution */ } else { duk_pop(ctx); } } done: if (buffer) { free(buffer); buffer = NULL; } return retval; } #else /* NO_READLINE */ static int handle_interactive(duk_context *ctx) { const char *prompt = "duk> "; char *buffer = NULL; int retval = 0; int rc; duk_eval_string(ctx, GREET_CODE("")); duk_pop(ctx); /* * Note: using readline leads to valgrind-reported leaks inside * readline itself. Execute code from an input file (and not * through stdin) for clean valgrind runs. */ rl_initialize(); for (;;) { if (buffer) { free(buffer); buffer = NULL; } buffer = readline(prompt); if (!buffer) { break; } if (buffer && buffer[0] != (char) 0) { add_history(buffer); } duk_push_lstring(ctx, buffer, strlen(buffer)); duk_push_string(ctx, "input"); if (buffer) { free(buffer); buffer = NULL; } interactive_mode = 1; /* global */ rc = duk_safe_call(ctx, wrapped_compile_execute, 2 /*nargs*/, 1 /*nret*/); if (rc != DUK_EXEC_SUCCESS) { /* in interactive mode, write to stdout */ print_pop_error(ctx, stdout); retval = -1; /* an error 'taints' the execution */ } else { duk_pop(ctx); } } if (buffer) { free(buffer); buffer = NULL; } return retval; }
static int handle_fh(duk_context *ctx, FILE *f, const char *filename, const char *bytecode_filename) { char *buf = NULL; int len; size_t got; int rc; int retval = -1; if (fseek(f, 0, SEEK_END) < 0) { goto error; } len = (int) ftell(f); if (fseek(f, 0, SEEK_SET) < 0) { goto error; } buf = (char *) malloc(len); if (!buf) { goto error; } got = fread((void *) buf, (size_t) 1, (size_t) len, f); duk_push_string(ctx, bytecode_filename); duk_push_pointer(ctx, (void *) buf); duk_push_uint(ctx, (duk_uint_t) got); duk_push_string(ctx, filename); interactive_mode = 0; /* global */ rc = duk_safe_call(ctx, wrapped_compile_execute, 4 /*nargs*/, 1 /*nret*/); #if defined(DUK_CMDLINE_AJSHEAP) ajsheap_clear_exec_timeout(); #endif free(buf); buf = NULL; if (rc != DUK_EXEC_SUCCESS) { print_pop_error(ctx, stderr); goto error; } else { duk_pop(ctx); retval = 0; } /* fall thru */ cleanup: if (buf) { free(buf); } return retval; error: fprintf(stderr, "error in executing file %s\n", filename); fflush(stderr); goto cleanup; }
static int handle_eval(duk_context *ctx, const char *code) { int rc; int retval = -1; duk_push_string(ctx, code); duk_push_string(ctx, "eval"); interactive_mode = 0; /* global */ rc = duk_safe_call(ctx, wrapped_compile_execute, 2 /*nargs*/, 1 /*nret*/); if (rc != DUK_EXEC_SUCCESS) { print_pop_error(ctx, stderr); } else { duk_pop(ctx); retval = 0; } return retval; }
/** Run the accessor. * @param accessorFileName The file name of the accessor, suitable getAccessorCode() * @param timeout The number of milliseconds to wait after the * accessor is instantiated and initialized. If the timeout is less than zero, * then the timeout will be forever. * @return 0 if successfully, non-zero if there is an error. */ int runAccessorHost(duk_context *ctx, const char *accessorFileName, int timeout) { int rc; //fprintf(stderr, "%s:%d: About to load C version of c_eventloop.\n", __FILE__, __LINE__); // Use duk_peval_string_noresult() and avoid interning the string. Good // for low memory, see // http://duktape.org/api.html#duk_peval_string_noresult if (duk_peval_string(ctx, c_eventloop_js) != 0) { fprintf(stderr, "%s:%d: Loading C version of c_eventloop failed. Error was:\n", __FILE__, __LINE__); print_pop_error(ctx, stderr); return 1; } else { //printf("%s: Loading C version of c_eventloop worked\n", __FILE__); duk_pop(ctx); } // Use duk_peval_string_noresult() and avoid interning the string. Good // for low memory, see // http://duktape.org/api.html#duk_peval_string_noresult if (duk_peval_string(ctx, ___duktapeHost_js) != 0) { fprintf(stderr, "%s:%d: Loading C version of duktapeHost failed. Error was:\n", __FILE__, __LINE__); print_pop_error(ctx, stderr); return 2; } else { //printf("%s: Loading C version of duktapeHost worked\n", __FILE__); duk_pop(ctx); } // Call instantiateAndInitialize() on the accessorFileName, then timeout. // Build the command to be evaled. // FIXME: Note that for deployment, we could save memory and // choose one or the other at compile time. int length = strlen(accessorFileName); if (timeout >= 0) { // Increase 136 if the first snprintf string changes length += 136 + 8 /* Approximate Length of timeout value as a string */; } else { // Increase 79 if the second snprintf string changes. length += 79; } char buf[length]; if (timeout >= 0) { // Timeout. // While exiting, invoke wrapup() on any accessors that were // created. The TrainableTest accessor expects wrapup to be // called so that it can report an error if fire() was never // called. // requestEventLoopExit() is defined in ecma_eventloop.js snprintf(buf, length, "var a=['%s'],t=this;t.b=instantiateAndInitialize(a),setTimeout(function(){for(var i in t.b)t.b[i].wrapup();requestEventLoopExit()},%d);", accessorFileName, timeout); } else { // Prevent the script from exiting by repeating the empty function // every ~25 days. snprintf(buf, length, "var a=['%s'];instantiateAndInitialize(a);setInterval(function(){},2147483647);", accessorFileName); } // Eval the command, avoid interning the string. if (duk_peval_string(ctx, buf) != 0) { fprintf(stderr, "%s:%d: Failed to invoke accessor %s. Command was:\n%s\nError was:\n", __FILE__, __LINE__, accessorFileName, buf); print_pop_error(ctx, stderr); return 3; } else { duk_pop(ctx); } // Compile solution //duk_compile(ctx, 0); /* duk_push_global_object(ctx); /\* 'this' binding *\/ */ /* duk_insert(ctx, -2); /\* [ ... global func ] *\/ */ /* duk_put_prop_string(ctx, -2, "_USERCODE"); */ /* duk_pop(ctx); */ /* duk_eval_string(ctx, "setTimeout(function() { _USERCODE(); }, 0);"); */ /* duk_pop(ctx); */ rc = duk_safe_call(ctx, eventloop_run, 0 /*nargs*/, 1 /*nrets*/); if (rc != 0) { fprintf(stderr, "%s:%d: %s: Failed invoke eventloop_run()\n", __FILE__, __LINE__, accessorFileName); return 4; } //fprintf(stderr, "runAccessorHost() done.\n"); return 0; }
static int handle_interactive(duk_context *ctx) { const char *prompt = "duk> "; char *buffer = NULL; int retval = 0; int rc; int got_eof = 0; duk_eval_string(ctx, GREET_CODE(" [no readline]")); duk_pop(ctx); buffer = (char *) malloc(LINEBUF_SIZE); if (!buffer) { fprintf(stderr, "failed to allocated a line buffer\n"); fflush(stderr); retval = -1; goto done; } while (!got_eof) { size_t idx = 0; fwrite(prompt, 1, strlen(prompt), stdout); fflush(stdout); for (;;) { int c = fgetc(stdin); if (c == EOF) { got_eof = 1; break; } else if (c == '\n') { break; } else if (idx >= LINEBUF_SIZE) { fprintf(stderr, "line too long\n"); fflush(stderr); retval = -1; goto done; } else { buffer[idx++] = (char) c; } } duk_push_lstring(ctx, buffer, idx); duk_push_string(ctx, "input"); interactive_mode = 1; /* global */ rc = duk_safe_call(ctx, wrapped_compile_execute, 2 /*nargs*/, 1 /*nret*/); if (rc != DUK_EXEC_SUCCESS) { /* in interactive mode, write to stdout */ print_pop_error(ctx, stdout); retval = -1; /* an error 'taints' the execution */ } else { duk_pop(ctx); } } done: if (buffer) { free(buffer); buffer = NULL; } return retval; }