name: duk_safe_call proto: | duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t nargs, duk_idx_t nrets); stack: | [ ... arg1! ...! argN! ] -> [ ... ret1! ...! retN! ] summary: |
Perform a protected pure C function call inside the current value stack frame
(the call is not visible on the call stack). nargs
topmost values in the
current value stack frame are identified as call arguments, and nrets
return values are provided after the call returns.
The return value is:
DUK_EXEC_SUCCESS
(0): call succeeded, nargs
arguments are replaced
with nrets
return values. (This return code constant is guaranteed to be
zero, so that one can check for success with a "zero or non-zero" check.)DUK_EXEC_ERROR
: call failed, nargs
arguments are replaced with
nrets
values, first of which is an error value and the rest are undefined
.
(In exceptional cases, e.g. when there are too few arguments on the value stack, the call
returns non-zero but may leave the stack in an inconsistent state.)Because this call operates on the current value stack frame, stack behavior differs a bit from other call types. Although the target function signature matches Duktape/C functions, value stack and return code policies are different.
The top nargs
elements of the stack top are identified as arguments to
func
establishing a "base index" for the return stack as:
(duk_get_top() - nargs)
When func
returns, it indicates with its return value the number of
return values it has pushed on top of the stack; multiple or zero return
values possible. The stack is then manipulated so that there are exactly
nrets
values starting at the "base index" established before the call.
Note that since func
has full access to the value stack, it may modify
the stack below the indended arguments and even pop elements below the "base index"
off the stack. Such elements are restored with undefined
values before
returning, to ensure that the stack is always in a consistent state upon returning.
If an error occurs, the stack will still have nrets
values at "base index";
the first of such values is the error, and the remaining values are undefined
.
If nrets
is zero, the error will not be present on the stack (the return stack
top will equal the "base index"), so calling this function with nrets
as 0
is not very useful.
Example with nargs = 3
, nrets = 2
, func
returns 4.
Pipe chars indicate logical boundaries:
.--- frame bottom | | .--- "base index" v v [ ... | ... | a b c ] stack before calling 'func' [ ... | ... | a b | x y z w ] stack after calling 'func', which has popped one argument and written four return values (and returned 4) [ ... | ... | x y ] stack after duk_safe_call() returns, 2 (= nrets) first 'func' return values are left at "base index"
func
uses caller stack frame, so bottom-based references
are dangerous within 'func'.