static duk_ret_t duk_android_log_print(duk_context *ctx) { int n = duk_get_top(ctx); switch (n) { case 1: LOGD("ScriptEngine", "%s", duk_safe_to_string(ctx, 0)); break; case 2: LOGD("ScriptEngine", "%s %s", duk_safe_to_string(ctx, 0), duk_safe_to_string(ctx, 1)); break; case 3: LOGD("ScriptEngine", "%s %s %s", duk_safe_to_string(ctx, 0), duk_safe_to_string(ctx, 1), duk_safe_to_string(ctx, 2)); break; case 4: { LOGD("ScriptEngine", "%s %s %s %s", duk_safe_to_string(ctx, 0), duk_safe_to_string(ctx, 1), duk_safe_to_string(ctx, 2), duk_safe_to_string(ctx, 3)); } break; case 0: { LOGD("ScriptEngine", "\n"); } break; default: { LOGW("ScriptEngine", "too many args %d to print, javascript print only support less than 4 args\n", n); } break; } return 0; }
int main(int argc, const char *argv[]) { duk_context *ctx = NULL; ctx = duk_create_heap_default(); if (!ctx) { printf("Failed to create a Duktape heap.\n"); exit(1); } duk_push_global_object(ctx); duk_push_c_function(ctx, native_prime_check, 2 /*nargs*/); duk_put_prop_string(ctx, -2, "primeCheckNative"); if (duk_peval_file(ctx, "prime.js") != 0) { printf("Error: %s\n", duk_safe_to_string(ctx, -1)); goto finished; } duk_pop(ctx); /* ignore result */ duk_get_prop_string(ctx, -1, "primeTest"); if (duk_pcall(ctx, 0) != 0) { printf("Error: %s\n", duk_safe_to_string(ctx, -1)); } duk_pop(ctx); /* ignore result */ finished: duk_destroy_heap(ctx); exit(0); }
DUK_EXTERNAL int sjs_vm_eval_code(const sjs_vm_t* vm, const char* filename, const char* code, size_t len, FILE* foutput, FILE* ferror) { int r; assert(vm); duk_context* ctx = vm->ctx; duk_push_pointer(ctx, (void *) code); duk_push_uint(ctx, len); duk_push_string(ctx, filename); r = duk_safe_call(ctx, sjs__compile_execute, 3 /*nargs*/, 1 /*nret*/); if (r != DUK_EXEC_SUCCESS) { if (ferror) { duk_safe_call(ctx, sjs__get_error_stack, 1 /*nargs*/, 1 /*nrets*/); fprintf(ferror, "%s\n", duk_safe_to_string(ctx, -1)); fflush(ferror); } } else { if (foutput) { fprintf(foutput, "= %s\n", duk_safe_to_string(ctx, -1)); fflush(foutput); } } duk_pop(ctx); return r; }
static duk_ret_t test_is_prototype_of(duk_context *ctx, void *udata) { (void) udata; prep(ctx); /* obj0.isPrototypeOf(dummy) -> false, traverses prototype chain of dummy */ duk_eval_string(ctx, "Object.prototype.isPrototypeOf"); duk_dup(ctx, 0); duk_push_object(ctx); duk_call_method(ctx, 1); printf("Object.prototype.isPrototypeOf result: %s\n", duk_safe_to_string(ctx, -1)); duk_pop(ctx); /* obj0.isPrototypeOf(obj1) -> true, traverses prototype chain of obj1 */ duk_eval_string(ctx, "Object.prototype.isPrototypeOf"); duk_dup(ctx, 0); duk_dup(ctx, 1); duk_call_method(ctx, 1); printf("Object.prototype.isPrototypeOf result: %s\n", duk_safe_to_string(ctx, -1)); duk_pop(ctx); /* dummy.isPrototypeOf(obj0) -> traverses prototype chain of obj0 and throws */ duk_eval_string(ctx, "Object.prototype.isPrototypeOf"); duk_push_object(ctx); duk_dup(ctx, 0); duk_call_method(ctx, 1); printf("Object.prototype.isPrototypeOf result: %s\n", duk_safe_to_string(ctx, -1)); duk_pop(ctx); return 0; }
int main(int argc, const char *argv[]) { duk_context *ctx = NULL; char line[4096]; size_t idx; int ch; (void) argc; (void) argv; ctx = duk_create_heap_default(); if (!ctx) { printf("Failed to create a Duktape heap.\n"); exit(1); } push_file_as_string(ctx, "process.js"); if (duk_peval(ctx) != 0) { printf("Error: %s\n", duk_safe_to_string(ctx, -1)); goto finished; } duk_pop(ctx); /* ignore result */ memset(line, 0, sizeof(line)); idx = 0; for (;;) { if (idx >= sizeof(line)) { printf("Line too long\n"); exit(1); } ch = fgetc(stdin); if (ch == 0x0a) { line[idx++] = '\0'; duk_push_global_object(ctx); duk_get_prop_string(ctx, -1 /*index*/, "processLine"); duk_push_string(ctx, line); if (duk_pcall(ctx, 1 /*nargs*/) != 0) { printf("Error: %s\n", duk_safe_to_string(ctx, -1)); } else { printf("%s\n", duk_safe_to_string(ctx, -1)); } duk_pop(ctx); /* pop result/error */ idx = 0; } else if (ch == EOF) { break; } else { line[idx++] = (char) ch; } } finished: duk_destroy_heap(ctx); exit(0); }
void test(duk_context *ctx) { duk_int_t rc; /* From API doc */ duk_push_string(ctx, "print('Hello world!'); 123;"); duk_eval(ctx); printf("return value is: %lf\n", duk_get_number(ctx, -1)); duk_pop(ctx); /* Function expression */ duk_push_string(ctx, "(function adder(x,y) { return x+y; })"); duk_eval(ctx); /* [ func ] */ duk_push_int(ctx, 123); duk_push_int(ctx, 234); duk_call(ctx, 2); /* [ func 123 234 ] -> [ result ] */ printf("adder(123, 234) -> %lf\n", duk_get_number(ctx, -1)); duk_pop(ctx); /* Protected eval with success */ duk_push_string(ctx, "print('Hello world!'); 123;"); rc = duk_peval(ctx); printf("return value is: %s (rc=%d)\n", duk_safe_to_string(ctx, -1), (int) rc); duk_pop(ctx); /* Protected eval with failure */ duk_push_string(ctx, "throw new Error('eval error');"); rc = duk_peval(ctx); printf("return value is: %s (rc=%d)\n", duk_safe_to_string(ctx, -1), (int) rc); duk_pop(ctx); /* Protected eval with syntax error */ duk_push_string(ctx, "obj = {"); rc = duk_peval(ctx); printf("return value is: %s (rc=%d)\n", duk_safe_to_string(ctx, -1), (int) rc); duk_pop(ctx); /* Plain eval with no result */ printf("top=%ld\n", (long) duk_get_top(ctx)); duk_push_string(ctx, "print('doing eval');"); duk_eval_noresult(ctx); /* Protected eval with no result, no error */ printf("top=%ld\n", (long) duk_get_top(ctx)); duk_push_string(ctx, "print('doing peval');"); rc = duk_peval_noresult(ctx); printf("rc=%d\n", (int) rc); /* Protected eval with no result, syntax error */ printf("top=%ld\n", (long) duk_get_top(ctx)); duk_push_string(ctx, "print('doing peval'); obj = {"); rc = duk_peval_noresult(ctx); printf("rc=%d\n", (int) rc); printf("top: %ld\n", (long) duk_get_top(ctx)); }
bool StyleContext::evalFunction(FunctionID id) { // Get all functions (array) in context if (!duk_get_global_string(m_ctx, FUNC_ID)) { LOGE("EvalFilterFn - functions array not initialized"); duk_pop(m_ctx); // pop [undefined] sitting at stack top return false; } // Get function at index `id` from functions array, put it at stack top if (!duk_get_prop_index(m_ctx, -1, id)) { LOGE("EvalFilterFn - function %d not set", id); duk_pop(m_ctx); // pop "undefined" sitting at stack top duk_pop(m_ctx); // pop functions (array) now sitting at stack top return false; } // pop fns array duk_remove(m_ctx, -2); // call popped function (sitting at stack top), evaluated value is put on stack top if (duk_pcall(m_ctx, 0) != 0) { LOGE("EvalFilterFn: %s", duk_safe_to_string(m_ctx, -1)); duk_pop(m_ctx); return false; } return true; }
bool StyleContext::setFunctions(const std::vector<std::string>& _functions) { auto arr_idx = duk_push_array(m_ctx); int id = 0; bool ok = true; for (auto& function : _functions) { duk_push_string(m_ctx, function.c_str()); duk_push_string(m_ctx, ""); if (duk_pcompile(m_ctx, DUK_COMPILE_FUNCTION) == 0) { duk_put_prop_index(m_ctx, arr_idx, id); } else { LOGW("Compile failed: %s\n%s\n---", duk_safe_to_string(m_ctx, -1), function.c_str()); duk_pop(m_ctx); ok = false; } id++; } if (!duk_put_global_string(m_ctx, FUNC_ID)) { LOGE("'fns' object not set"); } DUMP("setFunctions\n"); return ok; }
/* * Evaluate a string as Duktape code in the selected heap. * Usage: eval token code * Return value: the result of the evaluation coerced to string. * Side effects: may change the Duktape interpreter heap. */ static int Eval_Cmd(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { duk_context *ctx; duk_int_t duk_result; const char *js_code; if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, USAGE_EVAL); return TCL_ERROR; } ctx = parse_id(cdata, interp, objv[1], 0); if (ctx == NULL) { return TCL_ERROR; } js_code = Tcl_GetString(objv[2]); duk_result = duk_peval_string(ctx, js_code); Tcl_SetObjResult(interp, Tcl_NewStringObj( duk_safe_to_string(ctx, -1), -1)); duk_pop(ctx); if (duk_result == 0) { return TCL_OK; } else { return TCL_ERROR; } }
DUK_EXTERNAL void duk_push_context_dump(duk_context *ctx) { duk_idx_t idx; duk_idx_t top; /* We don't duk_require_stack() here now, but rely on the caller having * enough space. */ top = duk_get_top(ctx); duk_push_array(ctx); for (idx = 0; idx < top; idx++) { duk_dup(ctx, idx); duk_put_prop_index(ctx, -2, idx); } /* XXX: conversion errors should not propagate outwards. * Perhaps values need to be coerced individually? */ duk_bi_json_stringify_helper(ctx, duk_get_top_index(ctx), /*idx_value*/ DUK_INVALID_INDEX, /*idx_replacer*/ DUK_INVALID_INDEX, /*idx_space*/ DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_ASCII_ONLY | DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/); duk_push_sprintf(ctx, "ctx: top=%ld, stack=%s", (long) top, (const char *) duk_safe_to_string(ctx, -1)); duk_replace(ctx, -3); /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */ duk_pop(ctx); DUK_ASSERT(duk_is_string(ctx, -1)); }
static duk_ret_t test_basic(duk_context *ctx, void *udata) { duk_idx_t i, n; duk_int_t rc; (void) udata; duk_push_undefined(ctx); duk_push_null(ctx); duk_push_true(ctx); duk_push_false(ctx); duk_push_string(ctx, "foo"); duk_push_int(ctx, 123); duk_push_object(ctx); duk_push_pointer(ctx, (void *) NULL); duk_push_pointer(ctx, (void *) 0xdeadbeefUL); n = duk_get_top(ctx); printf("top: %ld\n", (long) n); for (i = 0; i <= n; i++) { rc = duk_safe_call(ctx, safe_helper, (void *) i, 0, 1); if (rc != DUK_EXEC_SUCCESS) { printf("index %ld: %s\n", (long) i, duk_safe_to_string(ctx, -1)); } duk_pop(ctx); } printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
/* Basic dump/load test which exercises all constant types and has an inner * function. Hex dumping the bytecode provides an exact test case dependency * to the dump format so that any accidental changes break the test. */ static duk_ret_t test_basic(duk_context *ctx) { unsigned char *p; duk_size_t i, sz; /* Integer constants generate LDINT now so also use a fractional * constant to exercise number constants. * * Compiled as a program; force source filename. */ duk_push_string(ctx, "print('hello', (function adder(x,y) { return x+y; })(1, 2), 3.14);"); duk_push_string(ctx, "fakeFilename.js"); duk_compile(ctx, 0); duk_dump_function(ctx); printf("dump result type: %d\n", (int) duk_get_type(ctx, -1)); fflush(stdout); p = (unsigned char *) duk_get_buffer(ctx, -1, &sz); for (i = 0; i < sz; i++) { printf("%02x", (int) p[i]); } printf("\n"); fflush(stdout); /* Load test function from dump and execute it. */ duk_load_function(ctx); printf("load result type: %d\n", (int) duk_get_type(ctx, -1)); fflush(stdout); duk_call(ctx, 0); printf("call result type: %d\n", (int) duk_get_type(ctx, -1)); fflush(stdout); printf("call result: %s\n", duk_safe_to_string(ctx, -1)); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
Variant DuktapeScriptFunction::call(const std::vector<Variant> & args) { // Get function wrapper from stash duk_push_global_stash(m_context); duk_get_prop_index(m_context, -1, m_stashIndex); // Push arguments for (Variant var : args) { m_scriptBackend->pushToDukStack(var); } // Call function duk_int_t error = duk_pcall(m_context, args.size()); // Check for error if (error) { // Raise script exception m_scriptBackend->m_scriptContext->scriptException(std::string(duk_safe_to_string(m_context, -1))); duk_pop_2(m_context); return Variant(); } // Convert return value Variant value = m_scriptBackend->fromDukStack(-1); duk_pop_2(m_context); return value; }
/* Custom internal prototype is lost during a dump/load. */ static duk_ret_t test_internal_prototype_lost(duk_context *ctx) { duk_eval_string(ctx, "(function () {\n" " var f = function test() {};\n" " Object.setPrototypeOf(f, { myProperty: 'myValue' });\n" " print(f.myProperty);\n" " return f;\n" "})()"); duk_dump_function(ctx); duk_load_function(ctx); duk_get_prop_string(ctx, -1, "myProperty"); printf("myProperty: %s\n", duk_safe_to_string(ctx, -1)); duk_pop(ctx); duk_get_prototype(ctx, -1); duk_eval_string(ctx, "Function.prototype"); printf("f prototype is Function.prototype: %d\n", (int) duk_strict_equals(ctx, -1, -2)); duk_pop_2(ctx); duk_pop(ctx); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
void StyleContext::initFunctions(const Scene& _scene) { if (_scene.id == m_sceneId) { return; } m_sceneId = _scene.id; auto arr_idx = duk_push_array(m_ctx); int id = 0; for (auto& function : _scene.functions()) { //logMsg("compile '%s'\n", function.c_str()); duk_push_string(m_ctx, function.c_str()); duk_push_string(m_ctx, ""); if (duk_pcompile(m_ctx, DUK_COMPILE_FUNCTION) == 0) { duk_put_prop_index(m_ctx, arr_idx, id); } else { logMsg("Error: compile failed: %s\n", duk_safe_to_string(m_ctx, -1)); duk_pop(m_ctx); } id++; } if (!duk_put_global_string(m_ctx, FUNC_ID)) { logMsg("Error: 'fns' object not set\n"); } DUMP("setScene - %d functions\n", id); }
static int es_sqlite_create(duk_context *ctx) { char path[PATH_MAX]; char errbuf[512]; es_context_t *ec = es_get(ctx); const char *name = duk_safe_to_string(ctx, 0); // Create the db-dir for this plugin snprintf(path, sizeof(path), "%s/databases", ec->ec_storage); if(fa_makedirs(path, errbuf, sizeof(errbuf))) duk_error(ctx, DUK_ERR_ERROR, "Unable to create directory %s -- %s", path, errbuf); snprintf(path, sizeof(path), "%s/databases/%s", ec->ec_storage, name); sqlite3 *db = db_open(path, 0); if(db == NULL) duk_error(ctx, DUK_ERR_ERROR, "Unable to open database -- check logs"); es_sqlite_t *es = es_resource_create(ec, &es_resource_sqlite, 0); es->es_db = db; es->es_name = strdup(name); es_resource_push(ctx, &es->super); return 1; }
static duk_ret_t test_ecma_call_success(duk_context *ctx) { duk_idx_t i; /* Ensure stack space for a lot of elements. */ duk_require_stack(ctx, STACK_REQUIRE + 1); /* Make a function call. Call handling resizes the value stack * back and forth. At the end, the value stack guaranteed size * must include the STACK_REQUIRE checked above. */ duk_eval_string(ctx, "(function () { print('hello from ecma func'); return 123 })"); duk_call(ctx, 0 /*nargs*/); printf("duk_call: %s\n", duk_safe_to_string(ctx, -1)); /* It would be quite awkward for user code to have no stack * guarantees at this point, i.e. require the user code to * call duk_require_stack(ctx, STACK_REQUIRE) again here. */ for (i = 0; i < STACK_REQUIRE; i++) { duk_push_int(ctx, 123); } printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
static duk_ret_t test_2a(duk_context *ctx, void *udata) { (void) udata; /* Test first with nothing on stack index -3. */ duk_safe_call(ctx, test__null, NULL, 0, 1); printf("%s\n", duk_safe_to_string(ctx, 0)); duk_pop(ctx); duk_set_top(ctx, 0); duk_push_undefined(ctx); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_null(ctx); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_true(ctx); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_false(ctx); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_number(ctx, 123.0); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_string(ctx, "foo\x00" "bar"); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_fixed_buffer(ctx, 16); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_pointer(ctx, NULL); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_pointer(ctx, (void *) 0xdeadbeefUL); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_object(ctx); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_array(ctx); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_c_function(ctx, dummy_func, 0); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_c_lightfunc(ctx, dummy_func, 0, 0, 0); test__require_calls(ctx); duk_set_top(ctx, 0); duk_eval_string(ctx, "(function dummy(){})"); test__require_calls(ctx); duk_set_top(ctx, 0); duk_push_thread(ctx); test__require_calls(ctx); printf("done\n"); return 0; }
/* Dump/load mandelbrot. No inner functions but a bit more code. */ static duk_ret_t test_mandel(duk_context *ctx) { unsigned char *p; duk_size_t i, sz; printf("Mandelbrot source length: %ld\n", (long) strlen(MANDELBROT)); /* Compiled as a function; force source filename. */ duk_push_string(ctx, MANDELBROT); duk_push_string(ctx, "mandel.js"); duk_compile(ctx, DUK_COMPILE_FUNCTION); duk_dump_function(ctx); p = (unsigned char *) duk_get_buffer(ctx, -1, &sz); for (i = 0; i < sz; i++) { printf("%02x", (int) p[i]); } printf("\n"); fflush(stdout); /* Load test function from dump and execute it. */ duk_load_function(ctx); duk_call(ctx, 0); printf("call result: %s\n", duk_safe_to_string(ctx, -1)); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
/*----------------------------------------------------------------------------*/ static duk_ret_t kbjs_sleep(duk_context *context) { /* Check if first argument is a number */ /* STACK: [..., interval] */ if (duk_is_nan(context, (duk_idx_t)-1)) duk_error(context, (duk_errcode_t)kbjs_ArgumentTypeError, kbjs_Error_fmt(kbjs_ArgumentTypeError), SLEEP_FUNC_NAME, "Number", 0, duk_safe_to_string(context, (duk_idx_t)-1)); /* Get first argument as integer in miliseconds */ long ms = (long)floor(fabs(duk_get_number(context, (duk_idx_t)-1))); long s = ms / S_TO_MS; /* Sleep this thread */ struct timespec interval = { (time_t)s, (ms - s*S_TO_MS)*MS_TO_NS }; nanosleep(&interval, NULL); return (duk_ret_t)0; }
static duk_ret_t my_print(duk_context *ctx) { duk_push_string(ctx, " "); duk_insert(ctx, 0); duk_join(ctx, duk_get_top(ctx) - 1); printf("%s\n", duk_safe_to_string(ctx, -1)); return 0; }
static duk_ret_t handle_assert(duk_context *ctx) { if (duk_to_boolean(ctx, 0)) { return 0; } duk_error(ctx, DUK_ERR_ERROR, "assertion failed: %s", duk_safe_to_string(ctx, 1)); return 0; }
bool StyleContext::evalFilter(FunctionID _id) const { if (!duk_get_global_string(m_ctx, FUNC_ID)) { logMsg("Error: evalFilterFn - functions not initialized\n"); return false; } if (!duk_get_prop_index(m_ctx, -1, _id)) { logMsg("Error: evalFilterFn - function %d not set\n", _id); } if (duk_pcall(m_ctx, 0) != 0) { logMsg("Error: evalFilterFn: %s\n", duk_safe_to_string(m_ctx, -1)); } bool result = false; if (duk_is_boolean(m_ctx, -1)) { result = duk_get_boolean(m_ctx, -1); } // pop result duk_pop(m_ctx); // pop fns obj duk_pop(m_ctx); DUMP("evalFilterFn\n"); return result; }
/* Custom external prototype is lost during a dump/load. */ static duk_ret_t test_external_prototype_lost(duk_context *ctx) { duk_eval_string(ctx, "(function () {\n" " var f = function test() {};\n" " var proto = { myProperty: 'myValue' };\n" " f.prototype = proto;\n" " var inst = new f();\n" " print('inst prototype is Function.prototype: ' + (Object.getPrototypeOf(inst) === Function.prototype));\n" " print('inst prototype is custom prototype: ' + (Object.getPrototypeOf(inst) === proto));\n" " print(inst.myProperty);\n" " return f;\n" "})()"); duk_dump_function(ctx); duk_load_function(ctx); duk_get_prototype(ctx, -1); duk_eval_string(ctx, "Function.prototype"); printf("f prototype is Function.prototype: %d\n", (int) duk_strict_equals(ctx, -1, -2)); duk_pop_2(ctx); duk_new(ctx, 0); duk_get_prop_string(ctx, -1, "myProperty"); printf("myProperty: %s\n", duk_safe_to_string(ctx, -1)); duk_pop(ctx); duk_pop(ctx); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
static int es_sqlite_query(duk_context *ctx) { int argc = duk_get_top(ctx); if(argc < 2) return DUK_RET_TYPE_ERROR; es_sqlite_t *es = es_resource_get(ctx, 0, &es_resource_sqlite); const char *query = duk_safe_to_string(ctx, 1); if(es->es_stmt) { sqlite3_finalize(es->es_stmt); es->es_stmt = NULL; } int rc = db_prepare(es->es_db, &es->es_stmt, query); if(rc != SQLITE_OK) { if(es->es_transaction && rc == SQLITE_LOCKED) duk_error(ctx, ST_ERROR_SQLITE_BASE | rc , "Deadlock"); duk_error(ctx, ST_ERROR_SQLITE_BASE | rc, "Sqlite error 0x%x -- %s", rc, sqlite3_errmsg(es->es_db)); } sqlite3_stmt *stmt = es->es_stmt; for(int i = 2; i < argc; i++) { int sqlite_arg = i - 1; if(duk_is_null_or_undefined(ctx, i)) { sqlite3_bind_null(stmt, sqlite_arg); } else if(duk_is_number(ctx, i)) { sqlite3_bind_double(stmt, sqlite_arg, duk_get_number(ctx, i)); } else if(duk_is_boolean(ctx, i)) { sqlite3_bind_int(stmt, sqlite_arg, duk_get_boolean(ctx, i)); } else { sqlite3_bind_text(stmt, sqlite_arg, duk_safe_to_string(ctx, i), -1, SQLITE_STATIC); } } es_sqlite_stmt_step(ctx, es); return 0; }
DUK_EXTERNAL int sjs_vm_eval_code(const sjs_vm_t* vm, const char* filename, const char* code, size_t len, FILE* foutput, FILE* ferror, bool use_strict) { int r; assert(vm); duk_context* ctx = vm->ctx; duk_push_boolean(ctx, use_strict); duk_push_pointer(ctx, (void *) code); duk_push_uint(ctx, len); duk_push_string(ctx, filename); r = duk_safe_call(ctx, sjs__compile_execute, 4 /*nargs*/, 1 /*nret*/); if (r != DUK_EXEC_SUCCESS) { if (ferror) { duk_safe_call(ctx, sjs__get_error_stack, 1 /*nargs*/, 1 /*nrets*/); fprintf(ferror, "%s\n", duk_safe_to_string(ctx, -1)); fflush(ferror); } } else { if (foutput) { /* TODO: make this optional with a parameter? */ /* beautify output */ duk_eval_string(ctx, "(function (v) {\n" " try {\n" " return Duktape.enc('jx', v, null, 4);\n" " } catch (e) {\n" " return String(v);\n" " }\n" "})"); duk_insert(ctx, -2); duk_call(ctx, 1); fprintf(foutput, "= %s\n", duk_safe_to_string(ctx, -1)); fflush(foutput); } } duk_pop(ctx); return r; }
static duk_ret_t test_1(duk_context *ctx) { duk_eval_string(ctx, "new Date(123456)"); duk_push_string(ctx, "\xffValue"); duk_get_prop(ctx, -2); printf("Date._Value: %s\n", duk_safe_to_string(ctx, -1)); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
static duk_ret_t test_get_nonobject(duk_context *ctx, void *udata) { (void) udata; duk_push_int(ctx, 123); duk_get_finalizer(ctx, -1); printf("read finalizer: %s\n", duk_safe_to_string(ctx, -1)); return 0; }
void StyleContext::parseSceneGlobals(const YAML::Node& node, const std::string& key, int seqIndex, duk_idx_t dukObject) { switch(node.Type()) { case YAML::NodeType::Scalar: if (key.size() == 0) { duk_push_string(m_ctx, node.Scalar().c_str()); duk_put_prop_index(m_ctx, dukObject, seqIndex); } else { auto nodeValue = node.Scalar(); if (nodeValue.compare(0, 8, "function") == 0) { duk_push_string(m_ctx, key.c_str()); // push property key duk_push_string(m_ctx, nodeValue.c_str()); // push function string duk_push_string(m_ctx, ""); if (duk_pcompile(m_ctx, DUK_COMPILE_FUNCTION) == 0) { // compile function duk_put_prop(m_ctx, -3); // put {key: function()} } else { LOGW("Compile failed in global function: %s\n%s\n---", duk_safe_to_string(m_ctx, -1), nodeValue.c_str()); duk_pop(m_ctx); //pop error duk_pop(m_ctx); //pop key // push property as a string duk_push_string(m_ctx, nodeValue.c_str()); duk_put_prop_string(m_ctx, dukObject, key.c_str()); } } else { duk_push_string(m_ctx, nodeValue.c_str()); duk_put_prop_string(m_ctx, dukObject, key.c_str()); } } break; case YAML::NodeType::Sequence: { auto seqObj = duk_push_array(m_ctx); for (int i = 0; i < node.size(); i++) { parseSceneGlobals(node[i], "", i, seqObj); } duk_put_prop_string(m_ctx, seqObj-1, key.c_str()); break; } case YAML::NodeType::Map: { //duk_push_string(m_ctx, key.c_str()); auto mapObj = duk_push_object(m_ctx); for (auto& mapNode : node) { auto itemKey = mapNode.first.Scalar(); parseSceneGlobals(mapNode.second, itemKey, 0, mapObj); } duk_put_prop_string(m_ctx, mapObj-1, key.c_str()); } default: break; } return; }
static duk_ret_t test_basic(duk_context *ctx, void *udata) { duk_idx_t i, n; duk_int_t rc; (void) udata; duk_push_undefined(ctx); duk_push_null(ctx); duk_push_true(ctx); duk_push_false(ctx); duk_push_string(ctx, ""); duk_push_string(ctx, "foo"); duk_push_int(ctx, 123); duk_push_object(ctx); duk_push_fixed_buffer(ctx, 0); duk_push_fixed_buffer(ctx, 1024); duk_push_dynamic_buffer(ctx, 0); duk_push_dynamic_buffer(ctx, 2048); duk_eval_string(ctx, "(function () { return new ArrayBuffer(16); })()"); duk_eval_string(ctx, "(function () { return new Uint32Array(16); })()"); duk_eval_string(ctx, "(function () { return new DataView(new ArrayBuffer(16)); })()"); duk_eval_string(ctx, "(function () { return new Uint32Array(16).subarray(3, 6); })()"); duk_eval_string(ctx, "(function () { return new Buffer('ABCDEFGH'); })()"); duk_eval_string(ctx, "(function () { return new Buffer('ABCDEFGH').slice(3, 6); })()"); n = duk_get_top(ctx); printf("top: %ld\n", (long) n); for (i = 0; i <= n; i++) { rc = duk_safe_call(ctx, safe_helper1, (void *) i, 0, 1); if (rc != DUK_EXEC_SUCCESS) { printf("index %ld: %s\n", (long) i, duk_safe_to_string(ctx, -1)); } duk_pop(ctx); rc = duk_safe_call(ctx, safe_helper2, (void *) i, 0, 1); if (rc != DUK_EXEC_SUCCESS) { printf("index %ld: %s\n", (long) i, duk_safe_to_string(ctx, -1)); } duk_pop(ctx); } printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }