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.
95 lines
2.2 KiB
95 lines
2.2 KiB
/*
|
|
* If duk_safe_call() target pops too many value stcak elements,
|
|
* 'undefined' values are inserted at the index where return
|
|
* values begin to restore the stack shape.
|
|
*
|
|
* Example, duk_safe_call() with nargs=4, nrets=5:
|
|
*
|
|
* [ a b c d e f g X Y Z W ]
|
|
* <-----> args
|
|
* ^
|
|
* `---- retbase=7 (index from bottom)
|
|
*
|
|
* Caller pops too much:
|
|
*
|
|
* [ a b ]
|
|
*
|
|
* then pushes two return values L and M:
|
|
*
|
|
* [ a b L M ]
|
|
*
|
|
* and returns rc=2 to indicate two actual return values are present.
|
|
*
|
|
* This is resolved by injecting 'undefined' values to lift the intended
|
|
* return values to 'retbase' index (U=undefined):
|
|
*
|
|
* [ a b U U U U U L M ]
|
|
*
|
|
* Finally, because 5 values were expected, further 'undefined' values are
|
|
* pushed to fulfill the API contract:
|
|
*
|
|
* [ a b U U U U U L M U U U ]
|
|
* <------->
|
|
* ^
|
|
* `---- retbase=7
|
|
*/
|
|
|
|
/*===
|
|
a b c d e f g X Y Z W
|
|
top before: 11
|
|
a b L M
|
|
duk_safe_call() rc: 0
|
|
a b undefined undefined undefined undefined undefined L M undefined undefined undefined
|
|
final top: 12
|
|
===*/
|
|
|
|
static void dump_value_stack(duk_context *ctx) {
|
|
duk_idx_t i;
|
|
|
|
for (i = 0; i < duk_get_top(ctx); i++) {
|
|
if (i > 0) {
|
|
printf(" ");
|
|
}
|
|
duk_dup(ctx, i);
|
|
printf("%s", duk_to_string(ctx, -1));
|
|
duk_pop(ctx);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
static duk_ret_t my_func(duk_context *ctx, void *udata) {
|
|
(void) udata;
|
|
duk_set_top(ctx, 2);
|
|
duk_push_string(ctx, "L");
|
|
duk_push_string(ctx, "M");
|
|
dump_value_stack(ctx);
|
|
return 2;
|
|
}
|
|
|
|
void test(duk_context *ctx) {
|
|
duk_int_t rc;
|
|
|
|
duk_push_string(ctx, "a");
|
|
duk_push_string(ctx, "b");
|
|
duk_push_string(ctx, "c");
|
|
duk_push_string(ctx, "d");
|
|
duk_push_string(ctx, "e");
|
|
duk_push_string(ctx, "f");
|
|
duk_push_string(ctx, "g");
|
|
|
|
duk_push_string(ctx, "X");
|
|
duk_push_string(ctx, "Y");
|
|
duk_push_string(ctx, "Z");
|
|
duk_push_string(ctx, "W");
|
|
|
|
dump_value_stack(ctx);
|
|
|
|
printf("top before: %ld\n", (long) duk_get_top(ctx));
|
|
|
|
rc = duk_safe_call(ctx, my_func, NULL, 4, 5);
|
|
printf("duk_safe_call() rc: %ld\n", (long) rc);
|
|
|
|
dump_value_stack(ctx);
|
|
|
|
printf("final top: %ld\n", (long) duk_get_top(ctx));
|
|
}
|
|
|