/* demonstrate how pushing too many elements causes an error */ static duk_ret_t test_1(duk_context *ctx, void *udata) { int i; (void) udata; for (i = 0; i < 1000; i++) { duk_push_int(ctx, 123); } printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
/* duk_del_prop(), non-configurable virtual property of a plain string. * Same behavior when called inside/outside of a Duktape/C activation. */ static duk_ret_t test_delprop_c(duk_context *ctx) { duk_ret_t rc; prep(ctx); duk_push_int(ctx, 5); rc = duk_del_prop(ctx, 2); printf("delete 'test_string'[5] -> rc=%d\n", (int) rc); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
static int sys1_fstat(duk_context *ctx) { int fd = duk_to_int(ctx, 0); struct stat stat; int rc; rc = fstat(fd, &stat); sys1_push_stat(ctx, &stat); duk_push_int(ctx, rc); duk_put_prop_string(ctx, -2, "rc"); return 1; }
void test(duk_context *ctx) { duk_idx_t idx; duk_push_int(ctx, 123); duk_push_int(ctx, 234); duk_push_int(ctx, 345); for (idx = -5; idx <= 5; idx++) { printf("top=%ld, idx=%ld, duk_is_valid_index -> %d\n", (long) duk_get_top(ctx), (long) idx, (int) duk_is_valid_index(ctx, idx)); } for (idx = -5; idx <= 5; idx++) { duk_push_int(ctx, idx); duk_safe_call(ctx, req_valid_idx, 1, 1); printf("idx=%ld, duk_require_valid_index -> %s\n", (long) idx, duk_to_string(ctx, -1)); duk_pop(ctx); } }
/* duk_del_prop(), non-configurable virtual property of a plain string, * called from inside a Duktape/C context. */ int test_1c(duk_context *ctx) { int rc; prep(ctx); duk_push_int(ctx, 5); rc = duk_del_prop(ctx, 2); printf("delete 'test_string'[5] -> rc=%d\n", rc); printf("final top: %d\n", duk_get_top(ctx)); return 0; }
static int sys1_lstat(duk_context *ctx) { const char *path = duk_to_string(ctx, 0); struct stat stat; int rc; rc = lstat(path, &stat); sys1_push_stat(ctx, &stat); duk_push_int(ctx, rc); duk_put_prop_string(ctx, -2, "rc"); return 1; }
static int sys1_lseek(duk_context *ctx) { int fd = duk_to_int(ctx, 0); off_t offset = duk_to_int(ctx, 1); int whence = duk_to_int(ctx, 2); off_t rc; rc = lseek(fd, offset, whence); duk_push_int(ctx, rc); return 1; }
/* duk_del_prop(), success cases */ static duk_ret_t test_delprop_a_safecall(duk_context *ctx, void *udata) { duk_ret_t rc; (void) udata; prep(ctx); /* existing, configurable */ duk_push_string(ctx, "foo"); rc = duk_del_prop(ctx, 0); printf("delete obj.foo -> rc=%d\n", (int) rc); /* nonexistent */ duk_push_string(ctx, "nonexistent"); rc = duk_del_prop(ctx, 0); printf("delete obj.nonexistent -> rc=%d\n", (int) rc); /* nonexistent */ duk_push_int(ctx, 123); rc = duk_del_prop(ctx, 0); printf("delete obj[123] -> rc=%d\n", (int) rc); /* nonexistent, array */ duk_push_string(ctx, "nonexistent"); rc = duk_del_prop(ctx, 1); printf("delete arr.nonexistent -> rc=%d\n", (int) rc); /* existing, configurable, array */ duk_push_int(ctx, 2); rc = duk_del_prop(ctx, 1); printf("delete arr[2] -> rc=%d\n", (int) rc); duk_json_encode(ctx, 0); printf("final object: %s\n", duk_to_string(ctx, 0)); duk_json_encode(ctx, 1); printf("final array: %s\n", duk_to_string(ctx, 1)); printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
static duk_ret_t test_1(duk_context *ctx) { duk_idx_t i, n; duk_set_top(ctx, 0); duk_push_undefined(ctx); duk_push_null(ctx); duk_push_true(ctx); duk_push_false(ctx); duk_push_int(ctx, 0); duk_push_int(ctx, 1); duk_push_nan(ctx); duk_push_number(ctx, INFINITY); duk_push_string(ctx, ""); duk_push_string(ctx, "foo"); duk_push_object(ctx); duk_push_number(ctx, 123.456); duk_to_object(ctx, -1); /* Number(123.456) */ duk_push_thread(ctx); duk_push_fixed_buffer(ctx, 0); duk_push_fixed_buffer(ctx, 1024); duk_push_dynamic_buffer(ctx, 0); duk_push_dynamic_buffer(ctx, 1024); duk_push_pointer(ctx, (void *) NULL); duk_push_pointer(ctx, (void *) 0xdeadbeef); n = duk_get_top(ctx); printf("top: %ld\n", (long) n); for (i = 0; i < n; i++) { duk_int_t t1, t2; t1 = duk_get_type(ctx, i); duk_to_primitive(ctx, i, DUK_HINT_NONE); t2 = duk_get_type(ctx, i); printf("index %ld, ToString(result): '%s', type: %ld -> %ld\n", (long) i, duk_to_string(ctx, i), (long) t1, (long) t2); } return 0; }
static int sys1_write(duk_context *ctx) { int fd = duk_to_int(ctx, 0); size_t bufsize; void *buf = duk_to_buffer(ctx, 1, &bufsize); int len = duk_to_int(ctx, 2); ssize_t rc; rc = write(fd, buf, len); duk_push_int(ctx, rc); return 1; }
static duk_ret_t test_putprop(duk_context *ctx, void *udata) { (void) udata; prep(ctx); /* Property exists, own property */ duk_push_int(ctx, 1001); duk_put_prop_string(ctx, 0, "foo"); printf("putprop foo done\n"); /* Property exists, inherited property */ duk_push_int(ctx, 1002); duk_put_prop_string(ctx, 0, "bar"); printf("putprop bar done\n"); /* Property doesn't exist, terminate with error */ duk_push_int(ctx, 1003); duk_put_prop_string(ctx, 0, "quux"); printf("putprop quux done\n"); return 0; }
static duk_ret_t js_RawFile_get_position(duk_context* ctx) { FILE* file; duk_push_this(ctx); file = duk_require_sphere_obj(ctx, -1, "RawFile"); duk_pop(ctx); if (file == NULL) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "RawFile:position - File has been closed"); duk_push_int(ctx, ftell(file)); return 1; }
/* * Create a global array refs in the heap stash. */ void mn_ref_setup(duk_context *ctx) { duk_push_heap_stash(ctx); /* Create a new array with one `0` at index `0`. */ duk_push_array(ctx); duk_push_int(ctx, 0); duk_put_prop_index(ctx, -2, 0); /* Store it as "refs" in the heap stash */ duk_put_prop_string(ctx, -2, "refs"); duk_pop(ctx); }
static duk_ret_t js_Font_getStringWidth(duk_context* ctx) { const char* text = duk_to_string(ctx, 0); font_t* font; duk_push_this(ctx); font = duk_require_sphere_obj(ctx, -1, "Font"); duk_pop(ctx); duk_push_int(ctx, get_text_width(font, text)); return 1; }
static duk_ret_t js_Font_getStringHeight(duk_context* ctx) { const char* text = duk_to_string(ctx, 0); int width = duk_require_int(ctx, 1); font_t* font; int num_lines; duk_push_this(ctx); font = duk_require_sphere_obj(ctx, -1, "Font"); duk_pop(ctx); duk_push_c_function(ctx, js_Font_wordWrapString, DUK_VARARGS); duk_push_this(ctx); duk_push_string(ctx, text); duk_push_int(ctx, width); duk_call_method(ctx, 2); duk_get_prop_string(ctx, -1, "length"); num_lines = duk_get_int(ctx, -1); duk_pop(ctx); duk_pop(ctx); duk_push_int(ctx, get_font_line_height(font) * num_lines); return 1; }
static duk_ret_t js_Font_getStringWidth(duk_context* ctx) { const char* text = duk_to_string(ctx, 0); font_t* font; duk_push_this(ctx); duk_get_prop_string(ctx, -1, "\xFF" "ptr"); font = duk_get_pointer(ctx, -1); duk_pop(ctx); duk_pop(ctx); duk_push_int(ctx, get_text_width(font, text)); return 1; }
static duk_ret_t API__getmininginfo ( duk_context * ctx ) { duk_idx_t idx; idx = duk_push_object(ctx); duk_push_int ( ctx, nBestHeight ); duk_put_prop_string ( ctx, idx, "blocks" ); duk_push_int ( ctx, nLastBlockSize ); duk_put_prop_string ( ctx, idx, "currentblocksize" ); duk_push_int ( ctx, nLastBlockTx ); duk_put_prop_string ( ctx, idx, "currentblocktx" ); duk_push_number ( ctx, GetDifficulty(NULL) ); duk_put_prop_string ( ctx, idx, "difficulty" ); duk_push_string ( ctx, GetWarnings("statusbar").c_str() ); duk_put_prop_string ( ctx, idx, "errors" ); duk_push_boolean ( ctx, GetBoolArg ("-gen") ); duk_put_prop_string ( ctx, idx, "generate" ); duk_push_int ( ctx, GetArg ( "-genproclimit", -1 ) ); duk_put_prop_string ( ctx, idx, "genproclimit" ); duk_push_int ( ctx, 0 ); /* (TODO) */ duk_put_prop_string ( ctx, idx, "hashespersec" ); duk_push_number ( ctx, mempool.size() ); duk_put_prop_string ( ctx, idx, "pooledtx" ); duk_push_boolean ( ctx, fTestNet ); duk_put_prop_string ( ctx, idx, "testnet" ); return 1; }
void test(duk_context *ctx) { duk_idx_t i, funcidx, argcount; duk_ret_t rc; /* test C function arg count variants */ duk_push_c_function(ctx, my_int_adder, 0); /* [0] = c func with 0 args */ duk_push_c_function(ctx, my_int_adder, 1); /* [1] = c func with 1 arg */ duk_push_c_function(ctx, my_int_adder, 2); /* [2] = c func with 2 args */ duk_push_c_function(ctx, my_int_adder, DUK_VARARGS); /* [3] = c func with varargs */ for (funcidx = 0; funcidx < 4; funcidx++) { for (argcount = 0; argcount < 5; argcount++) { duk_dup(ctx, funcidx); for (i = 0; i < argcount; i++) { duk_push_int(ctx, i + 1); /* 1, 2, 3, ... */ } /* [ ... func <args> ] */ duk_call(ctx, argcount); printf("funcidx=%ld, argcount=%ld -> result=%ld\n", (long) funcidx, (long) argcount, (long) duk_to_int(ctx, -1)); duk_pop(ctx); } } /* test C function return value 0 and negative */ duk_set_top(ctx, 0); duk_push_c_function(ctx, my_zero_ret, 0); duk_call(ctx, 0); printf("top after calling my_zero_ret: %ld, retval='%s'\n", (long) duk_get_top(ctx), duk_to_string(ctx, -1)); duk_pop(ctx); duk_set_top(ctx, 0); duk_push_c_function(ctx, my_neg_ret, 0); rc = duk_pcall(ctx, 0); printf("top after calling my_neg_ret: %ld, rc=%d, retval='%s'\n", (long) duk_get_top(ctx), (int) rc, duk_to_string(ctx, -1)); duk_pop(ctx); duk_set_top(ctx, 0); duk_push_c_function(ctx, my_type_error_ret, 0); rc = duk_pcall(ctx, 0); printf("top after calling my_type_error_ret: %ld, rc=%d, retval='%s'\n", (long) duk_get_top(ctx), (int) rc, duk_to_string(ctx, -1)); duk_pop(ctx); }
int duk_builtin_duk_object_gc(duk_context *ctx) { #ifdef DUK_USE_MARK_AND_SWEEP duk_hthread *thr = (duk_hthread *) ctx; int flags; int rc; flags = duk_get_int(ctx, 0); rc = duk_heap_mark_and_sweep(thr->heap, flags); duk_push_int(ctx, rc); return 1; #else return 0; #endif }
/* demonstrate how using one large duk_check_stack_top() before such * a loop works. */ int check_1(duk_context *ctx) { int i; int rc; rc = duk_check_stack_top(ctx, 1000); printf("rc=%d\n", rc); for (i = 0; i < 1000; i++) { duk_push_int(ctx, 123); } printf("final top: %d\n", duk_get_top(ctx)); return 0; }
/* demonstrate how using one large duk_check_stack_top() before such * a loop works. */ static duk_ret_t check_1_inner(duk_context *ctx) { int i; duk_ret_t rc; rc = duk_check_stack_top(ctx, 1000); printf("rc=%d\n", (int) rc); for (i = 0; i < 1000; i++) { duk_push_int(ctx, 123); } printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
duk_ret_t duk_bi_number_constructor(duk_context *ctx) { duk_idx_t nargs; duk_hobject *h_this; /* * The Number constructor uses ToNumber(arg) for number coercion * (coercing an undefined argument to NaN). However, if the * argument is not given at all, +0 must be used instead. To do * this, a vararg function is used. */ nargs = duk_get_top(ctx); if (nargs == 0) { duk_push_int(ctx, 0); } duk_to_number(ctx, 0); duk_set_top(ctx, 1); DUK_ASSERT_TOP(ctx, 1); if (!duk_is_constructor_call(ctx)) { return 1; } /* * E5 Section 15.7.2.1 requires that the constructed object * must have the original Number.prototype as its internal * prototype. However, since Number.prototype is non-writable * and non-configurable, this doesn't have to be enforced here: * The default object (bound to 'this') is OK, though we have * to change its class. * * Internal value set to ToNumber(arg) or +0; if no arg given, * ToNumber(undefined) = NaN, so special treatment is needed * (above). String internal value is immutable. */ /* XXX: helper */ duk_push_this(ctx); h_this = duk_get_hobject(ctx, -1); DUK_ASSERT(h_this != NULL); DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER); DUK_ASSERT(h_this->prototype == ((duk_hthread *) ctx)->builtins[DUK_BIDX_NUMBER_PROTOTYPE]); DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER); DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this)); duk_dup(ctx, 0); /* -> [ val obj val ] */ duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); return 0; /* no return value -> don't replace created value */ }
/* registers a block r,g,b and returns it's id */ int js_register_block(duk_context *ctx) { /* get r, g, b values */ const int r = duk_get_int(ctx, 0); const int g = duk_get_int(ctx, 1); const int b = duk_get_int(ctx, 2); /* registers block, may allocate more memory */ register_block(r, g, b); /* return block's id */ duk_push_int(ctx, blocks_len - 1); return 1; }
static int sys1_dprint(duk_context *ctx) { int fd = duk_to_int(ctx, 0); const char *buf = duk_to_string(ctx, 1); int len; ssize_t rc; len = strlen(buf); rc = write(fd, buf, len); duk_push_int(ctx, rc); return 1; }
DUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) { duk_context *ctx = (duk_context *) thr; duk_hobject *h; duk_hstring *h_bc; duk_small_int_t re_flags; /* [ ... escape_source bytecode ] */ h_bc = duk_get_hstring(ctx, -1); DUK_ASSERT(h_bc != NULL); DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h_bc) >= 1); /* always at least the header */ DUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h_bc) >= 1); DUK_ASSERT((duk_small_int_t) DUK_HSTRING_GET_DATA(h_bc)[0] < 0x80); /* flags always encodes to 1 byte */ re_flags = (duk_small_int_t) DUK_HSTRING_GET_DATA(h_bc)[0]; /* [ ... escaped_source bytecode ] */ duk_push_object(ctx); h = duk_get_hobject(ctx, -1); DUK_ASSERT(h != NULL); duk_insert(ctx, -3); /* [ ... regexp_object escaped_source bytecode ] */ DUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP); DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]); duk_xdef_prop_stridx(ctx, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE); /* [ ... regexp_object escaped_source ] */ duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_SOURCE, DUK_PROPDESC_FLAGS_NONE); /* [ ... regexp_object ] */ duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_GLOBAL)); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_GLOBAL, DUK_PROPDESC_FLAGS_NONE); duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_IGNORE_CASE)); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_IGNORE_CASE, DUK_PROPDESC_FLAGS_NONE); duk_push_boolean(ctx, (re_flags & DUK_RE_FLAG_MULTILINE)); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_MULTILINE, DUK_PROPDESC_FLAGS_NONE); duk_push_int(ctx, 0); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W); /* [ ... regexp_object ] */ }
static int sys1_execve(duk_context *ctx) { const char *filename = duk_to_string(ctx, 0); int rc; char **argv; char **envp; int argc = 0, envc = 0, i; // count arguments // FIXME: Use duk_get_length() instead ? while(1) { rc = duk_get_prop_index(ctx, 1, argc); duk_pop(ctx); if(rc == 0) break; argc++; } argv = malloc(sizeof(char*)*(argc+1)); for(i=0;i<argc;i++) { duk_get_prop_index(ctx, 1, i); argv[i] = (char*) duk_to_string(ctx, 3); duk_pop(ctx); } argv[i] = (void*)0; // count arguments // FIXME: Use duk_get_length() instead ? while(1) { rc = duk_get_prop_index(ctx, 2, envc); duk_pop(ctx); if(rc == 0) break; envc++; } envp = malloc(sizeof(char*)*(envc+1)); for(i=0;i<envc;i++) { duk_get_prop_index(ctx, 2, i); envp[i] = (char*) duk_to_string(ctx, 3); duk_pop(ctx); } envp[i] = (void*)0; rc = execve(filename, argv, envp); duk_push_int(ctx, rc); return 1; }
static void callJavascriptScanlineName(tic_mem* memory, s32 row, void* data, const char* name) { tic_machine* machine = (tic_machine*)memory; duk_context* duk = machine->js; if(duk_get_global_string(duk, name)) { duk_push_int(duk, row); if(duk_pcall(duk, 1) != 0) machine->data->error(machine->data->data, duk_safe_to_string(duk, -1)); } duk_pop(duk); }
/* same test but with one element checks, once per loop */ int check_2(duk_context *ctx) { int i; int rc; for (i = 0; i < 1000; i++) { rc = duk_check_stack_top(ctx, i + 1); if (rc == 0) { printf("duk_check_stack failed\n"); } duk_push_int(ctx, 123); } printf("final top: %d\n", duk_get_top(ctx)); return 0; }
/* same test but with one element checks, once per loop */ static duk_ret_t check_2(duk_context *ctx) { int i; duk_ret_t rc; for (i = 0; i < 1000; i++) { rc = duk_check_stack(ctx, 1); if (rc == 0) { printf("duk_check_stack failed\n"); } duk_push_int(ctx, 123); } printf("final top: %ld\n", (long) duk_get_top(ctx)); return 0; }
void test(duk_context *ctx) { int idx; int norm_idx; duk_push_int(ctx, 123); duk_push_int(ctx, 234); duk_push_int(ctx, 345); for (idx = -5; idx <= 5; idx++) { norm_idx = duk_normalize_index(ctx, idx); if (norm_idx == DUK_INVALID_INDEX) { printf("top=%d, idx=%d, duk_normalize_index -> DUK_INVALID_INDEX\n", duk_get_top(ctx), idx); } else { printf("top=%d, idx=%d, duk_normalize_index -> %d\n", duk_get_top(ctx), idx, norm_idx); } } for (idx = -5; idx <= 5; idx++) { duk_push_int(ctx, idx); duk_safe_call(ctx, req_norm_idx, 1, 1, DUK_INVALID_INDEX); printf("idx=%d -> duk_require_normalize_index -> %s\n", idx, duk_to_string(ctx, -1)); duk_pop(ctx); } }