DUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_context *ctx) { /* String constructor needs to distinguish between an argument not given at all * vs. given as 'undefined'. We're a vararg function to handle this properly. */ if (duk_get_top(ctx) == 0) { duk_push_hstring_stridx(ctx, DUK_STRIDX_EMPTY_STRING); } else { duk_to_string(ctx, 0); } DUK_ASSERT(duk_is_string(ctx, 0)); duk_set_top(ctx, 1); if (duk_is_constructor_call(ctx)) { duk_push_object_helper(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING), DUK_BIDX_STRING_PROTOTYPE); /* String object internal value is immutable */ duk_dup(ctx, 0); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); } /* Note: unbalanced stack on purpose */ return 1; }
DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_context *ctx) { if (!duk_is_constructor_call(ctx) && !duk_is_null_or_undefined(ctx, 0)) { duk_to_object(ctx, 0); return 1; } if (duk_is_object(ctx, 0)) { return 1; } /* Pointer and buffer primitive values are treated like other * primitives values which have a fully fledged object counterpart: * promote to an object value. Lightfuncs are coerced with * ToObject() even they could also be returned as is. */ if (duk_check_type_mask(ctx, 0, DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_BOOLEAN | DUK_TYPE_MASK_NUMBER | DUK_TYPE_MASK_POINTER | DUK_TYPE_MASK_BUFFER | DUK_TYPE_MASK_LIGHTFUNC)) { duk_to_object(ctx, 0); return 1; } duk_push_object_helper(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), DUK_BIDX_OBJECT_PROTOTYPE); return 1; }
int duk_bi_pointer_constructor(duk_context *ctx) { /* FIXME: this behavior is quite useless now; it would be nice to be able * to create pointer values from e.g. numbers or strings. Numbers are * problematic on 64-bit platforms though. Hex encoded strings? */ if (duk_get_top(ctx) == 0) { duk_push_pointer(ctx, NULL); } else { duk_to_pointer(ctx, 0); } DUK_ASSERT(duk_is_pointer(ctx, 0)); duk_set_top(ctx, 1); if (duk_is_constructor_call(ctx)) { duk_push_object_helper(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER), DUK_BIDX_POINTER_PROTOTYPE); /* Pointer object internal value is immutable */ duk_dup(ctx, 0); duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); } /* Note: unbalanced stack on purpose */ return 1; }
int duk_builtin_object_constructor(duk_context *ctx) { if (!duk_is_constructor_call(ctx) && !duk_is_null_or_undefined(ctx, 0)) { duk_to_object(ctx, 0); return 1; } if (duk_is_object(ctx, 0)) { return 1; } if (duk_check_type_mask(ctx, 0, DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_BOOLEAN | DUK_TYPE_MASK_NUMBER)) { duk_to_object(ctx, 0); return 1; } /* FIXME: handling for POINTER and BUFFER */ duk_push_object_helper(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), DUK_BIDX_OBJECT_PROTOTYPE); return 1; }
duk_ret_t JsLibrarian::Constructor(duk_context* duktapeContext) { try { if (duk_get_top(duktapeContext) != 0) JavaScriptHelper::Throw(duktapeContext, "No arguments for Librarian constructor expected"); if (duk_is_constructor_call(duktapeContext)) duk_push_this(duktapeContext); else duk_push_object(duktapeContext); duk_push_pointer(duktapeContext, new JsLibrarian); duk_put_prop_string(duktapeContext, -2, "__Ptr"); duk_push_c_function(duktapeContext, JsLibrarian::Destructor, 1); duk_set_finalizer(duktapeContext, -2); duk_push_c_function(duktapeContext, JsLibrarian::Files, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Files"); duk_push_c_function(duktapeContext, JsLibrarian::DependencyCheck, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "DependencyCheck"); duk_push_c_function(duktapeContext, JsLibrarian::Output, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Output"); duk_push_c_function(duktapeContext, JsLibrarian::BeforeLink, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "BeforeLink"); duk_push_c_function(duktapeContext, JsLibrarian::Create, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Create"); return 1; } catch (std::exception& e) { JavaScriptHelper::Throw(duktapeContext, e.what()); } }
static duk_ret_t my_func_2(duk_context *ctx) { printf("duk_is_constructor_call: %d\n", (int) duk_is_constructor_call(ctx)); /* this replaces the freshly constructed object, and does NOT have * the same internal prototype as the fresh object. */ duk_eval_string(ctx, "({ name: 'replacement' })"); return 1; }
DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx) { duk_hobject *h_target; duk_hobject *h_handler; if (!duk_is_constructor_call(ctx)) { return DUK_RET_TYPE_ERROR; } /* Reject a proxy object as the target because it would need * special handler in property lookups. (ES6 has no such restriction) */ h_target = duk_require_hobject_or_lfunc_coerce(ctx, 0); DUK_ASSERT(h_target != NULL); if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_target)) { return DUK_RET_TYPE_ERROR; } /* Reject a proxy object as the handler because it would cause * potentially unbounded recursion. (ES6 has no such restriction) */ h_handler = duk_require_hobject_or_lfunc_coerce(ctx, 1); DUK_ASSERT(h_handler != NULL); if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h_handler)) { return DUK_RET_TYPE_ERROR; } /* XXX: the returned value is exotic in ES6, but we use a * simple object here with no prototype. Without a prototype, * [[DefaultValue]] coercion fails which is abit confusing. * No callable check/handling in the current Proxy subset. */ (void) duk_push_object_helper_proto(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), NULL); DUK_ASSERT_TOP(ctx, 3); /* Make _Target and _Handler non-configurable and non-writable. * They can still be forcibly changed by C code (both user and * Duktape internal), but not by Ecmascript code. */ /* Proxy target */ duk_dup(ctx, 0); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE); /* Proxy handler */ duk_dup(ctx, 1); duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_INT_HANDLER, DUK_PROPDESC_FLAGS_NONE); return 1; /* replacement handler */ }
/* Constructor */ DUK_INTERNAL duk_ret_t duk_bi_logger_constructor(duk_context *ctx) { duk_hthread *thr = (duk_hthread *) ctx; duk_idx_t nargs; /* Calling as a non-constructor is not meaningful. */ if (!duk_is_constructor_call(ctx)) { return DUK_RET_TYPE_ERROR; } nargs = duk_get_top(ctx); duk_set_top(ctx, 1); duk_push_this(ctx); /* [ name this ] */ if (nargs == 0) { /* Automatic defaulting of logger name from caller. This would * work poorly with tail calls, but constructor calls are currently * never tail calls, so tail calls are not an issue now. */ if (thr->callstack_top >= 2) { duk_activation *act_caller = thr->callstack + thr->callstack_top - 2; duk_hobject *func_caller; func_caller = DUK_ACT_GET_FUNC(act_caller); if (func_caller) { /* Stripping the filename might be a good idea * ("/foo/bar/quux.js" -> logger name "quux"), * but now used verbatim. */ duk_push_hobject(ctx, func_caller); duk_get_prop_stridx(ctx, -1, DUK_STRIDX_FILE_NAME); duk_replace(ctx, 0); } } } /* the stack is unbalanced here on purpose; we only rely on the * initial two values: [ name this ]. */ if (duk_is_string(ctx, 0)) { duk_dup(ctx, 0); duk_put_prop_stridx(ctx, 1, DUK_STRIDX_LC_N); } else { /* don't set 'n' at all, inherited value is used as name */ } duk_compact(ctx, 1); return 0; /* keep default instance */ }
duk_ret_t duk_bi_number_constructor(duk_context *ctx) { duk_idx_t nargs; duk_hobject *h_this; /* * The Number constructor uses ToNumber(arg) for number coercion * (coercing an undefined argument to NaN). However, if the * argument is not given at all, +0 must be used instead. To do * this, a vararg function is used. */ nargs = duk_get_top(ctx); if (nargs == 0) { duk_push_int(ctx, 0); } duk_to_number(ctx, 0); duk_set_top(ctx, 1); DUK_ASSERT_TOP(ctx, 1); if (!duk_is_constructor_call(ctx)) { return 1; } /* * E5 Section 15.7.2.1 requires that the constructed object * must have the original Number.prototype as its internal * prototype. However, since Number.prototype is non-writable * and non-configurable, this doesn't have to be enforced here: * The default object (bound to 'this') is OK, though we have * to change its class. * * Internal value set to ToNumber(arg) or +0; if no arg given, * ToNumber(undefined) = NaN, so special treatment is needed * (above). String internal value is immutable. */ /* XXX: helper */ duk_push_this(ctx); h_this = duk_get_hobject(ctx, -1); DUK_ASSERT(h_this != NULL); DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER); DUK_ASSERT(h_this->prototype == ((duk_hthread *) ctx)->builtins[DUK_BIDX_NUMBER_PROTOTYPE]); DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER); DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this)); duk_dup(ctx, 0); /* -> [ val obj val ] */ duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); return 0; /* no return value -> don't replace created value */ }
int duk_builtin_date_constructor(duk_context *ctx) { int nargs = duk_get_top(ctx); int is_cons = duk_is_constructor_call(ctx); double dparts[NUM_PARTS]; double d; DUK_DDDPRINT("Date constructor, nargs=%d, is_cons=%d", nargs, is_cons); duk_push_object_helper(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE), DUK_BIDX_DATE_PROTOTYPE); /* Unlike most built-ins, the internal [[PrimitiveValue]] of a Date * is mutable. */ if (nargs == 0 || !is_cons) { d = timeclip(GET_NOW_TIMEVAL(ctx)); duk_push_number(ctx, d); duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W); if (!is_cons) { /* called as a normal function: return new Date().toString() */ duk_to_string(ctx, -1); } return 1; } else if (nargs == 1) { duk_to_primitive(ctx, 0, DUK_HINT_NONE); if (duk_is_string(ctx, 0)) { parse_string(ctx, duk_to_string(ctx, 0)); duk_replace(ctx, 0); /* may be NaN */ } d = timeclip(duk_to_number(ctx, 0)); duk_push_number(ctx, d); duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W); return 1; } set_parts_from_args(ctx, dparts, nargs); /* Parts are in local time, convert when setting. */ set_this_timeval_from_dparts(ctx, dparts, FLAG_LOCALTIME /*flags*/); /* -> [ ... this timeval ] */ duk_pop(ctx); /* -> [ ... this ] */ return 1; }
static duk_ret_t my_func_1(duk_context *ctx) { printf("duk_is_constructor_call: %d\n", (int) duk_is_constructor_call(ctx)); /* check 'this'; it should have internal prototype set below to * constructor's "prototype" property. */ duk_push_this(ctx); duk_push_string(ctx, "own_value"); duk_put_prop_string(ctx, -2, "own_key"); duk_enum(ctx, -1, 0 /*enum_flags*/); while (duk_next(ctx, -1, 1 /*get_value*/)) { printf("key='%s', value='%s'\n", duk_to_string(ctx, -2), duk_to_string(ctx, -1)); duk_pop_2(ctx); } duk_pop(ctx); duk_pop(ctx); return 0; }
duk_ret_t duk_bi_boolean_constructor(duk_context *ctx) { duk_hobject *h_this; duk_to_boolean(ctx, 0); if (duk_is_constructor_call(ctx)) { /* FIXME: helper; rely on Boolean.prototype as being non-writable, non-configurable */ duk_push_this(ctx); h_this = duk_get_hobject(ctx, -1); DUK_ASSERT(h_this != NULL); DUK_ASSERT(h_this->prototype == ((duk_hthread *) ctx)->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]); DUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN); duk_dup(ctx, 0); /* -> [ val obj val ] */ duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); /* FIXME: proper flags? */ } /* unbalanced stack */ return 1; }
DUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx) { /* Behavior for constructor and non-constructor call is * the same except for augmenting the created error. When * called as a constructor, the caller (duk_new()) will handle * augmentation; when called as normal function, we need to do * it here. */ duk_hthread *thr = (duk_hthread *) ctx; duk_small_int_t bidx_prototype = duk_get_current_magic(ctx); /* same for both error and each subclass like TypeError */ duk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR); DUK_UNREF(thr); duk_push_object_helper(ctx, flags_and_class, bidx_prototype); /* If message is undefined, the own property 'message' is not set at * all to save property space. An empty message is inherited anyway. */ if (!duk_is_undefined(ctx, 0)) { duk_to_string(ctx, 0); duk_dup_0(ctx); /* [ message error message ] */ duk_xdef_prop_stridx(ctx, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC); } /* Augment the error if called as a normal function. __FILE__ and __LINE__ * are not desirable in this case. */ #ifdef DUK_USE_AUGMENT_ERROR_CREATE if (!duk_is_constructor_call(ctx)) { duk_err_augment_error_create(thr, thr, NULL, 0, 1 /*noblame_fileline*/); } #endif return 1; }
DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) { duk_uint_t arg_mask; arg_mask = duk_get_type_mask(thr, 0); if (!duk_is_constructor_call(thr) && /* not a constructor call */ ((arg_mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) == 0)) { /* and argument not null or undefined */ duk_to_object(thr, 0); return 1; } /* Pointer and buffer primitive values are treated like other * primitives values which have a fully fledged object counterpart: * promote to an object value. Lightfuncs and plain buffers are * coerced with ToObject() even they could also be returned as is. */ if (arg_mask & (DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_BOOLEAN | DUK_TYPE_MASK_NUMBER | DUK_TYPE_MASK_POINTER | DUK_TYPE_MASK_BUFFER | DUK_TYPE_MASK_LIGHTFUNC)) { /* For DUK_TYPE_OBJECT the coercion is a no-op and could * be checked for explicitly, but Object(obj) calls are * not very common so opt for minimal footprint. */ duk_to_object(thr, 0); return 1; } (void) duk_push_object_helper(thr, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_FASTREFS | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT), DUK_BIDX_OBJECT_PROTOTYPE); return 1; }
int duk_bi_buffer_constructor(duk_context *ctx) { if (duk_get_top(ctx) == 0) { (void) duk_push_fixed_buffer(ctx, 0); } else { duk_to_buffer(ctx, 0, NULL); } DUK_ASSERT(duk_is_buffer(ctx, 0)); duk_set_top(ctx, 1); if (duk_is_constructor_call(ctx)) { duk_push_object_helper(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_SPECIAL_BUFFEROBJ | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER), DUK_BIDX_BUFFER_PROTOTYPE); /* Buffer object internal value is immutable */ duk_dup(ctx, 0); duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); } /* Note: unbalanced stack on purpose */ return 1; }
int my_func(duk_context *ctx) { printf("duk_is_constructor_call: %d\n", duk_is_constructor_call(ctx)); return 0; }
int duk_bi_buffer_constructor(duk_context *ctx) { duk_size_t buf_size; duk_small_int_t buf_dynamic; duk_uint8_t *buf_data; const duk_uint8_t *src_data; duk_hobject *h_obj; /* * Constructor arguments are currently somewhat compatible with * (keep it that way if possible): * * http://nodejs.org/api/buffer.html * */ buf_dynamic = duk_get_boolean(ctx, 1); /* default to false */ switch (duk_get_type(ctx, 0)) { case DUK_TYPE_NUMBER: /* new buffer of specified size */ buf_size = (duk_size_t) duk_to_int(ctx, 0); (void) duk_push_buffer(ctx, buf_size, buf_dynamic); break; case DUK_TYPE_BUFFER: /* return input buffer, converted to a Buffer object if called as a * constructor (no change if called as a function). */ duk_set_top(ctx, 1); break; case DUK_TYPE_STRING: /* new buffer with string contents */ src_data = (const duk_uint8_t *) duk_get_lstring(ctx, 0, &buf_size); DUK_ASSERT(src_data != NULL); /* even for zero-length string */ buf_data = (duk_uint8_t *) duk_push_buffer(ctx, buf_size, buf_dynamic); DUK_MEMCPY((void *) buf_data, (const void *) src_data, (size_t) buf_size); break; case DUK_TYPE_OBJECT: /* Buffer object: get the plain buffer inside. If called as as * constructor, a new Buffer object pointing to the same plain * buffer is created below. */ h_obj = duk_get_hobject(ctx, 0); DUK_ASSERT(h_obj != NULL); if (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) != DUK_HOBJECT_CLASS_BUFFER) { return DUK_RET_TYPE_ERROR; } duk_get_prop_stridx(ctx, 0, DUK_STRIDX_INT_VALUE); DUK_ASSERT(duk_is_buffer(ctx, -1)); break; case DUK_TYPE_NONE: default: return DUK_RET_TYPE_ERROR; } /* stack is unbalanced, but: [ <something> buf ] */ if (duk_is_constructor_call(ctx)) { duk_push_object_helper(ctx, DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_EXOTIC_BUFFEROBJ | DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BUFFER), DUK_BIDX_BUFFER_PROTOTYPE); /* Buffer object internal value is immutable */ duk_dup(ctx, -2); duk_def_prop_stridx(ctx, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE); } /* Note: unbalanced stack on purpose */ return 1; }
/* XXX: much to improve (code size) */ DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) { duk_hobject *h_pattern; DUK_ASSERT_TOP(thr, 2); h_pattern = duk_get_hobject(thr, 0); if (!duk_is_constructor_call(thr) && h_pattern != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP && duk_is_undefined(thr, 1)) { /* Called as a function, pattern has [[Class]] "RegExp" and * flags is undefined -> return object as is. */ /* XXX: ES2015 has a NewTarget SameValue() check which is not * yet implemented. */ duk_dup_0(thr); return 1; } /* Else functionality is identical for function call and constructor * call. */ if (h_pattern != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) { duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE); if (duk_is_undefined(thr, 1)) { /* In ES5 one would need to read the flags individually; * in ES2015 just read .flags. */ duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS); } else { /* In ES2015 allowed; overrides argument RegExp flags. */ duk_dup_1(thr); } } else { if (duk_is_undefined(thr, 0)) { duk_push_hstring_empty(thr); } else { duk_dup_0(thr); duk_to_string(thr, -1); /* Rejects Symbols. */ } if (duk_is_undefined(thr, 1)) { duk_push_hstring_empty(thr); } else { duk_dup_1(thr); duk_to_string(thr, -1); /* Rejects Symbols. */ } /* [ ... pattern flags ] */ } DUK_DDD(DUK_DDDPRINT("RegExp constructor/function call, pattern=%!T, flags=%!T", (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1))); /* [ ... pattern flags ] (both uncoerced) */ duk_to_string(thr, -2); duk_to_string(thr, -1); duk_regexp_compile(thr); /* [ ... bytecode escaped_source ] */ duk_regexp_create_instance(thr); /* [ ... RegExp ] */ return 1; }
//duk_bool_t duk_is_constructor_call(duk_context *ctx); duk_bool_t aperl_duk_is_constructor_call(duk_context *ctx) { duk_bool_t ret = duk_is_constructor_call(ctx); return ret; }
/* XXX: Make this obsolete by adding a function flag for rejecting a * non-constructor call automatically? */ DUK_INTERNAL void duk_require_constructor_call(duk_context *ctx) { if (!duk_is_constructor_call(ctx)) { DUK_ERROR_TYPE((duk_hthread *) ctx, DUK_STR_CONSTRUCT_ONLY); } }
bool Context::isConstructorCall() { return (duk_is_constructor_call(m_handle) ? true: false); }
/* XXX: much to improve (code size) */ DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx) { duk_hthread *thr = (duk_hthread *) ctx; duk_hobject *h_pattern; DUK_ASSERT_TOP(ctx, 2); h_pattern = duk_get_hobject(ctx, 0); if (!duk_is_constructor_call(ctx) && h_pattern != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP && duk_is_undefined(ctx, 1)) { /* Called as a function, pattern has [[Class]] "RegExp" and * flags is undefined -> return object as is. */ duk_dup(ctx, 0); return 1; } /* Else functionality is identical for function call and constructor * call. */ if (h_pattern != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) { if (duk_is_undefined(ctx, 1)) { duk_bool_t flag_g, flag_i, flag_m; duk_get_prop_stridx(ctx, 0, DUK_STRIDX_SOURCE); flag_g = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_GLOBAL, NULL); flag_i = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_IGNORE_CASE, NULL); flag_m = duk_get_prop_stridx_boolean(ctx, 0, DUK_STRIDX_MULTILINE, NULL); duk_push_sprintf(ctx, "%s%s%s", (const char *) (flag_g ? "g" : ""), (const char *) (flag_i ? "i" : ""), (const char *) (flag_m ? "m" : "")); /* [ ... pattern flags ] */ } else { return DUK_RET_TYPE_ERROR; } } else { if (duk_is_undefined(ctx, 0)) { duk_push_string(ctx, ""); } else { duk_dup(ctx, 0); duk_to_string(ctx, -1); } if (duk_is_undefined(ctx, 1)) { duk_push_string(ctx, ""); } else { duk_dup(ctx, 1); duk_to_string(ctx, -1); } /* [ ... pattern flags ] */ } DUK_DDD(DUK_DDDPRINT("RegExp constructor/function call, pattern=%!T, flags=%!T", (duk_tval *) duk_get_tval(ctx, -2), (duk_tval *) duk_get_tval(ctx, -1))); /* [ ... pattern flags ] */ duk_regexp_compile(thr); /* [ ... bytecode escaped_source ] */ duk_regexp_create_instance(thr); /* [ ... RegExp ] */ return 1; }
duk_ret_t JsExe::Constructor(duk_context* duktapeContext) { try { if (duk_get_top(duktapeContext) != 0) JavaScriptHelper::Throw(duktapeContext, "No arguments for Exe/Dll constructor expected"); if (duk_is_constructor_call(duktapeContext)) duk_push_this(duktapeContext); else duk_push_object(duktapeContext); duk_push_pointer(duktapeContext, new JsExe); duk_put_prop_string(duktapeContext, -2, "__Ptr"); duk_push_c_function(duktapeContext, JsExe::Destructor, 1); duk_set_finalizer(duktapeContext, -2); duk_push_c_function(duktapeContext, JsExe::Build, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Build"); duk_push_c_function(duktapeContext, JsExe::Files, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Files"); duk_push_c_function(duktapeContext, JsExe::DependencyCheck, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "DependencyCheck"); duk_push_c_function(duktapeContext, JsExe::CRT, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "CRT"); duk_push_c_function(duktapeContext, JsExe::ObjDir, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "ObjDir"); duk_push_c_function(duktapeContext, JsExe::Includes, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Includes"); duk_push_c_function(duktapeContext, JsExe::Defines, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Defines"); duk_push_c_function(duktapeContext, JsExe::Threads, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Threads"); duk_push_c_function(duktapeContext, JsExe::CompileArgs, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "CompileArgs"); duk_push_c_function(duktapeContext, JsExe::CompileArgs, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Args"); duk_push_c_function(duktapeContext, JsExe::PrecompiledHeader, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "PrecompiledHeader"); duk_push_c_function(duktapeContext, JsExe::WarningLevel, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "WarningLevel"); duk_push_c_function(duktapeContext, JsExe::WarningAsError, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "WarningAsError"); duk_push_c_function(duktapeContext, JsExe::WarningDisable, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "WarningDisable"); duk_push_c_function(duktapeContext, JsExe::Output, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Output"); duk_push_c_function(duktapeContext, JsExe::LibPath, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "LibPath"); duk_push_c_function(duktapeContext, JsExe::Libs, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Libs"); duk_push_c_function(duktapeContext, JsExe::ImportLib, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "ImportLib"); duk_push_c_function(duktapeContext, JsExe::Def, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Def"); duk_push_c_function(duktapeContext, JsExe::LinkArgs, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "LinkArgs"); duk_push_c_function(duktapeContext, JsExe::Res, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Res"); duk_push_c_function(duktapeContext, JsExe::BeforeCompile, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "BeforeCompile"); duk_push_c_function(duktapeContext, JsExe::BeforeLink, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "BeforeLink"); duk_push_c_function(duktapeContext, JsExe::Create, DUK_VARARGS); duk_put_prop_string(duktapeContext, -2, "Create"); return 1; } catch (std::exception& e) { JavaScriptHelper::Throw(duktapeContext, e.what()); } }
static duk_ret_t test_func(duk_context *ctx, void *udata) { (void) udata; if (ctx) { printf("dummy - return here\n"); fflush(stdout); return 0; } /* Up-to-date for Duktape 1.3.0, alphabetical order: * $ cd website/api; ls *.yaml */ (void) duk_alloc_raw(ctx, 0); (void) duk_alloc(ctx, 0); (void) duk_base64_decode(ctx, 0); (void) duk_base64_encode(ctx, 0); (void) duk_buffer_to_string(ctx, 0); (void) duk_call_method(ctx, 0); (void) duk_call_prop(ctx, 0, 0); (void) duk_call(ctx, 0); (void) duk_char_code_at(ctx, 0, 0); (void) duk_check_stack_top(ctx, 0); (void) duk_check_stack(ctx, 0); (void) duk_check_type_mask(ctx, 0, 0); (void) duk_check_type(ctx, 0, 0); (void) duk_compact(ctx, 0); (void) duk_compile_lstring_filename(ctx, 0, "dummy", 0); (void) duk_compile_lstring(ctx, 0, "dummy", 0); (void) duk_compile_string_filename(ctx, 0, "dummy"); (void) duk_compile_string(ctx, 0, "dummy"); (void) duk_compile(ctx, 0); (void) duk_concat(ctx, 0); (void) duk_config_buffer(ctx, 0, NULL, 0); (void) duk_copy(ctx, 0, 0); (void) duk_create_heap_default(); (void) duk_create_heap(NULL, NULL, NULL, NULL, NULL); (void) duk_debugger_attach(ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); (void) duk_debugger_cooperate(ctx); (void) duk_debugger_detach(ctx); (void) duk_debugger_notify(ctx, 0); (void) duk_debugger_pause(ctx); (void) duk_decode_string(ctx, 0, NULL, NULL); (void) duk_def_prop(ctx, 0, 0); (void) duk_del_prop_index(ctx, 0, 0); (void) duk_del_prop_string(ctx, 0, "dummy"); (void) duk_del_prop(ctx, 0); (void) duk_destroy_heap(ctx); (void) duk_dump_function(ctx); (void) duk_dup_top(ctx); (void) duk_dup(ctx, 0); (void) duk_enum(ctx, 0, 0); (void) duk_equals(ctx, 0, 0); duk_error_va(ctx, 0, NULL, NULL); duk_error(ctx, 0, "dummy"); /* (void) cast won't work without variadic macros */ (void) duk_eval_lstring_noresult(ctx, "dummy", 0); (void) duk_eval_lstring(ctx, "dummy", 0); (void) duk_eval_noresult(ctx); (void) duk_eval_string_noresult(ctx, "dummy"); (void) duk_eval_string(ctx, "dummy"); (void) duk_eval(ctx); (void) duk_fatal(ctx, "dummy"); (void) duk_free_raw(ctx, NULL); (void) duk_free(ctx, NULL); (void) duk_gc(ctx, 0); (void) duk_get_boolean(ctx, 0); (void) duk_get_buffer_data(ctx, 0, NULL); (void) duk_get_buffer(ctx, 0, NULL); (void) duk_get_c_function(ctx, 0); (void) duk_get_context(ctx, 0); (void) duk_get_current_magic(ctx); (void) duk_get_error_code(ctx, 0); (void) duk_get_finalizer(ctx, 0); (void) duk_get_global_string(ctx, 0); (void) duk_get_heapptr(ctx, 0); (void) duk_get_int(ctx, 0); (void) duk_get_length(ctx, 0); (void) duk_get_lstring(ctx, 0, NULL); (void) duk_get_magic(ctx, 0); (void) duk_get_memory_functions(ctx, NULL); (void) duk_get_number(ctx, 0); (void) duk_get_pointer(ctx, 0); (void) duk_get_prop_index(ctx, 0, 0); (void) duk_get_prop_string(ctx, 0, "dummy"); (void) duk_get_prop(ctx, 0); (void) duk_get_prototype(ctx, 0); (void) duk_get_string(ctx, 0); (void) duk_get_top_index(ctx); (void) duk_get_top(ctx); (void) duk_get_type_mask(ctx, 0); (void) duk_get_type(ctx, 0); (void) duk_get_uint(ctx, 0); (void) duk_has_prop_index(ctx, 0, 0); (void) duk_has_prop_string(ctx, 0, "dummy"); (void) duk_has_prop(ctx, 0); (void) duk_hex_decode(ctx, 0); (void) duk_hex_encode(ctx, 0); (void) duk_insert(ctx, 0); (void) duk_instanceof(ctx, 0, 0); (void) duk_is_array(ctx, 0); (void) duk_is_boolean(ctx, 0); (void) duk_is_bound_function(ctx, 0); (void) duk_is_buffer(ctx, 0); (void) duk_is_callable(ctx, 0); (void) duk_is_c_function(ctx, 0); (void) duk_is_constructor_call(ctx); (void) duk_is_dynamic_buffer(ctx, 0); (void) duk_is_ecmascript_function(ctx, 0); (void) duk_is_error(ctx, 0); (void) duk_is_eval_error(ctx, 0); (void) duk_is_fixed_buffer(ctx, 0); (void) duk_is_function(ctx, 0); (void) duk_is_lightfunc(ctx, 0); (void) duk_is_nan(ctx, 0); (void) duk_is_null_or_undefined(ctx, 0); (void) duk_is_null(ctx, 0); (void) duk_is_number(ctx, 0); (void) duk_is_object_coercible(ctx, 0); (void) duk_is_object(ctx, 0); (void) duk_is_pointer(ctx, 0); (void) duk_is_primitive(ctx, 0); (void) duk_is_range_error(ctx, 0); (void) duk_is_reference_error(ctx, 0); (void) duk_is_strict_call(ctx); (void) duk_is_string(ctx, 0); (void) duk_is_syntax_error(ctx, 0); (void) duk_is_thread(ctx, 0); (void) duk_is_type_error(ctx, 0); (void) duk_is_undefined(ctx, 0); (void) duk_is_uri_error(ctx, 0); (void) duk_is_valid_index(ctx, 0); (void) duk_join(ctx, 0); (void) duk_json_decode(ctx, 0); (void) duk_json_encode(ctx, 0); (void) duk_load_function(ctx); (void) duk_map_string(ctx, 0, NULL, NULL); (void) duk_new(ctx, 0); (void) duk_next(ctx, 0, 0); (void) duk_normalize_index(ctx, 0); (void) duk_pcall_method(ctx, 0); (void) duk_pcall_prop(ctx, 0, 0); (void) duk_pcall(ctx, 0); (void) duk_pcompile_lstring_filename(ctx, 0, "dummy", 0); (void) duk_pcompile_lstring(ctx, 0, "dummy", 0); (void) duk_pcompile_string_filename(ctx, 0, "dummy"); (void) duk_pcompile_string(ctx, 0, "dummy"); (void) duk_pcompile(ctx, 0); (void) duk_peval_lstring_noresult(ctx, "dummy", 0); (void) duk_peval_lstring(ctx, "dummy", 0); (void) duk_peval_noresult(ctx); (void) duk_peval_string_noresult(ctx, "dummy"); (void) duk_peval_string(ctx, "dummy"); (void) duk_peval(ctx); (void) duk_pnew(ctx, 0); (void) duk_pop_2(ctx); (void) duk_pop_3(ctx); (void) duk_pop_n(ctx, 0); (void) duk_pop(ctx); (void) duk_push_array(ctx); (void) duk_push_boolean(ctx, 0); (void) duk_push_buffer_object(ctx, 0, 0, 0, 0); (void) duk_push_buffer(ctx, 0, 0); (void) duk_push_c_function(ctx, NULL, 0); (void) duk_push_c_lightfunc(ctx, NULL, 0, 0, 0); (void) duk_push_context_dump(ctx); (void) duk_push_current_function(ctx); (void) duk_push_current_thread(ctx); (void) duk_push_dynamic_buffer(ctx, 0); (void) duk_push_error_object_va(ctx, 0, NULL, NULL); (void) duk_push_error_object(ctx, 0, "dummy"); (void) duk_push_external_buffer(ctx); (void) duk_push_false(ctx); (void) duk_push_fixed_buffer(ctx, 0); (void) duk_push_global_object(ctx); (void) duk_push_global_stash(ctx); (void) duk_push_heap_stash(ctx); (void) duk_push_heapptr(ctx, NULL); (void) duk_push_int(ctx, 0); (void) duk_push_lstring(ctx, "dummy", 0); (void) duk_push_nan(ctx); (void) duk_push_null(ctx); (void) duk_push_number(ctx, 0.0); (void) duk_push_object(ctx); (void) duk_push_pointer(ctx, NULL); (void) duk_push_sprintf(ctx, "dummy"); (void) duk_push_string(ctx, "dummy"); (void) duk_push_this(ctx); (void) duk_push_thread_new_globalenv(ctx); (void) duk_push_thread_stash(ctx, NULL); (void) duk_push_thread(ctx); (void) duk_push_true(ctx); (void) duk_push_uint(ctx, 0); (void) duk_push_undefined(ctx); (void) duk_push_vsprintf(ctx, "dummy", NULL); (void) duk_put_function_list(ctx, 0, NULL); (void) duk_put_global_string(ctx, NULL); (void) duk_put_number_list(ctx, 0, NULL); (void) duk_put_prop_index(ctx, 0, 0); (void) duk_put_prop_string(ctx, 0, "dummy"); (void) duk_put_prop(ctx, 0); (void) duk_realloc_raw(ctx, NULL, 0); (void) duk_realloc(ctx, NULL, 0); (void) duk_remove(ctx, 0); (void) duk_replace(ctx, 0); (void) duk_require_boolean(ctx, 0); (void) duk_require_buffer_data(ctx, 0, NULL); (void) duk_require_buffer(ctx, 0, NULL); (void) duk_require_c_function(ctx, 0); (void) duk_require_callable(ctx, 0); (void) duk_require_context(ctx, 0); (void) duk_require_function(ctx, 0); (void) duk_require_heapptr(ctx, 0); (void) duk_require_int(ctx, 0); (void) duk_require_lstring(ctx, 0, NULL); (void) duk_require_normalize_index(ctx, 0); (void) duk_require_null(ctx, 0); (void) duk_require_number(ctx, 0); (void) duk_require_object_coercible(ctx, 0); (void) duk_require_pointer(ctx, 0); (void) duk_require_stack_top(ctx, 0); (void) duk_require_stack(ctx, 0); (void) duk_require_string(ctx, 0); (void) duk_require_top_index(ctx); (void) duk_require_type_mask(ctx, 0, 0); (void) duk_require_uint(ctx, 0); (void) duk_require_undefined(ctx, 0); (void) duk_require_valid_index(ctx, 0); (void) duk_resize_buffer(ctx, 0, 0); (void) duk_safe_call(ctx, NULL, NULL, 0, 0); (void) duk_safe_to_lstring(ctx, 0, NULL); (void) duk_safe_to_string(ctx, 0); (void) duk_set_finalizer(ctx, 0); (void) duk_set_global_object(ctx); (void) duk_set_magic(ctx, 0, 0); (void) duk_set_prototype(ctx, 0); (void) duk_set_top(ctx, 0); (void) duk_steal_buffer(ctx, 0, NULL); (void) duk_strict_equals(ctx, 0, 0); (void) duk_substring(ctx, 0, 0, 0); (void) duk_swap_top(ctx, 0); (void) duk_swap(ctx, 0, 0); (void) duk_throw(ctx); (void) duk_to_boolean(ctx, 0); (void) duk_to_buffer(ctx, 0, NULL); (void) duk_to_defaultvalue(ctx, 0, 0); (void) duk_to_dynamic_buffer(ctx, 0, NULL); (void) duk_to_fixed_buffer(ctx, 0, NULL); (void) duk_to_int32(ctx, 0); (void) duk_to_int(ctx, 0); (void) duk_to_lstring(ctx, 0, NULL); (void) duk_to_null(ctx, 0); (void) duk_to_number(ctx, 0); (void) duk_to_object(ctx, 0); (void) duk_to_pointer(ctx, 0); (void) duk_to_primitive(ctx, 0, 0); (void) duk_to_string(ctx, 0); (void) duk_to_uint16(ctx, 0); (void) duk_to_uint32(ctx, 0); (void) duk_to_uint(ctx, 0); (void) duk_to_undefined(ctx, 0); (void) duk_trim(ctx, 0); (void) duk_xcopy_top(ctx, NULL, 0); (void) duk_xmove_top(ctx, NULL, 0); printf("never here\n"); fflush(stdout); return 0; }
static duk_ret_t my_func(duk_context *ctx) { printf("duk_is_constructor_call: %d\n", (int) duk_is_constructor_call(ctx)); return 0; }