How to make function calls

How to make function calls

API calls for invoking functions are mostly quite straightforward: they are given a target function and a list of arguments. However, the following Ecmascript specific details complicate matters a bit:

  • Ecmascript function/method calls involve a "this" binding which varies between API calls and Ecmascript call idioms. If not given, the "this" binding defaults to undefined (but coerces to the global object unless the target function is strict; Duktape/C functions are always strict).

  • Constructor calls have special behavior for their "this" binding and their return value. The "this" binding is initialized to a "default instance" and the return value has special handling, allowing the default instance to be replaced. See Internal and external prototype.

The C API provides protected and unprotected variants. Their difference is that protected calls catch errors; an error is indicated by the C API call return value, and the error object is placed on the value stack. One can then e.g. read the traceback of the error.

The table below summarizes API calls, using unprotected calls as examples:

Ecmascript idiom Duktape C API idiom This binding Value stack
var result = func('foo', 'bar'); duk_get_global_string(ctx, "func");
duk_push_string(ctx, "foo");
duk_push_string(ctx, "bar")
duk_call(ctx, 2 /*nargs*/);
/* result on stack top */
undefined [ func "foo" "bar" ] -> [ result ]
var result = func.call('myThis', 'foo', 'bar'); duk_get_global_string(ctx, "func");
duk_push_string(ctx, "myThis"); duk_push_string(ctx, "foo");
duk_push_string(ctx, "bar")
duk_call_method(ctx, 2 /*nargs*/);
/* result on stack top */
"myThis" [ func "myThis" "foo" "bar" ] -> [ result ]
var result = obj.func('foo', 'bar'); duk_push_string(ctx, "func");
duk_push_string(ctx, "foo");
duk_push_string(ctx, "bar")
duk_call_prop(ctx, obj_idx, 2 /*nargs*);
/* result on stack top */
obj [ "func" "foo" "bar" ] -> [ result ]
Last edited by Sami Vaarala, 2017-09-16 22:53:18