static void run_decoders(struct parser_state *state) { size_t i; const char* name; struct tokens *tokens = &state->tokens; for(i = 0; i < tokens->cnt; i++) { const char *cstring = TOKEN_GET(&tokens->data[i], cstring); struct decode_result res; res.pos_begin = res.pos_end = 0; res.append = 0; if(tokens->data[i].type == TOK_FUNCTION && i+13 < tokens->cnt) { name = NULL; ++i; if(tokens->data[i].type == TOK_IDENTIFIER_NAME) { cstring = TOKEN_GET(&tokens->data[i], cstring); name = cstring; ++i; } if(match_parameters(&tokens->data[i], de_packer_3, sizeof(de_packer_3)/sizeof(de_packer_3[0])) != -1 || match_parameters(&tokens->data[i], de_packer_2, sizeof(de_packer_2)/sizeof(de_packer_2[0])) != -1) { /* find function decl. end */ handle_de(tokens->data, i, tokens->cnt, name, &res); } } else if(i+2 < tokens->cnt && tokens->data[i].type == TOK_IDENTIFIER_NAME && cstring && !strcmp("dF", cstring) && tokens->data[i+1].type == TOK_PAR_OPEN) { /* TODO: also match signature of dF function (possibly * declared using unescape */ handle_df(tokens->data, i+2, &res); } else if(i+2 < tokens->cnt && tokens->data[i].type == TOK_IDENTIFIER_NAME && cstring && !strcmp("eval", cstring) && tokens->data[i+1].type == TOK_PAR_OPEN) { handle_eval(tokens, i+2, &res); } if(res.pos_end > res.pos_begin) { struct tokens parent_tokens; if(res.pos_end < tokens->cnt && tokens->data[res.pos_end].type == TOK_SEMICOLON) res.pos_end++; parent_tokens = state->tokens;/* save current tokens */ /* initialize embedded context */ memset(&state->tokens, 0, sizeof(state->tokens)); if(++state->rec > 16) cli_dbgmsg(MODULE "recursion limit reached\n"); else { cli_js_process_buffer(state, res.txtbuf.data, res.txtbuf.pos); --state->rec; } free(res.txtbuf.data); /* state->tokens still refers to the embedded/nested context * here */ if(!res.append) { replace_token_range(&parent_tokens, res.pos_begin, res.pos_end, &state->tokens); } else { /* delete tokens */ replace_token_range(&parent_tokens, res.pos_begin, res.pos_end, NULL); append_tokens(&parent_tokens, &state->tokens); } /* end of embedded context, restore tokens state */ free(state->tokens.data); state->tokens = parent_tokens; } state_update_scope(state, &state->tokens.data[i]); } }
int main(int argc, char *argv[]) { duk_context *ctx = NULL; int retval = 0; int have_files = 0; int have_eval = 0; int interactive = 0; int memlimit_high = 1; int alloc_provider = ALLOC_DEFAULT; int i; #ifdef DUK_CMDLINE_AJSHEAP alloc_provider = ALLOC_AJSHEAP; #endif /* * Signal handling setup */ #ifndef NO_SIGNAL set_sigint_handler(); /* This is useful at the global level; libraries should avoid SIGPIPE though */ /*signal(SIGPIPE, SIG_IGN);*/ #endif /* * Parse options */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!arg) { goto usage; } if (strcmp(arg, "--restrict-memory") == 0) { memlimit_high = 0; } else if (strcmp(arg, "-i") == 0) { interactive = 1; } else if (strcmp(arg, "-e") == 0) { have_eval = 1; if (i == argc - 1) { goto usage; } i++; /* skip code */ } else if (strcmp(arg, "--alloc-default") == 0) { alloc_provider = ALLOC_DEFAULT; } else if (strcmp(arg, "--alloc-logging") == 0) { alloc_provider = ALLOC_LOGGING; } else if (strcmp(arg, "--alloc-torture") == 0) { alloc_provider = ALLOC_TORTURE; } else if (strcmp(arg, "--alloc-hybrid") == 0) { alloc_provider = ALLOC_HYBRID; } else if (strcmp(arg, "--alloc-ajsheap") == 0) { alloc_provider = ALLOC_AJSHEAP; } else if (strlen(arg) >= 1 && arg[0] == '-') { goto usage; } else { have_files = 1; } } if (!have_files && !have_eval) { interactive = 1; } /* * Memory limit */ #ifndef NO_RLIMIT set_resource_limits(memlimit_high ? MEM_LIMIT_HIGH : MEM_LIMIT_NORMAL); #else if (memlimit_high == 0) { fprintf(stderr, "Warning: option --restrict-memory ignored, no rlimit support\n"); fflush(stderr); } #endif /* * Create context */ ctx = NULL; if (!ctx && alloc_provider == ALLOC_LOGGING) { #ifdef DUK_CMDLINE_ALLOC_LOGGING ctx = duk_create_heap(duk_alloc_logging, duk_realloc_logging, duk_free_logging, NULL, NULL); #else fprintf(stderr, "Warning: option --alloc-logging ignored, no logging allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_TORTURE) { #ifdef DUK_CMDLINE_ALLOC_TORTURE ctx = duk_create_heap(duk_alloc_torture, duk_realloc_torture, duk_free_torture, NULL, NULL); #else fprintf(stderr, "Warning: option --alloc-torture ignored, no torture allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_HYBRID) { #ifdef DUK_CMDLINE_ALLOC_HYBRID void *udata = duk_alloc_hybrid_init(); if (!udata) { fprintf(stderr, "Failed to init hybrid allocator\n"); fflush(stderr); } else { ctx = duk_create_heap(duk_alloc_hybrid, duk_realloc_hybrid, duk_free_hybrid, udata, NULL); } #else fprintf(stderr, "Warning: option --alloc-hybrid ignored, no hybrid allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_AJSHEAP) { #ifdef DUK_CMDLINE_AJSHEAP ajsheap_init(); ctx = duk_create_heap(AJS_Alloc, AJS_Realloc, AJS_Free, (void *) &ctx, /* alloc_udata */ NULL); /* fatal_handler */ #else fprintf(stderr, "Warning: option --alloc-ajsheap ignored, no ajsheap allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_DEFAULT) { ctx = duk_create_heap_default(); } if (!ctx) { fprintf(stderr, "Failed to create Duktape heap\n"); fflush(stderr); exit(-1); } #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { fprintf(stdout, "Pool dump after heap creation\n"); fflush(stdout); AJS_HeapDump(); fflush(stdout); } #endif #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { ajsheap_register(ctx); } #endif /* * Execute any argument file(s) */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!arg) { continue; } else if (strlen(arg) == 2 && strcmp(arg, "-e") == 0) { /* Here we know the eval arg exists but check anyway */ if (i == argc - 1) { retval = 1; goto cleanup; } if (handle_eval(ctx, argv[i + 1]) != 0) { retval = 1; goto cleanup; } i++; /* skip code */ continue; } else if (strlen(arg) >= 1 && arg[0] == '-') { continue; } if (handle_file(ctx, arg) != 0) { retval = 1; goto cleanup; } } /* * Enter interactive mode if options indicate it */ if (interactive) { if (handle_interactive(ctx) != 0) { retval = 1; goto cleanup; } } /* * Cleanup and exit */ cleanup: if (interactive) { fprintf(stderr, "Cleaning up...\n"); fflush(stderr); } #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { fprintf(stdout, "Pool dump before duk_destroy_heap(), before forced gc\n"); fflush(stdout); AJS_HeapDump(); fflush(stdout); duk_gc(ctx, 0); fprintf(stdout, "Pool dump before duk_destroy_heap(), after forced gc\n"); fflush(stdout); AJS_HeapDump(); fflush(stdout); } #endif if (ctx) { duk_destroy_heap(ctx); } #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { fprintf(stdout, "Pool dump after duk_destroy_heap() (should have zero allocs)\n"); fflush(stdout); AJS_HeapDump(); fflush(stdout); } #endif return retval; /* * Usage */ usage: fprintf(stderr, "Usage: duk [options] [<filenames>]\n" "\n" " -i enter interactive mode after executing argument file(s) / eval code\n" " -e CODE evaluate code\n" " --restrict-memory use lower memory limit (used by test runner)\n" " --alloc-default use Duktape default allocator\n" #ifdef DUK_CMDLINE_ALLOC_LOGGING " --alloc-logging use logging allocator (writes to /tmp)\n" #endif #ifdef DUK_CMDLINE_ALLOC_TORTURE " --alloc-torture use torture allocator\n" #endif #ifdef DUK_CMDLINE_ALLOC_HYBRID " --alloc-hybrid use hybrid allocator\n" #endif #ifdef DUK_CMDLINE_AJSHEAP " --alloc-ajsheap use ajsheap allocator (enabled by default with 'ajduk')\n" #endif "\n" "If <filename> is omitted, interactive mode is started automatically.\n"); fflush(stderr); exit(1); }
// Load the script void evaluateJavaScript(char * javascript) { duk_context *ctx = duk_create_heap_default(); if (handle_eval(ctx, javascript) != 0) { fprintf(stderr, "handle_eval() returned non-zero, the script was:\n", javascript); } }
int main(int argc, char *argv[]) { duk_context *ctx = NULL; int retval = 0; int have_files = 0; int have_eval = 0; int interactive = 0; int memlimit_high = 1; int alloc_provider = ALLOC_DEFAULT; int ajsheap_log = 0; int debugger = 0; const char *compile_filename = NULL; int i; #ifdef DUK_CMDLINE_AJSHEAP alloc_provider = ALLOC_AJSHEAP; #endif (void) ajsheap_log; /* * Signal handling setup */ #ifndef NO_SIGNAL set_sigint_handler(); /* This is useful at the global level; libraries should avoid SIGPIPE though */ /*signal(SIGPIPE, SIG_IGN);*/ #endif /* * Parse options */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!arg) { goto usage; } if (strcmp(arg, "--restrict-memory") == 0) { memlimit_high = 0; } else if (strcmp(arg, "-i") == 0) { interactive = 1; } else if (strcmp(arg, "-c") == 0) { if (i == argc - 1) { goto usage; } i++; compile_filename = argv[i]; } else if (strcmp(arg, "-e") == 0) { have_eval = 1; if (i == argc - 1) { goto usage; } i++; /* skip code */ } else if (strcmp(arg, "--alloc-default") == 0) { alloc_provider = ALLOC_DEFAULT; } else if (strcmp(arg, "--alloc-logging") == 0) { alloc_provider = ALLOC_LOGGING; } else if (strcmp(arg, "--alloc-torture") == 0) { alloc_provider = ALLOC_TORTURE; } else if (strcmp(arg, "--alloc-hybrid") == 0) { alloc_provider = ALLOC_HYBRID; } else if (strcmp(arg, "--alloc-ajsheap") == 0) { alloc_provider = ALLOC_AJSHEAP; } else if (strcmp(arg, "--ajsheap-log") == 0) { ajsheap_log = 1; } else if (strcmp(arg, "--debugger") == 0) { debugger = 1; } else if (strlen(arg) >= 1 && arg[0] == '-') { goto usage; } else { have_files = 1; } } if (!have_files && !have_eval) { interactive = 1; } /* * Memory limit */ #ifndef NO_RLIMIT set_resource_limits(memlimit_high ? MEM_LIMIT_HIGH : MEM_LIMIT_NORMAL); #else if (memlimit_high == 0) { fprintf(stderr, "Warning: option --restrict-memory ignored, no rlimit support\n"); fflush(stderr); } #endif /* * Create context */ ctx = NULL; if (!ctx && alloc_provider == ALLOC_LOGGING) { #ifdef DUK_CMDLINE_ALLOC_LOGGING ctx = duk_create_heap(duk_alloc_logging, duk_realloc_logging, duk_free_logging, (void *) 0xdeadbeef, NULL); #else fprintf(stderr, "Warning: option --alloc-logging ignored, no logging allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_TORTURE) { #ifdef DUK_CMDLINE_ALLOC_TORTURE ctx = duk_create_heap(duk_alloc_torture, duk_realloc_torture, duk_free_torture, (void *) 0xdeadbeef, NULL); #else fprintf(stderr, "Warning: option --alloc-torture ignored, no torture allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_HYBRID) { #ifdef DUK_CMDLINE_ALLOC_HYBRID void *udata = duk_alloc_hybrid_init(); if (!udata) { fprintf(stderr, "Failed to init hybrid allocator\n"); fflush(stderr); } else { ctx = duk_create_heap(duk_alloc_hybrid, duk_realloc_hybrid, duk_free_hybrid, udata, NULL); } #else fprintf(stderr, "Warning: option --alloc-hybrid ignored, no hybrid allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_AJSHEAP) { #ifdef DUK_CMDLINE_AJSHEAP ajsheap_init(); ctx = duk_create_heap( ajsheap_log ? ajsheap_alloc_wrapped : AJS_Alloc, ajsheap_log ? ajsheap_realloc_wrapped : AJS_Realloc, ajsheap_log ? ajsheap_free_wrapped : AJS_Free, (void *) 0xdeadbeef, /* heap_udata: ignored by AjsHeap, use as marker */ NULL ); /* fatal_handler */ #else fprintf(stderr, "Warning: option --alloc-ajsheap ignored, no ajsheap allocator support\n"); fflush(stderr); #endif } if (!ctx && alloc_provider == ALLOC_DEFAULT) { ctx = duk_create_heap_default(); } if (!ctx) { fprintf(stderr, "Failed to create Duktape heap\n"); fflush(stderr); exit(-1); } #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { fprintf(stdout, "Pool dump after heap creation\n"); ajsheap_dump(); } #endif #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { ajsheap_register(ctx); } #endif if (debugger) { #ifdef DUK_CMDLINE_DEBUGGER_SUPPORT fprintf(stderr, "Debugger enabled, create socket and wait for connection\n"); fflush(stderr); duk_trans_socket_init(); duk_trans_socket_waitconn(); fprintf(stderr, "Debugger connected, call duk_debugger_attach() and then execute requested file(s)/eval\n"); fflush(stderr); duk_debugger_attach(ctx, duk_trans_socket_read_cb, duk_trans_socket_write_cb, duk_trans_socket_peek_cb, duk_trans_socket_read_flush_cb, duk_trans_socket_write_flush_cb, debugger_detached, (void *) 0xbeef1234); #else fprintf(stderr, "Warning: option --debugger ignored, no debugger support\n"); fflush(stderr); #endif } #if 0 /* Manual test for duk_debugger_cooperate() */ { for (i = 0; i < 60; i++) { printf("cooperate: %d\n", i); usleep(1000000); duk_debugger_cooperate(ctx); } } #endif /* * Execute any argument file(s) */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!arg) { continue; } else if (strlen(arg) == 2 && strcmp(arg, "-e") == 0) { /* Here we know the eval arg exists but check anyway */ if (i == argc - 1) { retval = 1; goto cleanup; } if (handle_eval(ctx, argv[i + 1]) != 0) { retval = 1; goto cleanup; } i++; /* skip code */ continue; } else if (strlen(arg) == 2 && strcmp(arg, "-c") == 0) { i++; /* skip filename */ continue; } else if (strlen(arg) >= 1 && arg[0] == '-') { continue; } if (handle_file(ctx, arg, compile_filename) != 0) { retval = 1; goto cleanup; } } /* * Enter interactive mode if options indicate it */ if (interactive) { if (handle_interactive(ctx) != 0) { retval = 1; goto cleanup; } } /* * Cleanup and exit */ cleanup: if (interactive) { fprintf(stderr, "Cleaning up...\n"); fflush(stderr); } #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { fprintf(stdout, "Pool dump before duk_destroy_heap(), before forced gc\n"); ajsheap_dump(); duk_gc(ctx, 0); fprintf(stdout, "Pool dump before duk_destroy_heap(), after forced gc\n"); ajsheap_dump(); } #endif if (ctx) { duk_destroy_heap(ctx); } #ifdef DUK_CMDLINE_AJSHEAP if (alloc_provider == ALLOC_AJSHEAP) { fprintf(stdout, "Pool dump after duk_destroy_heap() (should have zero allocs)\n"); ajsheap_dump(); } #endif return retval; /* * Usage */ usage: fprintf(stderr, "Usage: duk [options] [<filenames>]\n" "\n" " -i enter interactive mode after executing argument file(s) / eval code\n" " -e CODE evaluate code\n" " -c FILE compile into bytecode (use with only one file argument)\n" " --restrict-memory use lower memory limit (used by test runner)\n" " --alloc-default use Duktape default allocator\n" #ifdef DUK_CMDLINE_ALLOC_LOGGING " --alloc-logging use logging allocator (writes to /tmp)\n" #endif #ifdef DUK_CMDLINE_ALLOC_TORTURE " --alloc-torture use torture allocator\n" #endif #ifdef DUK_CMDLINE_ALLOC_HYBRID " --alloc-hybrid use hybrid allocator\n" #endif #ifdef DUK_CMDLINE_AJSHEAP " --alloc-ajsheap use ajsheap allocator (enabled by default with 'ajduk')\n" " --ajsheap-log write alloc log to /tmp/ajduk-alloc-log.txt\n" #endif #ifdef DUK_CMDLINE_DEBUGGER_SUPPORT " --debugger start example debugger\n" #endif "\n" "If <filename> is omitted, interactive mode is started automatically.\n"); fflush(stderr); exit(1); }
int main(int argc, char *argv[]) { duk_context *ctx = NULL; int retval = 0; int have_files = 0; int have_eval = 0; int interactive = 0; int memlimit_high = 1; int alloc_provider = ALLOC_DEFAULT; int ajsheap_log = 0; int debugger = 0; int recreate_heap = 0; int verbose = 0; const char *compile_filename = NULL; int i; #ifdef DUK_CMDLINE_AJSHEAP alloc_provider = ALLOC_AJSHEAP; #endif (void) ajsheap_log; /* * Signal handling setup */ #ifndef NO_SIGNAL set_sigint_handler(); /* This is useful at the global level; libraries should avoid SIGPIPE though */ /*signal(SIGPIPE, SIG_IGN);*/ #endif /* * Parse options */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!arg) { goto usage; } if (strcmp(arg, "--restrict-memory") == 0) { memlimit_high = 0; } else if (strcmp(arg, "-i") == 0) { interactive = 1; } else if (strcmp(arg, "-c") == 0) { if (i == argc - 1) { goto usage; } i++; compile_filename = argv[i]; } else if (strcmp(arg, "-e") == 0) { have_eval = 1; if (i == argc - 1) { goto usage; } i++; /* skip code */ } else if (strcmp(arg, "--alloc-default") == 0) { alloc_provider = ALLOC_DEFAULT; } else if (strcmp(arg, "--alloc-logging") == 0) { alloc_provider = ALLOC_LOGGING; } else if (strcmp(arg, "--alloc-torture") == 0) { alloc_provider = ALLOC_TORTURE; } else if (strcmp(arg, "--alloc-hybrid") == 0) { alloc_provider = ALLOC_HYBRID; } else if (strcmp(arg, "--alloc-ajsheap") == 0) { alloc_provider = ALLOC_AJSHEAP; } else if (strcmp(arg, "--ajsheap-log") == 0) { ajsheap_log = 1; } else if (strcmp(arg, "--debugger") == 0) { debugger = 1; } else if (strcmp(arg, "--recreate-heap") == 0) { recreate_heap = 1; } else if (strcmp(arg, "--verbose") == 0) { verbose = 1; } else if (strlen(arg) >= 1 && arg[0] == '-') { goto usage; } else { have_files = 1; } } if (!have_files && !have_eval) { interactive = 1; } /* * Memory limit */ #ifndef NO_RLIMIT set_resource_limits(memlimit_high ? MEM_LIMIT_HIGH : MEM_LIMIT_NORMAL); #else if (memlimit_high == 0) { fprintf(stderr, "Warning: option --restrict-memory ignored, no rlimit support\n"); fflush(stderr); } #endif /* * Create heap */ ctx = create_duktape_heap(alloc_provider, debugger); /* * Execute any argument file(s) */ for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!arg) { continue; } else if (strlen(arg) == 2 && strcmp(arg, "-e") == 0) { /* Here we know the eval arg exists but check anyway */ if (i == argc - 1) { retval = 1; goto cleanup; } if (handle_eval(ctx, argv[i + 1]) != 0) { retval = 1; goto cleanup; } i++; /* skip code */ continue; } else if (strlen(arg) == 2 && strcmp(arg, "-c") == 0) { i++; /* skip filename */ continue; } else if (strlen(arg) >= 1 && arg[0] == '-') { continue; } if (verbose) { fprintf(stderr, "*** Executing file: %s\n", arg); fflush(stderr); } if (handle_file(ctx, arg, compile_filename) != 0) { retval = 1; goto cleanup; } if (recreate_heap) { if (verbose) { fprintf(stderr, "*** Recreating heap...\n"); fflush(stderr); } destroy_duktape_heap(ctx, alloc_provider); ctx = create_duktape_heap(alloc_provider, debugger); } } /* * Enter interactive mode if options indicate it */ if (interactive) { if (handle_interactive(ctx) != 0) { retval = 1; goto cleanup; } } /* * Cleanup and exit */ cleanup: if (interactive) { fprintf(stderr, "Cleaning up...\n"); fflush(stderr); } if (ctx) { destroy_duktape_heap(ctx, alloc_provider); } ctx = NULL; return retval; /* * Usage */ usage: fprintf(stderr, "Usage: duk [options] [<filenames>]\n" "\n" " -i enter interactive mode after executing argument file(s) / eval code\n" " -e CODE evaluate code\n" " -c FILE compile into bytecode (use with only one file argument)\n" " --verbose verbose messages to stderr\n" " --restrict-memory use lower memory limit (used by test runner)\n" " --alloc-default use Duktape default allocator\n" #ifdef DUK_CMDLINE_ALLOC_LOGGING " --alloc-logging use logging allocator (writes to /tmp)\n" #endif #ifdef DUK_CMDLINE_ALLOC_TORTURE " --alloc-torture use torture allocator\n" #endif #ifdef DUK_CMDLINE_ALLOC_HYBRID " --alloc-hybrid use hybrid allocator\n" #endif #ifdef DUK_CMDLINE_AJSHEAP " --alloc-ajsheap use ajsheap allocator (enabled by default with 'ajduk')\n" " --ajsheap-log write alloc log to /tmp/ajduk-alloc-log.txt\n" #endif #ifdef DUK_CMDLINE_DEBUGGER_SUPPORT " --debugger start example debugger\n" #endif " --recreate-heap recreate heap after every file\n" "\n" "If <filename> is omitted, interactive mode is started automatically.\n"); fflush(stderr); exit(1); }