Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duk_bi_error.c File Reference
#include "duk_internal.h"

Go to the source code of this file.

Macros

#define DUK__OUTPUT_TYPE_TRACEBACK   (-1)
 
#define DUK__OUTPUT_TYPE_FILENAME   0
 
#define DUK__OUTPUT_TYPE_LINENUMBER   1
 

Functions

DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared (duk_context *ctx)
 
DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string (duk_context *ctx)
 
DUK_LOCAL duk_ret_t duk__error_getter_helper (duk_context *ctx, duk_small_int_t output_type)
 
DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter (duk_context *ctx)
 
DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter (duk_context *ctx)
 
DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter (duk_context *ctx)
 
DUK_LOCAL duk_ret_t duk__error_setter_helper (duk_context *ctx, duk_small_uint_t stridx_key)
 
DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter (duk_context *ctx)
 
DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter (duk_context *ctx)
 
DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter (duk_context *ctx)
 

Macro Definition Documentation

◆ DUK__OUTPUT_TYPE_FILENAME

#define DUK__OUTPUT_TYPE_FILENAME   0

◆ DUK__OUTPUT_TYPE_LINENUMBER

#define DUK__OUTPUT_TYPE_LINENUMBER   1

◆ DUK__OUTPUT_TYPE_TRACEBACK

#define DUK__OUTPUT_TYPE_TRACEBACK   (-1)

Function Documentation

◆ duk__error_getter_helper()

DUK_LOCAL duk_ret_t duk__error_getter_helper ( duk_context * ctx,
duk_small_int_t output_type )

Definition at line 117 of file duktape-1.5.2/src-separate/duk_bi_error.c.

