mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.2 KiB
173 lines
4.2 KiB
/*
|
|
* API tests for duk_get_heapptr(), duk_require_heapptr(), duk_push_heapptr().
|
|
*/
|
|
|
|
/*===
|
|
*** test_basic (duk_safe_call)
|
|
top: 7
|
|
idx 0: type 1, duk_get_heapptr() -> NULL
|
|
idx 0: type 1, duk_require_heapptr() -> TypeError: unexpected type
|
|
top: 7
|
|
idx 1: type 2, duk_get_heapptr() -> NULL
|
|
idx 1: type 2, duk_require_heapptr() -> TypeError: unexpected type
|
|
top: 7
|
|
idx 2: type 3, duk_get_heapptr() -> NULL
|
|
idx 2: type 3, duk_require_heapptr() -> TypeError: unexpected type
|
|
top: 7
|
|
idx 3: type 4, duk_get_heapptr() -> NULL
|
|
idx 3: type 4, duk_require_heapptr() -> TypeError: unexpected type
|
|
top: 7
|
|
idx 4: type 5, duk_get_heapptr() -> non-NULL
|
|
idx 4: type 5, duk_require_heapptr() -> non-NULL
|
|
top: 7
|
|
idx 5: type 6, duk_get_heapptr() -> non-NULL
|
|
idx 5: type 6, duk_require_heapptr() -> non-NULL
|
|
top: 7
|
|
idx 6: type 7, duk_get_heapptr() -> non-NULL
|
|
idx 6: type 7, duk_require_heapptr() -> non-NULL
|
|
top: 7
|
|
idx 7: type 0, duk_get_heapptr() -> NULL
|
|
idx 7: type 5, duk_require_heapptr() -> Error: invalid index
|
|
"test string"
|
|
{foo:"bar"}
|
|
|deadbeef|
|
|
undefined
|
|
final top: 0
|
|
==> rc=0, result='undefined'
|
|
*** test_api_example (duk_safe_call)
|
|
obj.foo: bar
|
|
final top: 2
|
|
==> rc=0, result='undefined'
|
|
===*/
|
|
|
|
static duk_ret_t raw_require_heapptr(duk_context *ctx) {
|
|
duk_idx_t i;
|
|
void *ptr;
|
|
|
|
i = duk_require_uint(ctx, -1);
|
|
duk_pop(ctx);
|
|
|
|
ptr = duk_require_heapptr(ctx, i);
|
|
|
|
printf("idx %ld: type %ld, duk_require_heapptr() -> %s\n",
|
|
(long) i, (long) duk_get_type(ctx, i), (ptr ? "non-NULL" : "NULL"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static duk_ret_t test_basic(duk_context *ctx) {
|
|
duk_idx_t i, n;
|
|
void *ptr;
|
|
void *p1, *p2, *p3;
|
|
duk_int_t ret;
|
|
|
|
duk_push_undefined(ctx);
|
|
duk_push_null(ctx);
|
|
duk_push_boolean(ctx, 1);
|
|
duk_push_number(ctx, 123.0);
|
|
duk_push_string(ctx, "test string");
|
|
duk_eval_string(ctx, "({ foo: 'bar' })");
|
|
duk_eval_string(ctx, "Duktape.dec('hex', 'deadbeef');"); /* buffer */
|
|
|
|
/* Print pointer NULL/non-NULL */
|
|
|
|
n = duk_get_top(ctx);
|
|
for (i = 0; i < n + 1; i++) {
|
|
/* Note: access i == n on purpose (invalid index) */
|
|
|
|
ptr = duk_get_heapptr(ctx, i);
|
|
|
|
printf("top: %ld\n", (long) duk_get_top(ctx));
|
|
|
|
printf("idx %ld: type %ld, duk_get_heapptr() -> %s\n",
|
|
(long) i, (long) duk_get_type(ctx, i), (ptr ? "non-NULL" : "NULL"));
|
|
|
|
duk_push_uint(ctx, (duk_uint_t) i);
|
|
ret = duk_safe_call(ctx, raw_require_heapptr, 1 /*nargs*/, 1 /*nrets*/);
|
|
if (ret == DUK_EXEC_SUCCESS) {
|
|
;
|
|
} else {
|
|
printf("idx %ld: type %ld, duk_require_heapptr() -> %s\n",
|
|
(long) i, (long) duk_get_type(ctx, i), duk_safe_to_string(ctx, -1));
|
|
}
|
|
duk_pop(ctx);
|
|
}
|
|
|
|
/* Write the values to the global stash to simulate whatever
|
|
* reachability mechanisms user code uses.
|
|
*/
|
|
|
|
n = duk_get_top(ctx);
|
|
duk_push_global_stash(ctx);
|
|
for (i = 0; i < n; i++) {
|
|
duk_dup(ctx, i);
|
|
duk_put_prop_index(ctx, -2, (duk_uarridx_t) i);
|
|
}
|
|
|
|
/* Get borrowed references */
|
|
|
|
p1 = duk_get_heapptr(ctx, 4);
|
|
p2 = duk_get_heapptr(ctx, 5);
|
|
p3 = duk_get_heapptr(ctx, 6);
|
|
|
|
/* Erase value stack, simulating user code moving on and relying on
|
|
* stashed values keeping the target values reachable. Force a GC
|
|
* for good measure.
|
|
*/
|
|
|
|
duk_set_top(ctx, 0);
|
|
duk_gc(ctx, 0);
|
|
|
|
/* Push the values back one by one and test that they're intact. */
|
|
|
|
duk_eval_string(ctx, "(function (v) { print(Duktape.enc('jx', v)); })");
|
|
|
|
duk_dup_top(ctx);
|
|
duk_push_heapptr(ctx, p1);
|
|
duk_call(ctx, 1);
|
|
duk_pop(ctx);
|
|
|
|
duk_dup_top(ctx);
|
|
duk_push_heapptr(ctx, p2);
|
|
duk_call(ctx, 1);
|
|
duk_pop(ctx);
|
|
|
|
duk_dup_top(ctx);
|
|
duk_push_heapptr(ctx, p3);
|
|
duk_call(ctx, 1);
|
|
duk_pop(ctx);
|
|
|
|
duk_dup_top(ctx);
|
|
duk_push_heapptr(ctx, NULL);
|
|
duk_call(ctx, 1);
|
|
duk_pop(ctx);
|
|
|
|
duk_pop(ctx);
|
|
|
|
/* Done. */
|
|
|
|
printf("final top: %ld\n", (long) duk_get_top(ctx));
|
|
return 0;
|
|
}
|
|
|
|
static duk_ret_t test_api_example(duk_context *ctx) {
|
|
void *ptr;
|
|
|
|
duk_eval_string(ctx, "({ foo: 'bar' })");
|
|
ptr = duk_get_heapptr(ctx, -1);
|
|
|
|
duk_put_global_string(ctx, "ref");
|
|
duk_set_top(ctx, 0);
|
|
|
|
duk_push_heapptr(ctx, ptr);
|
|
duk_get_prop_string(ctx, -1, "foo");
|
|
printf("obj.foo: %s\n", duk_safe_to_string(ctx, -1)); /* prints 'bar' */
|
|
|
|
printf("final top: %ld\n", (long) duk_get_top(ctx));
|
|
return 0;
|
|
}
|
|
|
|
void test(duk_context *ctx) {
|
|
TEST_SAFE_CALL(test_basic);
|
|
TEST_SAFE_CALL(test_api_example);
|
|
}
|
|
|