コード例 #1
0
/* 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;
}
コード例 #2
0
ファイル: test-del-prop.c プロジェクト: jmptrader/duktape
/* 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;
}
コード例 #3
0
ファイル: sys1.c プロジェクト: jelaas/sysjs
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;
}
コード例 #4
0
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);
	}
}
コード例 #5
0
ファイル: test-del-prop.c プロジェクト: BpLife/duktape
/* 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;
}
コード例 #6
0
ファイル: sys1.c プロジェクト: jelaas/sysjs
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;
}
コード例 #7
0
ファイル: sys1.c プロジェクト: jelaas/sysjs
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;
}
コード例 #8
0
ファイル: test-del-prop.c プロジェクト: jmptrader/duktape
/* 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;
}
コード例 #9
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;
}
コード例 #10
0
ファイル: sys1.c プロジェクト: jelaas/sysjs
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;
}
コード例 #11
0
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;
}
コード例 #12
0
ファイル: rawfile.c プロジェクト: caivega/minisphere
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;
}
コード例 #13
0
ファイル: ref.c プロジェクト: hypoalex/mininode
/*
 * 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);
}
コード例 #14
0
ファイル: font.c プロジェクト: svaarala/minisphere
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;
}
コード例 #15
0
ファイル: font.c プロジェクト: svaarala/minisphere
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;
}
コード例 #16
0
ファイル: font.c プロジェクト: carriercomm/minisphere
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;
}
コード例 #17
0
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;
}
コード例 #18
0
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);
}
コード例 #19
0
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
}
コード例 #20
0
/* 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;
}
コード例 #21
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;
}
コード例 #22
0
ファイル: duk_bi_number.c プロジェクト: cherry-wb/duktape
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 */
}
コード例 #23
0
ファイル: generate.c プロジェクト: numpad/generator
/* 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;
}
コード例 #24
0
ファイル: sys1.c プロジェクト: jelaas/sysjs
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;
}
コード例 #25
0
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 ] */
}
コード例 #26
0
ファイル: sys1.c プロジェクト: jelaas/sysjs
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;
}
コード例 #27
0
ファイル: jsapi.c プロジェクト: rdrpenguin04/TIC-80
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);
}
コード例 #28
0
/* 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;
}
コード例 #29
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;
}
コード例 #30
0
ファイル: test-normalize-index.c プロジェクト: BpLife/duktape
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);
	}
}