117 {
118 duk_hthread *thr = (duk_hthread *) ctx;
119 duk_idx_t idx_td;
120 duk_small_int_t i; /* traceback depth fits into 16 bits */
121 duk_small_int_t t; /* stack type fits into 16 bits */
122 duk_small_int_t count_func = 0; /* traceback depth ensures fits into 16 bits */
123 const char *str_tailcall = " tailcall";
124 const char *str_strict = " strict";
125 const char *str_construct = " construct";
126 const char *str_prevyield = " preventsyield";
127 const char *str_directeval = " directeval";
128 const char *str_empty = "";
129
130 DUK_ASSERT_TOP(ctx, 0); /* fixed arg count */
131 DUK_UNREF(thr);
132
133 duk_push_this(ctx);
135 idx_td = duk_get_top_index(ctx);
136
138 duk_push_this(ctx);
139
140 /* [ ... this tracedata sep this ] */
141
142 /* XXX: skip null filename? */
143
144 if (duk_check_type(ctx, idx_td, DUK_TYPE_OBJECT)) {
145 /* Current tracedata contains 2 entries per callstack entry. */
146 for (i = 0; ; i += 2) {
147 duk_int_t pc;
148 duk_int_t line;
149 duk_int_t flags;
150 duk_double_t d;
151 const char *funcname;
152 const char *filename;
153 duk_hobject *h_func;
154 duk_hstring *h_name;
155
156 duk_require_stack(ctx, 5);
157 duk_get_prop_index(ctx, idx_td, i);
158 duk_get_prop_index(ctx, idx_td, i + 1);
159 d = duk_to_number(ctx, -1);
161 flags = (duk_int_t) DUK_FLOOR(d / DUK_DOUBLE_2TO32);
162 t = (duk_small_int_t) duk_get_type(ctx, -2);
163
164 if (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) {
165 /*
166 * Ecmascript/native function call or lightfunc call
167 */
168
169 count_func++;
170
171 /* [ ... v1(func) v2(pc+flags) ] */
172
173 h_func = duk_get_hobject(ctx, -2); /* NULL for lightfunc */
174
177
178#if defined(DUK_USE_PC2LINE)
179 line = duk_hobject_pc2line_query(ctx, -4, (duk_uint_fast32_t) pc);
180#else
181 line = 0;
182#endif
183
184 /* [ ... v1 v2 name filename ] */
185
186 /* When looking for .fileName/.lineNumber, blame first
187 * function which has a .fileName.
188 */
189 if (duk_is_string(ctx, -1)) {
190 if (output_type == DUK__OUTPUT_TYPE_FILENAME) {
191 return 1;
192 } else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {
193 duk_push_int(ctx, line);
194 return 1;
195 }
196 }
197
198 /* XXX: Change 'anon' handling here too, to use empty string for anonymous functions? */
199 /* XXX: Could be improved by coercing to a readable duk_tval (especially string escaping) */
200 h_name = duk_get_hstring(ctx, -2); /* may be NULL */
201 funcname = (h_name == NULL || h_name == DUK_HTHREAD_STRING_EMPTY_STRING(thr)) ?
202 "[anon]" : (const char *) DUK_HSTRING_GET_DATA(h_name);
203 filename = duk_get_string(ctx, -1);
204 filename = filename ? filename : "";
206 DUK_ASSERT(filename != NULL);
207
208 if (h_func == NULL) {
209 duk_push_sprintf(ctx, "at %s light%s%s%s%s%s",
210 (const char *) funcname,
211 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),
212 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),
213 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),
214 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),
215 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));
216 } else if (DUK_HOBJECT_HAS_NATIVEFUNCTION(h_func)) {
217 duk_push_sprintf(ctx, "at %s (%s) native%s%s%s%s%s",
218 (const char *) funcname,
219 (const char *) filename,
220 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),
221 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),
222 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),
223 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),
224 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));
225 } else {
226 duk_push_sprintf(ctx, "at %s (%s:%ld)%s%s%s%s%s",
227 (const char *) funcname,
228 (const char *) filename,
229 (long) line,
230 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),
231 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),
232 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),
233 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),
234 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));
235 }
236 duk_replace(ctx, -5); /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */
237 duk_pop_n(ctx, 3); /* -> [ ... str ] */
238 } else if (t == DUK_TYPE_STRING) {
239 /*
240 * __FILE__ / __LINE__ entry, here 'pc' is line number directly.
241 * Sometimes __FILE__ / __LINE__ is reported as the source for
242 * the error (fileName, lineNumber), sometimes not.
243 */
244
245 /* [ ... v1(filename) v2(line+flags) ] */
246
247 /* When looking for .fileName/.lineNumber, blame compilation
248 * or C call site unless flagged not to do so.
249 */
250 if (!(flags & DUK_TB_FLAG_NOBLAME_FILELINE)) {
251 if (output_type == DUK__OUTPUT_TYPE_FILENAME) {
252 duk_pop(ctx);
253 return 1;
254 } else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {
255 duk_push_int(ctx, pc);
256 return 1;
257 }
258 }
259
260 duk_push_sprintf(ctx, "at [anon] (%s:%ld) internal",
261 (const char *) duk_get_string(ctx, -2), (long) pc);
262 duk_replace(ctx, -3); /* [ ... v1 v2 str ] -> [ ... str v2 ] */
263 duk_pop(ctx); /* -> [ ... str ] */
264 } else {
265 /* unknown, ignore */
266 duk_pop_2(ctx);
267 break;
268 }
269 }
270
271 if (count_func >= DUK_USE_TRACEBACK_DEPTH) {
272 /* Possibly truncated; there is no explicit truncation
273 * marker so this is the best we can do.
274 */
275
277 }
278 }
279
280 /* [ ... this tracedata sep this str1 ... strN ] */
281
282 if (output_type != DUK__OUTPUT_TYPE_TRACEBACK) {
283 return 0;
284 } else {
285 /* The 'this' after 'sep' will get ToString() coerced by
286 * duk_join() automatically. We don't want to do that
287 * coercion when providing .fileName or .lineNumber (GH-254).
288 */
289 duk_join(ctx, duk_get_top(ctx) - (idx_td + 2) /*count, not including sep*/);
290 return 1;
291 }
292}
duk_int_fast32_t duk_int_t
duk_uint32_t duk_uint_fast32_t
#define DUK_ACT_FLAG_TAILCALLED
#define DUK_ACT_FLAG_PREVENT_YIELD
DUK_EXTERNAL void duk_pop_2(duk_context *ctx)
#define DUK_HSTRING_GET_DATA(x)
#define DUK_STRIDX_BRACKETED_ELLIPSIS
DUK_EXTERNAL void duk_push_this(duk_context *ctx)
DUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx)
DUK_EXTERNAL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t index, duk_int_t type)
DUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_context *ctx, duk_small_int_t stridx)
DUK_EXTERNAL void duk_require_stack(duk_context *ctx, duk_idx_t extra)
#define DUK_TB_FLAG_NOBLAME_FILELINE
DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val)
DUK_EXTERNAL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t index)
#define DUK_ACT_FLAG_DIRECT_EVAL
DUK_EXTERNAL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL void duk_replace(duk_context *ctx, duk_idx_t to_index)
DUK_EXTERNAL const char * duk_get_string(duk_context *ctx, duk_idx_t index)
#define DUK_ACT_FLAG_CONSTRUCT
DUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_context *ctx, duk_idx_t idx_func, duk_uint_fast32_t pc)
DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx)
DUK_EXTERNAL duk_idx_t duk_get_top(duk_context *ctx)
DUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index)
#define DUK_HOBJECT_HAS_NATIVEFUNCTION(h)
#define DUK_STRIDX_INT_TRACEDATA
DUK_EXTERNAL const char * duk_push_sprintf(duk_context *ctx, const char *fmt,...)
DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count)
#define DUK_ASSERT_TOP(ctx, n)
DUK_EXTERNAL void duk_pop(duk_context *ctx)
DUK_INTERNAL_DECL duk_hobject * duk_get_hobject(duk_context *ctx, duk_idx_t index)
#define DUK_HTHREAD_STRING_EMPTY_STRING(thr)
DUK_INTERNAL_DECL duk_hstring * duk_get_hstring(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index)
#define DUK_STRIDX_NEWLINE_4SPACE
DUK_EXTERNAL void duk_join(duk_context *ctx, duk_idx_t count)
#define NULL
Definition gmacros.h:924
static int funcname(LexState *ls, expdesc *v)

