/* Uint8Array, "partial slice" */
static duk_ret_t test_uint8array_indexed_1b(duk_context *ctx, void *udata) {
	(void) udata;

	duk_push_dynamic_buffer(ctx, 150);
	setup_typedarray_slice(ctx, -1, "Uint8Array", 30, 100);
	shared_read_write_index(ctx, 30 + 95);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
/* ArrayBuffer, "full slice" */
static duk_ret_t test_arraybuffer_indexed_1a(duk_context *ctx, void *udata) {
	(void) udata;

	duk_push_dynamic_buffer(ctx, 100);
	setup_arraybuffer(ctx, -1);
	shared_read_write_index(ctx, 95);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
/* Node.js Buffer, "partial slice" */
static duk_ret_t test_nodejs_buffer_indexed_1b(duk_context *ctx, void *udata) {
	(void) udata;

	duk_push_dynamic_buffer(ctx, 150);
	setup_nodejs_buffer_slice(ctx, -1, 30, 130);
	shared_read_write_index(ctx, 30 + 95);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
示例#4
0
static duk_ret_t test_basic(duk_context *ctx) {
	duk_idx_t i, n;

	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++) {
		void *buf;
		duk_size_t len;

		len = (duk_size_t) 0xdeadbeefUL;
		buf = duk_get_buffer_data(ctx, i, &len);
		if (len == 0) {
			/* avoid printing 'buf' if len is zero, as it is not predictable */
			printf("index %ld: length 0\n", (long) i);
		} else {
			printf("index %ld: length %lu, ptr-is-NULL %d\n",
			       (long) i, (unsigned long) len, (buf == NULL ? 1 : 0));
		}
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
示例#5
0
static duk_ret_t test_1(duk_context *ctx, void *udata) {
	duk_idx_t i, n;

	(void) udata;

	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;
}
示例#6
0
void test(duk_context *ctx) {
	duk_idx_t i, n;

	duk_push_undefined(ctx);
	duk_push_null(ctx);
	duk_push_boolean(ctx, 0);
	duk_push_boolean(ctx, 123);
	duk_push_number(ctx, 234);
	duk_push_string(ctx, "foo");
	duk_push_object(ctx);
	duk_push_array(ctx);
	duk_push_c_function(ctx, my_c_func, DUK_VARARGS);
	duk_push_fixed_buffer(ctx, 1024);
	duk_push_dynamic_buffer(ctx, 1024);
	duk_push_pointer(ctx, (void *) 0xdeadbeefUL);

	n = duk_get_top(ctx);
	for (i = 0; i < n + 1; i++) {  /* end on invalid index on purpose */
		duk_int_t typeval, typemask;

		typeval = duk_get_type(ctx, i);
		typemask = duk_get_type_mask(ctx, i);

		printf("stack[%ld] --> type=%ld mask=0x%08lx ",
		       (long) i, (long) typeval, (long) typemask);

		switch(duk_get_type(ctx, i)) {
		case DUK_TYPE_NONE:       printf("none"); break;
		case DUK_TYPE_UNDEFINED:  printf("undefined"); break;
		case DUK_TYPE_NULL:       printf("null"); break;
		case DUK_TYPE_BOOLEAN:    printf("boolean"); break;
		case DUK_TYPE_NUMBER:     printf("number"); break;
		case DUK_TYPE_STRING:     printf("string"); break;
		case DUK_TYPE_OBJECT:     printf("object"); break;
		case DUK_TYPE_BUFFER:     printf("buffer"); break;
		case DUK_TYPE_POINTER:    printf("pointer"); break;
		default:                  printf("unknown(%d)", (int) duk_get_type(ctx, i)); break;
		}

		printf(" bool=%d num=%lf str=%s buf-is-null=%d ptr=%p",
		       (int) duk_get_boolean(ctx, i),
		       (double) duk_get_number(ctx, i),
		       duk_get_string(ctx, i),
		       (duk_get_buffer(ctx, i, NULL) == NULL ? 1 : 0),
		       duk_get_pointer(ctx, i));

		printf(" isobj=%d isarr=%d isfunc=%d",
		       (int) duk_is_object(ctx, i),
		       (int) duk_is_array(ctx, i),
		       (int) duk_is_function(ctx, i));

		printf("\n");
	}
}
static duk_ret_t test_typedarray_set_1(duk_context *ctx, void *udata) {
	int i, dst, src;
	unsigned char *data;

	(void) udata;

	data = (unsigned char *) duk_push_dynamic_buffer(ctx, 10);  /* index 0 */
	for (i = 0; i < 10; i++) {
		data[i] = 0x40 + i;
	}

	/* Some combinations are not set() compatible and cause a RangeError
	 * (source longer than target).  But this set should exercise byte copy,
	 * fast copy, and slow copy code paths.
	 */

	setup_typedarray(ctx, 0, "Uint8Array");               /* index 1, length 10 */
	setup_typedarray_slice(ctx, 0, "Uint8Array", 2, 5);   /* index 2, length 5 */
	setup_typedarray(ctx, 0, "Uint16Array");              /* index 3, length 5 */
	setup_typedarray_slice(ctx, 0, "Uint16Array", 2, 3);  /* index 4, length 3 */
	duk_eval_string(ctx, "[ 1, 2, 3, 4, 5 ]");            /* index 5, length 5 */

	for (i = 10; i >= 0; i--) {
		duk_resize_buffer(ctx, 0, i);

		/* Various copy combinations.  Resulting buffer is omitted;
		 * when both dst and src are typedarrays they share the same
		 * underlying buffer. so the results are a bit confusing (and
		 * not important to memory safety).
		 */

		for (dst = 1; dst <= 4; dst++) {
			for (src = 1; src <= 5; src++) {
				printf("%d %d %d\n", i, dst, src);
				duk_eval_string(ctx,
					"(function (dst, src) {\n"
					"    for (var i = 0; i < dst.length; i++) { dst[i] = 0x11; }\n"
					"    try { dst.set(src); } catch (e) { print(e.name); }\n"
					"})\n");
				duk_dup(ctx, dst);
				duk_dup(ctx, src);
				duk_call(ctx, 2);
				duk_pop(ctx);
			}
		}
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
示例#8
0
int test_1(duk_context *ctx) {
	void *ptr;
	size_t sz;
	int i;

	duk_set_top(ctx, 0);
	duk_push_fixed_buffer(ctx, 1024);
	duk_push_fixed_buffer(ctx, 0);
	duk_push_dynamic_buffer(ctx, 1024);
	duk_push_dynamic_buffer(ctx, 0);

	for (i = 0; i < 4; i++) {
		sz = (size_t) 0xdeadbeef;
		ptr = duk_require_buffer(ctx, i, &sz);
		printf("buffer: ptr-is-NULL=%d, sz=%d\n", (sz == 0 ? -1 : (ptr == NULL ? 1 : 0)), (int) sz);

		sz = (size_t) 0xdeadbeef;
		ptr = duk_require_buffer(ctx, i, NULL);
		printf("buffer\n");
	}

	return 0;
}
static duk_ret_t test_basic(duk_context *ctx, void *udata) {
	duk_uint_t test[] = {
		DUK_BUFOBJ_NODEJS_BUFFER,
		DUK_BUFOBJ_ARRAYBUFFER,
		DUK_BUFOBJ_DATAVIEW,
		DUK_BUFOBJ_INT8ARRAY,
		DUK_BUFOBJ_UINT8ARRAY,
		DUK_BUFOBJ_UINT8CLAMPEDARRAY,
		DUK_BUFOBJ_INT16ARRAY,
		DUK_BUFOBJ_UINT16ARRAY,
		DUK_BUFOBJ_INT32ARRAY,
		DUK_BUFOBJ_UINT32ARRAY,
		DUK_BUFOBJ_FLOAT32ARRAY,
		DUK_BUFOBJ_FLOAT64ARRAY,
	};
	int i;
	unsigned char extbuf[256];

	(void) udata;

	for (i = 0; i < sizeof(test) / sizeof(duk_uint_t); i++) {
		switch (i % 3) {
		case 0:
			duk_push_fixed_buffer(ctx, 256);
			break;
		case 1:
			duk_push_dynamic_buffer(ctx, 256);
			break;
		case 2:
			duk_push_external_buffer(ctx);
			duk_config_buffer(ctx, -1, (void *) extbuf, 256);
			break;
		}

		duk_push_undefined(ctx);  /* dummy */

		duk_push_buffer_object(ctx, -2, 128, 32, test[i]);

		duk_eval_string(ctx, "dumpBufferInfo");
		duk_dup(ctx, -2);
		duk_call(ctx, 1);

		/* ... plain undefined bufferobject result */
		duk_pop_n(ctx, 4);
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
static duk_ret_t test_nodejs_buffer_write_1(duk_context *ctx, void *udata) {
	int i, dst, src;
	unsigned char *data;

	(void) udata;

	data = (unsigned char *) duk_push_dynamic_buffer(ctx, 10);  /* index 0 */
	for (i = 0; i < 10; i++) {
		data[i] = 0x40 + i;
	}

	setup_nodejs_buffer(ctx, 0);              /* index 1 */
	setup_nodejs_buffer_slice(ctx, 0, 1, 4);  /* index 2 */
	setup_nodejs_buffer_slice(ctx, 0, 3, 7);  /* index 3 */
	setup_nodejs_buffer_slice(ctx, 0, 6, 9);  /* index 4 */
	duk_push_string(ctx, "");                 /* index 5 */
	duk_push_string(ctx, "fo");               /* index 6 */
	duk_push_string(ctx, "bar");              /* index 7 */
	duk_push_string(ctx, "quux");             /* index 8 */

	for (i = 10; i >= 0; i--) {
		duk_resize_buffer(ctx, 0, i);

		/* The resulting buffers are not printed here; they're not very
		 * intuitive because both the source and the destination share
		 * the same underlying buffer.
		 */

		for (dst = 1; dst <= 4; dst++) {
			for (src = 5; src <= 8; src++) {
				printf("%d %d %d\n", i, dst, src);
				duk_eval_string(ctx,
					"(function (dst, src) {\n"
					"    for (var i = 0; i < dst.length; i++) { dst[i] = 0x11; }\n"
					"    dst.write(src);\n"
					"    for (var i = 0; i < dst.length; i++) { dst[i] = 0x11; }\n"
					"    dst.write(src, 1);\n"
					"})");
				duk_dup(ctx, dst);
				duk_dup(ctx, src);
				duk_call(ctx, 2);
				duk_pop(ctx);
			}
		}
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
static duk_ret_t test_json_serialize_1(duk_context *ctx, void *udata) {
	unsigned char *data;
	int i;
	duk_uarridx_t arridx = 0;

	(void) udata;

	data = (unsigned char *) duk_push_dynamic_buffer(ctx, 20);
	for (i = 0; i < 20; i++) {
		data[i] = 0x40 + i;
	}

	duk_push_array(ctx);  /* index 1 */
	setup_duktape_buffer(ctx, 0);
	duk_put_prop_index(ctx, 1, arridx++);
	setup_nodejs_buffer(ctx, 0);
	duk_put_prop_index(ctx, 1, arridx++);
	setup_nodejs_buffer_slice(ctx, 0, 3, 5);
	duk_put_prop_index(ctx, 1, arridx++);
	setup_arraybuffer(ctx, 0);
	duk_put_prop_index(ctx, 1, arridx++);
	setup_typedarray(ctx, 0, "Uint8Array");
	duk_put_prop_index(ctx, 1, arridx++);
	setup_typedarray_slice(ctx, 0, "Uint8Array", 2, 6);
	duk_put_prop_index(ctx, 1, arridx++);
	setup_typedarray(ctx, 0, "Uint32Array");
	duk_put_prop_index(ctx, 1, arridx++);
	setup_typedarray_slice(ctx, 0, "Uint32Array", 4, 1);
	duk_put_prop_index(ctx, 1, arridx++);

	/* Serialize with a full backing buffer first. */

	for (i = 20; i >= 0; i--) {
		printf("resize to %d\n", i);
		duk_resize_buffer(ctx, 0, i);

		duk_dup(ctx, 1);
		duk_json_encode(ctx, -1);
		printf("%s\n", duk_to_string(ctx, -1));
		duk_pop(ctx);
		duk_eval_string(ctx, "(function (v) { print(Duktape.enc('jx', v)); })");
		duk_dup(ctx, 1);
		duk_call(ctx, 1);
		duk_pop(ctx);
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
示例#12
0
/* Underlying buffer doesn't cover logical slice. */
static duk_ret_t test_uncovered_buffer(duk_context *ctx) {
	unsigned char *p;
	duk_size_t sz;

	duk_push_dynamic_buffer(ctx, 64);  /* 16x4 elements */

	duk_eval_string(ctx,
		"(function (plain_buffer) {\n"
		"    var b = new ArrayBuffer(plain_buffer);\n"
		"    return new Uint32Array(b).subarray(1,5);\n"
		"})");
	duk_dup(ctx, 0);
	duk_call(ctx, 1);  /* -> [ plain_buffer Uint32Array ] */

	/* Initially OK. */
	sz = (duk_size_t) 0xdeadbeefUL;
	p = duk_get_buffer_data(ctx, -1, &sz);
	if (p) {
		printf("p is not NULL, sz=%ld\n", (long) sz);
	} else {
		printf("p is NULL\n");
	}

	/* Resize; slice still covered. */
	duk_resize_buffer(ctx, 0, 20);  /* 5x4 = 20, subarray is [1*4, 5*4[ */
	sz = (duk_size_t) 0xdeadbeefUL;
	p = duk_get_buffer_data(ctx, -1, &sz);
	if (p) {
		printf("p is not NULL, sz=%ld\n", (long) sz);
	} else {
		printf("p is NULL\n");
	}

	/* Resize; no longer covered. */
	duk_resize_buffer(ctx, 0, 19);
	sz = (duk_size_t) 0xdeadbeefUL;
	p = duk_get_buffer_data(ctx, -1, &sz);
	if (p) {
		printf("p is not NULL, sz=%ld\n", (long) sz);
	} else {
		printf("p is NULL\n");
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
static int test_nodejs_buffer_copy_1(duk_context *ctx) {
	int i, dst, src;
	unsigned char *data;

	data = (unsigned char *) duk_push_dynamic_buffer(ctx, 10);  /* index 0 */
	for (i = 0; i < 10; i++) {
		data[i] = 0x40 + i;
	}

	setup_nodejs_buffer(ctx, 0);
	setup_nodejs_buffer_slice(ctx, 0, 1, 4);
	setup_nodejs_buffer_slice(ctx, 0, 3, 7);
	setup_nodejs_buffer_slice(ctx, 0, 6, 9);

	for (i = 10; i >= 0; i--) {
		duk_resize_buffer(ctx, 0, i);

		/* The resulting buffers are not printed here; they're not very
		 * intuitive because both the source and the destination share
		 * the same underlying buffer.
		 */

		for (dst = 1; dst <= 4; dst++) {
			for (src = 1; src <= 4; src++) {
				printf("%d %d %d\n", i, dst, src);
				duk_eval_string(ctx,
					"(function (dst, src) {\n"
					"    for (var i = 0; i < dst.length; i++) { dst[i] = 0x11; }\n"
					"    for (var i = 0; i < src.length; i++) { src[i] = 0x22; }\n"
					"    src.copy(dst);\n"
					"    for (var i = 0; i < dst.length; i++) { dst[i] = 0x11; }\n"
					"    for (var i = 0; i < src.length; i++) { src[i] = 0x22; }\n"
					"    src.copy(dst, 4, 1);\n"
					"})");
				duk_dup(ctx, dst);
				duk_dup(ctx, src);
				duk_call(ctx, 2);
				duk_pop(ctx);
			}
		}
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
static duk_ret_t test_typedarray_constructor_copy_1(duk_context *ctx, void *udata) {
	int i;
	unsigned char *data;

	(void) udata;

	data = (unsigned char *) duk_push_dynamic_buffer(ctx, 10);  /* index 0 */
	for (i = 0; i < 10; i++) {
		data[i] = 0x40 + i;
	}

	setup_typedarray(ctx, 0, "Uint8Array");  /* index 1 */

	for (i = 10; i >= 0; i--) {
		duk_resize_buffer(ctx, 0, i);

		/* Compatible copy, uses byte copy when buffer is covered. */
		duk_eval_string(ctx,
			"(function (src) {\n"
			"    var buf = new Uint8Array(src);\n"
			"    print(Duktape.enc('jx', buf));\n"
			"})\n");
		duk_dup(ctx, 1);
		duk_call(ctx, 1);
		duk_pop(ctx);

		/* Incompatible copy, uses "fast copy" when buffer is covered.
		 * Endian specific output.
		 */
		duk_eval_string(ctx,
			"(function (src) {\n"
			"    var buf = new Uint16Array(src);\n"
			"    print(Duktape.enc('jx', buf));\n"
			"})\n");
		duk_dup(ctx, 1);
		duk_call(ctx, 1);
		duk_pop(ctx);
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
static void create_escaped_source(duk_hthread *thr, int idx_pattern) {
	duk_context *ctx = (duk_context *) thr;
	duk_hstring *h;
	duk_hbuffer_dynamic *buf;
	const duk_uint8_t *p;
	duk_size_t i, n;
	duk_uint_fast8_t c_prev, c;

	h = duk_get_hstring(ctx, idx_pattern);
	DUK_ASSERT(h != NULL);
	p = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);
	n = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);

	if (n == 0) {
		/* return '(?:)' */
		duk_push_hstring_stridx(ctx, DUK_STRIDX_ESCAPED_EMPTY_REGEXP);
		return;
	}

	duk_push_dynamic_buffer(ctx, 0);
	buf = (duk_hbuffer_dynamic *) duk_get_hbuffer(ctx, -1);
	DUK_ASSERT(buf != NULL);

	c_prev = (duk_uint_fast8_t) 0;

	for (i = 0; i < n; i++) {
		c = p[i];

		if (c == (duk_uint_fast8_t) '/' && c_prev != (duk_uint_fast8_t) '\\') {
			/* Unescaped '/' ANYWHERE in the regexp (in disjunction,
			 * inside a character class, ...) => same escape works.
			 */
			duk_hbuffer_append_byte(thr, buf, (duk_uint8_t) '\\');
		}
		duk_hbuffer_append_byte(thr, buf, (duk_uint8_t) c);

		c_prev = c;
	}

	duk_to_string(ctx, -1);  /* -> [ ... escaped_source ] */
}
/* source: dynamic buffer, target: dynamic buffer */
static duk_ret_t test_2b(duk_context *ctx) {
	unsigned char *p;
	void *q;
	duk_size_t sz;

	duk_set_top(ctx, 0);

	p = (unsigned char *) duk_push_dynamic_buffer(ctx, 16);
	p[0] = 1;
	p[15] = 2;
	dump_buffer(ctx);

	q = duk_to_dynamic_buffer(ctx, -1, &sz);
	printf("q is NULL: %d\n", (q == NULL ? 1 : 0));
	printf("p == q: %d\n", (p == q ? 1 : 0));
	printf("sz=%lu\n", (unsigned long) sz);
	dump_buffer(ctx);

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
static duk_ret_t test_nodejs_buffer_compare_1(duk_context *ctx, void *udata) {
	int i, dst, src;
	unsigned char *data;

	(void) udata;

	/* There are two relevant methods: Buffer.compare and Buffer.prototype.compare() */

	data = (unsigned char *) duk_push_dynamic_buffer(ctx, 10);  /* index 0 */
	for (i = 0; i < 10; i++) {
		data[i] = 0x40 + i;
	}

	setup_nodejs_buffer(ctx, 0);
	setup_nodejs_buffer_slice(ctx, 0, 1, 4);
	setup_nodejs_buffer_slice(ctx, 0, 3, 7);
	setup_nodejs_buffer_slice(ctx, 0, 6, 9);

	for (i = 10; i >= 0; i--) {
		duk_resize_buffer(ctx, 0, i);

		for (dst = 1; dst <= 4; dst++) {
			for (src = 1; src <= 4; src++) {
				printf("%d %d %d\n", i, dst, src);
				duk_eval_string(ctx,
					"(function (dst, src) {\n"
					"    print(Buffer.compare(dst, src), dst.compare(src));\n"
					"})");
				duk_dup(ctx, dst);
				duk_dup(ctx, src);
				duk_call(ctx, 2);
				duk_pop(ctx);
			}
		}
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
示例#18
0
文件: io.c 项目: saghul/sjs
/*
 * Read data from a file. Args:
 * - 0: FILE
 * - 1: nread (a number or a Buffer-ish object)
 */
static duk_ret_t io_fread(duk_context* ctx) {
    FILE* f;
    size_t nread, r;
    char* buf;
    int create_buf = 0;

    f = duk_require_pointer(ctx, 0);
    if (duk_is_number(ctx, 1)) {
        nread = duk_require_int(ctx, 1);
        buf = duk_push_dynamic_buffer(ctx, nread);
        create_buf = 1;
    } else {
        buf = duk_require_buffer_data(ctx, 1, &nread);
        if (buf == NULL || nread == 0) {
            duk_error(ctx, DUK_ERR_TYPE_ERROR, "invalid buffer");
            return -42;    /* control never returns here */
        }
    }

    r = fread(buf, 1, nread, f);
    if (ferror(f)) {
        if (create_buf) {
            duk_pop(ctx);
        }
        clearerr(f);
        SJS_THROW_ERRNO_ERROR2(EIO);
        return -42;    /* control never returns here */
    }

    if (create_buf) {
        /* return the string we read */
        duk_resize_buffer(ctx, -1, r);
    } else {
        /* the data was written to the buffer, return how much we read */
        duk_push_int(ctx, r);
    }

    return 1;
}
static duk_ret_t test_nodejs_buffer_concat_1(duk_context *ctx, void *udata) {
	int i;
	unsigned char *data;

	(void) udata;

	data = (unsigned char *) duk_push_dynamic_buffer(ctx, 10);  /* index 0 */
	for (i = 0; i < 10; i++) {
		data[i] = 0x40 + i;
	}

	setup_nodejs_buffer(ctx, 0);
	setup_nodejs_buffer_slice(ctx, 0, 1, 6);
	setup_nodejs_buffer_slice(ctx, 0, 3, 7);
	setup_nodejs_buffer_slice(ctx, 0, 6, 9);
	setup_nodejs_buffer_slice(ctx, 0, 1, 8);

	for (i = 10; i >= 0; i--) {
		duk_resize_buffer(ctx, 0, i);

		printf("%d\n", i);
		duk_eval_string(ctx,
			"(function (arg1, arg2, arg3, arg4, arg5) {\n"
			"    var res = Buffer.concat([ arg1, arg2, arg3, arg4, arg5 ]);\n"
			"    print(Duktape.enc('jx', res));\n"
			"})");
		duk_dup(ctx, 1);
		duk_dup(ctx, 2);
		duk_dup(ctx, 3);
		duk_dup(ctx, 4);
		duk_dup(ctx, 5);
		duk_call(ctx, 5);
		duk_pop(ctx);
	}

	printf("final top: %ld\n", (long) duk_get_top(ctx));
	return 0;
}
示例#20
0
void test(duk_context *ctx) {
	duk_idx_t i, n;

	duk_push_undefined(ctx);
	duk_push_null(ctx);
	duk_push_boolean(ctx, 0);
	duk_push_boolean(ctx, 123);
	duk_push_number(ctx, 234);
	duk_push_string(ctx, "foo");
	duk_push_object(ctx);
	duk_push_array(ctx);
	duk_push_c_function(ctx, my_c_func, DUK_VARARGS);
	duk_push_fixed_buffer(ctx, 1024);
	duk_push_dynamic_buffer(ctx, 1024);
	duk_push_pointer(ctx, (void *) 0xdeadbeefUL);

	n = duk_get_top(ctx);
	for (i = 0; i < n + 1; i++) {  /* end on invalid index on purpose */
		printf("stack[%ld] --> DUK_TYPE_NUMBER=%ld DUK_TYPE_NONE=%ld\n",
		       (long) i, (long) duk_check_type(ctx, i, DUK_TYPE_NUMBER),
		       (long) duk_check_type(ctx, i, DUK_TYPE_NONE));
	}
}
示例#21
0
duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hbuffer_dynamic *h;
	duk_idx_t i, n;
	duk_ucodepoint_t cp;

	/* XXX: It would be nice to build the string directly but ToUint16()
	 * coercion is needed so a generic helper would not be very
	 * helpful (perhaps coerce the value stack first here and then
	 * build a string from a duk_tval number sequence in one go?).
	 */

	n = duk_get_top(ctx);
	duk_push_dynamic_buffer(ctx, 0);  /* XXX: initial spare size estimate from 'n' */
	h = (duk_hbuffer_dynamic *) duk_get_hbuffer(ctx, -1);

	for (i = 0; i < n; i++) {
		cp = duk_to_uint16(ctx, i);
		duk_hbuffer_append_cesu8(thr, h, cp);
	}

	duk_to_string(ctx, -1);
	return 1;
}
void test(duk_context *ctx) {
	char *buf1, *buf2, *buf3;
	duk_idx_t i, j, n;

	duk_push_undefined(ctx);
	duk_push_null(ctx);
	duk_push_true(ctx);
	duk_push_false(ctx);
	duk_push_number(ctx, -INFINITY);
	duk_push_number(ctx, -123.0);
	duk_push_number(ctx, -0.0);
	duk_push_number(ctx, +0.0);
	duk_push_number(ctx, +123.0);
	duk_push_number(ctx, +INFINITY);

	duk_push_number(ctx, NAN);
	duk_push_string(ctx, "");
	duk_push_string(ctx, "foo");
	duk_push_string(ctx, "bar");
	duk_push_object(ctx);
	duk_push_array(ctx);
	(void) duk_push_fixed_buffer(ctx, 0);
	buf1 = (char *) duk_push_fixed_buffer(ctx, 3);
	buf1[0] = 'f';  buf1[1] = 'o'; buf1[2] = 'o';
	buf2 = (char *) duk_push_dynamic_buffer(ctx, 3);
	buf2[0] = 'f';  buf2[1] = 'o'; buf2[2] = 'o';
	buf3 = (char *) duk_push_dynamic_buffer(ctx, 3);
	buf3[0] = 'b';  buf3[1] = 'a'; buf3[2] = 'r';

	duk_push_pointer(ctx, NULL);
	duk_push_pointer(ctx, (void *) 0xdeadbeef);

	n = duk_get_top(ctx);
	for (i = 0; i < n; i++) {
		duk_dup(ctx, i);
		printf("index %ld -> type %d, value '%s'\n", (long) i,
		       (int) duk_get_type(ctx, i), duk_to_string(ctx, -1));
		duk_pop(ctx);
	}

	for (i = 0; i <= n + 1; i++) {
		for (j = 0; j <= n + 1; j++) {
			duk_idx_t idx1, idx2;
			duk_bool_t eq, seq;

			/* Note: i and j run up to 'n + 1' (invalid index) on purpose. */
			idx1 = (i == n + 1 ? DUK_INVALID_INDEX : i);
			idx2 = (j == n + 1 ? DUK_INVALID_INDEX : j);

			eq = duk_equals(ctx, i, j);
			seq = duk_strict_equals(ctx, i, j);

			/* Print nothing if neither equality is true */
			if (!eq && !seq) {
				continue;
			}

			if (idx1 == DUK_INVALID_INDEX) {
				printf("DUK_INVALID_INDEX");
			} else {
				printf("%ld", (long) idx1);
			}
			printf(" vs. ");
			if (idx2 == DUK_INVALID_INDEX) {
				printf("DUK_INVALID_INDEX");
			} else {
				printf("%ld", (long) idx2);
			}
			printf(" -> equals=%d, strict_equals=%d\n", (int) eq, (int) seq);
		}
	}
}
//void *duk_push_dynamic_buffer(duk_context *ctx, duk_size_t size);
void *aperl_duk_push_dynamic_buffer(duk_context *ctx, duk_size_t size) {
	void *ret = duk_push_dynamic_buffer(ctx, size);
	return ret;
}
示例#24
0
int test_1(duk_context *ctx) {
	int 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_number(ctx, 123.456);
	duk_push_number(ctx, -123.456);
	duk_push_number(ctx, 123.999);
	duk_push_number(ctx, -123.999);
	duk_push_nan(ctx);
	duk_push_number(ctx, INFINITY);
	duk_push_string(ctx, "");
	duk_push_string(ctx, "foo");
	duk_push_string(ctx, "123");
	duk_push_string(ctx, "123.456");
	duk_push_string(ctx, "123.456e3");
	duk_push_string(ctx, "  -123.456e+3  ");
	duk_push_string(ctx, "NaN");
	duk_push_string(ctx, "-Infinity");
	duk_push_string(ctx, "+Infinity");
	duk_push_string(ctx, "Infinity");
	duk_push_string(ctx, "Infinityx");
	duk_push_string(ctx, "xInfinity");
	duk_push_string(ctx, "  Infinity  ");
	duk_push_object(ctx);
	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: %d\n", n);
	for (i = 0; i < n; i++) {
		double dval_pre;
		double dval_post;
		int ival;

		dval_pre = duk_get_number(ctx, i);  /* number before ToInteger() coercion */
		ival = duk_to_int(ctx, i);
		dval_post = duk_get_number(ctx, i);      /* number after ToInteger() coercion */
		printf("index %d, ", i);
		if (ival == INT_MIN) {
			printf("int: INT_MIN");
		} else if (ival == INT_MAX) {
			printf("int: INT_MAX");
		} else {
			printf("int: %d", ival);
		}
		printf(", number before: %lf, number after: %lf\n", dval_pre, dval_post);
	}

	return 0;
}
void duk_regexp_compile(duk_hthread *thr) {
	duk_context *ctx = (duk_context *) thr;
	duk_re_compiler_ctx re_ctx;
	duk_lexer_point lex_point;
	duk_hstring *h_pattern;
	duk_hstring *h_flags;
	duk_hbuffer_dynamic *h_buffer;

	DUK_ASSERT(thr != NULL);
	DUK_ASSERT(ctx != NULL);

	/*
	 *  Args validation
	 */

	/* TypeError if fails */
	h_pattern = duk_require_hstring(ctx, -2);
	h_flags = duk_require_hstring(ctx, -1);

	/*
	 *  Create normalized 'source' property (E5 Section 15.10.3).
	 */

	/* [ ... pattern flags ] */

	create_escaped_source(thr, -2);

	/* [ ... pattern flags escaped_source ] */

	/*
	 *  Init compilation context
	 */

	duk_push_dynamic_buffer(ctx, 0);
	h_buffer = (duk_hbuffer_dynamic *) duk_require_hbuffer(ctx, -1);
	DUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buffer));

	/* [ ... pattern flags escaped_source buffer ] */

	DUK_MEMSET(&re_ctx, 0, sizeof(re_ctx));
	DUK_LEXER_INITCTX(&re_ctx.lex);  /* duplicate zeroing, expect for (possible) NULL inits */
	re_ctx.thr = thr;
	re_ctx.lex.thr = thr;
	re_ctx.lex.input = DUK_HSTRING_GET_DATA(h_pattern);
	re_ctx.lex.input_length = DUK_HSTRING_GET_BYTELEN(h_pattern);
	re_ctx.buf = h_buffer;
	re_ctx.recursion_limit = DUK_RE_COMPILE_RECURSION_LIMIT;
	re_ctx.re_flags = parse_regexp_flags(thr, h_flags);

	DUK_DDPRINT("regexp compiler ctx initialized, flags=0x%08x, recursion_limit=%d",
	            (unsigned int) re_ctx.re_flags, (int) re_ctx.recursion_limit);

	/*
	 *  Init lexer
	 */

	lex_point.offset = 0;		/* expensive init, just want to fill window */
	lex_point.line = 1;
	DUK_LEXER_SETPOINT(&re_ctx.lex, &lex_point);

	/*
	 *  Compilation
	 */

	DUK_DPRINT("starting regexp compilation");

	append_u32(&re_ctx, DUK_REOP_SAVE);
	append_u32(&re_ctx, 0);
	(void) parse_disjunction(&re_ctx, 1);  /* 1 = expect eof */
	append_u32(&re_ctx, DUK_REOP_SAVE);
	append_u32(&re_ctx, 1);
	append_u32(&re_ctx, DUK_REOP_MATCH);

	DUK_DPRINT("regexp bytecode size (before header) is %d bytes",
	           (int) DUK_HBUFFER_GET_SIZE(re_ctx.buf));

	/*
	 *  Check for invalid backreferences; note that it is NOT an error
	 *  to back-reference a capture group which has not yet been introduced
	 *  in the pattern (as in /\1(foo)/); in fact, the backreference will
	 *  always match!  It IS an error to back-reference a capture group
	 *  which will never be introduced in the pattern.  Thus, we can check
	 *  for such references only after parsing is complete.
	 */

	if (re_ctx.highest_backref > re_ctx.captures) {
		DUK_ERROR(thr, DUK_ERR_SYNTAX_ERROR, "invalid backreference(s)");
	}

	/*
	 *  Emit compiled regexp header: flags, ncaptures
	 *  (insertion order inverted on purpose)
	 */

	insert_u32(&re_ctx, 0, (re_ctx.captures + 1) * 2);
	insert_u32(&re_ctx, 0, re_ctx.re_flags);

	DUK_DPRINT("regexp bytecode size (after header) is %d bytes",
	           (int) DUK_HBUFFER_GET_SIZE(re_ctx.buf));
	DUK_DDDPRINT("compiled regexp: %!xO", re_ctx.buf);

	/* [ ... pattern flags escaped_source buffer ] */

	duk_to_string(ctx, -1);  /* coerce to string */

	/* [ ... pattern flags escaped_source bytecode ] */

	/*
	 *  Finalize stack
	 */

	duk_remove(ctx, -4);     /* -> [ ... flags escaped_source bytecode ] */
	duk_remove(ctx, -3);     /* -> [ ... escaped_source bytecode ] */

	DUK_DPRINT("regexp compilation successful, bytecode: %!T, escaped source: %!T",
	           duk_get_tval(ctx, -1), duk_get_tval(ctx, -2));
}
示例#26
0
void test(duk_context *ctx) {
	int i, n;

	/* 0 */
	duk_push_string(ctx, "foo");

	/* 1 */
	duk_push_string(ctx, "\xe1\x88\xb4xyz");  /* 4 chars, first char utf-8 encoded U+1234 */

	/* 2 */
	duk_push_object(ctx);  /* no length property */

	/* 3 */
	duk_push_object(ctx);  /* length: 123 */
	duk_push_int(ctx, 123);
	duk_put_prop_string(ctx, -2, "length");

	/* 4 */
	duk_push_object(ctx);  /* length: "bar" */
	duk_push_string(ctx, "bar");
	duk_put_prop_string(ctx, -2, "length");

	/* 5 */
	duk_push_object(ctx);  /* length: 123.9, fractional number */
	duk_push_number(ctx, 123.9);
	duk_put_prop_string(ctx, -2, "length");

	/* 6 */
	duk_push_object(ctx);  /* length: negative but within 32-bit range after ToInteger() */
	duk_push_number(ctx, -0.9);
	duk_put_prop_string(ctx, -2, "length");

	/* 7 */
	duk_push_object(ctx);  /* length: negative, outside 32-bit range */
	duk_push_number(ctx, -1);
	duk_put_prop_string(ctx, -2, "length");

	/* 8 */
	duk_push_object(ctx);  /* length: outside 32-bit range but within range after ToInteger() */
	duk_push_number(ctx, 4294967295.9);
	duk_put_prop_string(ctx, -2, "length");

	/* 9 */
	duk_push_object(ctx);  /* length: outside 32-bit range */
	duk_push_number(ctx, 4294967296);
	duk_put_prop_string(ctx, -2, "length");

	/* 10 */
	duk_push_object(ctx);  /* length: nan */
	duk_push_nan(ctx);
	duk_put_prop_string(ctx, -2, "length");

	/* 11 */
	duk_push_object(ctx);  /* length: +Infinity */
	duk_push_number(ctx, INFINITY);
	duk_put_prop_string(ctx, -2, "length");

	/* 12 */
	duk_push_object(ctx);  /* length: -Infinity */
	duk_push_number(ctx, -INFINITY);
	duk_put_prop_string(ctx, -2, "length");

	/* 13 */
	duk_push_fixed_buffer(ctx, 1234);

	/* 14 */
	duk_push_dynamic_buffer(ctx, 2345);

	/* 15 */
	duk_push_undefined(ctx);

	/* 16 */
	duk_push_null(ctx);

	/* 17 */
	duk_push_true(ctx);

	/* 18 */
	duk_push_false(ctx);

	n = duk_get_top(ctx);
	printf("top: %d\n", n);
	for (i = 0; i < n; i++) {
		printf("index %d: length %u\n", i, (unsigned int) duk_get_length(ctx, i));
	}
}
示例#27
0
duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hstring *h_input;
	duk_hstring *h_repl;
	duk_hstring *h_match;
	duk_hstring *h_search;
	duk_hobject *h_re;
	duk_hbuffer_dynamic *h_buf;
#ifdef DUK_USE_REGEXP_SUPPORT
	duk_small_int_t is_regexp;
	duk_small_int_t is_global;
#endif
	duk_small_int_t is_repl_func;
	duk_uint32_t match_start_coff, match_start_boff;
#ifdef DUK_USE_REGEXP_SUPPORT
	duk_small_int_t match_caps;
#endif
	duk_uint32_t prev_match_end_boff;
	duk_uint8_t *r_start, *r_end, *r;   /* repl string scan */

	DUK_ASSERT_TOP(ctx, 2);
	h_input = duk_push_this_coercible_to_string(ctx);
	DUK_ASSERT(h_input != NULL);
	duk_push_dynamic_buffer(ctx, 0);
	h_buf = (duk_hbuffer_dynamic *) duk_get_hbuffer(ctx, -1);
	DUK_ASSERT(h_buf != NULL);
	DUK_ASSERT_TOP(ctx, 4);

	/* stack[0] = search value
	 * stack[1] = replace value
	 * stack[2] = input string
	 * stack[3] = result buffer
	 */

	h_re = duk_get_hobject_with_class(ctx, 0, DUK_HOBJECT_CLASS_REGEXP);
	if (h_re) {
#ifdef DUK_USE_REGEXP_SUPPORT
		is_regexp = 1;
		is_global = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_GLOBAL, NULL);

		if (is_global) {
			/* start match from beginning */
			duk_push_int(ctx, 0);
			duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LAST_INDEX);
		}
#else  /* DUK_USE_REGEXP_SUPPORT */
		return DUK_RET_UNSUPPORTED_ERROR;
#endif  /* DUK_USE_REGEXP_SUPPORT */
	} else {
		duk_to_string(ctx, 0);
#ifdef DUK_USE_REGEXP_SUPPORT
		is_regexp = 0;
		is_global = 0;
#endif
	}

	if (duk_is_function(ctx, 1)) {
		is_repl_func = 1;
		r_start = NULL;
		r_end = NULL;
	} else {
		is_repl_func = 0;
		h_repl = duk_to_hstring(ctx, 1);
		DUK_ASSERT(h_repl != NULL);
		r_start = DUK_HSTRING_GET_DATA(h_repl);
		r_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl);
	}

	prev_match_end_boff = 0;

	for (;;) {
		/*
		 *  If matching with a regexp:
		 *    - non-global RegExp: lastIndex not touched on a match, zeroed
		 *      on a non-match
		 *    - global RegExp: on match, lastIndex will be updated by regexp
		 *      executor to point to next char after the matching part (so that
		 *      characters in the matching part are not matched again)
		 *
		 *  If matching with a string:
		 *    - always non-global match, find first occurrence
		 *
		 *  We need:
		 *    - The character offset of start-of-match for the replacer function
		 *    - The byte offsets for start-of-match and end-of-match to implement
		 *      the replacement values $&, $`, and $', and to copy non-matching
		 *      input string portions (including header and trailer) verbatim.
		 *
		 *  NOTE: the E5.1 specification is a bit vague how the RegExp should
		 *  behave in the replacement process; e.g. is matching done first for
		 *  all matches (in the global RegExp case) before any replacer calls
		 *  are made?  See: test-bi-string-proto-replace.js for discussion.
		 */

		DUK_ASSERT_TOP(ctx, 4);

#ifdef DUK_USE_REGEXP_SUPPORT
		if (is_regexp) {
			duk_dup(ctx, 0);
			duk_dup(ctx, 2);
			duk_regexp_match(thr);  /* [ ... regexp input ] -> [ res_obj ] */
			if (!duk_is_object(ctx, -1)) {
				duk_pop(ctx);
				break;
			}

			duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INDEX);
			DUK_ASSERT(duk_is_number(ctx, -1));
			match_start_coff = duk_get_int(ctx, -1);
			duk_pop(ctx);

			duk_get_prop_index(ctx, -1, 0);
			DUK_ASSERT(duk_is_string(ctx, -1));
			h_match = duk_get_hstring(ctx, -1);
			DUK_ASSERT(h_match != NULL);
			duk_pop(ctx);  /* h_match is borrowed, remains reachable through match_obj */

			if (DUK_HSTRING_GET_BYTELEN(h_match) == 0) {
				/* This should be equivalent to match() algorithm step 8.f.iii.2:
				 * detect an empty match and allow it, but don't allow it twice.
				 */
				duk_uint32_t last_index;

				duk_get_prop_stridx(ctx, 0, DUK_STRIDX_LAST_INDEX);
				last_index = duk_get_int(ctx, -1);  /* FIXME: duk_get_uint32() */
				DUK_DDD(DUK_DDDPRINT("empty match, bump lastIndex: %d -> %d", last_index, last_index + 1));
				duk_pop(ctx);
				duk_push_int(ctx, last_index + 1);
				duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LAST_INDEX);
			}

			match_caps = duk_get_length(ctx, -1);
		} else {
#else  /* DUK_USE_REGEXP_SUPPORT */
		{  /* unconditionally */
#endif  /* DUK_USE_REGEXP_SUPPORT */
			duk_uint8_t *p_start, *p_end, *p;   /* input string scan */
			duk_uint8_t *q_start;               /* match string */
			duk_size_t q_blen;

#ifdef DUK_USE_REGEXP_SUPPORT
			DUK_ASSERT(!is_global);  /* single match always */
#endif

			p_start = DUK_HSTRING_GET_DATA(h_input);
			p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
			p = p_start;

			h_search = duk_get_hstring(ctx, 0);
			DUK_ASSERT(h_search != NULL);
			q_start = DUK_HSTRING_GET_DATA(h_search);
			q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);

			p_end -= q_blen;  /* ensure full memcmp() fits in while */

			match_start_coff = 0;

			while (p <= p_end) {
				DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));
				if (DUK_MEMCMP((void *) p, (void *) q_start, (size_t) q_blen) == 0) {
					duk_dup(ctx, 0);
					h_match = duk_get_hstring(ctx, -1);
					DUK_ASSERT(h_match != NULL);
#ifdef DUK_USE_REGEXP_SUPPORT
					match_caps = 0;
#endif
					goto found;
				}

				/* track utf-8 non-continuation bytes */
				if ((p[0] & 0xc0) != 0x80) {
					match_start_coff++;
				}
				p++;
			}

			/* not found */
			break;
		}
	 found:

		/* stack[0] = search value
		 * stack[1] = replace value
		 * stack[2] = input string
		 * stack[3] = result buffer
		 * stack[4] = regexp match OR match string
		 */

		match_start_boff = duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);

		duk_hbuffer_append_bytes(thr,
		                         h_buf,
		                         DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,
		                         (size_t) (match_start_boff - prev_match_end_boff));

		prev_match_end_boff = match_start_boff + DUK_HSTRING_GET_BYTELEN(h_match);

		if (is_repl_func) {
			duk_idx_t idx_args;
			duk_hstring *h_repl;

			/* regexp res_obj is at index 4 */

			duk_dup(ctx, 1);
			idx_args = duk_get_top(ctx);

#ifdef DUK_USE_REGEXP_SUPPORT
			if (is_regexp) {
				duk_int_t idx;
				duk_require_stack(ctx, match_caps + 2);
				for (idx = 0; idx < match_caps; idx++) {
					/* match followed by capture(s) */
					duk_get_prop_index(ctx, 4, idx);
				}
			} else {
#else  /* DUK_USE_REGEXP_SUPPORT */
			{  /* unconditionally */
#endif  /* DUK_USE_REGEXP_SUPPORT */
				/* match == search string, by definition */
				duk_dup(ctx, 0);
			}
			duk_push_int(ctx, match_start_coff);
			duk_dup(ctx, 2);

			/* [ ... replacer match [captures] match_char_offset input ] */

			duk_call(ctx, duk_get_top(ctx) - idx_args);
			h_repl = duk_to_hstring(ctx, -1);  /* -> [ ... repl_value ] */
			DUK_ASSERT(h_repl != NULL);
			duk_hbuffer_append_hstring(thr, h_buf, h_repl);
			duk_pop(ctx);  /* repl_value */
		} else {
			r = r_start;

			while (r < r_end) {
				duk_int_t ch1;
				duk_int_t ch2;
#ifdef DUK_USE_REGEXP_SUPPORT
				duk_int_t ch3;
#endif
				duk_size_t left;

				ch1 = *r++;
				if (ch1 != (duk_int_t) '$') {
					goto repl_write;
				}
				left = r_end - r;

				if (left <= 0) {
					goto repl_write;
				}

				ch2 = r[0];
				switch ((duk_small_int_t) ch2) {
				case (duk_int_t) '$': {
					ch1 = (1 << 8) + (duk_int_t) '$';
					goto repl_write;
				}
				case (duk_int_t) '&': {
					duk_hbuffer_append_hstring(thr, h_buf, h_match);
					r++;
					continue;
				}
				case (duk_int_t) '`': {
					duk_hbuffer_append_bytes(thr,
					                         h_buf,
					                         DUK_HSTRING_GET_DATA(h_input),
					                         match_start_boff);
					r++;
					continue;
				}
				case (duk_int_t) '\'': {
					duk_uint32_t match_end_boff;

					/* Use match charlen instead of bytelen, just in case the input and
					 * match codepoint encodings would have different lengths.
					 */
					match_end_boff = duk_heap_strcache_offset_char2byte(thr,
					                                                    h_input,
					                                                    match_start_coff + DUK_HSTRING_GET_CHARLEN(h_match));

					duk_hbuffer_append_bytes(thr,
					                         h_buf,
					                         DUK_HSTRING_GET_DATA(h_input) + match_end_boff,
					                         DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff);
					r++;
					continue;
				}
				default: {
#ifdef DUK_USE_REGEXP_SUPPORT
					duk_int_t capnum, captmp, capadv;
					/* FIXME: optional check, match_caps is zero if no regexp,
					 * so dollar will be interpreted literally anyway.
					 */

					if (!is_regexp) {
						goto repl_write;
					}

					if (!(ch2 >= (duk_int_t) '0' && ch2 <= (duk_int_t) '9')) {
						goto repl_write;
					}
					capnum = ch2 - (duk_int_t) '0';
					capadv = 1;

					if (left >= 2) {
						ch3 = r[1];
						if (ch3 >= (duk_int_t) '0' && ch3 <= (duk_int_t) '9') {
							captmp = capnum * 10 + (ch3 - (duk_int_t) '0');
							if (captmp < match_caps) {
								capnum = captmp;
								capadv = 2;
							}
						}
					}

					if (capnum > 0 && capnum < match_caps) {
						DUK_ASSERT(is_regexp != 0);  /* match_caps == 0 without regexps */

						/* regexp res_obj is at offset 4 */
						duk_get_prop_index(ctx, 4, capnum);
						if (duk_is_string(ctx, -1)) {
							DUK_ASSERT(duk_get_hstring(ctx, -1) != NULL);
							duk_hbuffer_append_hstring(thr, h_buf, duk_get_hstring(ctx, -1));
						} else {
							/* undefined -> skip (replaced with empty) */
						}
						duk_pop(ctx);
						r += capadv;
						continue;
					} else {
						goto repl_write;
					}
#else  /* DUK_USE_REGEXP_SUPPORT */
					goto repl_write;  /* unconditionally */
#endif  /* DUK_USE_REGEXP_SUPPORT */
				}  /* default case */
				}  /* switch (ch2) */

			 repl_write:
				/* ch1 = (r_increment << 8) + byte */
				duk_hbuffer_append_byte(thr, h_buf, (duk_uint8_t) (ch1 & 0xff));
				r += ch1 >> 8;
			}  /* while repl */
		}  /* if (is_repl_func) */

		duk_pop(ctx);  /* pop regexp res_obj or match string */

#ifdef DUK_USE_REGEXP_SUPPORT
		if (!is_global) {
#else
		{  /* unconditionally; is_global==0 */
#endif
			break;
		}
	}

	/* trailer */
	duk_hbuffer_append_bytes(thr,
	                         h_buf,
	                         DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,
	                         (size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff));

	DUK_ASSERT_TOP(ctx, 4);
	duk_to_string(ctx, -1);
	return 1;
}

/*
 *  split()
 */

/* FIXME: very messy now, but works; clean up, remove unused variables (nomimally
 * used so compiler doesn't complain).
 */

int duk_bi_string_prototype_split(duk_context *ctx) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hstring *h_input;
	duk_hstring *h_sep;
	duk_uint32_t limit;
	duk_uint32_t arr_idx;
#ifdef DUK_USE_REGEXP_SUPPORT
	duk_small_int_t is_regexp;
#endif
	duk_small_int_t matched;  /* set to 1 if any match exists (needed for empty input special case) */
	duk_uint32_t prev_match_end_coff, prev_match_end_boff;
	duk_uint32_t match_start_boff, match_start_coff;
	duk_uint32_t match_end_boff, match_end_coff;

	DUK_UNREF(thr);

	h_input = duk_push_this_coercible_to_string(ctx);
	DUK_ASSERT(h_input != NULL);

	duk_push_array(ctx);

	if (duk_is_undefined(ctx, 1)) {
		limit = 0xffffffffUL;
	} else {
		limit = duk_to_uint32(ctx, 1);
	}

	if (limit == 0) {
		return 1;
	}

	/* If the separator is a RegExp, make a "clone" of it.  The specification
	 * algorithm calls [[Match]] directly for specific indices; we emulate this
	 * by tweaking lastIndex and using a "force global" variant of duk_regexp_match()
	 * which will use global-style matching even when the RegExp itself is non-global.
	 */

	if (duk_is_undefined(ctx, 0)) {
		/* The spec algorithm first does "R = ToString(separator)" before checking
		 * whether separator is undefined.  Since this is side effect free, we can
		 * skip the ToString() here.
		 */
		duk_dup(ctx, 2);
		duk_put_prop_index(ctx, 3, 0);
		return 1;
	} else if (duk_get_hobject_with_class(ctx, 0, DUK_HOBJECT_CLASS_REGEXP) != NULL) {
#ifdef DUK_USE_REGEXP_SUPPORT
		duk_push_hobject(ctx, thr->builtins[DUK_BIDX_REGEXP_CONSTRUCTOR]);
		duk_dup(ctx, 0);
		duk_new(ctx, 1);  /* [ ... RegExp val ] -> [ ... res ] */
		duk_replace(ctx, 0);
		/* lastIndex is initialized to zero by new RegExp() */
		is_regexp = 1;
#else
		return DUK_RET_UNSUPPORTED_ERROR;
#endif
	} else {
		duk_to_string(ctx, 0);
#ifdef DUK_USE_REGEXP_SUPPORT
		is_regexp = 0;
#endif
	}

	/* stack[0] = separator (string or regexp)
	 * stack[1] = limit
	 * stack[2] = input string
	 * stack[3] = result array
	 */

	prev_match_end_boff = 0;
	prev_match_end_coff = 0;
	arr_idx = 0;
	matched = 0;

	for (;;) {
		/*
		 *  The specification uses RegExp [[Match]] to attempt match at specific
		 *  offsets.  We don't have such a primitive, so we use an actual RegExp
		 *  and tweak lastIndex.  Since the RegExp may be non-global, we use a
		 *  special variant which forces global-like behavior for matching.
		 */

		DUK_ASSERT_TOP(ctx, 4);

#ifdef DUK_USE_REGEXP_SUPPORT
		if (is_regexp) {
			duk_dup(ctx, 0);
			duk_dup(ctx, 2);
			duk_regexp_match_force_global(thr);  /* [ ... regexp input ] -> [ res_obj ] */
			if (!duk_is_object(ctx, -1)) {
				duk_pop(ctx);
				break;
			}
			matched = 1;

			duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INDEX);
			DUK_ASSERT(duk_is_number(ctx, -1));
			match_start_coff = duk_get_int(ctx, -1);
			match_start_boff = duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);
			duk_pop(ctx);

			if (match_start_coff == DUK_HSTRING_GET_CHARLEN(h_input)) {
				/* don't allow an empty match at the end of the string */
				duk_pop(ctx);
				break;
			}

			duk_get_prop_stridx(ctx, 0, DUK_STRIDX_LAST_INDEX);
			DUK_ASSERT(duk_is_number(ctx, -1));
			match_end_coff = duk_get_int(ctx, -1);
			match_end_boff = duk_heap_strcache_offset_char2byte(thr, h_input, match_end_coff);
			duk_pop(ctx);

			/* empty match -> bump and continue */
			if (prev_match_end_boff == match_end_boff) {
				duk_push_int(ctx, match_end_coff + 1);
				duk_put_prop_stridx(ctx, 0, DUK_STRIDX_LAST_INDEX);
				duk_pop(ctx);
				continue;
			}
		} else {
#else  /* DUK_USE_REGEXP_SUPPORT */
		{  /* unconditionally */
#endif  /* DUK_USE_REGEXP_SUPPORT */
			duk_uint8_t *p_start, *p_end, *p;   /* input string scan */
			duk_uint8_t *q_start;               /* match string */
			duk_size_t q_blen, q_clen;

			p_start = DUK_HSTRING_GET_DATA(h_input);
			p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
			p = p_start + prev_match_end_boff;

			h_sep = duk_get_hstring(ctx, 0);
			DUK_ASSERT(h_sep != NULL);
			q_start = DUK_HSTRING_GET_DATA(h_sep);
			q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sep);
			q_clen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_sep);

			p_end -= q_blen;  /* ensure full memcmp() fits in while */

			match_start_coff = prev_match_end_coff;

			if (q_blen == 0) {
				/* Handle empty separator case: it will always match, and always
				 * triggers the check in step 13.c.iii initially.  Note that we
				 * must skip to either end of string or start of first codepoint,
				 * skipping over any continuation bytes!
				 *
				 * Don't allow an empty string to match at the end of the input.
				 */

				matched = 1;  /* empty separator can always match */

				match_start_coff++;
				p++;
				while (p < p_end) {
					if ((p[0] & 0xc0) != 0x80) {
						goto found;
					}
					p++;
				}
				goto not_found;
			}

			DUK_ASSERT(q_blen > 0 && q_clen > 0);
			while (p <= p_end) {
				DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));
				DUK_ASSERT(q_blen > 0);  /* no issues with empty memcmp() */
				if (DUK_MEMCMP((void *) p, (void *) q_start, (size_t) q_blen) == 0) {
					/* never an empty match, so step 13.c.iii can't be triggered */
					goto found;
				}

				/* track utf-8 non-continuation bytes */
				if ((p[0] & 0xc0) != 0x80) {
					match_start_coff++;
				}
				p++;
			}

		 not_found:
			/* not found */
			break;

		 found:
			matched = 1;
			match_start_boff = (duk_uint32_t) (p - p_start);
			match_end_coff = match_start_coff + q_clen;
			match_end_boff = match_start_boff + q_blen;

			/* empty match (may happen with empty separator) -> bump and continue */
			if (prev_match_end_boff == match_end_boff) {
				prev_match_end_boff++;
				prev_match_end_coff++;
				continue;
			}
		}  /* if (is_regexp) */

		/* stack[0] = separator (string or regexp)
		 * stack[1] = limit
		 * stack[2] = input string
		 * stack[3] = result array
		 * stack[4] = regexp res_obj (if is_regexp)
		 */

		DUK_DDD(DUK_DDDPRINT("split; match_start b=%d,c=%d, match_end b=%d,c=%d, prev_end b=%d,c=%d",
		                     (int) match_start_boff, (int) match_start_coff,
		                     (int) match_end_boff, (int) match_end_coff,
		                     (int) prev_match_end_boff, (int) prev_match_end_coff));

		duk_push_lstring(ctx,
		                 (const char *) (DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff),
		                 (size_t) (match_start_boff - prev_match_end_boff));
		duk_put_prop_index(ctx, 3, arr_idx);
		arr_idx++;
		if (arr_idx >= limit) {
			goto hit_limit;
		}

#ifdef DUK_USE_REGEXP_SUPPORT
		if (is_regexp) {
			duk_size_t i, len;

			len = duk_get_length(ctx, 4);
			for (i = 1; i < len; i++) {
				duk_get_prop_index(ctx, 4, i);
				duk_put_prop_index(ctx, 3, arr_idx);
				arr_idx++;
				if (arr_idx >= limit) {
					goto hit_limit;
				}
			}

			duk_pop(ctx);
			/* lastIndex already set up for next match */
		} else {
#else  /* DUK_USE_REGEXP_SUPPORT */
		{  /* unconditionally */
#endif  /* DUK_USE_REGEXP_SUPPORT */
			/* no action */
		}

		prev_match_end_boff = match_end_boff;
		prev_match_end_coff = match_end_coff;
		continue;
	}  /* for */

	/* Combined step 11 (empty string special case) and 14-15. */

	DUK_DDD(DUK_DDDPRINT("split trailer; prev_end b=%d,c=%d",
	                     (int) prev_match_end_boff, (int) prev_match_end_coff));

	if (DUK_HSTRING_GET_CHARLEN(h_input) > 0 || !matched) {
		/* Add trailer if:
		 *   a) non-empty input
		 *   b) empty input and no (zero size) match found (step 11)
		 */

		duk_push_lstring(ctx,
		                 (const char *) DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,
		                 (size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff));
		duk_put_prop_index(ctx, 3, arr_idx);
		/* No arr_idx update or limit check */
	}

	return 1;

 hit_limit:
#ifdef DUK_USE_REGEXP_SUPPORT
	if (is_regexp) {
		duk_pop(ctx);
	}
#endif

	return 1;
}

/*
 *  Various
 */

#ifdef DUK_USE_REGEXP_SUPPORT
static void duk__to_regexp_helper(duk_context *ctx, duk_idx_t index, int force_new) {
	duk_hthread *thr = (duk_hthread *) ctx;
	duk_hobject *h;

	/* Shared helper for match() steps 3-4, search() steps 3-4. */

	DUK_ASSERT(index >= 0);

	if (force_new) {
		goto do_new;
	}

	h = duk_get_hobject_with_class(ctx, index, DUK_HOBJECT_CLASS_REGEXP);
	if (!h) {
		goto do_new;
	}
	return;

 do_new:
	duk_push_hobject(ctx, thr->builtins[DUK_BIDX_REGEXP_CONSTRUCTOR]);
	duk_dup(ctx, index);
	duk_new(ctx, 1);  /* [ ... RegExp val ] -> [ ... res ] */
	duk_replace(ctx, index);
}
#endif  /* DUK_USE_REGEXP_SUPPORT */

#ifdef DUK_USE_REGEXP_SUPPORT
duk_ret_t duk_bi_string_prototype_search(duk_context *ctx) {
	duk_hthread *thr = (duk_hthread *) ctx;

	/* Easiest way to implement the search required by the specification
	 * is to do a RegExp test() with lastIndex forced to zero.  To avoid
	 * side effects on the argument, "clone" the RegExp if a RegExp was
	 * given as input.
	 *
	 * The global flag of the RegExp should be ignored; setting lastIndex
	 * to zero (which happens when "cloning" the RegExp) should have an
	 * equivalent effect.
	 */

	DUK_ASSERT_TOP(ctx, 1);
	(void) duk_push_this_coercible_to_string(ctx);  /* at index 1 */
	duk__to_regexp_helper(ctx, 0 /*index*/, 1 /*force_new*/);

	/* stack[0] = regexp
	 * stack[1] = string
	 */

	/* Avoid using RegExp.prototype methods, as they're writable and
	 * configurable and may have been changed.
	 */

	duk_dup(ctx, 0);
	duk_dup(ctx, 1);  /* [ ... re_obj input ] */
	duk_regexp_match(thr);  /* -> [ ... res_obj ] */

	if (!duk_is_object(ctx, -1)) {
		duk_push_int(ctx, -1);
		return 1;
	}

	duk_get_prop_stridx(ctx, -1, DUK_STRIDX_INDEX);
	DUK_ASSERT(duk_is_number(ctx, -1));
	return 1;
}
#else  /* DUK_USE_REGEXP_SUPPORT */
duk_ret_t duk_bi_string_prototype_search(duk_context *ctx) {
	DUK_UNREF(ctx);
	return DUK_RET_UNSUPPORTED_ERROR;
}
示例#28
0
static duk_ret_t test_1(duk_context *ctx) {
	duk_int_t i, j, n;
	char *ptr;

	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, 1);
	duk_push_number(ctx, -123.456);
	duk_push_nan(ctx);
	duk_push_number(ctx, INFINITY);
	duk_push_number(ctx, -INFINITY);
	duk_push_string(ctx, "");
	duk_push_string(ctx, "foo");
	duk_push_lstring(ctx, "foo\0bar", 7);
	duk_push_object(ctx);
	duk_push_thread(ctx);
	(void) duk_push_fixed_buffer(ctx, 0);
	ptr = (char *) duk_push_fixed_buffer(ctx, 16);
	for (i = 0; i < 16; i++) {
		ptr[i] = (char) ('a' + i);
	}
	(void) duk_push_dynamic_buffer(ctx, 0);
	ptr = (char *) duk_push_dynamic_buffer(ctx, 16);
	for (i = 0; i < 16; i++) {
		ptr[i] = (char) ('a' + i);
	}
	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++) {
		const unsigned char *p;
		duk_size_t sz;

		duk_dup(ctx, i);
		sz = (duk_size_t) 0xdeadbeef;
		p = (const unsigned char *) duk_to_lstring(ctx, -1, &sz);
		printf("index %ld, string: '", (long) i);
		for (j = 0; j < sz; j++) {
			if (p[j] >= 0x20 && p[j] <= 0x7e) {
				printf("%c", (int) p[j]);
			} else {
				printf("\\x%02x", (int) p[j]);
			}
		}
		printf("', length %lu\n", (unsigned long) sz);
		duk_pop(ctx);

		duk_dup(ctx, i);
		sz = (duk_size_t) 0xdeadbeef;
		p = (const unsigned char *) duk_to_lstring(ctx, -1, NULL);
		printf("index %ld, string: '%s'\n", (long) i, (const char *) p);
		duk_pop(ctx);
	}

	return 0;
}
示例#29
0
static duk_ret_t test_func(duk_context *ctx, void *udata) {
	(void) udata;

	if (ctx) {
		printf("dummy - return here\n"); fflush(stdout);
		return 0;
	}

	/* Up-to-date for Duktape 1.3.0, alphabetical order:
	 * $ cd website/api; ls *.yaml
	 */

	(void) duk_alloc_raw(ctx, 0);
	(void) duk_alloc(ctx, 0);
	(void) duk_base64_decode(ctx, 0);
	(void) duk_base64_encode(ctx, 0);
	(void) duk_buffer_to_string(ctx, 0);
	(void) duk_call_method(ctx, 0);
	(void) duk_call_prop(ctx, 0, 0);
	(void) duk_call(ctx, 0);
	(void) duk_char_code_at(ctx, 0, 0);
	(void) duk_check_stack_top(ctx, 0);
	(void) duk_check_stack(ctx, 0);
	(void) duk_check_type_mask(ctx, 0, 0);
	(void) duk_check_type(ctx, 0, 0);
	(void) duk_compact(ctx, 0);
	(void) duk_compile_lstring_filename(ctx, 0, "dummy", 0);
	(void) duk_compile_lstring(ctx, 0, "dummy", 0);
	(void) duk_compile_string_filename(ctx, 0, "dummy");
	(void) duk_compile_string(ctx, 0, "dummy");
	(void) duk_compile(ctx, 0);
	(void) duk_concat(ctx, 0);
	(void) duk_config_buffer(ctx, 0, NULL, 0);
	(void) duk_copy(ctx, 0, 0);
	(void) duk_create_heap_default();
	(void) duk_create_heap(NULL, NULL, NULL, NULL, NULL);
	(void) duk_debugger_attach(ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	(void) duk_debugger_cooperate(ctx);
	(void) duk_debugger_detach(ctx);
	(void) duk_debugger_notify(ctx, 0);
	(void) duk_debugger_pause(ctx);
	(void) duk_decode_string(ctx, 0, NULL, NULL);
	(void) duk_def_prop(ctx, 0, 0);
	(void) duk_del_prop_index(ctx, 0, 0);
	(void) duk_del_prop_string(ctx, 0, "dummy");
	(void) duk_del_prop(ctx, 0);
	(void) duk_destroy_heap(ctx);
	(void) duk_dump_function(ctx);
	(void) duk_dup_top(ctx);
	(void) duk_dup(ctx, 0);
	(void) duk_enum(ctx, 0, 0);
	(void) duk_equals(ctx, 0, 0);
	duk_error_va(ctx, 0, NULL, NULL);
	duk_error(ctx, 0, "dummy");  /* (void) cast won't work without variadic macros */
	(void) duk_eval_lstring_noresult(ctx, "dummy", 0);
	(void) duk_eval_lstring(ctx, "dummy", 0);
	(void) duk_eval_noresult(ctx);
	(void) duk_eval_string_noresult(ctx, "dummy");
	(void) duk_eval_string(ctx, "dummy");
	(void) duk_eval(ctx);
	(void) duk_fatal(ctx, "dummy");
	(void) duk_free_raw(ctx, NULL);
	(void) duk_free(ctx, NULL);
	(void) duk_gc(ctx, 0);
	(void) duk_get_boolean(ctx, 0);
	(void) duk_get_buffer_data(ctx, 0, NULL);
	(void) duk_get_buffer(ctx, 0, NULL);
	(void) duk_get_c_function(ctx, 0);
	(void) duk_get_context(ctx, 0);
	(void) duk_get_current_magic(ctx);
	(void) duk_get_error_code(ctx, 0);
	(void) duk_get_finalizer(ctx, 0);
	(void) duk_get_global_string(ctx, 0);
	(void) duk_get_heapptr(ctx, 0);
	(void) duk_get_int(ctx, 0);
	(void) duk_get_length(ctx, 0);
	(void) duk_get_lstring(ctx, 0, NULL);
	(void) duk_get_magic(ctx, 0);
	(void) duk_get_memory_functions(ctx, NULL);
	(void) duk_get_number(ctx, 0);
	(void) duk_get_pointer(ctx, 0);
	(void) duk_get_prop_index(ctx, 0, 0);
	(void) duk_get_prop_string(ctx, 0, "dummy");
	(void) duk_get_prop(ctx, 0);
	(void) duk_get_prototype(ctx, 0);
	(void) duk_get_string(ctx, 0);
	(void) duk_get_top_index(ctx);
	(void) duk_get_top(ctx);
	(void) duk_get_type_mask(ctx, 0);
	(void) duk_get_type(ctx, 0);
	(void) duk_get_uint(ctx, 0);
	(void) duk_has_prop_index(ctx, 0, 0);
	(void) duk_has_prop_string(ctx, 0, "dummy");
	(void) duk_has_prop(ctx, 0);
	(void) duk_hex_decode(ctx, 0);
	(void) duk_hex_encode(ctx, 0);
	(void) duk_insert(ctx, 0);
	(void) duk_instanceof(ctx, 0, 0);
	(void) duk_is_array(ctx, 0);
	(void) duk_is_boolean(ctx, 0);
	(void) duk_is_bound_function(ctx, 0);
	(void) duk_is_buffer(ctx, 0);
	(void) duk_is_callable(ctx, 0);
	(void) duk_is_c_function(ctx, 0);
	(void) duk_is_constructor_call(ctx);
	(void) duk_is_dynamic_buffer(ctx, 0);
	(void) duk_is_ecmascript_function(ctx, 0);
	(void) duk_is_error(ctx, 0);
	(void) duk_is_eval_error(ctx, 0);
	(void) duk_is_fixed_buffer(ctx, 0);
	(void) duk_is_function(ctx, 0);
	(void) duk_is_lightfunc(ctx, 0);
	(void) duk_is_nan(ctx, 0);
	(void) duk_is_null_or_undefined(ctx, 0);
	(void) duk_is_null(ctx, 0);
	(void) duk_is_number(ctx, 0);
	(void) duk_is_object_coercible(ctx, 0);
	(void) duk_is_object(ctx, 0);
	(void) duk_is_pointer(ctx, 0);
	(void) duk_is_primitive(ctx, 0);
	(void) duk_is_range_error(ctx, 0);
	(void) duk_is_reference_error(ctx, 0);
	(void) duk_is_strict_call(ctx);
	(void) duk_is_string(ctx, 0);
	(void) duk_is_syntax_error(ctx, 0);
	(void) duk_is_thread(ctx, 0);
	(void) duk_is_type_error(ctx, 0);
	(void) duk_is_undefined(ctx, 0);
	(void) duk_is_uri_error(ctx, 0);
	(void) duk_is_valid_index(ctx, 0);
	(void) duk_join(ctx, 0);
	(void) duk_json_decode(ctx, 0);
	(void) duk_json_encode(ctx, 0);
	(void) duk_load_function(ctx);
	(void) duk_map_string(ctx, 0, NULL, NULL);
	(void) duk_new(ctx, 0);
	(void) duk_next(ctx, 0, 0);
	(void) duk_normalize_index(ctx, 0);
	(void) duk_pcall_method(ctx, 0);
	(void) duk_pcall_prop(ctx, 0, 0);
	(void) duk_pcall(ctx, 0);
	(void) duk_pcompile_lstring_filename(ctx, 0, "dummy", 0);
	(void) duk_pcompile_lstring(ctx, 0, "dummy", 0);
	(void) duk_pcompile_string_filename(ctx, 0, "dummy");
	(void) duk_pcompile_string(ctx, 0, "dummy");
	(void) duk_pcompile(ctx, 0);
	(void) duk_peval_lstring_noresult(ctx, "dummy", 0);
	(void) duk_peval_lstring(ctx, "dummy", 0);
	(void) duk_peval_noresult(ctx);
	(void) duk_peval_string_noresult(ctx, "dummy");
	(void) duk_peval_string(ctx, "dummy");
	(void) duk_peval(ctx);
	(void) duk_pnew(ctx, 0);
	(void) duk_pop_2(ctx);
	(void) duk_pop_3(ctx);
	(void) duk_pop_n(ctx, 0);
	(void) duk_pop(ctx);
	(void) duk_push_array(ctx);
	(void) duk_push_boolean(ctx, 0);
	(void) duk_push_buffer_object(ctx, 0, 0, 0, 0);
	(void) duk_push_buffer(ctx, 0, 0);
	(void) duk_push_c_function(ctx, NULL, 0);
	(void) duk_push_c_lightfunc(ctx, NULL, 0, 0, 0);
	(void) duk_push_context_dump(ctx);
	(void) duk_push_current_function(ctx);
	(void) duk_push_current_thread(ctx);
	(void) duk_push_dynamic_buffer(ctx, 0);
	(void) duk_push_error_object_va(ctx, 0, NULL, NULL);
	(void) duk_push_error_object(ctx, 0, "dummy");
	(void) duk_push_external_buffer(ctx);
	(void) duk_push_false(ctx);
	(void) duk_push_fixed_buffer(ctx, 0);
	(void) duk_push_global_object(ctx);
	(void) duk_push_global_stash(ctx);
	(void) duk_push_heap_stash(ctx);
	(void) duk_push_heapptr(ctx, NULL);
	(void) duk_push_int(ctx, 0);
	(void) duk_push_lstring(ctx, "dummy", 0);
	(void) duk_push_nan(ctx);
	(void) duk_push_null(ctx);
	(void) duk_push_number(ctx, 0.0);
	(void) duk_push_object(ctx);
	(void) duk_push_pointer(ctx, NULL);
	(void) duk_push_sprintf(ctx, "dummy");
	(void) duk_push_string(ctx, "dummy");
	(void) duk_push_this(ctx);
	(void) duk_push_thread_new_globalenv(ctx);
	(void) duk_push_thread_stash(ctx, NULL);
	(void) duk_push_thread(ctx);
	(void) duk_push_true(ctx);
	(void) duk_push_uint(ctx, 0);
	(void) duk_push_undefined(ctx);
	(void) duk_push_vsprintf(ctx, "dummy", NULL);
	(void) duk_put_function_list(ctx, 0, NULL);
	(void) duk_put_global_string(ctx, NULL);
	(void) duk_put_number_list(ctx, 0, NULL);
	(void) duk_put_prop_index(ctx, 0, 0);
	(void) duk_put_prop_string(ctx, 0, "dummy");
	(void) duk_put_prop(ctx, 0);
	(void) duk_realloc_raw(ctx, NULL, 0);
	(void) duk_realloc(ctx, NULL, 0);
	(void) duk_remove(ctx, 0);
	(void) duk_replace(ctx, 0);
	(void) duk_require_boolean(ctx, 0);
	(void) duk_require_buffer_data(ctx, 0, NULL);
	(void) duk_require_buffer(ctx, 0, NULL);
	(void) duk_require_c_function(ctx, 0);
	(void) duk_require_callable(ctx, 0);
	(void) duk_require_context(ctx, 0);
	(void) duk_require_function(ctx, 0);
	(void) duk_require_heapptr(ctx, 0);
	(void) duk_require_int(ctx, 0);
	(void) duk_require_lstring(ctx, 0, NULL);
	(void) duk_require_normalize_index(ctx, 0);
	(void) duk_require_null(ctx, 0);
	(void) duk_require_number(ctx, 0);
	(void) duk_require_object_coercible(ctx, 0);
	(void) duk_require_pointer(ctx, 0);
	(void) duk_require_stack_top(ctx, 0);
	(void) duk_require_stack(ctx, 0);
	(void) duk_require_string(ctx, 0);
	(void) duk_require_top_index(ctx);
	(void) duk_require_type_mask(ctx, 0, 0);
	(void) duk_require_uint(ctx, 0);
	(void) duk_require_undefined(ctx, 0);
	(void) duk_require_valid_index(ctx, 0);
	(void) duk_resize_buffer(ctx, 0, 0);
	(void) duk_safe_call(ctx, NULL, NULL, 0, 0);
	(void) duk_safe_to_lstring(ctx, 0, NULL);
	(void) duk_safe_to_string(ctx, 0);
	(void) duk_set_finalizer(ctx, 0);
	(void) duk_set_global_object(ctx);
	(void) duk_set_magic(ctx, 0, 0);
	(void) duk_set_prototype(ctx, 0);
	(void) duk_set_top(ctx, 0);
	(void) duk_steal_buffer(ctx, 0, NULL);
	(void) duk_strict_equals(ctx, 0, 0);
	(void) duk_substring(ctx, 0, 0, 0);
	(void) duk_swap_top(ctx, 0);
	(void) duk_swap(ctx, 0, 0);
	(void) duk_throw(ctx);
	(void) duk_to_boolean(ctx, 0);
	(void) duk_to_buffer(ctx, 0, NULL);
	(void) duk_to_defaultvalue(ctx, 0, 0);
	(void) duk_to_dynamic_buffer(ctx, 0, NULL);
	(void) duk_to_fixed_buffer(ctx, 0, NULL);
	(void) duk_to_int32(ctx, 0);
	(void) duk_to_int(ctx, 0);
	(void) duk_to_lstring(ctx, 0, NULL);
	(void) duk_to_null(ctx, 0);
	(void) duk_to_number(ctx, 0);
	(void) duk_to_object(ctx, 0);
	(void) duk_to_pointer(ctx, 0);
	(void) duk_to_primitive(ctx, 0, 0);
	(void) duk_to_string(ctx, 0);
	(void) duk_to_uint16(ctx, 0);
	(void) duk_to_uint32(ctx, 0);
	(void) duk_to_uint(ctx, 0);
	(void) duk_to_undefined(ctx, 0);
	(void) duk_trim(ctx, 0);
	(void) duk_xcopy_top(ctx, NULL, 0);
	(void) duk_xmove_top(ctx, NULL, 0);

	printf("never here\n"); fflush(stdout);
	return 0;
}
示例#30
0
static duk_ret_t test_1(duk_context *ctx, void *udata) {
	duk_size_t i, n;
	char *buf;

	(void) udata;

	duk_set_top(ctx, 0);

	duk_push_undefined(ctx);
	duk_push_null(ctx);
	duk_push_true(ctx);
	duk_push_false(ctx);
	duk_push_nan(ctx);
	duk_push_number(ctx, -INFINITY);
	duk_push_number(ctx, +INFINITY);
	duk_push_number(ctx, -0.0);
	duk_push_number(ctx, +0.0);
	duk_push_int(ctx, 123);

	duk_push_string(ctx, "foo");
	duk_push_lstring(ctx, "foo\0bar", 7);  /* internal NULs are kept */
	duk_push_object(ctx);
	buf = (char *) duk_push_fixed_buffer(ctx, 0);
	buf = (char *) duk_push_fixed_buffer(ctx, 16);
	for (i = 0; i < 16; i++) {
		buf[i] = i;
	}
	buf = (char *) duk_push_dynamic_buffer(ctx, 0);
	buf = (char *) duk_push_dynamic_buffer(ctx, 16);
	for (i = 0; i < 16; i++) {
		buf[i] = i;
	}
	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;
		void *ptr;
		duk_size_t sz;

		duk_dup(ctx, i);
		t1 = duk_get_type(ctx, -1);
		sz = (duk_size_t) 0xdeadbeef;
		ptr = duk_to_buffer(ctx, -1, &sz);
		t2 = duk_get_type(ctx, -1);
		printf("index %ld, type %ld -> %ld, ptr-is-NULL %d, size %lu\n",
		       (long) i, (long) t1, (long) t2,
		       (sz == 0 ? -1 : (ptr == NULL ? 1 : 0)),
		       (unsigned long) sz);
		dump_buffer(ctx);
		duk_pop(ctx);

		/* just check that this doesn't break */
		duk_dup(ctx, i);
		ptr = duk_to_buffer(ctx, -1, NULL);
		duk_pop(ctx);
	}

	return 0;
}