References DUK__OUTPUT_TYPE_FILENAME, DUK__OUTPUT_TYPE_LINENUMBER, DUK__OUTPUT_TYPE_TRACEBACK, DUK_ACT_FLAG_CONSTRUCT, DUK_ACT_FLAG_DIRECT_EVAL, DUK_ACT_FLAG_PREVENT_YIELD, DUK_ACT_FLAG_STRICT, DUK_ACT_FLAG_TAILCALLED, DUK_ASSERT, DUK_ASSERT_TOP, duk_check_type(), DUK_DOUBLE_2TO32, DUK_FLOOR, DUK_FMOD, duk_get_hobject(), duk_get_hstring(), duk_get_prop_index(), duk_get_prop_stridx(), duk_get_string(), duk_get_top(), duk_get_top_index(), duk_get_type(), DUK_HOBJECT_HAS_NATIVEFUNCTION, duk_hobject_pc2line_query(), DUK_HSTRING_GET_DATA, DUK_HTHREAD_STRING_EMPTY_STRING, duk_is_string(), duk_join(), duk_pop(), duk_pop_2(), duk_pop_n(), duk_push_hstring_stridx(), duk_push_int(), duk_push_sprintf(), duk_push_this(), duk_replace(), duk_require_stack(), DUK_STRIDX_BRACKETED_ELLIPSIS, DUK_STRIDX_FILE_NAME, DUK_STRIDX_INT_TRACEDATA, DUK_STRIDX_NAME, DUK_STRIDX_NEWLINE_4SPACE, DUK_TB_FLAG_NOBLAME_FILELINE, duk_to_number(), DUK_TYPE_LIGHTFUNC, DUK_TYPE_OBJECT, DUK_TYPE_STRING, DUK_UNREF, DUK_USE_TRACEBACK_DEPTH, funcname(), and NULL.

Referenced by duk_bi_error_prototype_filename_getter(), duk_bi_error_prototype_linenumber_getter(), and duk_bi_error_prototype_stack_getter().

◆ duk__error_setter_helper()

DUK_LOCAL duk_ret_t duk__error_setter_helper ( duk_context * ctx,
duk_small_uint_t stridx_key )

Definition at line 347 of file duktape-1.5.2/src-separate/duk_bi_error.c.

347 {
348 /* Attempt to write 'stack', 'fileName', 'lineNumber' works as if
349 * user code called Object.defineProperty() to create an overriding
350 * own property. This allows user code to overwrite .fileName etc
351 * intuitively as e.g. "err.fileName = 'dummy'" as one might expect.
352 * See https://github.com/svaarala/duktape/issues/387.
353 */
354
355 DUK_ASSERT_TOP(ctx, 1); /* fixed arg count: value */
356
357 duk_push_this(ctx);
358 duk_push_hstring_stridx(ctx, (duk_small_int_t) stridx_key);
359 duk_dup(ctx, 0);
360
361 /* [ ... obj key value ] */
362
363 DUK_DD(DUK_DDPRINT("error setter: %!T %!T %!T",
364 duk_get_tval(ctx, -3), duk_get_tval(ctx, -2), duk_get_tval(ctx, -1)));
365
368 DUK_DEFPROP_HAVE_ENUMERABLE | /*not enumerable*/
370 return 0;
371}
DUK_EXTERNAL void duk_def_prop(duk_context *ctx, duk_idx_t obj_index, duk_uint_t flags)
DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index)
DUK_INTERNAL_DECL duk_tval * duk_get_tval(duk_context *ctx, duk_idx_t index)
#define DUK_DEFPROP_HAVE_VALUE
#define DUK_DEFPROP_CONFIGURABLE
#define DUK_DEFPROP_HAVE_WRITABLE
#define DUK_DEFPROP_HAVE_CONFIGURABLE
#define DUK_DEFPROP_HAVE_ENUMERABLE
#define DUK_DEFPROP_WRITABLE

References DUK_ASSERT_TOP, DUK_DD, DUK_DDPRINT, duk_def_prop(), DUK_DEFPROP_CONFIGURABLE, DUK_DEFPROP_HAVE_CONFIGURABLE, DUK_DEFPROP_HAVE_ENUMERABLE, DUK_DEFPROP_HAVE_VALUE, DUK_DEFPROP_HAVE_WRITABLE, DUK_DEFPROP_WRITABLE, duk_dup(), duk_get_tval(), duk_push_hstring_stridx(), and duk_push_this().

Referenced by duk_bi_error_prototype_filename_setter(), duk_bi_error_prototype_linenumber_setter(), and duk_bi_error_prototype_stack_setter().

◆ duk_bi_error_constructor_shared()

DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared ( duk_context * ctx)

Definition at line 7 of file duktape-1.5.2/src-separate/duk_bi_error.c.

7 {
8 /* Behavior for constructor and non-constructor call is
9 * the same except for augmenting the created error. When
10 * called as a constructor, the caller (duk_new()) will handle
11 * augmentation; when called as normal function, we need to do
12 * it here.
13 */
14
15 duk_hthread *thr = (duk_hthread *) ctx;
16 duk_small_int_t bidx_prototype = duk_get_current_magic(ctx);
17
18 /* same for both error and each subclass like TypeError */
19 duk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE |
21
22 DUK_UNREF(thr);
23
24 duk_push_object_helper(ctx, flags_and_class, bidx_prototype);
25
26 /* If message is undefined, the own property 'message' is not set at
27 * all to save property space. An empty message is inherited anyway.
28 */
29 if (!duk_is_undefined(ctx, 0)) {
30 duk_to_string(ctx, 0);
31 duk_dup(ctx, 0); /* [ message error message ] */
33 }
34
35 /* Augment the error if called as a normal function. __FILE__ and __LINE__
36 * are not desirable in this case.
37 */
38
39#ifdef DUK_USE_AUGMENT_ERROR_CREATE
40 if (!duk_is_constructor_call(ctx)) {
41 duk_err_augment_error_create(thr, thr, NULL, 0, 1 /*noblame_fileline*/);
42 }
43#endif
44
45 return 1;
46}
duk_uint_fast32_t duk_uint_t
DUK_EXTERNAL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t index)
#define DUK_HOBJECT_CLASS_AS_FLAGS(v)
DUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_bool_t noblame_fileline)
#define DUK_HOBJECT_CLASS_ERROR
DUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_context *ctx)
#define DUK_PROPDESC_FLAGS_WC
#define DUK_HOBJECT_FLAG_EXTENSIBLE
DUK_INTERNAL_DECL duk_idx_t duk_push_object_helper(duk_context *ctx, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx)
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_int_t duk_get_current_magic(duk_context *ctx)
DUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx, duk_small_uint_t desc_flags)

References duk_dup(), duk_err_augment_error_create(), duk_get_current_magic(), DUK_HOBJECT_CLASS_AS_FLAGS, DUK_HOBJECT_CLASS_ERROR, DUK_HOBJECT_FLAG_EXTENSIBLE, duk_is_constructor_call(), duk_is_undefined(), DUK_PROPDESC_FLAGS_WC, duk_push_object_helper(), DUK_STRIDX_MESSAGE, duk_to_string(), DUK_UNREF, duk_xdef_prop_stridx(), and NULL.

◆ duk_bi_error_prototype_filename_getter()

DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter ( duk_context * ctx)

Definition at line 302 of file duktape-1.5.2/src-separate/duk_bi_error.c.

302 {
304}
DUK_LOCAL duk_ret_t duk__error_getter_helper(duk_context *ctx, duk_small_int_t output_type)

References duk__error_getter_helper(), and DUK__OUTPUT_TYPE_FILENAME.

◆ duk_bi_error_prototype_filename_setter()

DUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter ( duk_context * ctx)

Definition at line 377 of file duktape-1.5.2/src-separate/duk_bi_error.c.

377 {
379}
DUK_LOCAL duk_ret_t duk__error_setter_helper(duk_context *ctx, duk_small_uint_t stridx_key)

References duk__error_setter_helper(), and DUK_STRIDX_FILE_NAME.

◆ duk_bi_error_prototype_linenumber_getter()

DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter ( duk_context * ctx)

◆ duk_bi_error_prototype_linenumber_setter()

DUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter ( duk_context * ctx)

◆ duk_bi_error_prototype_stack_getter()

DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter ( duk_context * ctx)

◆ duk_bi_error_prototype_stack_setter()

DUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter ( duk_context * ctx)

◆ duk_bi_error_prototype_to_string()

DUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string ( duk_context * ctx)

Definition at line 48 of file duktape-1.5.2/src-separate/duk_bi_error.c.

48 {
49 /* XXX: optimize with more direct internal access */
50
51 duk_push_this(ctx);
53
54 /* [ ... this ] */
55
57 if (duk_is_undefined(ctx, -1)) {
58 duk_pop(ctx);
59 duk_push_string(ctx, "Error");
60 } else {
61 duk_to_string(ctx, -1);
62 }
63
64 /* [ ... this name ] */
65
66 /* XXX: Are steps 6 and 7 in E5 Section 15.11.4.4 duplicated by
67 * accident or are they actually needed? The first ToString()
68 * could conceivably return 'undefined'.
69 */
71 if (duk_is_undefined(ctx, -1)) {
72 duk_pop(ctx);
73 duk_push_string(ctx, "");
74 } else {
75 duk_to_string(ctx, -1);
76 }
77
78 /* [ ... this name message ] */
79
80 if (duk_get_length(ctx, -2) == 0) {
81 /* name is empty -> return message */
82 return 1;
83 }
84 if (duk_get_length(ctx, -1) == 0) {
85 /* message is empty -> return name */
86 duk_pop(ctx);
87 return 1;
88 }
89 duk_push_string(ctx, ": ");
90 duk_insert(ctx, -2); /* ... name ': ' message */
91 duk_concat(ctx, 3);
92
93 return 1;
94}
DUK_EXTERNAL void duk_concat(duk_context *ctx, duk_idx_t count)
DUK_EXTERNAL const char * duk_push_string(duk_context *ctx, const char *str)
DUK_EXTERNAL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t index)
DUK_INTERNAL_DECL duk_hobject * duk_require_hobject_or_lfunc_coerce(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index)

References duk_concat(), duk_get_length(), duk_get_prop_stridx(), duk_insert(), duk_is_undefined(), duk_pop(), duk_push_string(), duk_push_this(), duk_require_hobject_or_lfunc_coerce(), DUK_STRIDX_MESSAGE, DUK_STRIDX_NAME, and duk_to_string().