Browse Source

Reformat some source files with clang-format

pull/2424/head
Sami Vaarala 3 years ago
parent
commit
4cc7e0ad85
  1. 696
      src-input/duk_bi_json.c
  2. 66
      src-input/duk_bi_math.c
  3. 63
      src-input/duk_bi_number.c
  4. 183
      src-input/duk_bi_object.c
  5. 6
      src-input/duk_bi_performance.c
  6. 7
      src-input/duk_bi_pointer.c
  7. 2
      src-input/duk_bi_promise.c
  8. 14
      src-input/duk_bi_protos.h
  9. 12
      src-input/duk_bi_proxy.c
  10. 4
      src-input/duk_bi_reflect.c
  11. 36
      src-input/duk_bi_regexp.c
  12. 227
      src-input/duk_bi_string.c
  13. 8
      src-input/duk_bi_symbol.c
  14. 64
      src-input/duk_bi_thread.c
  15. 283
      src-input/duk_dblunion.h
  16. 86
      src-input/duk_debug.h
  17. 4
      src-input/duk_debug_fixedbuffer.c
  18. 10
      src-input/duk_debug_macros.c
  19. 398
      src-input/duk_debug_vsnprintf.c
  20. 329
      src-input/duk_debugger.c
  21. 118
      src-input/duk_debugger.h
  22. 511
      src-input/duk_error.h
  23. 110
      src-input/duk_error_augment.c
  24. 18
      src-input/duk_error_longjmp.c
  25. 58
      src-input/duk_error_macros.c
  26. 15
      src-input/duk_error_misc.c
  27. 31
      src-input/duk_error_throw.c

696
src-input/duk_bi_json.c

File diff suppressed because it is too large

66
src-input/duk_bi_math.c

@ -141,7 +141,7 @@ DUK_LOCAL double duk__trunc(double x) {
return x >= 0.0 ? DUK_FLOOR(x) : DUK_CEIL(x);
#endif
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
DUK_LOCAL double duk__round_fixed(double x) {
/* Numbers half-way between integers must be rounded towards +Infinity,
@ -256,51 +256,23 @@ DUK_LOCAL double duk__atan2_fixed(double x, double y) {
return DUK_ATAN2(x, y);
}
#endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
#endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
/* order must match constants in genbuiltins.py */
DUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {
#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)
duk__fabs,
duk__acos,
duk__asin,
duk__atan,
duk__ceil,
duk__cos,
duk__exp,
duk__floor,
duk__log,
duk__round_fixed,
duk__sin,
duk__sqrt,
duk__tan,
duk__fabs, duk__acos, duk__asin, duk__atan, duk__ceil, duk__cos, duk__exp,
duk__floor, duk__log, duk__round_fixed, duk__sin, duk__sqrt, duk__tan,
#if defined(DUK_USE_ES6)
duk__cbrt,
duk__log2,
duk__log10,
duk__trunc
duk__cbrt, duk__log2, duk__log10, duk__trunc
#endif
#else /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
DUK_FABS,
DUK_ACOS,
DUK_ASIN,
DUK_ATAN,
DUK_CEIL,
DUK_COS,
DUK_EXP,
DUK_FLOOR,
DUK_LOG,
duk__round_fixed,
DUK_SIN,
DUK_SQRT,
DUK_TAN,
#else /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
DUK_FABS, DUK_ACOS, DUK_ASIN, DUK_ATAN, DUK_CEIL, DUK_COS, DUK_EXP,
DUK_FLOOR, DUK_LOG, duk__round_fixed, DUK_SIN, DUK_SQRT, DUK_TAN,
#if defined(DUK_USE_ES6)
duk__cbrt,
duk__log2,
duk__log10,
duk__trunc
duk__cbrt, duk__log2, duk__log10, duk__trunc
#endif
#endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
#endif /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */
};
/* order must match constants in genbuiltins.py */
@ -335,7 +307,7 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_hthread *thr) {
DUK_ASSERT(fun_idx >= 0);
DUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func)));
arg1 = duk_to_number(thr, 0); /* explicit ordered evaluation to match coercion semantics */
arg1 = duk_to_number(thr, 0); /* explicit ordered evaluation to match coercion semantics */
arg2 = duk_to_number(thr, 1);
fun = duk__two_arg_funcs[fun_idx];
duk_push_number(thr, (duk_double_t) fun((double) arg1, (double) arg2));
@ -421,7 +393,7 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) {
duk_push_number(thr, (duk_double_t) DUK_SQRT(sum) * max);
return 1;
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {
@ -430,7 +402,7 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {
d = duk_to_number(thr, 0);
if (duk_double_is_nan(d)) {
DUK_ASSERT(duk_is_nan(thr, -1));
return 1; /* NaN input -> return NaN */
return 1; /* NaN input -> return NaN */
}
if (duk_double_equals(d, 0.0)) {
/* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */
@ -439,7 +411,7 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {
duk_push_int(thr, (d > 0.0 ? 1 : -1));
return 1;
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {
@ -459,7 +431,7 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {
DUK_ASSERT(i <= 32);
duk_push_uint(thr, i);
return 1;
#else /* DUK_USE_PREFER_SIZE */
#else /* DUK_USE_PREFER_SIZE */
i = 0;
x = duk_to_uint32(thr, 0);
if (x & 0xffff0000UL) {
@ -495,9 +467,9 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {
DUK_ASSERT(i <= 32);
duk_push_uint(thr, i);
return 1;
#endif /* DUK_USE_PREFER_SIZE */
#endif /* DUK_USE_PREFER_SIZE */
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) {
@ -514,6 +486,6 @@ DUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) {
duk_push_i32(thr, (duk_int32_t) z);
return 1;
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_MATH_BUILTIN */
#endif /* DUK_USE_MATH_BUILTIN */

63
src-input/duk_bi_number.c

@ -19,8 +19,7 @@ DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {
goto done;
}
h = duk_get_hobject(thr, -1);
if (!h ||
(DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {
if (!h || (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {
DUK_DDD(DUK_DDDPRINT("unacceptable this value: %!T", (duk_tval *) duk_get_tval(thr, -1)));
DUK_ERROR_TYPE(thr, "number expected");
DUK_WO_NORETURN(return 0.0;);
@ -28,10 +27,11 @@ DUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {
duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);
DUK_ASSERT(duk_is_number(thr, -1));
DUK_DDD(DUK_DDDPRINT("number object: %!T, internal value: %!T",
(duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));
(duk_tval *) duk_get_tval(thr, -2),
(duk_tval *) duk_get_tval(thr, -1)));
duk_remove_m2(thr);
done:
done:
return duk_get_number(thr, -1);
}
@ -80,9 +80,9 @@ DUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) {
DUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);
DUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this));
duk_dup_0(thr); /* -> [ val obj val ] */
duk_dup_0(thr); /* -> [ val obj val ] */
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);
return 0; /* no return value -> don't replace created value */
return 0; /* no return value -> don't replace created value */
}
DUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_hthread *thr) {
@ -104,10 +104,7 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_hthread *thr) {
n2s_flags = 0;
duk_numconv_stringify(thr,
radix /*radix*/,
0 /*digits*/,
n2s_flags /*flags*/);
duk_numconv_stringify(thr, radix /*radix*/, 0 /*digits*/, n2s_flags /*flags*/);
return 1;
}
@ -145,16 +142,12 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) {
goto use_to_string;
}
n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |
DUK_N2S_FLAG_FRACTION_DIGITS;
n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT | DUK_N2S_FLAG_FRACTION_DIGITS;
duk_numconv_stringify(thr,
10 /*radix*/,
frac_digits /*digits*/,
n2s_flags /*flags*/);
duk_numconv_stringify(thr, 10 /*radix*/, frac_digits /*digits*/, n2s_flags /*flags*/);
return 1;
use_to_string:
use_to_string:
DUK_ASSERT_TOP(thr, 2);
duk_to_string(thr, -1);
return 1;
@ -170,7 +163,7 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr)
d = duk__push_this_number_plain(thr);
frac_undefined = duk_is_undefined(thr, 0);
duk_to_int(thr, 0); /* for side effects */
duk_to_int(thr, 0); /* for side effects */
c = (duk_small_int_t) DUK_FPCLASSIFY(d);
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {
@ -179,16 +172,12 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr)
frac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);
n2s_flags = DUK_N2S_FLAG_FORCE_EXP |
(frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT);
n2s_flags = DUK_N2S_FLAG_FORCE_EXP | (frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT);
duk_numconv_stringify(thr,
10 /*radix*/,
frac_digits + 1 /*leading digit + fractions*/,
n2s_flags /*flags*/);
duk_numconv_stringify(thr, 10 /*radix*/, frac_digits + 1 /*leading digit + fractions*/, n2s_flags /*flags*/);
return 1;
use_to_string:
use_to_string:
DUK_ASSERT_TOP(thr, 2);
duk_to_string(thr, -1);
return 1;
@ -213,7 +202,7 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {
}
DUK_ASSERT_TOP(thr, 2);
duk_to_int(thr, 0); /* for side effects */
duk_to_int(thr, 0); /* for side effects */
c = (duk_small_int_t) DUK_FPCLASSIFY(d);
if (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {
@ -222,16 +211,12 @@ DUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {
prec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21);
n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |
DUK_N2S_FLAG_NO_ZERO_PAD;
n2s_flags = DUK_N2S_FLAG_FIXED_FORMAT | DUK_N2S_FLAG_NO_ZERO_PAD;
duk_numconv_stringify(thr,
10 /*radix*/,
prec /*digits*/,
n2s_flags /*flags*/);
duk_numconv_stringify(thr, 10 /*radix*/, prec /*digits*/, n2s_flags /*flags*/);
return 1;
use_to_string:
use_to_string:
/* Used when precision is undefined; also used for NaN (-> "NaN"),
* and +/- infinity (-> "Infinity", "-Infinity").
*/
@ -257,16 +242,16 @@ DUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) {
d = duk_get_number(thr, 0);
switch (magic) {
case 0: /* isFinite() */
case 0: /* isFinite() */
ret = duk_double_is_finite(d);
break;
case 1: /* isInteger() */
case 1: /* isInteger() */
ret = duk_double_is_integer(d);
break;
case 2: /* isNaN() */
case 2: /* isNaN() */
ret = duk_double_is_nan(d);
break;
default: /* isSafeInteger() */
default: /* isSafeInteger() */
DUK_ASSERT(magic == 3);
ret = duk_double_is_safe_integer(d);
}
@ -275,6 +260,6 @@ DUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) {
duk_push_boolean(thr, ret);
return 1;
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_NUMBER_BUILTIN */
#endif /* DUK_USE_NUMBER_BUILTIN */

183
src-input/duk_bi_object.c

@ -19,8 +19,8 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {
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 */
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;
}
@ -30,13 +30,8 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {
* 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)) {
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.
@ -46,13 +41,12 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {
}
(void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
DUK_BIDX_OBJECT_PROTOTYPE);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_hthread *thr) {
@ -109,9 +103,8 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) {
DUK_ASSERT(proto != NULL || duk_is_null(thr, 0));
(void) duk_push_object_helper_proto(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),
proto);
if (!duk_is_undefined(thr, 1)) {
@ -132,7 +125,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) {
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *thr) {
@ -147,11 +140,9 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *
obj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
DUK_ASSERT(obj != NULL);
duk_to_object(thr, 1); /* properties object */
duk_to_object(thr, 1); /* properties object */
DUK_DDD(DUK_DDDPRINT("target=%!iT, properties=%!iT",
(duk_tval *) duk_get_tval(thr, 0),
(duk_tval *) duk_get_tval(thr, 1)));
DUK_DDD(DUK_DDDPRINT("target=%!iT, properties=%!iT", (duk_tval *) duk_get_tval(thr, 0), (duk_tval *) duk_get_tval(thr, 1)));
/*
* Two pass approach to processing the property descriptors.
@ -164,7 +155,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *
*/
for (pass = 0; pass < 2; pass++) {
duk_set_top(thr, 2); /* -> [ hobject props ] */
duk_set_top(thr, 2); /* -> [ hobject props ] */
duk_enum(thr, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/);
for (;;) {
@ -184,12 +175,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *
/* [ hobject props enum(props) key desc ] */
duk_hobject_prepare_property_descriptor(thr,
4 /*idx_desc*/,
&defprop_flags,
&idx_value,
&get,
&set);
duk_hobject_prepare_property_descriptor(thr, 4 /*idx_desc*/, &defprop_flags, &idx_value, &get, &set);
/* [ hobject props enum(props) key desc [multiple values] ] */
@ -201,14 +187,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *
key = duk_known_hstring(thr, 3);
DUK_ASSERT(key != NULL);
duk_hobject_define_property_helper(thr,
defprop_flags,
obj,
key,
idx_value,
get,
set,
1 /*throw_flag*/);
duk_hobject_define_property_helper(thr, defprop_flags, obj, key, idx_value, get, set, 1 /*throw_flag*/);
}
}
@ -219,7 +198,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *
duk_dup_0(thr);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread *thr) {
@ -228,7 +207,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread
duk_seal_freeze_raw(thr, 0, (duk_bool_t) duk_get_current_magic(thr) /*is_freeze*/);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hthread *thr) {
@ -240,34 +219,33 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hth
mask = duk_get_type_mask(thr, 0);
if (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {
DUK_ASSERT(is_frozen == 0 || is_frozen == 1);
duk_push_boolean(thr, (mask & DUK_TYPE_MASK_LIGHTFUNC) ?
1 : /* lightfunc always frozen and sealed */
(is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */
duk_push_boolean(thr,
(mask & DUK_TYPE_MASK_LIGHTFUNC) ? 1 : /* lightfunc always frozen and sealed */
(is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */
} else {
/* ES2015 Sections 19.1.2.12, 19.1.2.13: anything other than an object
* is considered to be already sealed and frozen.
*/
h = duk_get_hobject(thr, 0);
duk_push_boolean(thr, (h == NULL) ||
duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/));
duk_push_boolean(thr, (h == NULL) || duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/));
}
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_hthread *thr) {
DUK_ASSERT_TOP(thr, 0);
(void) duk_push_this_coercible_to_object(thr);
duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_TO_STRING);
#if 0 /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */
#if 0 /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */
duk_require_callable(thr, 1);
#endif
duk_dup_0(thr); /* -> [ O toString O ] */
duk_call_method(thr, 0); /* XXX: call method tail call? */
duk_dup_0(thr); /* -> [ O toString O ] */
duk_call_method(thr, 0); /* XXX: call method tail call? */
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) {
@ -275,7 +253,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) {
(void) duk_push_this_coercible_to_object(thr);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr) {
@ -286,7 +264,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr)
h_v = duk_get_hobject(thr, 0);
if (!h_v) {
duk_push_false(thr); /* XXX: tail call: return duk_push_false(thr) */
duk_push_false(thr); /* XXX: tail call: return duk_push_false(thr) */
return 1;
}
@ -296,22 +274,24 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr)
/* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare.
* Prototype loops should cause an error to be thrown.
*/
duk_push_boolean(thr, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));
duk_push_boolean(
thr,
duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_hthread *thr) {
return (duk_ret_t) duk_hobject_object_ownprop_helper(thr, 0 /*required_desc_flags*/);
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_hthread *thr) {
return (duk_ret_t) duk_hobject_object_ownprop_helper(thr, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/);
}
#endif /* DUK_USE_OBJECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
/* Shared helper to implement Object.getPrototypeOf,
@ -368,7 +348,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_hthread *thr) {
}
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
/* Shared helper to implement ES2015 Object.setPrototypeOf,
@ -387,7 +367,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {
duk_hobject *h_obj;
duk_hobject *h_new_proto;
duk_hobject *h_curr;
duk_ret_t ret_success = 1; /* retval for success path */
duk_ret_t ret_success = 1; /* retval for success path */
duk_uint_t mask;
duk_int_t magic;
@ -408,9 +388,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {
if (magic == 1) {
duk_require_object_coercible(thr, 0);
} else {
duk_require_hobject_accept_mask(thr, 0,
DUK_TYPE_MASK_LIGHTFUNC |
DUK_TYPE_MASK_BUFFER);
duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);
}
duk_require_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT);
}
@ -421,9 +399,8 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {
mask = duk_get_type_mask(thr, 0);
if (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {
duk_hobject *curr_proto;
curr_proto = thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ?
DUK_BIDX_FUNCTION_PROTOTYPE :
DUK_BIDX_UINT8ARRAY_PROTOTYPE];
curr_proto =
thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ? DUK_BIDX_FUNCTION_PROTOTYPE : DUK_BIDX_UINT8ARRAY_PROTOTYPE];
if (h_new_proto == curr_proto) {
goto skip;
}
@ -453,15 +430,15 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h_obj, h_new_proto);
/* fall thru */
skip:
skip:
duk_set_top(thr, 1);
if (magic == 2) {
duk_push_true(thr);
}
return ret_success;
fail_nonextensible:
fail_loop:
fail_nonextensible:
fail_loop:
if (magic != 2) {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
} else {
@ -469,7 +446,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {
return 1;
}
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *thr) {
@ -521,12 +498,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *th
* Lightfunc set/get values are coerced to full Functions.
*/
duk_hobject_prepare_property_descriptor(thr,
2 /*idx_desc*/,
&defprop_flags,
&idx_value,
&get,
&set);
duk_hobject_prepare_property_descriptor(thr, 2 /*idx_desc*/, &defprop_flags, &idx_value, &get, &set);
/*
* Use Object.defineProperty() helper for the actual operation.
@ -534,14 +506,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *th
DUK_ASSERT(magic == 0U || magic == 1U);
throw_flag = magic ^ 1U;
ret = duk_hobject_define_property_helper(thr,
defprop_flags,
obj,
key,
idx_value,
get,
set,
throw_flag);
ret = duk_hobject_define_property_helper(thr, defprop_flags, obj, key, idx_value, get, set, throw_flag);
/* Ignore the normalize/validate helper outputs on the value stack,
* they're popped automatically.
@ -556,7 +521,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *th
}
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_hthread *thr) {
@ -572,7 +537,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk
duk_hobject_object_get_own_property_descriptor(thr, -2);
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr) {
@ -595,7 +560,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr)
duk_push_boolean(thr, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h));
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
/* Shared helper for various key/symbol listings, magic:
@ -606,26 +571,17 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr)
*/
DUK_LOCAL const duk_small_uint_t duk__object_keys_enum_flags[4] = {
/* Object.keys() */
DUK_ENUM_OWN_PROPERTIES_ONLY |
DUK_ENUM_NO_PROXY_BEHAVIOR,
DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_NO_PROXY_BEHAVIOR,
/* Object.getOwnPropertyNames() */
DUK_ENUM_INCLUDE_NONENUMERABLE |
DUK_ENUM_OWN_PROPERTIES_ONLY |
DUK_ENUM_NO_PROXY_BEHAVIOR,
DUK_ENUM_INCLUDE_NONENUMERABLE | DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_NO_PROXY_BEHAVIOR,
/* Object.getOwnPropertySymbols() */
DUK_ENUM_INCLUDE_SYMBOLS |
DUK_ENUM_OWN_PROPERTIES_ONLY |
DUK_ENUM_EXCLUDE_STRINGS |
DUK_ENUM_INCLUDE_NONENUMERABLE |
DUK_ENUM_INCLUDE_SYMBOLS | DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_EXCLUDE_STRINGS | DUK_ENUM_INCLUDE_NONENUMERABLE |
DUK_ENUM_NO_PROXY_BEHAVIOR,
/* Reflect.ownKeys() */
DUK_ENUM_INCLUDE_SYMBOLS |
DUK_ENUM_OWN_PROPERTIES_ONLY |
DUK_ENUM_INCLUDE_NONENUMERABLE |
DUK_ENUM_NO_PROXY_BEHAVIOR
DUK_ENUM_INCLUDE_SYMBOLS | DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_NONENUMERABLE | DUK_ENUM_NO_PROXY_BEHAVIOR
};
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {
@ -657,9 +613,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {
#if defined(DUK_USE_ES6_PROXY)
/* XXX: better sharing of code between proxy target call sites */
if (DUK_LIKELY(!duk_hobject_proxy_check(obj,
&h_proxy_target,
&h_proxy_handler))) {
if (DUK_LIKELY(!duk_hobject_proxy_check(obj, &h_proxy_target, &h_proxy_handler))) {
goto skip_proxy;
}
@ -678,8 +632,8 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {
/* [ obj handler trap ] */
duk_insert(thr, -2);
duk_push_hobject(thr, h_proxy_target); /* -> [ obj trap handler target ] */
duk_call_method(thr, 1 /*nargs*/); /* -> [ obj trap_result ] */
duk_push_hobject(thr, h_proxy_target); /* -> [ obj trap handler target ] */
duk_call_method(thr, 1 /*nargs*/); /* -> [ obj trap_result ] */
h_trap_result = duk_require_hobject(thr, -1);
DUK_UNREF(h_trap_result);
@ -690,8 +644,8 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {
duk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);
return 1;
skip_proxy:
#endif /* DUK_USE_ES6_PROXY */
skip_proxy:
#endif /* DUK_USE_ES6_PROXY */
DUK_ASSERT_TOP(thr, 1);
magic = duk_get_current_magic(thr);
@ -699,7 +653,7 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {
enum_flags = duk__object_keys_enum_flags[magic];
return duk_hobject_get_enumerated_keys(thr, enum_flags);
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)
DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread *thr) {
@ -719,12 +673,8 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread
/* Object.preventExtensions() silent success for non-object. */
if (magic == 0) {
mask |= DUK_TYPE_MASK_UNDEFINED |
DUK_TYPE_MASK_NULL |
DUK_TYPE_MASK_BOOLEAN |
DUK_TYPE_MASK_NUMBER |
DUK_TYPE_MASK_STRING |
DUK_TYPE_MASK_POINTER;
mask |= DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_BOOLEAN | DUK_TYPE_MASK_NUMBER |
DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_POINTER;
}
if (duk_check_type_mask(thr, 0, mask)) {
@ -741,13 +691,13 @@ DUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread
*/
duk_hobject_compact_props(thr, h);
done:
done:
if (magic == 1) {
duk_push_true(thr);
}
return 1;
}
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */
/*
* __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__
@ -763,9 +713,10 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_hthread *thr)
/* [ ToObject(this) key getter/setter ] */
/* ToPropertyKey() coercion is not needed, duk_def_prop() does it. */
duk_def_prop(thr, 0, DUK_DEFPROP_SET_ENUMERABLE |
DUK_DEFPROP_SET_CONFIGURABLE |
(duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER));
duk_def_prop(thr,
0,
DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE |
(duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER));
return 0;
}
DUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr) {
@ -800,4 +751,4 @@ DUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr)
}
return 1;
}
#endif /* DUK_USE_ES8 */
#endif /* DUK_USE_ES8 */

6
src-input/duk_bi_performance.c

@ -18,7 +18,7 @@ DUK_INTERNAL duk_ret_t duk_bi_performance_now(duk_hthread *thr) {
return 1;
}
#if 0 /* Missing until semantics decided. */
#if 0 /* Missing until semantics decided. */
DUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) {
/* No decision yet how to handle timeOrigins, e.g. should one be
* initialized per heap, or per global object set. See
@ -27,5 +27,5 @@ DUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) {
duk_push_uint(thr, 0);
return 1;
}
#endif /* 0 */
#endif /* DUK_USE_PERFORMANCE_BUILTIN */
#endif /* 0 */
#endif /* DUK_USE_PERFORMANCE_BUILTIN */

7
src-input/duk_bi_pointer.c

@ -23,9 +23,8 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) {
if (duk_is_constructor_call(thr)) {
(void) duk_push_object_helper(thr,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),
DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),
DUK_BIDX_POINTER_PROTOTYPE);
/* Pointer object internal value is immutable. */
@ -70,6 +69,6 @@ DUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr
}
return 1;
type_error:
type_error:
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}

2
src-input/duk_bi_promise.c

@ -41,4 +41,4 @@ DUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) {
DUK_WO_NORETURN(return 0;);
}
#endif /* DUK_USE_PROMISE_BUILTIN */
#endif /* DUK_USE_PROMISE_BUILTIN */

14
src-input/duk_bi_protos.h

@ -12,7 +12,7 @@
* 32
* Include additional space to be safe.
*/
#define DUK_BI_DATE_ISO8601_BUFSIZE 40
#define DUK_BI_DATE_ISO8601_BUFSIZE 40
/* Helpers exposed for internal use */
DUK_INTERNAL_DECL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags);
@ -50,7 +50,10 @@ DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr,
DUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str);
#endif
#if defined(DUK_USE_DATE_FMT_STRFTIME)
DUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags);
DUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr,
duk_int_t *parts,
duk_int_t tzoffset,
duk_small_uint_t flags);
#endif
#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)
@ -61,10 +64,7 @@ DUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void);
#endif
DUK_INTERNAL_DECL
void duk_bi_json_parse_helper(duk_hthread *thr,
duk_idx_t idx_value,
duk_idx_t idx_reviver,
duk_small_uint_t flags);
void duk_bi_json_parse_helper(duk_hthread *thr, duk_idx_t idx_value, duk_idx_t idx_reviver, duk_small_uint_t flags);
DUK_INTERNAL_DECL
void duk_bi_json_stringify_helper(duk_hthread *thr,
duk_idx_t idx_value,
@ -78,4 +78,4 @@ DUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr)
DUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags);
#endif
#endif /* DUK_BUILTIN_PROTOS_H_INCLUDED */
#endif /* DUK_BUILTIN_PROTOS_H_INCLUDED */

12
src-input/duk_bi_proxy.c

@ -68,7 +68,7 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h
duk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WEC);
continue;
skip_key:
skip_key:
duk_pop(thr);
continue;
}
@ -85,14 +85,14 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h
* handled above.
*/
}
#endif /* DUK_USE_ES6_PROXY */
#endif /* DUK_USE_ES6_PROXY */
#if defined(DUK_USE_ES6_PROXY)
DUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_hthread *thr) {
DUK_ASSERT_TOP(thr, 2); /* [ target handler ] */
DUK_ASSERT_TOP(thr, 2); /* [ target handler ] */
duk_require_constructor_call(thr);
duk_push_proxy(thr, 0 /*flags*/); /* [ target handler ] -> [ proxy ] */
return 1; /* replacement */
duk_push_proxy(thr, 0 /*flags*/); /* [ target handler ] -> [ proxy ] */
return 1; /* replacement */
}
#endif /* DUK_USE_ES6_PROXY */
#endif /* DUK_USE_ES6_PROXY */

4
src-input/duk_bi_reflect.c

@ -47,7 +47,7 @@ DUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) {
tv_obj = DUK_GET_TVAL_POSIDX(thr, 0);
tv_key = DUK_GET_TVAL_POSIDX(thr, 1);
(void) duk_hobject_getprop(thr, tv_obj, tv_key); /* This could also be a duk_get_prop(). */
(void) duk_hobject_getprop(thr, tv_obj, tv_key); /* This could also be a duk_get_prop(). */
return 1;
}
@ -96,4 +96,4 @@ DUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) {
duk_push_boolean(thr, ret);
return 1;
}
#endif /* DUK_USE_REFLECT_BUILTIN */
#endif /* DUK_USE_REFLECT_BUILTIN */

36
src-input/duk_bi_regexp.c

@ -13,7 +13,7 @@ DUK_LOCAL void duk__get_this_regexp(duk_hthread *thr) {
h = duk_require_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_REGEXP);
DUK_ASSERT(h != NULL);
DUK_UNREF(h);
duk_insert(thr, 0); /* prepend regexp to valstack 0 index */
duk_insert(thr, 0); /* prepend regexp to valstack 0 index */
}
/* XXX: much to improve (code size) */
@ -23,10 +23,8 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {
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)) {
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.
*/
@ -41,8 +39,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {
* call.
*/
if (h_pattern != NULL &&
DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {
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;
@ -58,20 +55,21 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {
duk_push_hstring_empty(thr);
} else {
duk_dup_0(thr);
duk_to_string(thr, -1); /* Rejects Symbols. */
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. */
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)));
(duk_tval *) duk_get_tval(thr, -2),
(duk_tval *) duk_get_tval(thr, -1)));
/* [ ... pattern flags ] (both uncoerced) */
@ -121,7 +119,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) {
duk_push_this(thr);
duk_push_literal(thr, "/");
duk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE);
duk_dup_m2(thr); /* another "/" */
duk_dup_m2(thr); /* another "/" */
duk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);
duk_concat(thr, 4);
return 1;
@ -131,7 +129,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_hthread *thr) {
/* .flags is ES2015 but present even when ES2015 bindings are
* disabled because the constructor relies on it.
*/
duk_uint8_t buf[8]; /* enough for all flags + NUL */
duk_uint8_t buf[8]; /* enough for all flags + NUL */
duk_uint8_t *p = buf;
/* .flags is generic and works on any object. */
@ -172,7 +170,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
duk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);
duk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);
h_bc = duk_require_hstring(thr, -1);
re_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0]; /* Safe even if h_bc length is 0 (= NUL) */
re_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0]; /* Safe even if h_bc length is 0 (= NUL) */
duk_pop(thr);
} else if (h == thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]) {
/* In ES2015 and ES2016 a TypeError would be thrown here.
@ -183,7 +181,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
if (magic != 16 /* .source */) {
return 0;
}
duk_push_literal(thr, "(?:)"); /* .source handled by switch-case */
duk_push_literal(thr, "(?:)"); /* .source handled by switch-case */
re_flags = 0;
} else {
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
@ -192,15 +190,15 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
/* [ regexp source ] */
switch (magic) {
case 0: { /* global */
case 0: { /* global */
duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_GLOBAL));
break;
}
case 1: { /* ignoreCase */
case 1: { /* ignoreCase */
duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_IGNORE_CASE));
break;
}
case 2: { /* multiline */
case 2: { /* multiline */
duk_push_boolean(thr, (re_flags & DUK_RE_FLAG_MULTILINE));
break;
}
@ -214,7 +212,7 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
break;
}
#endif
default: { /* source */
default: { /* source */
/* leave 'source' on top */
break;
}
@ -223,4 +221,4 @@ DUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {
return 1;
}
#endif /* DUK_USE_REGEXP_SUPPORT */
#endif /* DUK_USE_REGEXP_SUPPORT */

227
src-input/duk_bi_string.c

@ -36,7 +36,8 @@ DUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, duk_idx_t i
return h;
}
DUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {
DUK_LOCAL duk_int_t
duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {
duk_int_t cpos;
duk_int_t bpos;
const duk_uint8_t *p_start, *p_end, *p;
@ -71,7 +72,7 @@ DUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this
* must be updated if 'p' is wound back (backward scanning).
*/
firstbyte = q_start[0]; /* leading byte of match string */
firstbyte = q_start[0]; /* leading byte of match string */
while (p <= p_end && p >= p_start) {
t = *p;
@ -137,15 +138,13 @@ DUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_hthread *thr) {
duk_replace(thr, 0);
}
}
duk_to_string(thr, 0); /* catches symbol argument for constructor call */
duk_to_string(thr, 0); /* catches symbol argument for constructor call */
DUK_ASSERT(duk_is_string(thr, 0));
duk_set_top(thr, 1); /* Top may be 1 or larger. */
duk_set_top(thr, 1); /* Top may be 1 or larger. */
if (duk_is_constructor_call(thr)) {
/* String object internal value is immutable */
flags = DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_FASTREFS |
DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |
flags = DUK_HOBJECT_FLAG_EXTENSIBLE | DUK_HOBJECT_FLAG_FASTREFS | DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);
duk_push_object_helper(thr, flags, DUK_BIDX_STRING_PROTOTYPE);
duk_dup_0(thr);
@ -171,7 +170,7 @@ DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t
n = duk_get_top(thr);
bw = &bw_alloc;
DUK_BW_INIT_PUSHBUF(thr, bw, (duk_size_t) n); /* initial estimate for ASCII only codepoints */
DUK_BW_INIT_PUSHBUF(thr, bw, (duk_size_t) n); /* initial estimate for ASCII only codepoints */
for (i = 0; i < n; i++) {
/* XXX: could improve bufwriter handling to write multiple codepoints
@ -185,8 +184,7 @@ DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t
* the same.
*/
duk_int32_t i32 = 0;
if (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) ||
i32 < 0 || i32 > 0x10ffffL) {
if (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) || i32 < 0 || i32 > 0x10ffffL) {
DUK_DCERROR_RANGE_INVALID_ARGS(thr);
}
DUK_ASSERT(i32 >= 0 && i32 <= 0x10ffffL);
@ -210,7 +208,7 @@ DUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t
}
DUK_BW_COMPACT(thr, bw);
(void) duk_buffer_to_string(thr, -1); /* Safe, extended UTF-8 or CESU-8 encoded. */
(void) duk_buffer_to_string(thr, -1); /* Safe, extended UTF-8 or CESU-8 encoded. */
return 1;
}
@ -252,10 +250,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {
goto type_error;
}
(void) duk_require_hstring_notsymbol(thr, -1); /* Reject symbols (and wrapped symbols). */
(void) duk_require_hstring_notsymbol(thr, -1); /* Reject symbols (and wrapped symbols). */
return 1;
type_error:
type_error:
DUK_DCERROR_TYPE_INVALID_ARGS(thr);
}
@ -391,7 +389,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) {
* ("undefined" and "null").
*/
duk_push_this(thr);
h = duk_to_hstring_m1(thr); /* Reject Symbols. */
h = duk_to_hstring_m1(thr); /* Reject Symbols. */
DUK_ASSERT(h != NULL);
len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);
@ -423,7 +421,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) {
duk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);
return 1;
}
#endif /* DUK_USE_SECTION_B */
#endif /* DUK_USE_SECTION_B */
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_hthread *thr) {
duk_hstring *h;
@ -482,7 +480,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_hthread *thr)
duk_hstring *h_search;
duk_int_t clen_this;
duk_int_t cpos;
duk_small_uint_t is_lastindexof = (duk_small_uint_t) duk_get_current_magic(thr); /* 0=indexOf, 1=lastIndexOf */
duk_small_uint_t is_lastindexof = (duk_small_uint_t) duk_get_current_magic(thr); /* 0=indexOf, 1=lastIndexOf */
h_this = duk_push_this_coercible_to_string(thr);
DUK_ASSERT(h_this != NULL);
@ -539,7 +537,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
duk_int_t match_caps;
#endif
duk_uint32_t prev_match_end_boff;
const duk_uint8_t *r_start, *r_end, *r; /* repl string scan */
const duk_uint8_t *r_start, *r_end, *r; /* repl string scan */
duk_size_t tmp_sz;
DUK_ASSERT_TOP(thr, 2);
@ -547,7 +545,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
DUK_ASSERT(h_input != NULL);
bw = &bw_alloc;
DUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input)); /* input size is good output starting point */
DUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input)); /* input size is good output starting point */
DUK_ASSERT_TOP(thr, 4);
@ -568,11 +566,11 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
duk_push_int(thr, 0);
duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
}
#else /* DUK_USE_REGEXP_SUPPORT */
#else /* DUK_USE_REGEXP_SUPPORT */
DUK_DCERROR_UNSUPPORTED(thr);
#endif /* DUK_USE_REGEXP_SUPPORT */
#endif /* DUK_USE_REGEXP_SUPPORT */
} else {
duk_to_string(thr, 0); /* rejects symbols */
duk_to_string(thr, 0); /* rejects symbols */
#if defined(DUK_USE_REGEXP_SUPPORT)
is_regexp = 0;
is_global = 0;
@ -587,7 +585,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
duk_hstring *h_repl;
is_repl_func = 0;
h_repl = duk_to_hstring(thr, 1); /* reject symbols */
h_repl = duk_to_hstring(thr, 1); /* reject symbols */
DUK_ASSERT(h_repl != NULL);
r_start = DUK_HSTRING_GET_DATA(h_repl);
r_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl);
@ -625,7 +623,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
if (is_regexp) {
duk_dup_0(thr);
duk_dup_2(thr);
duk_regexp_match(thr); /* [ ... regexp input ] -> [ res_obj ] */
duk_regexp_match(thr); /* [ ... regexp input ] -> [ res_obj ] */
if (!duk_is_object(thr, -1)) {
duk_pop(thr);
break;
@ -639,7 +637,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
duk_get_prop_index(thr, -1, 0);
DUK_ASSERT(duk_is_string(thr, -1));
h_match = duk_known_hstring(thr, -1);
duk_pop(thr); /* h_match is borrowed, remains reachable through match_obj */
duk_pop(thr); /* h_match is borrowed, remains reachable through match_obj */
if (DUK_HSTRING_GET_BYTELEN(h_match) == 0) {
/* This should be equivalent to match() algorithm step 8.f.iii.2:
@ -650,25 +648,26 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
last_index = (duk_uint32_t) duk_get_uint(thr, -1);
DUK_DDD(DUK_DDDPRINT("empty match, bump lastIndex: %ld -> %ld",
(long) last_index, (long) (last_index + 1)));
(long) last_index,
(long) (last_index + 1)));
duk_pop(thr);
duk_push_uint(thr, (duk_uint_t) (last_index + 1));
duk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);
}
DUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX); /* string limits */
DUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX); /* string limits */
match_caps = (duk_int_t) duk_get_length(thr, -1);
} else {
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
const duk_uint8_t *p_start, *p_end, *p; /* input string scan */
const duk_uint8_t *q_start; /* match string */
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
const duk_uint8_t *p_start, *p_end, *p; /* input string scan */
const duk_uint8_t *q_start; /* match string */
duk_size_t p_blen;
duk_size_t q_blen;
#if defined(DUK_USE_REGEXP_SUPPORT)
DUK_ASSERT(!is_global); /* single match always */
DUK_ASSERT(!is_global); /* single match always */
#endif
p_start = DUK_HSTRING_GET_DATA(h_input);
@ -681,10 +680,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);
if (q_blen > p_blen) {
break; /* no match */
break; /* no match */
}
p_end -= q_blen; /* ensure full memcmp() fits in while */
p_end -= q_blen; /* ensure full memcmp() fits in while */
DUK_ASSERT(p_end >= p);
match_start_coff = 0;
@ -710,7 +709,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
/* not found */
break;
}
found:
found:
/* stack[0] = search value
* stack[1] = replace value
@ -744,9 +743,9 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
duk_get_prop_index(thr, 4, (duk_uarridx_t) idx);
}
} else {
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
/* match == search string, by definition */
duk_dup_0(thr);
}
@ -756,12 +755,12 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
/* [ ... replacer match [captures] match_char_offset input ] */
duk_call(thr, duk_get_top(thr) - idx_args);
h_repl = duk_to_hstring_m1(thr); /* -> [ ... repl_value ] */
h_repl = duk_to_hstring_m1(thr); /* -> [ ... repl_value ] */
DUK_ASSERT(h_repl != NULL);
DUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_repl);
duk_pop(thr); /* repl_value */
duk_pop(thr); /* repl_value */
} else {
r = r_start;
@ -808,9 +807,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
* match codepoint encodings would have different lengths.
*/
/* XXX: charlen computed here, and also in char2byte helper. */
match_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr,
h_input,
match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));
match_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(
thr,
h_input,
match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));
tmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff);
DUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + match_end_boff, tmp_sz);
@ -846,7 +846,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
}
if (capnum > 0 && capnum < match_caps) {
DUK_ASSERT(is_regexp != 0); /* match_caps == 0 without regexps */
DUK_ASSERT(is_regexp != 0); /* match_caps == 0 without regexps */
/* regexp res_obj is at offset 4 */
duk_get_prop_index(thr, 4, (duk_uarridx_t) capnum);
@ -865,26 +865,26 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
} else {
goto repl_write;
}
#else /* DUK_USE_REGEXP_SUPPORT */
goto repl_write; /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
} /* default case */
} /* switch (ch2) */
#else /* DUK_USE_REGEXP_SUPPORT */
goto repl_write; /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
} /* default case */
} /* switch (ch2) */
repl_write:
repl_write:
/* ch1 = (r_increment << 8) + byte */
DUK_BW_WRITE_ENSURE_U8(thr, bw, (duk_uint8_t) (ch1 & 0xff));
r += ch1 >> 8;
} /* while repl */
} /* if (is_repl_func) */
} /* while repl */
} /* if (is_repl_func) */
duk_pop(thr); /* pop regexp res_obj or match string */
duk_pop(thr); /* pop regexp res_obj or match string */
#if defined(DUK_USE_REGEXP_SUPPORT)
if (!is_global) {
#else
{ /* unconditionally; is_global==0 */
{ /* unconditionally; is_global==0 */
#endif
break;
}
@ -896,7 +896,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
DUK_ASSERT_TOP(thr, 4);
DUK_BW_COMPACT(thr, bw);
(void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */
(void) duk_buffer_to_string(thr, -1); /* Safe if inputs are safe. */
return 1;
}
@ -916,7 +916,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
#if defined(DUK_USE_REGEXP_SUPPORT)
duk_bool_t is_regexp;
#endif
duk_bool_t matched; /* set to 1 if any match exists (needed for empty input special case) */
duk_bool_t matched; /* set to 1 if any match exists (needed for empty input special case) */
duk_uint32_t prev_match_end_coff, prev_match_end_boff;
duk_uint32_t match_start_boff, match_start_coff;
duk_uint32_t match_end_boff, match_end_coff;
@ -954,7 +954,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
#if defined(DUK_USE_REGEXP_SUPPORT)
duk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);
duk_dup_0(thr);
duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */
duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */
duk_replace(thr, 0);
/* lastIndex is initialized to zero by new RegExp() */
is_regexp = 1;
@ -993,7 +993,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
if (is_regexp) {
duk_dup_0(thr);
duk_dup_2(thr);
duk_regexp_match_force_global(thr); /* [ ... regexp input ] -> [ res_obj ] */
duk_regexp_match_force_global(thr); /* [ ... regexp input ] -> [ res_obj ] */
if (!duk_is_object(thr, -1)) {
duk_pop(thr);
break;
@ -1026,23 +1026,23 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
continue;
}
} else {
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
const duk_uint8_t *p_start, *p_end, *p; /* input string scan */
const duk_uint8_t *q_start; /* match string */
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
const duk_uint8_t *p_start, *p_end, *p; /* input string scan */
const duk_uint8_t *q_start; /* match string */
duk_size_t q_blen, q_clen;
p_start = DUK_HSTRING_GET_DATA(h_input);
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
p = p_start + prev_match_end_boff;
h_sep = duk_known_hstring(thr, 0); /* symbol already rejected above */
h_sep = duk_known_hstring(thr, 0); /* symbol already rejected above */
q_start = DUK_HSTRING_GET_DATA(h_sep);
q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sep);
q_clen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_sep);
p_end -= q_blen; /* ensure full memcmp() fits in while */
p_end -= q_blen; /* ensure full memcmp() fits in while */
match_start_coff = prev_match_end_coff;
@ -1055,7 +1055,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
* Don't allow an empty string to match at the end of the input.
*/
matched = 1; /* empty separator can always match */
matched = 1; /* empty separator can always match */
match_start_coff++;
p++;
@ -1071,7 +1071,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
DUK_ASSERT(q_blen > 0 && q_clen > 0);
while (p <= p_end) {
DUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));
DUK_ASSERT(q_blen > 0); /* no issues with empty memcmp() */
DUK_ASSERT(q_blen > 0); /* no issues with empty memcmp() */
if (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {
/* never an empty match, so step 13.c.iii can't be triggered */
goto found;
@ -1084,15 +1084,15 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
p++;
}
not_found:
not_found:
/* not found */
break;
found:
found:
matched = 1;
match_start_boff = (duk_uint32_t) (p - p_start);
match_end_coff = (duk_uint32_t) (match_start_coff + q_clen); /* constrained by string length */
match_end_boff = (duk_uint32_t) (match_start_boff + q_blen); /* ditto */
match_end_coff = (duk_uint32_t) (match_start_coff + q_clen); /* constrained by string length */
match_end_boff = (duk_uint32_t) (match_start_boff + q_blen); /* ditto */
/* empty match (may happen with empty separator) -> bump and continue */
if (prev_match_end_boff == match_end_boff) {
@ -1100,7 +1100,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
prev_match_end_coff++;
continue;
}
} /* if (is_regexp) */
} /* if (is_regexp) */
/* stack[0] = separator (string or regexp)
* stack[1] = limit
@ -1110,9 +1110,12 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
*/
DUK_DDD(DUK_DDDPRINT("split; match_start b=%ld,c=%ld, match_end b=%ld,c=%ld, prev_end b=%ld,c=%ld",
(long) match_start_boff, (long) match_start_coff,
(long) match_end_boff, (long) match_end_coff,
(long) prev_match_end_boff, (long) prev_match_end_coff));
(long) match_start_boff,
(long) match_start_coff,
(long) match_end_boff,
(long) match_end_coff,
(long) prev_match_end_boff,
(long) prev_match_end_coff));
duk_push_lstring(thr,
(const char *) (DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff),
@ -1129,7 +1132,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
len = duk_get_length(thr, 4);
for (i = 1; i < len; i++) {
DUK_ASSERT(i <= DUK_UARRIDX_MAX); /* cannot have >4G captures */
DUK_ASSERT(i <= DUK_UARRIDX_MAX); /* cannot have >4G captures */
duk_get_prop_index(thr, 4, (duk_uarridx_t) i);
duk_put_prop_index(thr, 3, arr_idx);
arr_idx++;
@ -1141,21 +1144,21 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
duk_pop(thr);
/* lastIndex already set up for next match */
} else {
#else /* DUK_USE_REGEXP_SUPPORT */
{ /* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
#else /* DUK_USE_REGEXP_SUPPORT */
{
/* unconditionally */
#endif /* DUK_USE_REGEXP_SUPPORT */
/* no action */
}
prev_match_end_boff = match_end_boff;
prev_match_end_coff = match_end_coff;
continue;
} /* for */
} /* for */
/* Combined step 11 (empty string special case) and 14-15. */
DUK_DDD(DUK_DDDPRINT("split trailer; prev_end b=%ld,c=%ld",
(long) prev_match_end_boff, (long) prev_match_end_coff));
DUK_DDD(DUK_DDDPRINT("split trailer; prev_end b=%ld,c=%ld", (long) prev_match_end_boff, (long) prev_match_end_coff));
if (DUK_HSTRING_GET_BYTELEN(h_input) > 0 || !matched) {
/* Add trailer if:
@ -1172,7 +1175,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {
return 1;
hit_limit:
hit_limit:
#if defined(DUK_USE_REGEXP_SUPPORT)
if (is_regexp) {
duk_pop(thr);
@ -1204,13 +1207,13 @@ DUK_LOCAL void duk__to_regexp_helper(duk_hthread *thr, duk_idx_t idx, duk_bool_t
}
return;
do_new:
do_new:
duk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);
duk_dup(thr, idx);
duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */
duk_new(thr, 1); /* [ ... RegExp val ] -> [ ... res ] */
duk_replace(thr, idx);
}
#endif /* DUK_USE_REGEXP_SUPPORT */
#endif /* DUK_USE_REGEXP_SUPPORT */
#if defined(DUK_USE_REGEXP_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {
@ -1225,7 +1228,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {
*/
DUK_ASSERT_TOP(thr, 1);
(void) duk_push_this_coercible_to_string(thr); /* at index 1 */
(void) duk_push_this_coercible_to_string(thr); /* at index 1 */
duk__to_regexp_helper(thr, 0 /*index*/, 1 /*force_new*/);
/* stack[0] = regexp
@ -1237,8 +1240,8 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {
*/
duk_dup_0(thr);
duk_dup_1(thr); /* [ ... re_obj input ] */
duk_regexp_match(thr); /* -> [ ... res_obj ] */
duk_dup_1(thr); /* [ ... re_obj input ] */
duk_regexp_match(thr); /* -> [ ... res_obj ] */
if (!duk_is_object(thr, -1)) {
duk_push_int(thr, -1);
@ -1249,7 +1252,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {
DUK_ASSERT(duk_is_number(thr, -1));
return 1;
}
#endif /* DUK_USE_REGEXP_SUPPORT */
#endif /* DUK_USE_REGEXP_SUPPORT */
#if defined(DUK_USE_REGEXP_SUPPORT)
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {
@ -1269,8 +1272,8 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {
*/
if (!global) {
duk_regexp_match(thr); /* -> [ res_obj ] */
return 1; /* return 'res_obj' */
duk_regexp_match(thr); /* -> [ res_obj ] */
return 1; /* return 'res_obj' */
}
/* Global case is more complex. */
@ -1291,7 +1294,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {
duk_dup_0(thr);
duk_dup_1(thr);
duk_regexp_match(thr); /* -> [ ... regexp string ] -> [ ... res_obj ] */
duk_regexp_match(thr); /* -> [ ... regexp string ] -> [ ... res_obj ] */
if (!duk_is_object(thr, -1)) {
duk_pop(thr);
@ -1310,24 +1313,24 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {
}
prev_last_index = this_index;
duk_get_prop_index(thr, -1, 0); /* match string */
duk_get_prop_index(thr, -1, 0); /* match string */
duk_put_prop_index(thr, 2, (duk_uarridx_t) arr_idx);
arr_idx++;
duk_pop(thr); /* res_obj */
duk_pop(thr); /* res_obj */
}
if (arr_idx == 0) {
duk_push_null(thr);
}
return 1; /* return 'res_arr' or 'null' */
return 1; /* return 'res_arr' or 'null' */
}
#endif /* DUK_USE_REGEXP_SUPPORT */
#endif /* DUK_USE_REGEXP_SUPPORT */
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_hthread *thr) {
/* duk_concat() coerces arguments with ToString() in correct order */
(void) duk_push_this_coercible_to_string(thr);
duk_insert(thr, 0); /* this is relatively expensive */
duk_insert(thr, 0); /* this is relatively expensive */
duk_concat(thr, duk_get_top(thr));
return 1;
}
@ -1392,10 +1395,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {
#if defined(DUK_USE_PREFER_SIZE)
p = buf;
while (count-- > 0) {
duk_memcpy((void *) p, (const void *) src, input_blen); /* copy size may be zero, but pointers are valid */
duk_memcpy((void *) p, (const void *) src, input_blen); /* copy size may be zero, but pointers are valid */
p += input_blen;
}
#else /* DUK_USE_PREFER_SIZE */
#else /* DUK_USE_PREFER_SIZE */
/* Take advantage of already copied pieces to speed up the process
* especially for small repeated strings.
*/
@ -1405,7 +1408,9 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {
for (;;) {
duk_size_t remain = (duk_size_t) (p_end - p);
DUK_DDD(DUK_DDDPRINT("remain=%ld, copy_size=%ld, input_blen=%ld, result_len=%ld",
(long) remain, (long) copy_size, (long) input_blen,
(long) remain,
(long) copy_size,
(long) input_blen,
(long) result_len));
if (remain <= copy_size) {
/* If result_len is zero, this case is taken and does
@ -1418,10 +1423,10 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {
p += copy_size;
}
src = (const duk_uint8_t *) buf; /* Use buf as source for larger copies. */
src = (const duk_uint8_t *) buf; /* Use buf as source for larger copies. */
copy_size = (duk_size_t) (p - buf);
}
#endif /* DUK_USE_PREFER_SIZE */
#endif /* DUK_USE_PREFER_SIZE */
/* XXX: It would be useful to be able to create a duk_hstring with
* a certain byte size whose data area wasn't initialized and which
@ -1432,13 +1437,13 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {
* intern table (they are not in heap_allocated).
*/
duk_buffer_to_string(thr, -1); /* Safe if input is safe. */
duk_buffer_to_string(thr, -1); /* Safe if input is safe. */
return 1;
fail_range:
fail_range:
DUK_DCERROR_RANGE_INVALID_ARGS(thr);
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr) {
duk_hstring *h1;
@ -1492,7 +1497,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr)
ret = -1;
goto done;
done:
done:
duk_push_int(thr, (duk_int_t) ret);
return 1;
}
@ -1579,11 +1584,11 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *
}
}
finish:
finish:
duk_push_boolean(thr, result);
return 1;
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_ES6 */
#if defined(DUK_USE_ES6)
DUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) {
@ -1606,5 +1611,5 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) {
duk_push_boolean(thr, pos >= 0);
return 1;
}
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_STRING_BUILTIN */
#endif /* DUK_USE_ES6 */
#endif /* DUK_USE_STRING_BUILTIN */

8
src-input/duk_bi_symbol.c

@ -39,7 +39,7 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {
buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1);
DUK_ASSERT(buf != NULL);
p = buf + 1;
DUK_ASSERT(desc != NULL || len == 0); /* may be NULL if len is 0 */
DUK_ASSERT(desc != NULL || len == 0); /* may be NULL if len is 0 */
duk_memcpy_unsafe((void *) p, (const void *) desc, len);
p += len;
if (magic == 0) {
@ -50,7 +50,9 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {
if (++thr->heap->sym_counter[0] == 0) {
thr->heap->sym_counter[1]++;
}
p += DUK_SPRINTF((char *) p, "\xFF" "%lx-%lx",
p += DUK_SPRINTF((char *) p,
"\xFF"
"%lx-%lx",
(unsigned long) thr->heap->sym_counter[1],
(unsigned long) thr->heap->sym_counter[0]);
if (desc == NULL) {
@ -167,4 +169,4 @@ DUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_hthread *thr) {
return 1;
}
#endif /* DUK_USE_SYMBOL_BUILTIN */
#endif /* DUK_USE_SYMBOL_BUILTIN */

64
src-input/duk_bi_thread.c

@ -31,7 +31,7 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) {
*/
duk_push_hobject(new_thr, func);
return 1; /* return thread */
return 1; /* return thread */
}
#endif
@ -77,14 +77,15 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
*/
if (thr->callstack_top < 2) {
DUK_DD(DUK_DDPRINT("resume state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.resume)"));
DUK_DD(DUK_DDPRINT(
"resume state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.resume)"));
goto state_error;
}
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */
DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */
caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);
if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {
@ -96,14 +97,12 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
* like for yield.
*/
if (thr_resume->state != DUK_HTHREAD_STATE_INACTIVE &&
thr_resume->state != DUK_HTHREAD_STATE_YIELDED) {
if (thr_resume->state != DUK_HTHREAD_STATE_INACTIVE && thr_resume->state != DUK_HTHREAD_STATE_YIELDED) {
DUK_DD(DUK_DDPRINT("resume state invalid: target thread must be INACTIVE or YIELDED"));
goto state_error;
}
DUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE ||
thr_resume->state == DUK_HTHREAD_STATE_YIELDED);
DUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE || thr_resume->state == DUK_HTHREAD_STATE_YIELDED);
/* Further state-dependent pre-checks */
@ -121,14 +120,13 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
* because an error in the RESUME handler call processing will
* not be handled very cleanly.
*/
if ((thr_resume->callstack_top != 0) ||
(thr_resume->valstack_top - thr_resume->valstack != 1)) {
if ((thr_resume->callstack_top != 0) || (thr_resume->valstack_top - thr_resume->valstack != 1)) {
goto state_error;
}
duk_push_tval(thr, DUK_GET_TVAL_NEGIDX(thr_resume, -1));
duk_resolve_nonbound_function(thr);
h_fun = duk_require_hobject(thr, -1); /* reject lightfuncs on purpose */
h_fun = duk_require_hobject(thr, -1); /* reject lightfuncs on purpose */
if (!DUK_HOBJECT_IS_CALLABLE(h_fun) || !DUK_HOBJECT_IS_COMPFUNC(h_fun)) {
goto state_error;
}
@ -157,8 +155,8 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
if (is_error) {
DUK_ASSERT_TOP(thr, 2); /* value (error) is at stack top */
duk_err_augment_error_throw(thr); /* in resumer's context */
DUK_ASSERT_TOP(thr, 2); /* value (error) is at stack top */
duk_err_augment_error_throw(thr); /* in resumer's context */
}
#endif
@ -182,21 +180,21 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {
/* lj value2: thread */
DUK_ASSERT(thr->valstack_bottom < thr->valstack_top);
DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2, &thr->valstack_bottom[0]); /* side effects */
DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2, &thr->valstack_bottom[0]); /* side effects */
/* lj value1: value */
DUK_ASSERT(thr->valstack_bottom + 1 < thr->valstack_top);
DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[1]); /* side effects */
DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[1]); /* side effects */
DUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);
thr->heap->lj.iserror = is_error;
DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* call is from executor, so we know we have a jmpbuf */
duk_err_longjmp(thr); /* execution resumes in bytecode executor */
DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* call is from executor, so we know we have a jmpbuf */
duk_err_longjmp(thr); /* execution resumes in bytecode executor */
DUK_UNREACHABLE();
/* Never here, fall through to error (from compiler point of view). */
state_error:
state_error:
DUK_DCERROR_TYPE_INVALID_STATE(thr);
}
#endif
@ -245,14 +243,15 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {
DUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);
if (thr->callstack_top < 2) {
DUK_DD(DUK_DDPRINT("yield state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.yield)"));
DUK_DD(DUK_DDPRINT(
"yield state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.yield)"));
goto state_error;
}
DUK_ASSERT(thr->callstack_curr != NULL);
DUK_ASSERT(thr->callstack_curr->parent != NULL);
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL); /* us */
DUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL); /* caller */
caller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);
if (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {
@ -260,10 +259,11 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {
goto state_error;
}
DUK_ASSERT(thr->callstack_preventcount >= 1); /* should never be zero, because we (Duktape.Thread.yield) are on the stack */
DUK_ASSERT(thr->callstack_preventcount >= 1); /* should never be zero, because we (Duktape.Thread.yield) are on the stack */
if (thr->callstack_preventcount != 1) {
/* Note: the only yield-preventing call is Duktape.Thread.yield(), hence check for 1, not 0 */
DUK_DD(DUK_DDPRINT("yield state invalid: there must be no yield-preventing calls in current thread callstack (preventcount is %ld)",
DUK_DD(DUK_DDPRINT("yield state invalid: there must be no yield-preventing calls in current thread callstack "
"(preventcount is %ld)",
(long) thr->callstack_preventcount));
goto state_error;
}
@ -277,18 +277,16 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
if (is_error) {
DUK_ASSERT_TOP(thr, 1); /* value (error) is at stack top */
duk_err_augment_error_throw(thr); /* in yielder's context */
DUK_ASSERT_TOP(thr, 1); /* value (error) is at stack top */
duk_err_augment_error_throw(thr); /* in yielder's context */
}
#endif
#if defined(DUK_USE_DEBUG)
if (is_error) {
DUK_DDD(DUK_DDDPRINT("YIELD ERROR: value=%!T",
(duk_tval *) duk_get_tval(thr, 0)));
DUK_DDD(DUK_DDDPRINT("YIELD ERROR: value=%!T", (duk_tval *) duk_get_tval(thr, 0)));
} else {
DUK_DDD(DUK_DDDPRINT("YIELD NORMAL: value=%!T",
(duk_tval *) duk_get_tval(thr, 0)));
DUK_DDD(DUK_DDDPRINT("YIELD NORMAL: value=%!T", (duk_tval *) duk_get_tval(thr, 0)));
}
#endif
@ -303,17 +301,17 @@ DUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {
/* lj value1: value */
DUK_ASSERT(thr->valstack_bottom < thr->valstack_top);
DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[0]); /* side effects */
DUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[0]); /* side effects */
DUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);
thr->heap->lj.iserror = is_error;
DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* call is from executor, so we know we have a jmpbuf */
duk_err_longjmp(thr); /* execution resumes in bytecode executor */
DUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL); /* call is from executor, so we know we have a jmpbuf */
duk_err_longjmp(thr); /* execution resumes in bytecode executor */
DUK_UNREACHABLE();
/* Never here, fall through to error (from compiler point of view). */
state_error:
state_error:
DUK_DCERROR_TYPE_INVALID_STATE(thr);
}
#endif

283
src-input/duk_dblunion.h

@ -66,7 +66,7 @@ union duk_double_union {
duk_uint16_t us[4];
duk_uint8_t uc[8];
#if defined(DUK_USE_PACKED_TVAL)
void *vp[2]; /* used by packed duk_tval, assumes sizeof(void *) == 4 */
void *vp[2]; /* used by packed duk_tval, assumes sizeof(void *) == 4 */
#endif
};
@ -78,64 +78,64 @@ typedef union duk_double_union duk_double_union;
#if defined(DUK_USE_DOUBLE_LE)
#if defined(DUK_USE_64BIT_OPS)
#define DUK_DBL_IDX_ULL0 0
#define DUK_DBL_IDX_ULL0 0
#endif
#define DUK_DBL_IDX_UI0 1
#define DUK_DBL_IDX_UI1 0
#define DUK_DBL_IDX_US0 3
#define DUK_DBL_IDX_US1 2
#define DUK_DBL_IDX_US2 1
#define DUK_DBL_IDX_US3 0
#define DUK_DBL_IDX_UC0 7
#define DUK_DBL_IDX_UC1 6
#define DUK_DBL_IDX_UC2 5
#define DUK_DBL_IDX_UC3 4
#define DUK_DBL_IDX_UC4 3
#define DUK_DBL_IDX_UC5 2
#define DUK_DBL_IDX_UC6 1
#define DUK_DBL_IDX_UC7 0
#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
#define DUK_DBL_IDX_UI0 1
#define DUK_DBL_IDX_UI1 0
#define DUK_DBL_IDX_US0 3
#define DUK_DBL_IDX_US1 2
#define DUK_DBL_IDX_US2 1
#define DUK_DBL_IDX_US3 0
#define DUK_DBL_IDX_UC0 7
#define DUK_DBL_IDX_UC1 6
#define DUK_DBL_IDX_UC2 5
#define DUK_DBL_IDX_UC3 4
#define DUK_DBL_IDX_UC4 3
#define DUK_DBL_IDX_UC5 2
#define DUK_DBL_IDX_UC6 1
#define DUK_DBL_IDX_UC7 0
#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
#elif defined(DUK_USE_DOUBLE_BE)
#if defined(DUK_USE_64BIT_OPS)
#define DUK_DBL_IDX_ULL0 0
#define DUK_DBL_IDX_ULL0 0
#endif
#define DUK_DBL_IDX_UI0 0
#define DUK_DBL_IDX_UI1 1
#define DUK_DBL_IDX_US0 0
#define DUK_DBL_IDX_US1 1
#define DUK_DBL_IDX_US2 2
#define DUK_DBL_IDX_US3 3
#define DUK_DBL_IDX_UC0 0
#define DUK_DBL_IDX_UC1 1
#define DUK_DBL_IDX_UC2 2
#define DUK_DBL_IDX_UC3 3
#define DUK_DBL_IDX_UC4 4
#define DUK_DBL_IDX_UC5 5
#define DUK_DBL_IDX_UC6 6
#define DUK_DBL_IDX_UC7 7
#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
#define DUK_DBL_IDX_UI0 0
#define DUK_DBL_IDX_UI1 1
#define DUK_DBL_IDX_US0 0
#define DUK_DBL_IDX_US1 1
#define DUK_DBL_IDX_US2 2
#define DUK_DBL_IDX_US3 3
#define DUK_DBL_IDX_UC0 0
#define DUK_DBL_IDX_UC1 1
#define DUK_DBL_IDX_UC2 2
#define DUK_DBL_IDX_UC3 3
#define DUK_DBL_IDX_UC4 4
#define DUK_DBL_IDX_UC5 5
#define DUK_DBL_IDX_UC6 6
#define DUK_DBL_IDX_UC7 7
#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
#elif defined(DUK_USE_DOUBLE_ME)
#if defined(DUK_USE_64BIT_OPS)
#define DUK_DBL_IDX_ULL0 0 /* not directly applicable, byte order differs from a double */
#define DUK_DBL_IDX_ULL0 0 /* not directly applicable, byte order differs from a double */
#endif
#define DUK_DBL_IDX_UI0 0
#define DUK_DBL_IDX_UI1 1
#define DUK_DBL_IDX_US0 1
#define DUK_DBL_IDX_US1 0
#define DUK_DBL_IDX_US2 3
#define DUK_DBL_IDX_US3 2
#define DUK_DBL_IDX_UC0 3
#define DUK_DBL_IDX_UC1 2
#define DUK_DBL_IDX_UC2 1
#define DUK_DBL_IDX_UC3 0
#define DUK_DBL_IDX_UC4 7
#define DUK_DBL_IDX_UC5 6
#define DUK_DBL_IDX_UC6 5
#define DUK_DBL_IDX_UC7 4
#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
#define DUK_DBL_IDX_UI0 0
#define DUK_DBL_IDX_UI1 1
#define DUK_DBL_IDX_US0 1
#define DUK_DBL_IDX_US1 0
#define DUK_DBL_IDX_US2 3
#define DUK_DBL_IDX_US3 2
#define DUK_DBL_IDX_UC0 3
#define DUK_DBL_IDX_UC1 2
#define DUK_DBL_IDX_UC2 1
#define DUK_DBL_IDX_UC3 0
#define DUK_DBL_IDX_UC4 7
#define DUK_DBL_IDX_UC5 6
#define DUK_DBL_IDX_UC6 5
#define DUK_DBL_IDX_UC7 4
#define DUK_DBL_IDX_VP0 DUK_DBL_IDX_UI0 /* packed tval */
#define DUK_DBL_IDX_VP1 DUK_DBL_IDX_UI1 /* packed tval */
#else
#error internal error
#endif
@ -145,57 +145,63 @@ typedef union duk_double_union duk_double_union;
* by duk_numconv.c and duk_tval.h.
*/
#define DUK_DBLUNION_SET_DOUBLE(u,v) do { \
#define DUK_DBLUNION_SET_DOUBLE(u, v) \
do { \
(u)->d = (v); \
} while (0)
#define DUK_DBLUNION_SET_HIGH32(u,v) do { \
#define DUK_DBLUNION_SET_HIGH32(u, v) \
do { \
(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \
} while (0)
#if defined(DUK_USE_64BIT_OPS)
#if defined(DUK_USE_DOUBLE_ME)
#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \
#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u, v) \
do { \
(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \
} while (0)
#else
#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \
#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u, v) \
do { \
(u)->ull[DUK_DBL_IDX_ULL0] = ((duk_uint64_t) (v)) << 32; \
} while (0)
#endif
#else /* DUK_USE_64BIT_OPS */
#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v) do { \
#else /* DUK_USE_64BIT_OPS */
#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u, v) \
do { \
(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \
(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \
} while (0)
#endif /* DUK_USE_64BIT_OPS */
#endif /* DUK_USE_64BIT_OPS */
#define DUK_DBLUNION_SET_LOW32(u,v) do { \
#define DUK_DBLUNION_SET_LOW32(u, v) \
do { \
(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \
} while (0)
#define DUK_DBLUNION_GET_DOUBLE(u) ((u)->d)
#define DUK_DBLUNION_GET_HIGH32(u) ((u)->ui[DUK_DBL_IDX_UI0])
#define DUK_DBLUNION_GET_LOW32(u) ((u)->ui[DUK_DBL_IDX_UI1])
#define DUK_DBLUNION_GET_DOUBLE(u) ((u)->d)
#define DUK_DBLUNION_GET_HIGH32(u) ((u)->ui[DUK_DBL_IDX_UI0])
#define DUK_DBLUNION_GET_LOW32(u) ((u)->ui[DUK_DBL_IDX_UI1])
#if defined(DUK_USE_64BIT_OPS)
#if defined(DUK_USE_DOUBLE_ME)
#define DUK_DBLUNION_SET_UINT64(u,v) do { \
#define DUK_DBLUNION_SET_UINT64(u, v) \
do { \
(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) ((v) >> 32); \
(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \
} while (0)
#define DUK_DBLUNION_GET_UINT64(u) \
((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | \
((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1]))
#define DUK_DBLUNION_GET_UINT64(u) ((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1]))
#else
#define DUK_DBLUNION_SET_UINT64(u,v) do { \
#define DUK_DBLUNION_SET_UINT64(u, v) \
do { \
(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \
} while (0)
#define DUK_DBLUNION_GET_UINT64(u) ((u)->ull[DUK_DBL_IDX_ULL0])
#define DUK_DBLUNION_GET_UINT64(u) ((u)->ull[DUK_DBL_IDX_ULL0])
#endif
#define DUK_DBLUNION_SET_INT64(u,v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v))
#define DUK_DBLUNION_GET_INT64(u) ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u)))
#endif /* DUK_USE_64BIT_OPS */
#define DUK_DBLUNION_SET_INT64(u, v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v))
#define DUK_DBLUNION_GET_INT64(u) ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u)))
#endif /* DUK_USE_64BIT_OPS */
/*
* Double NaN manipulation macros related to NaN normalization needed when
@ -226,102 +232,85 @@ typedef union duk_double_union duk_double_union;
#if defined(DUK_USE_64BIT_OPS)
#if defined(DUK_USE_DOUBLE_ME)
/* Macros for 64-bit ops + mixed endian doubles. */
#define DUK__DBLUNION_SET_NAN_FULL(u) do { \
#define DUK__DBLUNION_SET_NAN_FULL(u) \
do { \
(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \
} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \
((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))
#define DUK__DBLUNION_IS_ANYINF(u) \
(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000))
#define DUK__DBLUNION_IS_POSINF(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))
#define DUK__DBLUNION_IS_NEGINF(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))
#define DUK__DBLUNION_IS_POSINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))
#define DUK__DBLUNION_IS_NEGINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))
#define DUK__DBLUNION_IS_ANYZERO(u) \
(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_POSZERO(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))
#define DUK__DBLUNION_IS_POSZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))
#else
/* Macros for 64-bit ops + big/little endian doubles. */
#define DUK__DBLUNION_SET_NAN_FULL(u) do { \
#define DUK__DBLUNION_SET_NAN_FULL(u) \
do { \
(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \
} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \
((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))
#define DUK__DBLUNION_IS_ANYINF(u) \
(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000))
#define DUK__DBLUNION_IS_POSINF(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))
#define DUK__DBLUNION_IS_NEGINF(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))
#define DUK__DBLUNION_IS_POSINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))
#define DUK__DBLUNION_IS_NEGINF(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))
#define DUK__DBLUNION_IS_ANYZERO(u) \
(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_POSZERO(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) \
((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))
#define DUK__DBLUNION_IS_POSZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))
#define DUK__DBLUNION_IS_NEGZERO(u) ((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))
#endif
#else /* DUK_USE_64BIT_OPS */
#else /* DUK_USE_64BIT_OPS */
/* Macros for no 64-bit ops, any endianness. */
#define DUK__DBLUNION_SET_NAN_FULL(u) do { \
#define DUK__DBLUNION_SET_NAN_FULL(u) \
do { \
(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \
(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \
} while (0)
#define DUK__DBLUNION_IS_NAN_FULL(u) \
((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \
(((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || \
(u)->ui[DUK_DBL_IDX_UI1] != 0))
(((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || (u)->ui[DUK_DBL_IDX_UI1] != 0))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \
(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && \
((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_ANYINF(u) \
((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && \
((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_POSINF(u) \
(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && \
((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_NEGINF(u) \
(((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && \
((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_POSINF(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_NEGINF(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_ANYZERO(u) \
((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && \
((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_POSZERO(u) \
(((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && \
((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_NEGZERO(u) \
(((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && \
((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#endif /* DUK_USE_64BIT_OPS */
((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_POSZERO(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#define DUK__DBLUNION_IS_NEGZERO(u) (((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))
#endif /* DUK_USE_64BIT_OPS */
#define DUK__DBLUNION_SET_NAN_NOTFULL(u) do { \
#define DUK__DBLUNION_SET_NAN_NOTFULL(u) \
do { \
(u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \
} while (0)
#define DUK__DBLUNION_IS_NAN_NOTFULL(u) \
/* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \
((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \
(((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))
((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))
#define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \
/* E == 0x7ff, F == 8 => normalized NaN */ \
((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL)
#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u) do { \
#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u) \
do { \
if (DUK__DBLUNION_IS_NAN_FULL((u))) { \
DUK__DBLUNION_SET_NAN_FULL((u)); \
} \
} while (0)
#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u) do { \
#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u) \
do { \
/* Check must be full. */ \
if (DUK__DBLUNION_IS_NAN_FULL((u))) { \
DUK__DBLUNION_SET_NAN_NOTFULL((u)); \
@ -335,29 +324,30 @@ typedef union duk_double_union duk_double_union;
*/
#if defined(DUK_USE_PACKED_TVAL)
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))
#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_FULL((d))
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))
#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_FULL((d))
#if 0
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_NOTFULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))
#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_NOTFULL((d))
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_NOTFULL((u))
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))
#define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_NOTFULL((d))
#endif
#define DUK_DBLUNION_IS_NORMALIZED(u) \
(!DUK_DBLUNION_IS_NAN((u)) || /* either not a NaN */ \
DUK_DBLUNION_IS_NORMALIZED_NAN((u))) /* or is a normalized NaN */
#else /* DUK_USE_PACKED_TVAL */
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) /* nop: no need to normalize */
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */
#define DUK_DBLUNION_IS_NORMALIZED(u) 1 /* all doubles are considered normalized */
#define DUK_DBLUNION_SET_NAN(u) do { \
(!DUK_DBLUNION_IS_NAN((u)) || /* either not a NaN */ \
DUK_DBLUNION_IS_NORMALIZED_NAN((u))) /* or is a normalized NaN */
#else /* DUK_USE_PACKED_TVAL */
#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) /* nop: no need to normalize */
#define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */
#define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) /* (DUK_ISNAN((u)->d)) */
#define DUK_DBLUNION_IS_NORMALIZED(u) 1 /* all doubles are considered normalized */
#define DUK_DBLUNION_SET_NAN(u) \
do { \
/* in non-packed representation we don't care about which NaN is used */ \
(u)->d = DUK_DOUBLE_NAN; \
} while (0)
#endif /* DUK_USE_PACKED_TVAL */
#endif /* DUK_USE_PACKED_TVAL */
#define DUK_DBLUNION_IS_ANYINF(u) DUK__DBLUNION_IS_ANYINF((u))
#define DUK_DBLUNION_IS_POSINF(u) DUK__DBLUNION_IS_POSINF((u))
@ -370,7 +360,8 @@ typedef union duk_double_union duk_double_union;
/* XXX: native 64-bit byteswaps when available */
/* 64-bit byteswap, same operation independent of target endianness. */
#define DUK_DBLUNION_BSWAP64(u) do { \
#define DUK_DBLUNION_BSWAP64(u) \
do { \
duk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \
duk__bswaptmp1 = (u)->ui[0]; \
duk__bswaptmp2 = (u)->ui[1]; \
@ -384,7 +375,8 @@ typedef union duk_double_union duk_double_union;
* order. For a big endian target this is a no-op.
*/
#if defined(DUK_USE_DOUBLE_LE)
#define DUK_DBLUNION_DOUBLE_HTON(u) do { \
#define DUK_DBLUNION_DOUBLE_HTON(u) \
do { \
duk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \
duk__bswaptmp1 = (u)->ui[0]; \
duk__bswaptmp2 = (u)->ui[1]; \
@ -394,7 +386,8 @@ typedef union duk_double_union duk_double_union;
(u)->ui[1] = duk__bswaptmp1; \
} while (0)
#elif defined(DUK_USE_DOUBLE_ME)
#define DUK_DBLUNION_DOUBLE_HTON(u) do { \
#define DUK_DBLUNION_DOUBLE_HTON(u) \
do { \
duk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \
duk__bswaptmp1 = (u)->ui[0]; \
duk__bswaptmp2 = (u)->ui[1]; \
@ -404,7 +397,9 @@ typedef union duk_double_union duk_double_union;
(u)->ui[1] = duk__bswaptmp2; \
} while (0)
#elif defined(DUK_USE_DOUBLE_BE)
#define DUK_DBLUNION_DOUBLE_HTON(u) do { } while (0)
#define DUK_DBLUNION_DOUBLE_HTON(u) \
do { \
} while (0)
#else
#error internal error, double endianness insane
#endif
@ -421,4 +416,4 @@ typedef union duk_double_union duk_double_union;
#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] >> 31U))
#endif
#endif /* DUK_DBLUNION_H_INCLUDED */
#endif /* DUK_DBLUNION_H_INCLUDED */

86
src-input/duk_debug.h

@ -28,19 +28,25 @@
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)
#define DUK_D(x) x
#else
#define DUK_D(x) do { } while (0) /* omit */
#define DUK_D(x) \
do { \
} while (0) /* omit */
#endif
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)
#define DUK_DD(x) x
#else
#define DUK_DD(x) do { } while (0) /* omit */
#define DUK_DD(x) \
do { \
} while (0) /* omit */
#endif
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
#define DUK_DDD(x) x
#else
#define DUK_DDD(x) do { } while (0) /* omit */
#define DUK_DDD(x) \
do { \
} while (0) /* omit */
#endif
/*
@ -52,35 +58,35 @@
/* Note: combining __FILE__, __LINE__, and __func__ into fmt would be
* possible compile time, but waste some space with shared function names.
*/
#define DUK__DEBUG_LOG(lev,...) duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__);
#define DUK__DEBUG_LOG(lev, ...) \
duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__);
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)
#define DUK_DPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__)
#define DUK_DPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__)
#else
#define DUK_DPRINT(...)
#endif
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)
#define DUK_DDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__)
#define DUK_DDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__)
#else
#define DUK_DDPRINT(...)
#endif
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
#define DUK_DDDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__)
#define DUK_DDDPRINT(...) DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__)
#else
#define DUK_DDDPRINT(...)
#endif
#else /* DUK_USE_VARIADIC_MACROS */
#else /* DUK_USE_VARIADIC_MACROS */
#define DUK__DEBUG_STASH(lev) \
#define DUK__DEBUG_STASH(lev) \
(void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FILE_MACRO), \
(void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \
(void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \
(void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FUNC_MACRO), \
(void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \
(void) (duk_debug_level_stash = (lev))
(void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \
(void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \
(void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FUNC_MACRO), \
(void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), (void) (duk_debug_level_stash = (lev))
/* Without variadic macros resort to comma expression trickery to handle debug
* prints. This generates a lot of harmless warnings. These hacks are not
@ -89,34 +95,40 @@
*/
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)
#define DUK_DPRINT DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log /* args go here in parens */
#define DUK_DPRINT DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log /* args go here in parens */
#else
#define DUK_DPRINT 0 && /* args go here as a comma expression in parens */
#define DUK_DPRINT 0 && /* args go here as a comma expression in parens */
#endif
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)
#define DUK_DDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log /* args go here in parens */
#define DUK_DDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log /* args go here in parens */
#else
#define DUK_DDPRINT 0 && /* args */
#define DUK_DDPRINT 0 && /* args */
#endif
#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)
#define DUK_DDDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log /* args go here in parens */
#define DUK_DDDPRINT DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log /* args go here in parens */
#else
#define DUK_DDDPRINT 0 && /* args */
#define DUK_DDDPRINT 0 && /* args */
#endif
#endif /* DUK_USE_VARIADIC_MACROS */
#endif /* DUK_USE_VARIADIC_MACROS */
#else /* DUK_USE_DEBUG */
#else /* DUK_USE_DEBUG */
/*
* Exposed debug macros: debugging disabled
*/
#define DUK_D(x) do { } while (0) /* omit */
#define DUK_DD(x) do { } while (0) /* omit */
#define DUK_DDD(x) do { } while (0) /* omit */
#define DUK_D(x) \
do { \
} while (0) /* omit */
#define DUK_DD(x) \
do { \
} while (0) /* omit */
#define DUK_DDD(x) \
do { \
} while (0) /* omit */
#if defined(DUK_USE_VARIADIC_MACROS)
@ -124,15 +136,15 @@
#define DUK_DDPRINT(...)
#define DUK_DDDPRINT(...)
#else /* DUK_USE_VARIADIC_MACROS */
#else /* DUK_USE_VARIADIC_MACROS */
#define DUK_DPRINT 0 && /* args go here as a comma expression in parens */
#define DUK_DDPRINT 0 && /* args */
#define DUK_DDDPRINT 0 && /* args */
#define DUK_DPRINT 0 && /* args go here as a comma expression in parens */
#define DUK_DDPRINT 0 && /* args */
#define DUK_DDDPRINT 0 && /* args */
#endif /* DUK_USE_VARIADIC_MACROS */
#endif /* DUK_USE_VARIADIC_MACROS */
#endif /* DUK_USE_DEBUG */
#endif /* DUK_USE_DEBUG */
/*
* Structs
@ -153,16 +165,16 @@ struct duk_fixedbuffer {
#if defined(DUK_USE_DEBUG)
DUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap);
#if 0 /*unused*/
#if 0 /*unused*/
DUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...);
#endif
DUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size);
#if defined(DUK_USE_VARIADIC_MACROS)
DUK_INTERNAL_DECL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...);
#else /* DUK_USE_VARIADIC_MACROS */
#else /* DUK_USE_VARIADIC_MACROS */
/* parameter passing, not thread safe */
#define DUK_DEBUG_STASH_SIZE 128
#define DUK_DEBUG_STASH_SIZE 128
#if !defined(DUK_SINGLE_FILE)
DUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];
DUK_INTERNAL_DECL duk_int_t duk_debug_line_stash;
@ -170,7 +182,7 @@ DUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];
DUK_INTERNAL_DECL duk_int_t duk_debug_level_stash;
#endif
DUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...);
#endif /* DUK_USE_VARIADIC_MACROS */
#endif /* DUK_USE_VARIADIC_MACROS */
DUK_INTERNAL_DECL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length);
DUK_INTERNAL_DECL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x);
@ -179,6 +191,6 @@ DUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...)
DUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size);
DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);
#endif /* DUK_USE_DEBUG */
#endif /* DUK_USE_DEBUG */
#endif /* DUK_DEBUG_H_INCLUDED */
#endif /* DUK_DEBUG_H_INCLUDED */

4
src-input/duk_debug_fixedbuffer.c

@ -56,7 +56,7 @@ DUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) {
}
DUK_INTERNAL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size) {
char buf[64+1];
char buf[64 + 1];
duk_debug_format_funcptr(buf, sizeof(buf), fptr, fptr_size);
buf[sizeof(buf) - 1] = (char) 0;
duk_fb_put_cstring(fb, buf);
@ -66,4 +66,4 @@ DUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {
return (fb->offset >= fb->length);
}
#endif /* DUK_USE_DEBUG */
#endif /* DUK_USE_DEBUG */

10
src-input/duk_debug_macros.c

@ -18,7 +18,7 @@
#error debugging enabled (DUK_USE_DEBUG) but DUK_USE_DEBUG_WRITE not defined
#endif
#define DUK__DEBUG_BUFSIZE DUK_USE_DEBUG_BUFSIZE
#define DUK__DEBUG_BUFSIZE DUK_USE_DEBUG_BUFSIZE
#if defined(DUK_USE_VARIADIC_MACROS)
@ -46,7 +46,7 @@ DUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t lin
va_end(ap);
}
#else /* DUK_USE_VARIADIC_MACROS */
#else /* DUK_USE_VARIADIC_MACROS */
DUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];
DUK_INTERNAL duk_int_t duk_debug_line_stash;
@ -77,12 +77,12 @@ DUK_INTERNAL void duk_debug_log(const char *fmt, ...) {
va_end(ap);
}
#endif /* DUK_USE_VARIADIC_MACROS */
#endif /* DUK_USE_VARIADIC_MACROS */
#else /* DUK_USE_DEBUG */
#else /* DUK_USE_DEBUG */
/*
* Debugging disabled
*/
#endif /* DUK_USE_DEBUG */
#endif /* DUK_USE_DEBUG */

398
src-input/duk_debug_vsnprintf.c

@ -63,58 +63,58 @@
/* list of conversion specifiers that terminate a format tag;
* this is unfortunately guesswork.
*/
#define DUK__ALLOWED_STANDARD_SPECIFIERS "diouxXeEfFgGaAcsCSpnm"
#define DUK__ALLOWED_STANDARD_SPECIFIERS "diouxXeEfFgGaAcsCSpnm"
/* maximum length of standard format tag that we support */
#define DUK__MAX_FORMAT_TAG_LENGTH 32
#define DUK__MAX_FORMAT_TAG_LENGTH 32
/* heapobj recursion depth when deep printing is selected */
#define DUK__DEEP_DEPTH_LIMIT 8
#define DUK__DEEP_DEPTH_LIMIT 8
/* maximum recursion depth for loop detection stacks */
#define DUK__LOOP_STACK_DEPTH 256
#define DUK__LOOP_STACK_DEPTH 256
/* must match bytecode defines now; build autogenerate? */
DUK_LOCAL const char * const duk__bc_optab[256] = {
"LDREG", "STREG", "JUMP", "LDCONST", "LDINT", "LDINTX", "LDTHIS", "LDUNDEF",
"LDNULL", "LDTRUE", "LDFALSE", "GETVAR", "BNOT", "LNOT", "UNM", "UNP",
"EQ_RR", "EQ_CR", "EQ_RC", "EQ_CC", "NEQ_RR", "NEQ_CR", "NEQ_RC", "NEQ_CC",
"SEQ_RR", "SEQ_CR", "SEQ_RC", "SEQ_CC", "SNEQ_RR", "SNEQ_CR", "SNEQ_RC", "SNEQ_CC",
"GT_RR", "GT_CR", "GT_RC", "GT_CC", "GE_RR", "GE_CR", "GE_RC", "GE_CC",
"LT_RR", "LT_CR", "LT_RC", "LT_CC", "LE_RR", "LE_CR", "LE_RC", "LE_CC",
"IFTRUE_R", "IFTRUE_C", "IFFALSE_R", "IFFALSE_C", "ADD_RR", "ADD_CR", "ADD_RC", "ADD_CC",
"SUB_RR", "SUB_CR", "SUB_RC", "SUB_CC", "MUL_RR", "MUL_CR", "MUL_RC", "MUL_CC",
"DIV_RR", "DIV_CR", "DIV_RC", "DIV_CC", "MOD_RR", "MOD_CR", "MOD_RC", "MOD_CC",
"EXP_RR", "EXP_CR", "EXP_RC", "EXP_CC", "BAND_RR", "BAND_CR", "BAND_RC", "BAND_CC",
"BOR_RR", "BOR_CR", "BOR_RC", "BOR_CC", "BXOR_RR", "BXOR_CR", "BXOR_RC", "BXOR_CC",
"BASL_RR", "BASL_CR", "BASL_RC", "BASL_CC", "BLSR_RR", "BLSR_CR", "BLSR_RC", "BLSR_CC",
"BASR_RR", "BASR_CR", "BASR_RC", "BASR_CC", "INSTOF_RR", "INSTOF_CR", "INSTOF_RC", "INSTOF_CC",
"IN_RR", "IN_CR", "IN_RC", "IN_CC", "GETPROP_RR", "GETPROP_CR", "GETPROP_RC", "GETPROP_CC",
"PUTPROP_RR", "PUTPROP_CR", "PUTPROP_RC", "PUTPROP_CC", "DELPROP_RR", "DELPROP_CR", "DELPROP_RC", "DELPROP_CC",
"PREINCR", "PREDECR", "POSTINCR", "POSTDECR", "PREINCV", "PREDECV", "POSTINCV", "POSTDECV",
"PREINCP_RR", "PREINCP_CR", "PREINCP_RC", "PREINCP_CC", "PREDECP_RR", "PREDECP_CR", "PREDECP_RC", "PREDECP_CC",
"LDREG", "STREG", "JUMP", "LDCONST", "LDINT", "LDINTX", "LDTHIS", "LDUNDEF",
"LDNULL", "LDTRUE", "LDFALSE", "GETVAR", "BNOT", "LNOT", "UNM", "UNP",
"EQ_RR", "EQ_CR", "EQ_RC", "EQ_CC", "NEQ_RR", "NEQ_CR", "NEQ_RC", "NEQ_CC",
"SEQ_RR", "SEQ_CR", "SEQ_RC", "SEQ_CC", "SNEQ_RR", "SNEQ_CR", "SNEQ_RC", "SNEQ_CC",
"GT_RR", "GT_CR", "GT_RC", "GT_CC", "GE_RR", "GE_CR", "GE_RC", "GE_CC",
"LT_RR", "LT_CR", "LT_RC", "LT_CC", "LE_RR", "LE_CR", "LE_RC", "LE_CC",
"IFTRUE_R", "IFTRUE_C", "IFFALSE_R", "IFFALSE_C", "ADD_RR", "ADD_CR", "ADD_RC", "ADD_CC",
"SUB_RR", "SUB_CR", "SUB_RC", "SUB_CC", "MUL_RR", "MUL_CR", "MUL_RC", "MUL_CC",
"DIV_RR", "DIV_CR", "DIV_RC", "DIV_CC", "MOD_RR", "MOD_CR", "MOD_RC", "MOD_CC",
"EXP_RR", "EXP_CR", "EXP_RC", "EXP_CC", "BAND_RR", "BAND_CR", "BAND_RC", "BAND_CC",
"BOR_RR", "BOR_CR", "BOR_RC", "BOR_CC", "BXOR_RR", "BXOR_CR", "BXOR_RC", "BXOR_CC",
"BASL_RR", "BASL_CR", "BASL_RC", "BASL_CC", "BLSR_RR", "BLSR_CR", "BLSR_RC", "BLSR_CC",
"BASR_RR", "BASR_CR", "BASR_RC", "BASR_CC", "INSTOF_RR", "INSTOF_CR", "INSTOF_RC", "INSTOF_CC",
"IN_RR", "IN_CR", "IN_RC", "IN_CC", "GETPROP_RR", "GETPROP_CR", "GETPROP_RC", "GETPROP_CC",
"PUTPROP_RR", "PUTPROP_CR", "PUTPROP_RC", "PUTPROP_CC", "DELPROP_RR", "DELPROP_CR", "DELPROP_RC", "DELPROP_CC",
"PREINCR", "PREDECR", "POSTINCR", "POSTDECR", "PREINCV", "PREDECV", "POSTINCV", "POSTDECV",
"PREINCP_RR", "PREINCP_CR", "PREINCP_RC", "PREINCP_CC", "PREDECP_RR", "PREDECP_CR", "PREDECP_RC", "PREDECP_CC",
"POSTINCP_RR", "POSTINCP_CR", "POSTINCP_RC", "POSTINCP_CC", "POSTDECP_RR", "POSTDECP_CR", "POSTDECP_RC", "POSTDECP_CC",
"DECLVAR_RR", "DECLVAR_CR", "DECLVAR_RC", "DECLVAR_CC", "REGEXP_RR", "REGEXP_RC", "REGEXP_CR", "REGEXP_CC",
"CLOSURE", "TYPEOF", "TYPEOFID", "PUTVAR", "DELVAR", "RETREG", "RETUNDEF", "RETCONST",
"RETCONSTN", "LABEL", "ENDLABEL", "BREAK", "CONTINUE", "TRYCATCH", "ENDTRY", "ENDCATCH",
"ENDFIN", "THROW", "INVLHS", "CSREG", "CSVAR_RR", "CSVAR_CR", "CSVAR_RC", "CSVAR_CC",
"CALL0", "CALL1", "CALL2", "CALL3", "CALL4", "CALL5", "CALL6", "CALL7",
"CALL8", "CALL9", "CALL10", "CALL11", "CALL12", "CALL13", "CALL14", "CALL15",
"NEWOBJ", "NEWARR", "MPUTOBJ", "MPUTOBJI", "INITSET", "INITGET", "MPUTARR", "MPUTARRI",
"SETALEN", "INITENUM", "NEXTENUM", "NEWTARGET", "DEBUGGER", "NOP", "INVALID", "UNUSED207",
"GETPROPC_RR", "GETPROPC_CR", "GETPROPC_RC", "GETPROPC_CC", "UNUSED212", "UNUSED213", "UNUSED214", "UNUSED215",
"UNUSED216", "UNUSED217", "UNUSED218", "UNUSED219", "UNUSED220", "UNUSED221", "UNUSED222", "UNUSED223",
"UNUSED224", "UNUSED225", "UNUSED226", "UNUSED227", "UNUSED228", "UNUSED229", "UNUSED230", "UNUSED231",
"UNUSED232", "UNUSED233", "UNUSED234", "UNUSED235", "UNUSED236", "UNUSED237", "UNUSED238", "UNUSED239",
"UNUSED240", "UNUSED241", "UNUSED242", "UNUSED243", "UNUSED244", "UNUSED245", "UNUSED246", "UNUSED247",
"UNUSED248", "UNUSED249", "UNUSED250", "UNUSED251", "UNUSED252", "UNUSED253", "UNUSED254", "UNUSED255"
"DECLVAR_RR", "DECLVAR_CR", "DECLVAR_RC", "DECLVAR_CC", "REGEXP_RR", "REGEXP_RC", "REGEXP_CR", "REGEXP_CC",
"CLOSURE", "TYPEOF", "TYPEOFID", "PUTVAR", "DELVAR", "RETREG", "RETUNDEF", "RETCONST",
"RETCONSTN", "LABEL", "ENDLABEL", "BREAK", "CONTINUE", "TRYCATCH", "ENDTRY", "ENDCATCH",
"ENDFIN", "THROW", "INVLHS", "CSREG", "CSVAR_RR", "CSVAR_CR", "CSVAR_RC", "CSVAR_CC",
"CALL0", "CALL1", "CALL2", "CALL3", "CALL4", "CALL5", "CALL6", "CALL7",
"CALL8", "CALL9", "CALL10", "CALL11", "CALL12", "CALL13", "CALL14", "CALL15",
"NEWOBJ", "NEWARR", "MPUTOBJ", "MPUTOBJI", "INITSET", "INITGET", "MPUTARR", "MPUTARRI",
"SETALEN", "INITENUM", "NEXTENUM", "NEWTARGET", "DEBUGGER", "NOP", "INVALID", "UNUSED207",
"GETPROPC_RR", "GETPROPC_CR", "GETPROPC_RC", "GETPROPC_CC", "UNUSED212", "UNUSED213", "UNUSED214", "UNUSED215",
"UNUSED216", "UNUSED217", "UNUSED218", "UNUSED219", "UNUSED220", "UNUSED221", "UNUSED222", "UNUSED223",
"UNUSED224", "UNUSED225", "UNUSED226", "UNUSED227", "UNUSED228", "UNUSED229", "UNUSED230", "UNUSED231",
"UNUSED232", "UNUSED233", "UNUSED234", "UNUSED235", "UNUSED236", "UNUSED237", "UNUSED238", "UNUSED239",
"UNUSED240", "UNUSED241", "UNUSED242", "UNUSED243", "UNUSED244", "UNUSED245", "UNUSED246", "UNUSED247",
"UNUSED248", "UNUSED249", "UNUSED250", "UNUSED251", "UNUSED252", "UNUSED253", "UNUSED254", "UNUSED255"
};
typedef struct duk__dprint_state duk__dprint_state;
@ -164,14 +164,15 @@ DUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h)
duk_size_t i;
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);
for (i = 0; i < (duk_size_t) sizeof(*h); i++) {
duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *)h)[i]);
duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *) h)[i]);
}
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);
}
#if defined(DUK_USE_REFERENCE_COUNTING) /* currently implicitly also DUK_USE_DOUBLE_LINKED_HEAP */
#if defined(DUK_USE_REFERENCE_COUNTING) /* currently implicitly also DUK_USE_DOUBLE_LINKED_HEAP */
if (st->heavy) {
duk_fb_sprintf(fb, "[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld,"
duk_fb_sprintf(fb,
"[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld,"
"reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
(void *) DUK_HEAPHDR_GET_NEXT(NULL, h),
(void *) DUK_HEAPHDR_GET_PREV(NULL, h),
@ -185,7 +186,8 @@ DUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h)
}
#else
if (st->heavy) {
duk_fb_sprintf(fb, "[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
duk_fb_sprintf(fb,
"[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
(void *) DUK_HEAPHDR_GET_NEXT(NULL, h),
(unsigned long) DUK_HEAPHDR_GET_FLAGS(h),
(long) DUK_HEAPHDR_GET_TYPE(h),
@ -212,14 +214,15 @@ DUK_LOCAL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaph
duk_size_t i;
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);
for (i = 0; i < (duk_size_t) sizeof(*h); i++) {
duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *)h)[i]);
duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *) h)[i]);
}
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);
}
#if defined(DUK_USE_REFERENCE_COUNTING)
if (st->heavy) {
duk_fb_sprintf(fb, "[h_refcount=%lu,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
duk_fb_sprintf(fb,
"[h_refcount=%lu,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
(unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h),
(unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),
(long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),
@ -230,7 +233,8 @@ DUK_LOCAL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaph
}
#else
if (st->heavy) {
duk_fb_sprintf(fb, "[h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
duk_fb_sprintf(fb,
"[h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]",
(unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),
(long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),
(long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),
@ -301,7 +305,8 @@ DUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_boo
#endif
}
#define DUK__COMMA() do { \
#define DUK__COMMA() \
do { \
if (first) { \
first = 0; \
} else { \
@ -414,7 +419,8 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
duk__print_hstring(st, key, 0);
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COLON);
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(NULL, h, i)) {
duk_fb_sprintf(fb, "[get:%p,set:%p]",
duk_fb_sprintf(fb,
"[get:%p,set:%p]",
(void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.get,
(void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.set);
} else {
@ -428,158 +434,238 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
}
if (st->internal) {
if (DUK_HOBJECT_IS_ARRAY(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__array:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__array:true");
}
if (DUK_HOBJECT_HAS_EXTENSIBLE(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__extensible:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__extensible:true");
}
if (DUK_HOBJECT_HAS_CONSTRUCTABLE(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__constructable:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__constructable:true");
}
if (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__boundfunc:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__boundfunc:true");
}
if (DUK_HOBJECT_HAS_COMPFUNC(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__compfunc:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__compfunc:true");
}
if (DUK_HOBJECT_HAS_NATFUNC(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__natfunc:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__natfunc:true");
}
if (DUK_HOBJECT_HAS_BUFOBJ(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__bufobj:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__bufobj:true");
}
if (DUK_HOBJECT_IS_THREAD(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__thread:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__thread:true");
}
if (DUK_HOBJECT_HAS_ARRAY_PART(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__array_part:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__array_part:true");
}
if (DUK_HOBJECT_HAS_STRICT(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__strict:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__strict:true");
}
if (DUK_HOBJECT_HAS_NOTAIL(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__notail:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__notail:true");
}
if (DUK_HOBJECT_HAS_NEWENV(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__newenv:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__newenv:true");
}
if (DUK_HOBJECT_HAS_NAMEBINDING(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__namebinding:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__namebinding:true");
}
if (DUK_HOBJECT_HAS_CREATEARGS(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__createargs:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__createargs:true");
}
if (DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_array:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__exotic_array:true");
}
if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_stringobj:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__exotic_stringobj:true");
}
if (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_arguments:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__exotic_arguments:true");
}
if (DUK_HOBJECT_IS_BUFOBJ(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_bufobj:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__exotic_bufobj:true");
}
if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)) {
DUK__COMMA(); duk_fb_sprintf(fb, "__exotic_proxyobj:true");
DUK__COMMA();
duk_fb_sprintf(fb, "__exotic_proxyobj:true");
}
}
if (st->internal && DUK_HOBJECT_IS_ARRAY(h)) {
duk_harray *a = (duk_harray *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__length:%ld", (long) a->length);
DUK__COMMA(); duk_fb_sprintf(fb, "__length_nonwritable:%ld", (long) a->length_nonwritable);
DUK__COMMA();
duk_fb_sprintf(fb, "__length:%ld", (long) a->length);
DUK__COMMA();
duk_fb_sprintf(fb, "__length_nonwritable:%ld", (long) a->length_nonwritable);
} else if (st->internal && DUK_HOBJECT_IS_COMPFUNC(h)) {
duk_hcompfunc *f = (duk_hcompfunc *) h;
DUK__COMMA(); duk_fb_put_cstring(fb, "__data:");
DUK__COMMA();
duk_fb_put_cstring(fb, "__data:");
duk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));
DUK__COMMA(); duk_fb_put_cstring(fb, "__lexenv:"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_LEXENV(NULL, f));
DUK__COMMA(); duk_fb_put_cstring(fb, "__varenv:"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_VARENV(NULL, f));
DUK__COMMA(); duk_fb_sprintf(fb, "__nregs:%ld", (long) f->nregs);
DUK__COMMA(); duk_fb_sprintf(fb, "__nargs:%ld", (long) f->nargs);
DUK__COMMA();
duk_fb_put_cstring(fb, "__lexenv:");
duk__print_hobject(st, DUK_HCOMPFUNC_GET_LEXENV(NULL, f));
DUK__COMMA();
duk_fb_put_cstring(fb, "__varenv:");
duk__print_hobject(st, DUK_HCOMPFUNC_GET_VARENV(NULL, f));
DUK__COMMA();
duk_fb_sprintf(fb, "__nregs:%ld", (long) f->nregs);
DUK__COMMA();
duk_fb_sprintf(fb, "__nargs:%ld", (long) f->nargs);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
DUK__COMMA(); duk_fb_sprintf(fb, "__start_line:%ld", (long) f->start_line);
DUK__COMMA(); duk_fb_sprintf(fb, "__end_line:%ld", (long) f->end_line);
DUK__COMMA();
duk_fb_sprintf(fb, "__start_line:%ld", (long) f->start_line);
DUK__COMMA();
duk_fb_sprintf(fb, "__end_line:%ld", (long) f->end_line);
#endif
DUK__COMMA(); duk_fb_put_cstring(fb, "__data:");
DUK__COMMA();
duk_fb_put_cstring(fb, "__data:");
duk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));
} else if (st->internal && DUK_HOBJECT_IS_NATFUNC(h)) {
duk_hnatfunc *f = (duk_hnatfunc *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__func:");
DUK__COMMA();
duk_fb_sprintf(fb, "__func:");
duk_fb_put_funcptr(fb, (duk_uint8_t *) &f->func, sizeof(f->func));
DUK__COMMA(); duk_fb_sprintf(fb, "__nargs:%ld", (long) f->nargs);
DUK__COMMA(); duk_fb_sprintf(fb, "__magic:%ld", (long) f->magic);
DUK__COMMA();
duk_fb_sprintf(fb, "__nargs:%ld", (long) f->nargs);
DUK__COMMA();
duk_fb_sprintf(fb, "__magic:%ld", (long) f->magic);
} else if (st->internal && DUK_HOBJECT_IS_DECENV(h)) {
duk_hdecenv *e = (duk_hdecenv *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__thread:"); duk__print_hobject(st, (duk_hobject *) e->thread);
DUK__COMMA(); duk_fb_sprintf(fb, "__varmap:"); duk__print_hobject(st, (duk_hobject *) e->varmap);
DUK__COMMA(); duk_fb_sprintf(fb, "__regbase_byteoff:%ld", (long) e->regbase_byteoff);
DUK__COMMA();
duk_fb_sprintf(fb, "__thread:");
duk__print_hobject(st, (duk_hobject *) e->thread);
DUK__COMMA();
duk_fb_sprintf(fb, "__varmap:");
duk__print_hobject(st, (duk_hobject *) e->varmap);
DUK__COMMA();
duk_fb_sprintf(fb, "__regbase_byteoff:%ld", (long) e->regbase_byteoff);
} else if (st->internal && DUK_HOBJECT_IS_OBJENV(h)) {
duk_hobjenv *e = (duk_hobjenv *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__target:"); duk__print_hobject(st, (duk_hobject *) e->target);
DUK__COMMA(); duk_fb_sprintf(fb, "__has_this:%ld", (long) e->has_this);
DUK__COMMA();
duk_fb_sprintf(fb, "__target:");
duk__print_hobject(st, (duk_hobject *) e->target);
DUK__COMMA();
duk_fb_sprintf(fb, "__has_this:%ld", (long) e->has_this);
#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)
} else if (st->internal && DUK_HOBJECT_IS_BUFOBJ(h)) {
duk_hbufobj *b = (duk_hbufobj *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__buf:");
DUK__COMMA();
duk_fb_sprintf(fb, "__buf:");
duk__print_hbuffer(st, (duk_hbuffer *) b->buf);
DUK__COMMA(); duk_fb_sprintf(fb, "__buf_prop:");
DUK__COMMA();
duk_fb_sprintf(fb, "__buf_prop:");
duk__print_hobject(st, (duk_hobject *) b->buf_prop);
DUK__COMMA(); duk_fb_sprintf(fb, "__offset:%ld", (long) b->offset);
DUK__COMMA(); duk_fb_sprintf(fb, "__length:%ld", (long) b->length);
DUK__COMMA(); duk_fb_sprintf(fb, "__shift:%ld", (long) b->shift);
DUK__COMMA(); duk_fb_sprintf(fb, "__elemtype:%ld", (long) b->elem_type);
DUK__COMMA();
duk_fb_sprintf(fb, "__offset:%ld", (long) b->offset);
DUK__COMMA();
duk_fb_sprintf(fb, "__length:%ld", (long) b->length);
DUK__COMMA();
duk_fb_sprintf(fb, "__shift:%ld", (long) b->shift);
DUK__COMMA();
duk_fb_sprintf(fb, "__elemtype:%ld", (long) b->elem_type);
#endif
} else if (st->internal && DUK_HOBJECT_IS_PROXY(h)) {
duk_hproxy *p = (duk_hproxy *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__target:");
DUK__COMMA();
duk_fb_sprintf(fb, "__target:");
duk__print_hobject(st, p->target);
DUK__COMMA(); duk_fb_sprintf(fb, "__handler:");
DUK__COMMA();
duk_fb_sprintf(fb, "__handler:");
duk__print_hobject(st, p->handler);
} else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) {
duk_hthread *t = (duk_hthread *) h;
DUK__COMMA(); duk_fb_sprintf(fb, "__ptr_curr_pc:%p", (void *) t->ptr_curr_pc);
DUK__COMMA(); duk_fb_sprintf(fb, "__heap:%p", (void *) t->heap);
DUK__COMMA(); duk_fb_sprintf(fb, "__strict:%ld", (long) t->strict);
DUK__COMMA(); duk_fb_sprintf(fb, "__state:%ld", (long) t->state);
DUK__COMMA(); duk_fb_sprintf(fb, "__unused1:%ld", (long) t->unused1);
DUK__COMMA(); duk_fb_sprintf(fb, "__unused2:%ld", (long) t->unused2);
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack:%p", (void *) t->valstack);
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_end:%p/%ld", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_alloc_end:%p/%ld", (void *) t->valstack_alloc_end, (long) (t->valstack_alloc_end - t->valstack));
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_bottom:%p/%ld", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack));
DUK__COMMA(); duk_fb_sprintf(fb, "__valstack_top:%p/%ld", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_curr:%p", (void *) t->callstack_curr);
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_top:%ld", (long) t->callstack_top);
DUK__COMMA(); duk_fb_sprintf(fb, "__callstack_preventcount:%ld", (long) t->callstack_preventcount);
DUK__COMMA(); duk_fb_sprintf(fb, "__resumer:"); duk__print_hobject(st, (duk_hobject *) t->resumer);
DUK__COMMA(); duk_fb_sprintf(fb, "__compile_ctx:%p", (void *) t->compile_ctx);
DUK__COMMA();
duk_fb_sprintf(fb, "__ptr_curr_pc:%p", (void *) t->ptr_curr_pc);
DUK__COMMA();
duk_fb_sprintf(fb, "__heap:%p", (void *) t->heap);
DUK__COMMA();
duk_fb_sprintf(fb, "__strict:%ld", (long) t->strict);
DUK__COMMA();
duk_fb_sprintf(fb, "__state:%ld", (long) t->state);
DUK__COMMA();
duk_fb_sprintf(fb, "__unused1:%ld", (long) t->unused1);
DUK__COMMA();
duk_fb_sprintf(fb, "__unused2:%ld", (long) t->unused2);
DUK__COMMA();
duk_fb_sprintf(fb, "__valstack:%p", (void *) t->valstack);
DUK__COMMA();
duk_fb_sprintf(fb, "__valstack_end:%p/%ld", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));
DUK__COMMA();
duk_fb_sprintf(fb,
"__valstack_alloc_end:%p/%ld",
(void *) t->valstack_alloc_end,
(long) (t->valstack_alloc_end - t->valstack));
DUK__COMMA();
duk_fb_sprintf(fb,
"__valstack_bottom:%p/%ld",
(void *) t->valstack_bottom,
(long) (t->valstack_bottom - t->valstack));
DUK__COMMA();
duk_fb_sprintf(fb, "__valstack_top:%p/%ld", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));
DUK__COMMA();
duk_fb_sprintf(fb, "__callstack_curr:%p", (void *) t->callstack_curr);
DUK__COMMA();
duk_fb_sprintf(fb, "__callstack_top:%ld", (long) t->callstack_top);
DUK__COMMA();
duk_fb_sprintf(fb, "__callstack_preventcount:%ld", (long) t->callstack_preventcount);
DUK__COMMA();
duk_fb_sprintf(fb, "__resumer:");
duk__print_hobject(st, (duk_hobject *) t->resumer);
DUK__COMMA();
duk_fb_sprintf(fb, "__compile_ctx:%p", (void *) t->compile_ctx);
#if defined(DUK_USE_INTERRUPT_COUNTER)
DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_counter:%ld", (long) t->interrupt_counter);
DUK__COMMA(); duk_fb_sprintf(fb, "__interrupt_init:%ld", (long) t->interrupt_init);
DUK__COMMA();
duk_fb_sprintf(fb, "__interrupt_counter:%ld", (long) t->interrupt_counter);
DUK__COMMA();
duk_fb_sprintf(fb, "__interrupt_init:%ld", (long) t->interrupt_init);
#endif
/* XXX: print built-ins array? */
}
#if defined(DUK_USE_REFERENCE_COUNTING)
if (st->internal) {
DUK__COMMA(); duk_fb_sprintf(fb, "__refcount:%lu", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h));
DUK__COMMA();
duk_fb_sprintf(fb, "__refcount:%lu", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h));
}
#endif
if (st->internal) {
DUK__COMMA(); duk_fb_sprintf(fb, "__class:%ld", (long) DUK_HOBJECT_GET_CLASS_NUMBER(h));
DUK__COMMA();
duk_fb_sprintf(fb, "__class:%ld", (long) DUK_HOBJECT_GET_CLASS_NUMBER(h));
}
DUK__COMMA(); duk_fb_sprintf(fb, "__heapptr:%p", (void *) h); /* own pointer */
DUK__COMMA();
duk_fb_sprintf(fb, "__heapptr:%p", (void *) h); /* own pointer */
/* prototype should be last, for readability */
if (DUK_HOBJECT_GET_PROTOTYPE(NULL, h)) {
if (st->follow_proto) {
DUK__COMMA(); duk_fb_put_cstring(fb, "__prototype:"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h));
DUK__COMMA();
duk_fb_put_cstring(fb, "__prototype:");
duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h));
} else {
DUK__COMMA(); duk_fb_sprintf(fb, "__prototype:%p", (void *) DUK_HOBJECT_GET_PROTOTYPE(NULL, h));
DUK__COMMA();
duk_fb_sprintf(fb, "__prototype:%p", (void *) DUK_HOBJECT_GET_PROTOTYPE(NULL, h));
}
}
@ -605,7 +691,7 @@ DUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {
}
#endif
finished:
finished:
st->depth--;
if (pushed_loopstack) {
st->loop_stack_index--;
@ -632,12 +718,14 @@ DUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) {
if (DUK_HBUFFER_HAS_DYNAMIC(h)) {
if (DUK_HBUFFER_HAS_EXTERNAL(h)) {
duk_hbuffer_external *g = (duk_hbuffer_external *) h;
duk_fb_sprintf(fb, "buffer:external:%p:%ld",
duk_fb_sprintf(fb,
"buffer:external:%p:%ld",
(void *) DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(NULL, g),
(long) DUK_HBUFFER_EXTERNAL_GET_SIZE(g));
} else {
duk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;
duk_fb_sprintf(fb, "buffer:dynamic:%p:%ld",
duk_fb_sprintf(fb,
"buffer:dynamic:%p:%ld",
(void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),
(long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g));
}
@ -710,7 +798,7 @@ DUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval *tv) {
duk_size_t i;
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);
for (i = 0; i < (duk_size_t) sizeof(*tv); i++) {
duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *)tv)[i]);
duk_fb_sprintf(fb, "%02lx", (unsigned long) ((duk_uint8_t *) tv)[i]);
}
duk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);
}
@ -793,17 +881,22 @@ DUK_LOCAL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins) {
/* XXX: option to fix opcode length so it lines up nicely */
if (op == DUK_OP_JUMP) {
duk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS); /* from next pc */
duk_int_t diff2 = diff1 + 1; /* from curr pc */
duk_fb_sprintf(fb, "%s %ld (to pc%c%ld)",
(const char *) op_name, (long) diff1,
(int) (diff2 >= 0 ? '+' : '-'), /* char format: use int */
duk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS); /* from next pc */
duk_int_t diff2 = diff1 + 1; /* from curr pc */
duk_fb_sprintf(fb,
"%s %ld (to pc%c%ld)",
(const char *) op_name,
(long) diff1,
(int) (diff2 >= 0 ? '+' : '-'), /* char format: use int */
(long) (diff2 >= 0 ? diff2 : -diff2));
} else {
duk_fb_sprintf(fb, "%s %ld, %ld, %ld",
(const char *) op_name, (long) DUK_DEC_A(ins),
(long) DUK_DEC_B(ins), (long) DUK_DEC_C(ins));
duk_fb_sprintf(fb,
"%s %ld, %ld, %ld",
(const char *) op_name,
(long) DUK_DEC_A(ins),
(long) DUK_DEC_B(ins),
(long) DUK_DEC_C(ins));
}
}
@ -829,13 +922,16 @@ DUK_LOCAL void duk__print_catcher(duk__dprint_state *st, duk_catcher *cat) {
return;
}
duk_fb_sprintf(fb, "[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]",
duk_fb_sprintf(fb,
"[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]",
(void *) cat,
(void *) cat->parent, (void *) cat->h_varname, (void *) cat->pc_base,
(long) cat->idx_base, (unsigned long) cat->flags);
(void *) cat->parent,
(void *) cat->h_varname,
(void *) cat->pc_base,
(long) cat->idx_base,
(unsigned long) cat->flags);
}
DUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act) {
duk_fixedbuffer *fb = st->fb;
@ -850,12 +946,20 @@ DUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act)
/* prev_caller: conditional, omitted on purpose, it's rarely used. */
/* prev_line: conditional, omitted on purpose (but would be nice). */
duk_fb_sprintf(fb, "[activation ptr=%p tv_func=<omit> func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]",
duk_fb_sprintf(fb,
"[activation ptr=%p tv_func=<omit> func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p "
"bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]",
(void *) act,
(void *) act->func, (void *) act->parent, (void *) act->var_env,
(void *) act->lex_env, (void *) act->cat, (void *) act->curr_pc,
(long) act->bottom_byteoff, (long) act->retval_byteoff, (long) act->reserve_byteoff,
(long) act->flags);
(void *) act->func,
(void *) act->parent,
(void *) act->var_env,
(void *) act->lex_env,
(void *) act->cat,
(void *) act->curr_pc,
(long) act->bottom_byteoff,
(long) act->retval_byteoff,
(long) act->reserve_byteoff,
(long) act->flags);
}
DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap) {
@ -874,7 +978,7 @@ DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const cha
char ch = *p++;
const char *p_begfmt = NULL;
duk_bool_t got_exclamation = 0;
duk_bool_t got_long = 0; /* %lf, %ld etc */
duk_bool_t got_long = 0; /* %lf, %ld etc */
duk__dprint_state st;
if (ch != DUK_ASC_PERCENT) {
@ -1037,11 +1141,11 @@ DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const cha
}
goto done;
format_error:
format_error:
duk_fb_put_cstring(&fb, "FMTERR");
/* fall through */
done:
done:
retval = (duk_int_t) fb.offset;
duk_fb_put_byte(&fb, (duk_uint8_t) 0);
@ -1049,7 +1153,7 @@ DUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const cha
return retval;
}
#if 0 /*unused*/
#if 0 /*unused*/
DUK_INTERNAL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...) {
duk_int_t retval;
va_list ap;
@ -1090,4 +1194,4 @@ DUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_u
}
}
#endif /* DUK_USE_DEBUG */
#endif /* DUK_USE_DEBUG */

329
src-input/duk_debugger.c

@ -11,17 +11,23 @@
*/
#if defined(DUK_USE_ASSERTIONS)
#define DUK__DBG_TPORT_ENTER() do { \
#define DUK__DBG_TPORT_ENTER() \
do { \
DUK_ASSERT(heap->dbg_calling_transport == 0); \
heap->dbg_calling_transport = 1; \
} while (0)
#define DUK__DBG_TPORT_EXIT() do { \
#define DUK__DBG_TPORT_EXIT() \
do { \
DUK_ASSERT(heap->dbg_calling_transport == 1); \
heap->dbg_calling_transport = 0; \
} while (0)
#else
#define DUK__DBG_TPORT_ENTER() do {} while (0)
#define DUK__DBG_TPORT_EXIT() do {} while (0)
#define DUK__DBG_TPORT_ENTER() \
do { \
} while (0)
#define DUK__DBG_TPORT_EXIT() \
do { \
} while (0)
#endif
/*
@ -41,7 +47,8 @@ typedef union {
* Detach handling
*/
#define DUK__SET_CONN_BROKEN(thr,reason) do { \
#define DUK__SET_CONN_BROKEN(thr, reason) \
do { \
/* For now shared handler is fine. */ \
duk__debug_do_detach1((thr)->heap, (reason)); \
} while (0)
@ -62,7 +69,7 @@ DUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) {
DUK_D(DUK_DPRINT("debugger transport detaching, marking transport broken"));
heap->dbg_detaching = 1; /* prevent multiple in-progress detaches */
heap->dbg_detaching = 1; /* prevent multiple in-progress detaches */
if (heap->dbg_write_cb != NULL) {
duk_hthread *thr;
@ -90,8 +97,8 @@ DUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) {
heap->dbg_pause_act = NULL;
heap->dbg_pause_startline = 0;
heap->dbg_have_next_byte = 0;
duk_debug_clear_paused(heap); /* XXX: some overlap with field inits above */
heap->dbg_state_dirty = 0; /* XXX: clear_paused sets dirty; rework? */
duk_debug_clear_paused(heap); /* XXX: some overlap with field inits above */
heap->dbg_state_dirty = 0; /* XXX: clear_paused sets dirty; rework? */
/* Ensure there are no stale active breakpoint pointers.
* Breakpoint list is currently kept - we could empty it
@ -151,7 +158,7 @@ DUK_LOCAL void duk__debug_null_most_callbacks(duk_hthread *thr) {
heap = thr->heap;
DUK_D(DUK_DPRINT("transport read/write error, NULL all callbacks expected detached"));
heap->dbg_read_cb = NULL;
heap->dbg_write_cb = NULL; /* this is especially critical to avoid another write call in detach1() */
heap->dbg_write_cb = NULL; /* this is especially critical to avoid another write call in detach1() */
heap->dbg_peek_cb = NULL;
heap->dbg_read_flush_cb = NULL;
heap->dbg_write_flush_cb = NULL;
@ -173,7 +180,8 @@ DUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_
updated_flags = pause_flags & ~(DUK_PAUSE_FLAG_LINE_CHANGE);
DUK_D(DUK_DPRINT("no line info for current activation, disable line-based pause flags: 0x%08lx -> 0x%08lx",
(long) pause_flags, (long) updated_flags));
(long) pause_flags,
(long) updated_flags));
pause_flags = updated_flags;
}
@ -183,7 +191,8 @@ DUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_
heap->dbg_state_dirty = 1;
DUK_D(DUK_DPRINT("set state for automatic pause triggers, flags=0x%08lx, act=%p, startline=%ld",
(long) heap->dbg_pause_flags, (void *) heap->dbg_pause_act,
(long) heap->dbg_pause_flags,
(void *) heap->dbg_pause_act,
(long) heap->dbg_pause_startline));
}
@ -338,7 +347,7 @@ DUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_
if (got == 0 || got > left) {
DUK_D(DUK_DPRINT("connection error during read, return zero data"));
duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */
duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */
DUK__SET_CONN_BROKEN(thr, 1);
goto fail;
}
@ -346,14 +355,14 @@ DUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_
}
return;
fail:
fail:
duk_memzero((void *) data, (size_t) length);
}
DUK_INTERNAL duk_uint8_t duk_debug_read_byte(duk_hthread *thr) {
duk_uint8_t x;
x = 0; /* just in case callback is broken and won't write 'x' */
x = 0; /* just in case callback is broken and won't write 'x' */
duk_debug_read_bytes(thr, &x, 1);
return x;
}
@ -364,10 +373,7 @@ DUK_LOCAL duk_uint32_t duk__debug_read_uint32_raw(duk_hthread *thr) {
DUK_ASSERT(thr != NULL);
duk_debug_read_bytes(thr, buf, 4);
return ((duk_uint32_t) buf[0] << 24) |
((duk_uint32_t) buf[1] << 16) |
((duk_uint32_t) buf[2] << 8) |
(duk_uint32_t) buf[3];
return ((duk_uint32_t) buf[0] << 24) | ((duk_uint32_t) buf[1] << 16) | ((duk_uint32_t) buf[2] << 8) | (duk_uint32_t) buf[3];
}
DUK_LOCAL duk_int32_t duk__debug_read_int32_raw(duk_hthread *thr) {
@ -380,8 +386,7 @@ DUK_LOCAL duk_uint16_t duk__debug_read_uint16_raw(duk_hthread *thr) {
DUK_ASSERT(thr != NULL);
duk_debug_read_bytes(thr, buf, 2);
return ((duk_uint16_t) buf[0] << 8) |
(duk_uint16_t) buf[1];
return ((duk_uint16_t) buf[0] << 8) | (duk_uint16_t) buf[1];
}
DUK_INTERNAL duk_int32_t duk_debug_read_int(duk_hthread *thr) {
@ -413,10 +418,10 @@ DUK_LOCAL duk_hstring *duk__debug_read_hstring_raw(duk_hthread *thr, duk_uint32_
duk_debug_read_bytes(thr, buf, (duk_size_t) len);
duk_push_lstring(thr, (const char *) buf, (duk_size_t) len);
} else {
p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */
p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */
DUK_ASSERT(p != NULL);
duk_debug_read_bytes(thr, p, (duk_size_t) len);
(void) duk_buffer_to_string(thr, -1); /* Safety relies on debug client, which is OK. */
(void) duk_buffer_to_string(thr, -1); /* Safety relies on debug client, which is OK. */
}
return duk_require_hstring(thr, -1);
@ -442,17 +447,17 @@ DUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) {
return duk__debug_read_hstring_raw(thr, len);
fail:
fail:
DUK_D(DUK_DPRINT("debug connection error: failed to decode int"));
DUK__SET_CONN_BROKEN(thr, 1);
duk_push_hstring_empty(thr); /* always push some string */
duk_push_hstring_empty(thr); /* always push some string */
return duk_require_hstring(thr, -1);
}
DUK_LOCAL duk_hbuffer *duk__debug_read_hbuffer_raw(duk_hthread *thr, duk_uint32_t len) {
duk_uint8_t *p;
p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */
p = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len); /* zero for paranoia */
DUK_ASSERT(p != NULL);
duk_debug_read_bytes(thr, p, (duk_size_t) len);
@ -475,7 +480,7 @@ DUK_LOCAL void *duk__debug_read_pointer_raw(duk_hthread *thr) {
#endif
return (void *) pu.p;
fail:
fail:
DUK_D(DUK_DPRINT("debug connection error: failed to decode pointer"));
DUK__SET_CONN_BROKEN(thr, 1);
return (void *) NULL;
@ -533,7 +538,7 @@ DUK_INTERNAL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr) {
return (duk_heaphdr *) duk__debug_read_pointer_raw(thr);
fail:
fail:
DUK_D(DUK_DPRINT("debug connection error: failed to decode any pointer (object, pointer, heapptr)"));
DUK__SET_CONN_BROKEN(thr, 1);
return NULL;
@ -639,15 +644,15 @@ DUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {
duk_push_heapptr(thr, (void *) h);
break;
}
case DUK_DBG_IB_UNUSED: /* unused: not accepted in inbound messages */
case DUK_DBG_IB_UNUSED: /* unused: not accepted in inbound messages */
default:
goto fail;
}
return_ptr:
return_ptr:
return DUK_GET_TVAL_NEGIDX(thr, -1);
fail:
fail:
DUK_D(DUK_DPRINT("debug connection error: failed to decode tval"));
DUK__SET_CONN_BROKEN(thr, 1);
return NULL;
@ -697,7 +702,7 @@ DUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *dat
DUK__DBG_TPORT_EXIT();
if (got == 0 || got > left) {
duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */
duk__debug_null_most_callbacks(thr); /* avoid calling write callback in detach1() */
DUK_D(DUK_DPRINT("connection error during write"));
DUK__SET_CONN_BROKEN(thr, 1);
return;
@ -764,8 +769,7 @@ DUK_INTERNAL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x) {
* unsigned 32-bit dvalue.
*/
if (x >= 0x80000000UL) {
DUK_D(DUK_DPRINT("writing unsigned integer 0x%08lx as signed integer",
(long) x));
DUK_D(DUK_DPRINT("writing unsigned integer 0x%08lx as signed integer", (long) x));
}
duk_debug_write_int(thr, (duk_int32_t) x);
}
@ -806,9 +810,7 @@ DUK_INTERNAL void duk_debug_write_string(duk_hthread *thr, const char *data, duk
DUK_INTERNAL void duk_debug_write_cstring(duk_hthread *thr, const char *data) {
DUK_ASSERT(thr != NULL);
duk_debug_write_string(thr,
data,
data ? DUK_STRLEN(data) : 0);
duk_debug_write_string(thr, data, data ? DUK_STRLEN(data) : 0);
}
DUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h) {
@ -862,7 +864,7 @@ DUK_INTERNAL void duk_debug_write_pointer(duk_hthread *thr, void *ptr) {
DUK_INTERNAL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h) {
duk__debug_write_pointer_raw(thr, (void *) h, DUK_DBG_IB_HEAPPTR);
}
#endif /* DUK_USE_DEBUGGER_DUMPHEAP || DUK_USE_DEBUGGER_INSPECT */
#endif /* DUK_USE_DEBUGGER_DUMPHEAP || DUK_USE_DEBUGGER_INSPECT */
DUK_INTERNAL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj) {
duk_uint8_t buf[3];
@ -905,8 +907,7 @@ DUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) {
duk_debug_write_byte(thr, DUK_DBG_IB_NULL);
break;
case DUK_TAG_BOOLEAN:
DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 ||
DUK_TVAL_GET_BOOLEAN(tv) == 1);
DUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 || DUK_TVAL_GET_BOOLEAN(tv) == 1);
duk_debug_write_boolean(thr, DUK_TVAL_GET_BOOLEAN(tv));
break;
case DUK_TAG_POINTER:
@ -951,14 +952,22 @@ DUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) {
DUK_DD(DUK_DDPRINT("i32=%ld du1=%02x%02x%02x%02x%02x%02x%02x%02x "
"du2=%02x%02x%02x%02x%02x%02x%02x%02x",
(long) i32,
(unsigned int) du1.uc[0], (unsigned int) du1.uc[1],
(unsigned int) du1.uc[2], (unsigned int) du1.uc[3],
(unsigned int) du1.uc[4], (unsigned int) du1.uc[5],
(unsigned int) du1.uc[6], (unsigned int) du1.uc[7],
(unsigned int) du2.uc[0], (unsigned int) du2.uc[1],
(unsigned int) du2.uc[2], (unsigned int) du2.uc[3],
(unsigned int) du2.uc[4], (unsigned int) du2.uc[5],
(unsigned int) du2.uc[6], (unsigned int) du2.uc[7]));
(unsigned int) du1.uc[0],
(unsigned int) du1.uc[1],
(unsigned int) du1.uc[2],
(unsigned int) du1.uc[3],
(unsigned int) du1.uc[4],
(unsigned int) du1.uc[5],
(unsigned int) du1.uc[6],
(unsigned int) du1.uc[7],
(unsigned int) du2.uc[0],
(unsigned int) du2.uc[1],
(unsigned int) du2.uc[2],
(unsigned int) du2.uc[3],
(unsigned int) du2.uc[4],
(unsigned int) du2.uc[5],
(unsigned int) du2.uc[6],
(unsigned int) du2.uc[7]));
if (duk_memcmp((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) {
duk_debug_write_int(thr, i32);
@ -982,13 +991,13 @@ DUK_LOCAL void duk__debug_write_tval_heapptr(duk_hthread *thr, duk_tval *tv) {
duk_debug_write_tval(thr, tv);
}
}
#endif /* DUK_USE_DEBUGGER_DUMPHEAP */
#endif /* DUK_USE_DEBUGGER_DUMPHEAP */
/*
* Debug connection message write helpers
*/
#if 0 /* unused */
#if 0 /* unused */
DUK_INTERNAL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command) {
duk_debug_write_byte(thr, DUK_DBG_IB_REQUEST);
duk_debug_write_int(thr, command);
@ -1091,7 +1100,7 @@ DUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {
duk_activation *act;
duk_uint32_t pc;
DUK_ASSERT(thr->valstack_top > thr->valstack); /* At least: ... [err] */
DUK_ASSERT(thr->valstack_top > thr->valstack); /* At least: ... [err] */
duk_debug_write_notify(thr, DUK_DBG_CMD_THROW);
duk_debug_write_int(thr, (duk_int32_t) fatal);
@ -1132,7 +1141,7 @@ DUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {
duk_debug_write_eom(thr);
}
#endif /* DUK_USE_DEBUGGER_THROW_NOTIFY */
#endif /* DUK_USE_DEBUGGER_THROW_NOTIFY */
/*
* Debug message processing
@ -1156,9 +1165,9 @@ DUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) {
duk_debug_skip_bytes(thr, (duk_size_t) (x - 0x60));
return 0;
}
switch(x) {
switch (x) {
case DUK_DBG_IB_EOM:
return 1; /* Return 1: got EOM */
return 1; /* Return 1: got EOM */
case DUK_DBG_IB_REQUEST:
case DUK_DBG_IB_REPLY:
case DUK_DBG_IB_ERROR:
@ -1207,9 +1216,9 @@ DUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) {
return 0;
fail:
fail:
DUK__SET_CONN_BROKEN(thr, 1);
return 1; /* Pretend like we got EOM */
return 1; /* Pretend like we got EOM */
}
/* Skip dvalues to EOM. */
@ -1229,7 +1238,7 @@ DUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) {
level = duk_debug_read_int(thr);
if (level >= 0 || -level > (duk_int32_t) thr->callstack_top) {
duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "invalid callstack index");
return 0; /* zero indicates failure */
return 0; /* zero indicates failure */
}
return level;
}
@ -1298,7 +1307,7 @@ DUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {
duk_debug_clear_paused(heap);
pause_flags = 0;
#if 0 /* manual testing */
#if 0 /* manual testing */
pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE;
pause_flags |= DUK_PAUSE_FLAG_CAUGHT_ERROR;
pause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;
@ -1319,12 +1328,9 @@ DUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int3
DUK_D(DUK_DPRINT("debug command StepInto/StepOver/StepOut: %d", (int) cmd));
if (cmd == DUK_DBG_CMD_STEPINTO) {
pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |
DUK_PAUSE_FLAG_FUNC_ENTRY |
DUK_PAUSE_FLAG_FUNC_EXIT;
pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE | DUK_PAUSE_FLAG_FUNC_ENTRY | DUK_PAUSE_FLAG_FUNC_EXIT;
} else if (cmd == DUK_DBG_CMD_STEPOVER) {
pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |
DUK_PAUSE_FLAG_FUNC_EXIT;
pause_flags = DUK_PAUSE_FLAG_LINE_CHANGE | DUK_PAUSE_FLAG_FUNC_EXIT;
} else {
DUK_ASSERT(cmd == DUK_DBG_CMD_STEPOUT);
pause_flags = DUK_PAUSE_FLAG_FUNC_EXIT;
@ -1403,7 +1409,7 @@ DUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) {
if (act == NULL) {
return;
}
str = duk_debug_read_hstring(thr); /* push to stack */
str = duk_debug_read_hstring(thr); /* push to stack */
DUK_ASSERT(str != NULL);
rc = duk_js_getvar_activation(thr, act, str, 0);
@ -1432,7 +1438,7 @@ DUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {
if (act == NULL) {
return;
}
str = duk_debug_read_hstring(thr); /* push to stack */
str = duk_debug_read_hstring(thr); /* push to stack */
DUK_ASSERT(str != NULL);
tv = duk_debug_read_tval(thr);
if (tv == NULL) {
@ -1530,7 +1536,7 @@ DUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {
/* [ ... func varmap enum key value this ] */
duk_debug_write_hstring(thr, duk_get_hstring(thr, -3));
duk_debug_write_tval(thr, duk_get_tval(thr, -2));
duk_pop_3(thr); /* -> [ ... func varmap enum ] */
duk_pop_3(thr); /* -> [ ... func varmap enum ] */
}
} else {
DUK_D(DUK_DPRINT("varmap missing in GetLocals, ignore"));
@ -1565,12 +1571,12 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {
/* nargs == 2 so we can pass a callstack index to eval(). */
idx_func = duk_get_top(thr);
duk_push_c_function(thr, duk_bi_global_object_eval, 2 /*nargs*/);
duk_push_undefined(thr); /* 'this' binding shouldn't matter here */
duk_push_undefined(thr); /* 'this' binding shouldn't matter here */
/* Read callstack index, if non-null. */
if (duk_debug_peek_byte(thr) == DUK_DBG_IB_NULL) {
direct_eval = 0;
level = -1; /* Not needed, but silences warning. */
level = -1; /* Not needed, but silences warning. */
(void) duk_debug_read_byte(thr);
} else {
direct_eval = 1;
@ -1580,12 +1586,11 @@ DUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {
}
}
DUK_ASSERT(!direct_eval ||
(level < 0 && -level <= (duk_int32_t) thr->callstack_top));
DUK_ASSERT(!direct_eval || (level < 0 && -level <= (duk_int32_t) thr->callstack_top));
(void) duk_debug_read_hstring(thr);
if (direct_eval) {
duk_push_int(thr, level - 1); /* compensate for eval() call */
duk_push_int(thr, level - 1); /* compensate for eval() call */
}
/* [ ... eval "eval" eval_input level? ] */
@ -1640,7 +1645,7 @@ DUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) {
duk_debug_write_eom(thr);
DUK_D(DUK_DPRINT("debug connection detached, mark broken"));
DUK__SET_CONN_BROKEN(thr, 0); /* not an error */
DUK__SET_CONN_BROKEN(thr, 0); /* not an error */
}
DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
@ -1648,7 +1653,7 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
DUK_D(DUK_DPRINT("debug command AppRequest"));
old_top = duk_get_top(thr); /* save stack top */
old_top = duk_get_top(thr); /* save stack top */
if (heap->dbg_request_cb != NULL) {
duk_idx_t nrets;
@ -1664,7 +1669,7 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
DUK_D(DUK_DPRINT("failed to allocate space for request dvalue(s)"));
goto fail;
}
tv = duk_debug_read_tval(thr); /* push to stack */
tv = duk_debug_read_tval(thr); /* push to stack */
if (tv == NULL) {
/* detached */
return;
@ -1675,17 +1680,24 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
/* Request callback should push values for reply to client onto valstack */
DUK_D(DUK_DPRINT("calling into AppRequest request_cb with nvalues=%ld, old_top=%ld, top=%ld",
(long) nvalues, (long) old_top, (long) duk_get_top(thr)));
(long) nvalues,
(long) old_top,
(long) duk_get_top(thr)));
nrets = heap->dbg_request_cb(thr, heap->dbg_udata, nvalues);
DUK_D(DUK_DPRINT("returned from AppRequest request_cb; nvalues=%ld -> nrets=%ld, old_top=%ld, top=%ld",
(long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(thr)));
(long) nvalues,
(long) nrets,
(long) old_top,
(long) duk_get_top(thr)));
if (nrets >= 0) {
DUK_ASSERT(duk_get_top(thr) >= old_top + nrets);
if (duk_get_top(thr) < old_top + nrets) {
DUK_D(DUK_DPRINT("AppRequest callback doesn't match value stack configuration, "
"top=%ld < old_top=%ld + nrets=%ld; "
"this might mean it's unsafe to continue!",
(long) duk_get_top(thr), (long) old_top, (long) nrets));
(long) duk_get_top(thr),
(long) old_top,
(long) nrets));
goto fail;
}
@ -1705,7 +1717,7 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
duk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(thr, -1));
}
duk_set_top(thr, old_top); /* restore stack top */
duk_set_top(thr, old_top); /* restore stack top */
} else {
DUK_D(DUK_DPRINT("no request callback, treat AppRequest as unsupported"));
duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, "AppRequest unsupported by target");
@ -1713,8 +1725,8 @@ DUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {
return;
fail:
duk_set_top(thr, old_top); /* restore stack top */
fail:
duk_set_top(thr, old_top); /* restore stack top */
DUK__SET_CONN_BROKEN(thr, 1);
}
@ -1765,16 +1777,16 @@ DUK_LOCAL void duk__debug_dump_heaphdr(duk_hthread *thr, duk_heap *heap, duk_hea
k = DUK_HOBJECT_E_GET_KEY(heap, h, i);
duk_debug_write_heapptr(thr, (duk_heaphdr *) k);
if (k == NULL) {
duk_debug_write_int(thr, 0); /* isAccessor */
duk_debug_write_int(thr, 0); /* isAccessor */
duk_debug_write_unused(thr);
continue;
}
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {
duk_debug_write_int(thr, 1); /* isAccessor */
duk_debug_write_int(thr, 1); /* isAccessor */
duk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);
duk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);
} else {
duk_debug_write_int(thr, 0); /* isAccessor */
duk_debug_write_int(thr, 0); /* isAccessor */
duk__debug_write_tval_heapptr(thr, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);
}
@ -1836,7 +1848,7 @@ DUK_LOCAL void duk__debug_handle_dump_heap(duk_hthread *thr, duk_heap *heap) {
duk__debug_dump_strtab(thr, heap);
duk_debug_write_eom(thr);
}
#endif /* DUK_USE_DEBUGGER_DUMPHEAP */
#endif /* DUK_USE_DEBUGGER_DUMPHEAP */
DUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap) {
duk_activation *act;
@ -1905,11 +1917,11 @@ DUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap)
duk_debug_write_eom(thr);
return;
fail_args:
fail_args:
duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid argument");
return;
fail_index:
fail_index:
duk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, "invalid callstack index");
return;
}
@ -1961,53 +1973,22 @@ DUK_LOCAL duk_uint_t duk__debug_getinfo_hstring_masks[] = {
DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS,
#endif
DUK_HSTRING_FLAG_EXTDATA,
0 /* terminator */
0 /* terminator */
};
DUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = {
"extensible",
"constructable",
"callable",
"boundfunc",
"compfunc",
"natfunc",
"bufobj",
"fastrefs",
"array_part",
"strict",
"notail",
"newenv",
"namebinding",
"createargs",
"have_finalizer",
"exotic_array",
"exotic_stringobj",
"exotic_arguments",
"exotic_proxyobj",
"special_call"
"extensible", "constructable", "callable", "boundfunc", "compfunc", "natfunc", "bufobj",
"fastrefs", "array_part", "strict", "notail", "newenv", "namebinding", "createargs",
"have_finalizer", "exotic_array", "exotic_stringobj", "exotic_arguments", "exotic_proxyobj", "special_call"
/* NULL not needed here */
};
DUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = {
DUK_HOBJECT_FLAG_EXTENSIBLE,
DUK_HOBJECT_FLAG_CONSTRUCTABLE,
DUK_HOBJECT_FLAG_CALLABLE,
DUK_HOBJECT_FLAG_BOUNDFUNC,
DUK_HOBJECT_FLAG_COMPFUNC,
DUK_HOBJECT_FLAG_NATFUNC,
DUK_HOBJECT_FLAG_BUFOBJ,
DUK_HOBJECT_FLAG_FASTREFS,
DUK_HOBJECT_FLAG_ARRAY_PART,
DUK_HOBJECT_FLAG_STRICT,
DUK_HOBJECT_FLAG_NOTAIL,
DUK_HOBJECT_FLAG_NEWENV,
DUK_HOBJECT_FLAG_NAMEBINDING,
DUK_HOBJECT_FLAG_CREATEARGS,
DUK_HOBJECT_FLAG_HAVE_FINALIZER,
DUK_HOBJECT_FLAG_EXOTIC_ARRAY,
DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ,
DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS,
DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ,
DUK_HOBJECT_FLAG_SPECIAL_CALL,
0 /* terminator */
DUK_HOBJECT_FLAG_EXTENSIBLE, DUK_HOBJECT_FLAG_CONSTRUCTABLE, DUK_HOBJECT_FLAG_CALLABLE,
DUK_HOBJECT_FLAG_BOUNDFUNC, DUK_HOBJECT_FLAG_COMPFUNC, DUK_HOBJECT_FLAG_NATFUNC,
DUK_HOBJECT_FLAG_BUFOBJ, DUK_HOBJECT_FLAG_FASTREFS, DUK_HOBJECT_FLAG_ARRAY_PART,
DUK_HOBJECT_FLAG_STRICT, DUK_HOBJECT_FLAG_NOTAIL, DUK_HOBJECT_FLAG_NEWENV,
DUK_HOBJECT_FLAG_NAMEBINDING, DUK_HOBJECT_FLAG_CREATEARGS, DUK_HOBJECT_FLAG_HAVE_FINALIZER,
DUK_HOBJECT_FLAG_EXOTIC_ARRAY, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS,
DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ, DUK_HOBJECT_FLAG_SPECIAL_CALL, 0 /* terminator */
};
DUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = {
"dynamic",
@ -2017,7 +1998,7 @@ DUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = {
DUK_LOCAL duk_uint_t duk__debug_getinfo_hbuffer_masks[] = {
DUK_HBUFFER_FLAG_DYNAMIC,
DUK_HBUFFER_FLAG_EXTERNAL,
0 /* terminator */
0 /* terminator */
};
DUK_LOCAL void duk__debug_getinfo_flags_key(duk_hthread *thr, const char *key) {
@ -2043,7 +2024,7 @@ DUK_LOCAL void duk__debug_getinfo_prop_bool(duk_hthread *thr, const char *key, d
duk_debug_write_boolean(thr, val);
}
DUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const * keys, duk_uint_t *masks, duk_uint_t flags) {
DUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const *keys, duk_uint_t *masks, duk_uint_t flags) {
const char *key;
duk_uint_t mask;
@ -2055,7 +2036,10 @@ DUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const *
key = *keys++;
DUK_ASSERT(key != NULL);
DUK_DD(DUK_DDPRINT("inspect bitmask: key=%s, mask=0x%08lx, flags=0x%08lx", key, (unsigned long) mask, (unsigned long) flags));
DUK_DD(DUK_DDPRINT("inspect bitmask: key=%s, mask=0x%08lx, flags=0x%08lx",
key,
(unsigned long) mask,
(unsigned long) flags));
duk__debug_getinfo_prop_bool(thr, key, flags & mask);
}
}
@ -2131,9 +2115,12 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
DUK_D(DUK_DPRINT("debug command GetHeapObjInfo"));
DUK_UNREF(heap);
DUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1);
DUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1);
DUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1);
DUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) ==
sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1);
DUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) ==
sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1);
DUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) ==
sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1);
h = duk_debug_read_any_ptr(thr);
if (!h) {
@ -2321,7 +2308,7 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
duk_debug_write_heapptr(thr, (duk_heaphdr *) h_bufobj->buf);
}
}
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */
break;
}
case DUK_HTYPE_BUFFER: {
@ -2336,7 +2323,7 @@ DUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *h
duk__debug_getinfo_flags_key(thr, "dataptr");
duk_debug_write_pointer(thr, (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf));
duk__debug_getinfo_flags_key(thr, "data");
duk_debug_write_hbuffer(thr, h_buf); /* tolerates NULL h_buf */
duk_debug_write_hbuffer(thr, h_buf); /* tolerates NULL h_buf */
break;
}
default: {
@ -2374,8 +2361,7 @@ DUK_LOCAL void duk__debug_handle_get_obj_prop_desc(duk_hthread *thr, duk_heap *h
/* To use the shared helper need the virtual index. */
DUK_ASSERT(desc.e_idx >= 0 || desc.a_idx >= 0);
virtual_idx = (desc.a_idx >= 0 ? desc.a_idx :
(duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj) + desc.e_idx);
virtual_idx = (desc.a_idx >= 0 ? desc.a_idx : (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj) + desc.e_idx);
duk_debug_write_reply(thr);
rc = duk__debug_getprop_index(thr, heap, h_obj, (duk_uint_t) virtual_idx);
@ -2387,7 +2373,7 @@ DUK_LOCAL void duk__debug_handle_get_obj_prop_desc(duk_hthread *thr, duk_heap *h
}
return;
fail_args:
fail_args:
duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid args");
}
@ -2423,11 +2409,11 @@ DUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_h
duk_debug_write_eom(thr);
return;
fail_args:
fail_args:
duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, "invalid args");
}
#endif /* DUK_USE_DEBUGGER_INSPECT */
#endif /* DUK_USE_DEBUGGER_INSPECT */
/*
* Process incoming debug requests
@ -2525,7 +2511,7 @@ DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {
duk__debug_handle_dump_heap(thr, heap);
break;
}
#endif /* DUK_USE_DEBUGGER_DUMPHEAP */
#endif /* DUK_USE_DEBUGGER_DUMPHEAP */
case DUK_DBG_CMD_GETBYTECODE: {
duk__debug_handle_get_bytecode(thr, heap);
break;
@ -2547,12 +2533,12 @@ DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {
duk__debug_handle_get_obj_prop_desc_range(thr, heap);
break;
}
#endif /* DUK_USE_DEBUGGER_INSPECT */
#endif /* DUK_USE_DEBUGGER_INSPECT */
default: {
DUK_D(DUK_DPRINT("debug command unsupported: %d", (int) cmd));
duk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, "unsupported command");
}
} /* switch cmd */
} /* switch cmd */
break;
}
case DUK_DBG_IB_REPLY: {
@ -2571,14 +2557,14 @@ DUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {
DUK_D(DUK_DPRINT("invalid initial byte, drop connection: %d", (int) x));
goto fail;
}
} /* switch initial byte */
} /* switch initial byte */
DUK_ASSERT(duk_get_top(thr) >= entry_top);
duk_set_top(thr, entry_top);
duk__debug_skip_to_eom(thr);
return;
fail:
fail:
DUK_ASSERT(duk_get_top(thr) >= entry_top);
duk_set_top(thr, entry_top);
DUK__SET_CONN_BROKEN(thr, 1);
@ -2605,8 +2591,10 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t
#endif
DUK_D(DUK_DPRINT("process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld",
thr->heap->dbg_read_cb ? "not NULL" : "NULL", (long) no_block,
(long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing));
thr->heap->dbg_read_cb ? "not NULL" : "NULL",
(long) no_block,
(long) thr->heap->dbg_detaching,
(long) thr->heap->dbg_processing));
DUK_DD(DUK_DDPRINT("top at entry: %ld", (long) duk_get_top(thr)));
/* thr->heap->dbg_detaching may be != 0 if a debugger write outside
@ -2653,13 +2641,14 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t
DUK_D(DUK_DPRINT("detach pending (dbg_read_cb == NULL, dbg_detaching != 0), call detach2"));
duk__debug_do_detach2(thr->heap);
thr->heap->dbg_processing = 1; /* may be set to 0 by duk_debugger_attach() inside callback */
thr->heap->dbg_processing = 1; /* may be set to 0 by duk_debugger_attach() inside callback */
DUK_D(DUK_DPRINT("after detach2 (and possible reattach): dbg_read_cb=%s, dbg_detaching=%ld",
thr->heap->dbg_read_cb ? "not NULL" : "NULL", (long) thr->heap->dbg_detaching));
thr->heap->dbg_read_cb ? "not NULL" : "NULL",
(long) thr->heap->dbg_detaching));
}
DUK_ASSERT(thr->heap->dbg_detaching == 0); /* true even with reattach */
DUK_ASSERT(thr->heap->dbg_processing == 1); /* even after a detach and possible reattach */
DUK_ASSERT(thr->heap->dbg_detaching == 0); /* true even with reattach */
DUK_ASSERT(thr->heap->dbg_processing == 1); /* even after a detach and possible reattach */
if (thr->heap->dbg_read_cb == NULL) {
DUK_D(DUK_DPRINT("debug connection broken (and not detaching), stop processing messages"));
@ -2684,7 +2673,7 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t
duk__debug_process_message(thr);
duk__check_resend_status(thr);
retval = 1; /* processed one or more messages */
retval = 1; /* processed one or more messages */
}
DUK_ASSERT(thr->heap->dbg_detaching == 0);
@ -2694,7 +2683,7 @@ DUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t
/* As an initial implementation, read flush after exiting the message
* loop. If transport is broken, this is a no-op (with debug logs).
*/
duk_debug_read_flush(thr); /* this cannot initiate a detach */
duk_debug_read_flush(thr); /* this cannot initiate a detach */
DUK_ASSERT(thr->heap->dbg_detaching == 0);
DUK_DD(DUK_DDPRINT("top at exit: %ld", (long) duk_get_top(thr)));
@ -2745,11 +2734,8 @@ DUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev
/* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is
* guaranteed to be a non-NULL ECMAScript function.
*/
DUK_ASSERT(act->curr_pc == NULL ||
(fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)));
if (use_prev_pc &&
act->curr_pc != NULL &&
act->curr_pc > DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, fun)) {
DUK_ASSERT(act->curr_pc == NULL || (fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)));
if (use_prev_pc && act->curr_pc != NULL && act->curr_pc > DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, fun)) {
act->curr_pc--;
}
}
@ -2776,7 +2762,7 @@ DUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev
* with PC values.
*/
if (act != NULL) {
act->curr_pc = old_pc; /* restore PC */
act->curr_pc = old_pc; /* restore PC */
}
}
@ -2800,7 +2786,8 @@ DUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstr
if (heap->dbg_breakpoint_count >= DUK_HEAP_MAX_BREAKPOINTS) {
DUK_D(DUK_DPRINT("failed to add breakpoint for %O:%ld, all breakpoint slots used",
(duk_heaphdr *) filename, (long) line));
(duk_heaphdr *) filename,
(long) line));
return -1;
}
heap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;
@ -2809,7 +2796,7 @@ DUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstr
b->line = line;
DUK_HSTRING_INCREF(thr, filename);
return (duk_small_int_t) (heap->dbg_breakpoint_count - 1); /* index */
return (duk_small_int_t) (heap->dbg_breakpoint_count - 1); /* index */
}
DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index) {
@ -2827,7 +2814,7 @@ DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_
heap = thr->heap;
DUK_ASSERT(heap != NULL);
DUK_ASSERT(duk_debug_is_attached(thr->heap));
DUK_ASSERT_DISABLE(breakpoint_index >= 0); /* unsigned */
DUK_ASSERT_DISABLE(breakpoint_index >= 0); /* unsigned */
if (breakpoint_index >= heap->dbg_breakpoint_count) {
DUK_D(DUK_DPRINT("invalid breakpoint index: %ld", (long) breakpoint_index));
@ -2839,15 +2826,13 @@ DUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_
DUK_ASSERT(h != NULL);
move_size = sizeof(duk_breakpoint) * (heap->dbg_breakpoint_count - breakpoint_index - 1);
duk_memmove((void *) b,
(const void *) (b + 1),
(size_t) move_size);
duk_memmove((void *) b, (const void *) (b + 1), (size_t) move_size);
heap->dbg_breakpoint_count--;
heap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;
DUK_HSTRING_DECREF(thr, h); /* side effects */
DUK_UNREF(h); /* w/o refcounting */
DUK_HSTRING_DECREF(thr, h); /* side effects */
DUK_UNREF(h); /* w/o refcounting */
/* Breakpoint entries above the used area are left as garbage. */
@ -2873,10 +2858,10 @@ DUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) {
DUK_HEAP_SET_DEBUGGER_PAUSED(heap);
heap->dbg_state_dirty = 1;
duk_debug_clear_pause_state(heap);
DUK_ASSERT(heap->ms_running == 0); /* debugger can't be triggered within mark-and-sweep */
heap->ms_running = 2; /* prevent mark-and-sweep, prevent refzero queueing */
DUK_ASSERT(heap->ms_running == 0); /* debugger can't be triggered within mark-and-sweep */
heap->ms_running = 2; /* prevent mark-and-sweep, prevent refzero queueing */
heap->ms_prevent_count++;
DUK_ASSERT(heap->ms_prevent_count != 0); /* Wrap. */
DUK_ASSERT(heap->ms_prevent_count != 0); /* Wrap. */
DUK_ASSERT(heap->heap_thread != NULL);
}
}
@ -2902,8 +2887,8 @@ DUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) {
heap->dbg_pause_startline = 0;
}
#else /* DUK_USE_DEBUGGER_SUPPORT */
#else /* DUK_USE_DEBUGGER_SUPPORT */
/* No debugger support. */
#endif /* DUK_USE_DEBUGGER_SUPPORT */
#endif /* DUK_USE_DEBUGGER_SUPPORT */

118
src-input/duk_debugger.h

@ -4,77 +4,77 @@
/* Debugger protocol version is defined in the public API header. */
/* Initial bytes for markers. */
#define DUK_DBG_IB_EOM 0x00
#define DUK_DBG_IB_REQUEST 0x01
#define DUK_DBG_IB_REPLY 0x02
#define DUK_DBG_IB_ERROR 0x03
#define DUK_DBG_IB_NOTIFY 0x04
#define DUK_DBG_IB_EOM 0x00
#define DUK_DBG_IB_REQUEST 0x01
#define DUK_DBG_IB_REPLY 0x02
#define DUK_DBG_IB_ERROR 0x03
#define DUK_DBG_IB_NOTIFY 0x04
/* Other initial bytes. */
#define DUK_DBG_IB_INT4 0x10
#define DUK_DBG_IB_STR4 0x11
#define DUK_DBG_IB_STR2 0x12
#define DUK_DBG_IB_BUF4 0x13
#define DUK_DBG_IB_BUF2 0x14
#define DUK_DBG_IB_UNUSED 0x15
#define DUK_DBG_IB_UNDEFINED 0x16
#define DUK_DBG_IB_NULL 0x17
#define DUK_DBG_IB_TRUE 0x18
#define DUK_DBG_IB_FALSE 0x19
#define DUK_DBG_IB_NUMBER 0x1a
#define DUK_DBG_IB_OBJECT 0x1b
#define DUK_DBG_IB_POINTER 0x1c
#define DUK_DBG_IB_LIGHTFUNC 0x1d
#define DUK_DBG_IB_HEAPPTR 0x1e
#define DUK_DBG_IB_INT4 0x10
#define DUK_DBG_IB_STR4 0x11
#define DUK_DBG_IB_STR2 0x12
#define DUK_DBG_IB_BUF4 0x13
#define DUK_DBG_IB_BUF2 0x14
#define DUK_DBG_IB_UNUSED 0x15
#define DUK_DBG_IB_UNDEFINED 0x16
#define DUK_DBG_IB_NULL 0x17
#define DUK_DBG_IB_TRUE 0x18
#define DUK_DBG_IB_FALSE 0x19
#define DUK_DBG_IB_NUMBER 0x1a
#define DUK_DBG_IB_OBJECT 0x1b
#define DUK_DBG_IB_POINTER 0x1c
#define DUK_DBG_IB_LIGHTFUNC 0x1d
#define DUK_DBG_IB_HEAPPTR 0x1e
/* The short string/integer initial bytes starting from 0x60 don't have
* defines now.
*/
/* Error codes. */
#define DUK_DBG_ERR_UNKNOWN 0x00
#define DUK_DBG_ERR_UNSUPPORTED 0x01
#define DUK_DBG_ERR_TOOMANY 0x02
#define DUK_DBG_ERR_NOTFOUND 0x03
#define DUK_DBG_ERR_APPLICATION 0x04
#define DUK_DBG_ERR_UNKNOWN 0x00
#define DUK_DBG_ERR_UNSUPPORTED 0x01
#define DUK_DBG_ERR_TOOMANY 0x02
#define DUK_DBG_ERR_NOTFOUND 0x03
#define DUK_DBG_ERR_APPLICATION 0x04
/* Commands and notifys initiated by Duktape. */
#define DUK_DBG_CMD_STATUS 0x01
#define DUK_DBG_CMD_UNUSED_2 0x02 /* Duktape 1.x: print notify */
#define DUK_DBG_CMD_UNUSED_3 0x03 /* Duktape 1.x: alert notify */
#define DUK_DBG_CMD_UNUSED_4 0x04 /* Duktape 1.x: log notify */
#define DUK_DBG_CMD_THROW 0x05
#define DUK_DBG_CMD_DETACHING 0x06
#define DUK_DBG_CMD_APPNOTIFY 0x07
#define DUK_DBG_CMD_STATUS 0x01
#define DUK_DBG_CMD_UNUSED_2 0x02 /* Duktape 1.x: print notify */
#define DUK_DBG_CMD_UNUSED_3 0x03 /* Duktape 1.x: alert notify */
#define DUK_DBG_CMD_UNUSED_4 0x04 /* Duktape 1.x: log notify */
#define DUK_DBG_CMD_THROW 0x05
#define DUK_DBG_CMD_DETACHING 0x06
#define DUK_DBG_CMD_APPNOTIFY 0x07
/* Commands initiated by debug client. */
#define DUK_DBG_CMD_BASICINFO 0x10
#define DUK_DBG_CMD_TRIGGERSTATUS 0x11
#define DUK_DBG_CMD_PAUSE 0x12
#define DUK_DBG_CMD_RESUME 0x13
#define DUK_DBG_CMD_STEPINTO 0x14
#define DUK_DBG_CMD_STEPOVER 0x15
#define DUK_DBG_CMD_STEPOUT 0x16
#define DUK_DBG_CMD_LISTBREAK 0x17
#define DUK_DBG_CMD_ADDBREAK 0x18
#define DUK_DBG_CMD_DELBREAK 0x19
#define DUK_DBG_CMD_GETVAR 0x1a
#define DUK_DBG_CMD_PUTVAR 0x1b
#define DUK_DBG_CMD_GETCALLSTACK 0x1c
#define DUK_DBG_CMD_GETLOCALS 0x1d
#define DUK_DBG_CMD_EVAL 0x1e
#define DUK_DBG_CMD_DETACH 0x1f
#define DUK_DBG_CMD_DUMPHEAP 0x20
#define DUK_DBG_CMD_GETBYTECODE 0x21
#define DUK_DBG_CMD_APPREQUEST 0x22
#define DUK_DBG_CMD_GETHEAPOBJINFO 0x23
#define DUK_DBG_CMD_GETOBJPROPDESC 0x24
#define DUK_DBG_CMD_GETOBJPROPDESCRANGE 0x25
#define DUK_DBG_CMD_BASICINFO 0x10
#define DUK_DBG_CMD_TRIGGERSTATUS 0x11
#define DUK_DBG_CMD_PAUSE 0x12
#define DUK_DBG_CMD_RESUME 0x13
#define DUK_DBG_CMD_STEPINTO 0x14
#define DUK_DBG_CMD_STEPOVER 0x15
#define DUK_DBG_CMD_STEPOUT 0x16
#define DUK_DBG_CMD_LISTBREAK 0x17
#define DUK_DBG_CMD_ADDBREAK 0x18
#define DUK_DBG_CMD_DELBREAK 0x19
#define DUK_DBG_CMD_GETVAR 0x1a
#define DUK_DBG_CMD_PUTVAR 0x1b
#define DUK_DBG_CMD_GETCALLSTACK 0x1c
#define DUK_DBG_CMD_GETLOCALS 0x1d
#define DUK_DBG_CMD_EVAL 0x1e
#define DUK_DBG_CMD_DETACH 0x1f
#define DUK_DBG_CMD_DUMPHEAP 0x20
#define DUK_DBG_CMD_GETBYTECODE 0x21
#define DUK_DBG_CMD_APPREQUEST 0x22
#define DUK_DBG_CMD_GETHEAPOBJINFO 0x23
#define DUK_DBG_CMD_GETOBJPROPDESC 0x24
#define DUK_DBG_CMD_GETOBJPROPDESCRANGE 0x25
/* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx.
* The remaining flags are specific to the debugger.
*/
#define DUK_DBG_PROPFLAG_SYMBOL (1U << 8)
#define DUK_DBG_PROPFLAG_HIDDEN (1U << 9)
#define DUK_DBG_PROPFLAG_SYMBOL (1U << 8)
#define DUK_DBG_PROPFLAG_HIDDEN (1U << 9)
#if defined(DUK_USE_DEBUGGER_SUPPORT)
DUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap);
@ -121,7 +121,7 @@ DUK_INTERNAL_DECL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h)
#endif
DUK_INTERNAL_DECL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj);
DUK_INTERNAL_DECL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv);
#if 0 /* unused */
#if 0 /* unused */
DUK_INTERNAL_DECL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command);
#endif
DUK_INTERNAL_DECL void duk_debug_write_reply(duk_hthread *thr);
@ -146,6 +146,6 @@ DUK_INTERNAL_DECL duk_bool_t duk_debug_is_paused(duk_heap *heap);
DUK_INTERNAL_DECL void duk_debug_set_paused(duk_heap *heap);
DUK_INTERNAL_DECL void duk_debug_clear_paused(duk_heap *heap);
DUK_INTERNAL_DECL void duk_debug_clear_pause_state(duk_heap *heap);
#endif /* DUK_USE_DEBUGGER_SUPPORT */
#endif /* DUK_USE_DEBUGGER_SUPPORT */
#endif /* DUK_DEBUGGER_H_INCLUDED */
#endif /* DUK_DEBUGGER_H_INCLUDED */

511
src-input/duk_error.h

@ -53,79 +53,153 @@
/* Because there are quite many call sites, pack error code (require at most
* 8-bit) into a single argument.
*/
#define DUK_ERROR(thr,err,msg) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
#define DUK_ERROR(thr, err, msg) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \
} while (0)
#define DUK_ERROR_RAW(thr,file,line,err,msg) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
#define DUK_ERROR_RAW(thr, file, line, err, msg) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \
} while (0)
#define DUK_ERROR_FMT1(thr,err,fmt,arg1) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \
} while (0)
#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \
} while (0)
#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \
} while (0)
#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \
} while (0)
#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \
} while (0)
#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \
} while (0)
#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \
} while (0)
#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) do { \
duk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \
} while (0)
#else /* DUK_USE_VERBOSE_ERRORS */
#define DUK_ERROR(thr,err,msg) duk_err_handle_error((thr), (err))
#define DUK_ERROR_RAW(thr,file,line,err,msg) duk_err_handle_error((thr), (err))
#define DUK_ERROR_FMT1(thr,err,fmt,arg1) DUK_ERROR((thr),(err),(fmt))
#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))
#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) DUK_ERROR((thr),(err),(fmt))
#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))
#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) DUK_ERROR((thr),(err),(fmt))
#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))
#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR((thr),(err),(fmt))
#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))
#endif /* DUK_USE_VERBOSE_ERRORS */
#define DUK_ERROR_FMT1(thr, err, fmt, arg1) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
DUK_FILE_MACRO, \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1)); \
} while (0)
#define DUK_ERROR_RAW_FMT1(thr, file, line, err, fmt, arg1) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
(file), \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1)); \
} while (0)
#define DUK_ERROR_FMT2(thr, err, fmt, arg1, arg2) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
DUK_FILE_MACRO, \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1), \
(arg2)); \
} while (0)
#define DUK_ERROR_RAW_FMT2(thr, file, line, err, fmt, arg1, arg2) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
(file), \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1), \
(arg2)); \
} while (0)
#define DUK_ERROR_FMT3(thr, err, fmt, arg1, arg2, arg3) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
DUK_FILE_MACRO, \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1), \
(arg2), \
(arg3)); \
} while (0)
#define DUK_ERROR_RAW_FMT3(thr, file, line, err, fmt, arg1, arg2, arg3) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
(file), \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1), \
(arg2), \
(arg3)); \
} while (0)
#define DUK_ERROR_FMT4(thr, err, fmt, arg1, arg2, arg3, arg4) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
DUK_FILE_MACRO, \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1), \
(arg2), \
(arg3), \
(arg4)); \
} while (0)
#define DUK_ERROR_RAW_FMT4(thr, file, line, err, fmt, arg1, arg2, arg3, arg4) \
do { \
duk_errcode_t duk__err = (err); \
duk_int_t duk__line = (duk_int_t) (line); \
DUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); \
DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \
duk_err_handle_error_fmt((thr), \
(file), \
(((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), \
(fmt), \
(arg1), \
(arg2), \
(arg3), \
(arg4)); \
} while (0)
#else /* DUK_USE_VERBOSE_ERRORS */
#define DUK_ERROR(thr, err, msg) duk_err_handle_error((thr), (err))
#define DUK_ERROR_RAW(thr, file, line, err, msg) duk_err_handle_error((thr), (err))
#define DUK_ERROR_FMT1(thr, err, fmt, arg1) DUK_ERROR((thr), (err), (fmt))
#define DUK_ERROR_RAW_FMT1(thr, file, line, err, fmt, arg1) DUK_ERROR_RAW((thr), (file), (line), (err), (fmt))
#define DUK_ERROR_FMT2(thr, err, fmt, arg1, arg2) DUK_ERROR((thr), (err), (fmt))
#define DUK_ERROR_RAW_FMT2(thr, file, line, err, fmt, arg1, arg2) DUK_ERROR_RAW((thr), (file), (line), (err), (fmt))
#define DUK_ERROR_FMT3(thr, err, fmt, arg1, arg2, arg3) DUK_ERROR((thr), (err), (fmt))
#define DUK_ERROR_RAW_FMT3(thr, file, line, err, fmt, arg1, arg2, arg3) DUK_ERROR_RAW((thr), (file), (line), (err), (fmt))
#define DUK_ERROR_FMT4(thr, err, fmt, arg1, arg2, arg3, arg4) DUK_ERROR((thr), (err), (fmt))
#define DUK_ERROR_RAW_FMT4(thr, file, line, err, fmt, arg1, arg2, arg3, arg4) DUK_ERROR_RAW((thr), (file), (line), (err), (fmt))
#endif /* DUK_USE_VERBOSE_ERRORS */
/*
* Fatal error without context
@ -133,8 +207,7 @@
* The macro is an expression to make it compatible with DUK_ASSERT_EXPR().
*/
#define DUK_FATAL_WITHOUT_CONTEXT(msg) \
duk_default_fatal_handler(NULL, (msg))
#define DUK_FATAL_WITHOUT_CONTEXT(msg) duk_default_fatal_handler(NULL, (msg))
/*
* Error throwing helpers
@ -159,196 +232,252 @@
* vs. non-paranoid distinction affects only a few specific errors.
*/
#if defined(DUK_USE_PARANOID_ERRORS)
#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \
#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, expectname, lowmemstr) \
do { \
duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \
} while (0)
#else /* DUK_USE_PARANOID_ERRORS */
#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \
#else /* DUK_USE_PARANOID_ERRORS */
#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, expectname, lowmemstr) \
do { \
duk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \
} while (0)
#endif /* DUK_USE_PARANOID_ERRORS */
#endif /* DUK_USE_PARANOID_ERRORS */
#define DUK_ERROR_INTERNAL(thr) do { \
#define DUK_ERROR_INTERNAL(thr) \
do { \
duk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
#define DUK_DCERROR_INTERNAL(thr) do { \
#define DUK_DCERROR_INTERNAL(thr) \
do { \
DUK_ERROR_INTERNAL((thr)); \
return 0; \
} while (0)
#define DUK_ERROR_ALLOC_FAILED(thr) do { \
#define DUK_ERROR_ALLOC_FAILED(thr) \
do { \
duk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
#define DUK_ERROR_UNSUPPORTED(thr) do { \
#define DUK_ERROR_UNSUPPORTED(thr) \
do { \
DUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \
} while (0)
#define DUK_DCERROR_UNSUPPORTED(thr) do { \
#define DUK_DCERROR_UNSUPPORTED(thr) \
do { \
DUK_ERROR_UNSUPPORTED((thr)); \
return 0; \
} while (0)
#define DUK_ERROR_ERROR(thr,msg) do { \
#define DUK_ERROR_ERROR(thr, msg) \
do { \
duk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \
} while (0)
#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \
#define DUK_ERROR_RANGE_INDEX(thr, idx) \
do { \
duk_err_range_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx)); \
} while (0)
#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \
#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) \
do { \
duk_err_range_push_beyond((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \
#define DUK_ERROR_RANGE_INVALID_ARGS(thr) \
do { \
DUK_ERROR_RANGE((thr), DUK_STR_INVALID_ARGS); \
} while (0)
#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \
#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) \
do { \
DUK_ERROR_RANGE_INVALID_ARGS((thr)); \
return 0; \
} while (0)
#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \
#define DUK_ERROR_RANGE_INVALID_COUNT(thr) \
do { \
DUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \
} while (0)
#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \
#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) \
do { \
DUK_ERROR_RANGE_INVALID_COUNT((thr)); \
return 0; \
} while (0)
#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \
#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) \
do { \
DUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \
} while (0)
#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \
#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) \
do { \
DUK_ERROR_RANGE_INVALID_LENGTH((thr)); \
return 0; \
} while (0)
#define DUK_ERROR_RANGE(thr,msg) do { \
#define DUK_ERROR_RANGE(thr, msg) \
do { \
duk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \
} while (0)
#define DUK_ERROR_EVAL(thr,msg) do { \
#define DUK_ERROR_EVAL(thr, msg) \
do { \
DUK_ERROR((thr), DUK_ERR_EVAL_ERROR, (msg)); \
} while (0)
#define DUK_ERROR_REFERENCE(thr,msg) do { \
#define DUK_ERROR_REFERENCE(thr, msg) \
do { \
DUK_ERROR((thr), DUK_ERR_REFERENCE_ERROR, (msg)); \
} while (0)
#define DUK_ERROR_SYNTAX(thr,msg) do { \
#define DUK_ERROR_SYNTAX(thr, msg) \
do { \
DUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \
} while (0)
#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \
#define DUK_ERROR_TYPE_INVALID_ARGS(thr) \
do { \
duk_err_type_invalid_args((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \
#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) \
do { \
DUK_ERROR_TYPE_INVALID_ARGS((thr)); \
return 0; \
} while (0)
#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \
#define DUK_ERROR_TYPE_INVALID_STATE(thr) \
do { \
duk_err_type_invalid_state((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \
#define DUK_DCERROR_TYPE_INVALID_STATE(thr) \
do { \
DUK_ERROR_TYPE_INVALID_STATE((thr)); \
return 0; \
} while (0)
#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \
#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) \
do { \
duk_err_type_invalid_trap_result((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \
} while (0)
#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \
#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) \
do { \
DUK_ERROR_TYPE((thr), DUK_STR_INVALID_TRAP_RESULT); \
} while (0)
#define DUK_ERROR_TYPE(thr,msg) do { \
#define DUK_ERROR_TYPE(thr, msg) \
do { \
DUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \
} while (0)
#define DUK_ERROR_URI(thr,msg) do { \
#define DUK_ERROR_URI(thr, msg) \
do { \
DUK_ERROR((thr), DUK_ERR_URI_ERROR, (msg)); \
} while (0)
#else /* DUK_USE_VERBOSE_ERRORS */
#else /* DUK_USE_VERBOSE_ERRORS */
/* Non-verbose errors for low memory targets: no file, line, or message. */
#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \
#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, expectname, lowmemstr) \
do { \
duk_err_type((thr)); \
} while (0)
#define DUK_ERROR_INTERNAL(thr) do { \
#define DUK_ERROR_INTERNAL(thr) \
do { \
duk_err_error((thr)); \
} while (0)
#define DUK_DCERROR_INTERNAL(thr) do { \
#define DUK_DCERROR_INTERNAL(thr) \
do { \
DUK_UNREF((thr)); \
return DUK_RET_ERROR; \
} while (0)
#define DUK_ERROR_ALLOC_FAILED(thr) do { \
#define DUK_ERROR_ALLOC_FAILED(thr) \
do { \
duk_err_error((thr)); \
} while (0)
#define DUK_ERROR_UNSUPPORTED(thr) do { \
#define DUK_ERROR_UNSUPPORTED(thr) \
do { \
duk_err_error((thr)); \
} while (0)
#define DUK_DCERROR_UNSUPPORTED(thr) do { \
#define DUK_DCERROR_UNSUPPORTED(thr) \
do { \
DUK_UNREF((thr)); \
return DUK_RET_ERROR; \
} while (0)
#define DUK_ERROR_ERROR(thr,msg) do { \
#define DUK_ERROR_ERROR(thr, msg) \
do { \
duk_err_error((thr)); \
} while (0)
#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \
#define DUK_ERROR_RANGE_INDEX(thr, idx) \
do { \
duk_err_range((thr)); \
} while (0)
#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \
#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) \
do { \
duk_err_range((thr)); \
} while (0)
#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \
#define DUK_ERROR_RANGE_INVALID_ARGS(thr) \
do { \
duk_err_range((thr)); \
} while (0)
#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \
#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) \
do { \
DUK_UNREF((thr)); \
return DUK_RET_RANGE_ERROR; \
} while (0)
#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \
#define DUK_ERROR_RANGE_INVALID_COUNT(thr) \
do { \
duk_err_range((thr)); \
} while (0)
#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \
#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) \
do { \
DUK_UNREF((thr)); \
return DUK_RET_RANGE_ERROR; \
} while (0)
#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \
#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) \
do { \
duk_err_range((thr)); \
} while (0)
#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \
#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) \
do { \
DUK_UNREF((thr)); \
return DUK_RET_RANGE_ERROR; \
} while (0)
#define DUK_ERROR_RANGE(thr,msg) do { \
#define DUK_ERROR_RANGE(thr, msg) \
do { \
duk_err_range((thr)); \
} while (0)
#define DUK_ERROR_EVAL(thr,msg) do { \
#define DUK_ERROR_EVAL(thr, msg) \
do { \
duk_err_eval((thr)); \
} while (0)
#define DUK_ERROR_REFERENCE(thr,msg) do { \
#define DUK_ERROR_REFERENCE(thr, msg) \
do { \
duk_err_reference((thr)); \
} while (0)
#define DUK_ERROR_SYNTAX(thr,msg) do { \
#define DUK_ERROR_SYNTAX(thr, msg) \
do { \
duk_err_syntax((thr)); \
} while (0)
#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \
#define DUK_ERROR_TYPE_INVALID_ARGS(thr) \
do { \
duk_err_type((thr)); \
} while (0)
#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \
#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) \
do { \
DUK_UNREF((thr)); \
return DUK_RET_TYPE_ERROR; \
} while (0)
#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \
#define DUK_ERROR_TYPE_INVALID_STATE(thr) \
do { \
duk_err_type((thr)); \
} while (0)
#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \
#define DUK_DCERROR_TYPE_INVALID_STATE(thr) \
do { \
duk_err_type((thr)); \
} while (0)
#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \
#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) \
do { \
duk_err_type((thr)); \
} while (0)
#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \
#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) \
do { \
DUK_UNREF((thr)); \
return DUK_RET_TYPE_ERROR; \
} while (0)
#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \
#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) \
do { \
duk_err_type((thr)); \
} while (0)
#define DUK_ERROR_TYPE(thr,msg) do { \
#define DUK_ERROR_TYPE(thr, msg) \
do { \
duk_err_type((thr)); \
} while (0)
#define DUK_ERROR_URI(thr,msg) do { \
#define DUK_ERROR_URI(thr, msg) \
do { \
duk_err_uri((thr)); \
} while (0)
#endif /* DUK_USE_VERBOSE_ERRORS */
#endif /* DUK_USE_VERBOSE_ERRORS */
/*
* Assert macro: failure causes a fatal error.
@ -366,63 +495,72 @@
* we don't care about assertion text size because they're not used in production
* builds.
*/
#define DUK_ASSERT(x) do { \
if (!(x)) { \
DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x \
" (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"); \
} \
#define DUK_ASSERT(x) \
do { \
if (!(x)) { \
DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x " (" DUK_FILE_MACRO \
":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"); \
} \
} while (0)
/* Assertion compatible inside a comma expression, evaluates to void. */
#define DUK_ASSERT_EXPR(x) \
((void) ((x) ? 0 : (DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x \
" (" DUK_FILE_MACRO ":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"), 0)))
((void) ((x) ? 0 : \
(DUK_FATAL_WITHOUT_CONTEXT("assertion failed: " #x " (" DUK_FILE_MACRO \
":" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) ")"), \
0)))
#else /* DUK_USE_ASSERTIONS */
#else /* DUK_USE_ASSERTIONS */
#define DUK_ASSERT(x) do { /* assertion omitted */ } while (0)
#define DUK_ASSERT(x) \
do { /* assertion omitted */ \
} while (0)
#define DUK_ASSERT_EXPR(x) ((void) 0)
#define DUK_ASSERT_EXPR(x) ((void) 0)
#endif /* DUK_USE_ASSERTIONS */
#endif /* DUK_USE_ASSERTIONS */
/* this variant is used when an assert would generate a compile warning by
* being always true (e.g. >= 0 comparison for an unsigned value
*/
#define DUK_ASSERT_DISABLE(x) do { /* assertion disabled */ } while (0)
#define DUK_ASSERT_DISABLE(x) \
do { /* assertion disabled */ \
} while (0)
/*
* Assertion helpers
*/
#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)
#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) do { \
#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) \
do { \
DUK_ASSERT((h) == NULL || DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) (h)) > 0); \
} while (0)
#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) do { \
#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) \
do { \
if ((tv) != NULL && DUK_TVAL_IS_HEAP_ALLOCATED((tv))) { \
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(DUK_TVAL_GET_HEAPHDR((tv))) > 0); \
} \
} while (0)
#else
#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) /* no refcount check */
#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) /* no refcount check */
#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h) /* no refcount check */
#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv) /* no refcount check */
#endif
#define DUK_ASSERT_TOP(ctx,n) DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n))
#define DUK_ASSERT_TOP(ctx, n) DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n))
#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL)
#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) do { \
#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) \
do { \
duk_double_union duk__assert_tmp_du; \
duk__assert_tmp_du.d = (dval); \
DUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \
} while (0)
#else
#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) /* nop */
#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval) /* nop */
#endif
#define DUK_ASSERT_VS_SPACE(thr) \
DUK_ASSERT(thr->valstack_top < thr->valstack_end)
#define DUK_ASSERT_VS_SPACE(thr) DUK_ASSERT(thr->valstack_top < thr->valstack_end)
/*
* Helper to initialize a memory area (e.g. struct) with garbage when
@ -430,11 +568,14 @@
*/
#if defined(DUK_USE_ASSERTIONS)
#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \
#define DUK_ASSERT_SET_GARBAGE(ptr, size) \
do { \
duk_memset_unsafe((void *) (ptr), 0x5a, size); \
} while (0)
#else
#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0)
#define DUK_ASSERT_SET_GARBAGE(ptr, size) \
do { \
} while (0)
#endif
/*
@ -445,16 +586,19 @@
* or (b) Duktape calls which involve extending the valstack (e.g. getter call).
*/
#define DUK_VALSTACK_ASSERT_EXTRA 5 /* this is added to checks to allow for Duktape
* API calls in addition to function's own use
*/
/* This is added to checks to allow for Duktape API calls in addition to function's
* own use.
*/
#define DUK_VALSTACK_ASSERT_EXTRA 5
#if defined(DUK_USE_ASSERTIONS)
#define DUK_ASSERT_VALSTACK_SPACE(thr,n) do { \
#define DUK_ASSERT_VALSTACK_SPACE(thr, n) \
do { \
DUK_ASSERT((thr) != NULL); \
DUK_ASSERT((thr)->valstack_end - (thr)->valstack_top >= (n) + DUK_VALSTACK_ASSERT_EXTRA); \
} while (0)
#else
#define DUK_ASSERT_VALSTACK_SPACE(thr,n) /* no valstack space check */
#define DUK_ASSERT_VALSTACK_SPACE(thr, n) /* no valstack space check */
#endif
/*
@ -462,25 +606,35 @@
*/
#if defined(DUK_USE_VERBOSE_ERRORS)
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...));
#else /* DUK_USE_VERBOSE_ERRORS */
DUK_NORETURN(
DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg));
DUK_NORETURN(DUK_INTERNAL_DECL void
duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...));
#else /* DUK_USE_VERBOSE_ERRORS */
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code));
#endif /* DUK_USE_VERBOSE_ERRORS */
#endif /* DUK_USE_VERBOSE_ERRORS */
#if defined(DUK_USE_VERBOSE_ERRORS)
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr,
duk_errcode_t code,
const char *msg,
const char *filename,
duk_int_t line));
#else
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code));
#endif
DUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc));
#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE (1U << 0) /* if set, don't blame C file/line for .fileName and .lineNumber */
#define DUK_AUGMENT_FLAG_SKIP_ONE (1U << 1) /* if set, skip topmost activation in traceback construction */
#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE (1U << 0) /* if set, don't blame C file/line for .fileName and .lineNumber */
#define DUK_AUGMENT_FLAG_SKIP_ONE (1U << 1) /* if set, skip topmost activation in traceback construction */
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
DUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_small_uint_t flags);
DUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr,
duk_hthread *thr_callstack,
const char *filename,
duk_int_t line,
duk_small_uint_t flags);
#endif
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
DUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr);
@ -488,20 +642,31 @@ DUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr);
#if defined(DUK_USE_VERBOSE_ERRORS)
#if defined(DUK_USE_PARANOID_ERRORS)
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr,
const char *filename,
duk_int_t linenumber,
duk_idx_t idx,
const char *expect_name));
#else
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr,
const char *filename,
duk_int_t linenumber,
duk_idx_t idx,
const char *expect_name));
#endif
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx));
DUK_NORETURN(
DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));
DUK_NORETURN(
DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));
DUK_NORETURN(
DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber));
#else /* DUK_VERBOSE_ERRORS */
#else /* DUK_VERBOSE_ERRORS */
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr));
DUK_NORETURN(DUK_INTERNAL_DECL void duk_err_eval(duk_hthread *thr));
@ -522,4 +687,4 @@ DUK_INTERNAL_DECL void duk_err_check_debugger_integration(duk_hthread *thr);
DUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code);
#endif /* DUK_ERROR_H_INCLUDED */
#endif /* DUK_ERROR_H_INCLUDED */

110
src-input/duk_error_augment.c

@ -82,7 +82,7 @@ DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_c
* when it is called and that error replaces the original one.
*/
DUK_ASSERT_VALSTACK_SPACE(thr, 4); /* 3 entries actually needed below */
DUK_ASSERT_VALSTACK_SPACE(thr, 4); /* 3 entries actually needed below */
/* [ ... errval ] */
@ -93,23 +93,19 @@ DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_c
DUK_DD(DUK_DDPRINT("error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring"));
return;
}
tv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap,
thr->builtins[DUK_BIDX_DUKTAPE],
stridx_cb);
tv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, thr->builtins[DUK_BIDX_DUKTAPE], stridx_cb);
if (tv_hnd == NULL) {
DUK_DD(DUK_DDPRINT("error handler does not exist or is not a plain value: %!T",
(duk_tval *) tv_hnd));
DUK_DD(DUK_DDPRINT("error handler does not exist or is not a plain value: %!T", (duk_tval *) tv_hnd));
return;
}
DUK_DDD(DUK_DDDPRINT("error handler dump (callability not checked): %!T",
(duk_tval *) tv_hnd));
DUK_DDD(DUK_DDDPRINT("error handler dump (callability not checked): %!T", (duk_tval *) tv_hnd));
duk_push_tval(thr, tv_hnd);
/* [ ... errval errhandler ] */
duk_insert(thr, -2); /* -> [ ... errhandler errval ] */
duk_insert(thr, -2); /* -> [ ... errhandler errval ] */
duk_push_undefined(thr);
duk_insert(thr, -2); /* -> [ ... errhandler undefined(= this) errval ] */
duk_insert(thr, -2); /* -> [ ... errhandler undefined(= this) errval ] */
/* [ ... errhandler undefined errval ] */
@ -126,21 +122,25 @@ DUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_c
thr->heap->augmenting_error = 1;
rc = duk_pcall_method(thr, 1);
DUK_UNREF(rc); /* no need to check now: both success and error are OK */
DUK_UNREF(rc); /* no need to check now: both success and error are OK */
DUK_ASSERT(thr->heap->augmenting_error == 1);
thr->heap->augmenting_error = 0;
/* [ ... errval ] */
}
#endif /* DUK_USE_ERRTHROW || DUK_USE_ERRCREATE */
#endif /* DUK_USE_ERRTHROW || DUK_USE_ERRCREATE */
/*
* Add ._Tracedata to an error on the stack top.
*/
#if defined(DUK_USE_TRACEBACKS)
DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {
DUK_LOCAL void duk__add_traceback(duk_hthread *thr,
duk_hthread *thr_callstack,
const char *c_filename,
duk_int_t c_line,
duk_small_uint_t flags) {
duk_activation *act;
duk_int_t depth;
duk_int_t arr_size;
@ -162,15 +162,14 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
* See doc/error-objects.rst.
*/
DUK_DDD(DUK_DDDPRINT("adding traceback to object: %!T",
(duk_tval *) duk_get_tval(thr, -1)));
DUK_DDD(DUK_DDDPRINT("adding traceback to object: %!T", (duk_tval *) duk_get_tval(thr, -1)));
/* Preallocate array to correct size, so that we can just write out
* the _Tracedata values into the array part.
*/
act = thr->callstack_curr;
depth = DUK_USE_TRACEBACK_DEPTH;
DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */
DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */
if (depth > (duk_int_t) thr_callstack->callstack_top) {
depth = (duk_int_t) thr_callstack->callstack_top;
}
@ -212,7 +211,7 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
DUK_HSTRING_INCREF(thr, s);
tv++;
u32 = (duk_uint32_t) thr->compile_ctx->curr_token.start_line; /* (flags<<32) + (line), flags = 0 */
u32 = (duk_uint32_t) thr->compile_ctx->curr_token.start_line; /* (flags<<32) + (line), flags = 0 */
DUK_TVAL_SET_U32(tv, u32);
tv++;
}
@ -226,13 +225,15 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
if (c_filename) {
DUK_ASSERT(DUK_TVAL_IS_STRING(thr->valstack_top - 2));
s = DUK_TVAL_GET_STRING(thr->valstack_top - 2); /* interned c_filename */
s = DUK_TVAL_GET_STRING(thr->valstack_top - 2); /* interned c_filename */
DUK_ASSERT(s != NULL);
DUK_TVAL_SET_STRING(tv, s);
DUK_HSTRING_INCREF(thr, s);
tv++;
d = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) +
d = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ?
((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 :
0.0) +
(duk_double_t) c_line;
DUK_TVAL_SET_DOUBLE(tv, d);
tv++;
@ -247,11 +248,11 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
/* [... arr] */
DUK_ASSERT(act != NULL); /* depth check above, assumes book-keeping is correct */
DUK_ASSERT_DISABLE(act->pc >= 0); /* unsigned */
DUK_ASSERT(act != NULL); /* depth check above, assumes book-keeping is correct */
DUK_ASSERT_DISABLE(act->pc >= 0); /* unsigned */
/* Add function object. */
tv_src = &act->tv_func; /* object (function) or lightfunc */
tv_src = &act->tv_func; /* object (function) or lightfunc */
DUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_src) || DUK_TVAL_IS_LIGHTFUNC(tv_src));
DUK_TVAL_SET_TVAL(tv, tv_src);
DUK_TVAL_INCREF(thr, tv);
@ -263,8 +264,8 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
* PC == 0 for native code.
*/
pc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr_callstack, act);
DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */
DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits and non-negative */
DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */
DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits and non-negative */
d = ((duk_double_t) act->flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc;
DUK_TVAL_SET_DOUBLE(tv, d);
tv++;
@ -289,16 +290,20 @@ DUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack,
/* [ ... error arr ] */
duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA); /* -> [ ... error ] */
duk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA); /* -> [ ... error ] */
}
#endif /* DUK_USE_TRACEBACKS */
#endif /* DUK_USE_TRACEBACKS */
/*
* Add .fileName and .lineNumber to an error on the stack top.
*/
#if defined(DUK_USE_AUGMENT_ERROR_CREATE) && !defined(DUK_USE_TRACEBACKS)
DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {
DUK_LOCAL void duk__add_fileline(duk_hthread *thr,
duk_hthread *thr_callstack,
const char *c_filename,
duk_int_t c_line,
duk_small_uint_t flags) {
#if defined(DUK_USE_ASSERTIONS)
duk_int_t entry_top;
#endif
@ -336,7 +341,7 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
duk_uint32_t ecma_line;
duk_activation *act;
DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */
DUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX); /* callstack limits */
depth = DUK_USE_TRACEBACK_DEPTH;
if (depth > thr_callstack->callstack_top) {
depth = thr_callstack->callstack_top;
@ -355,10 +360,12 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
/* PC points to next instruction, find offending PC,
* PC == 0 for native code.
*/
pc = duk_hthread_get_act_prev_pc(thr, act); /* thr argument only used for thr->heap, so specific thread doesn't matter */
pc = duk_hthread_get_act_prev_pc(
thr,
act); /* thr argument only used for thr->heap, so specific thread doesn't matter */
DUK_UNREF(pc);
DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */
DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits and non-negative */
DUK_ASSERT_DISABLE(pc >= 0); /* unsigned */
DUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32); /* assume PC is at most 32 bits and non-negative */
duk_push_hobject(thr, func);
@ -379,7 +386,7 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
} else {
/* Native function, no relevant lineNumber. */
}
#endif /* DUK_USE_PC2LINE */
#endif /* DUK_USE_PC2LINE */
duk_push_u32(thr, ecma_line);
/* [ ... error func fileName lineNumber ] */
@ -398,7 +405,7 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
duk_push_undefined(thr);
}
define_props:
define_props:
/* [ ... error lineNumber fileName ] */
#if defined(DUK_USE_ASSERTIONS)
DUK_ASSERT(duk_get_top(thr) == entry_top + 2);
@ -406,7 +413,7 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
duk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);
}
#endif /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */
#endif /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */
/*
* Add line number to a compiler error.
@ -414,7 +421,6 @@ DUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, c
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
/* Append a "(line NNN)" to the "message" property of any error
* thrown during compilation. Usually compilation errors are
* SyntaxErrors but they can also be out-of-memory errors and
@ -429,8 +435,7 @@ DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
return;
}
DUK_DDD(DUK_DDDPRINT("compile error, before adding line info: %!T",
(duk_tval *) duk_get_tval(thr, -1)));
DUK_DDD(DUK_DDDPRINT("compile error, before adding line info: %!T", (duk_tval *) duk_get_tval(thr, -1)));
if (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_MESSAGE)) {
duk_bool_t at_end;
@ -452,7 +457,8 @@ DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
(long) thr->compile_ctx->lex.window[0].codepoint,
(long) thr->compile_ctx->lex.window[1].codepoint));
duk_push_sprintf(thr, " (line %ld%s)",
duk_push_sprintf(thr,
" (line %ld%s)",
(long) thr->compile_ctx->curr_token.start_line,
at_end ? ", end of input" : "");
duk_concat(thr, 2);
@ -461,10 +467,9 @@ DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
duk_pop(thr);
}
DUK_DDD(DUK_DDDPRINT("compile error, after adding line info: %!T",
(duk_tval *) duk_get_tval(thr, -1)));
DUK_DDD(DUK_DDDPRINT("compile error, after adding line info: %!T", (duk_tval *) duk_get_tval(thr, -1)));
}
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
/*
* Augment an error being created using Duktape specific properties
@ -472,7 +477,12 @@ DUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {
*/
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_hobject *obj, duk_small_uint_t flags) {
DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr,
duk_hthread *thr_callstack,
const char *c_filename,
duk_int_t c_line,
duk_hobject *obj,
duk_small_uint_t flags) {
#if defined(DUK_USE_ASSERTIONS)
duk_int_t entry_top;
#endif
@ -482,7 +492,7 @@ DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *th
#endif
DUK_ASSERT(obj != NULL);
DUK_UNREF(obj); /* unreferenced w/o tracebacks */
DUK_UNREF(obj); /* unreferenced w/o tracebacks */
duk__add_compiler_error_line(thr);
@ -507,7 +517,7 @@ DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *th
DUK_ASSERT(duk_get_top(thr) == entry_top);
#endif
}
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
/*
* Augment an error at creation time with _Tracedata/fileName/lineNumber
@ -525,7 +535,11 @@ DUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *th
*/
#if defined(DUK_USE_AUGMENT_ERROR_CREATE)
DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {
DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr,
duk_hthread *thr_callstack,
const char *c_filename,
duk_int_t c_line,
duk_small_uint_t flags) {
duk_hobject *obj;
DUK_ASSERT(thr != NULL);
@ -571,7 +585,7 @@ DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *th
duk__err_augment_user(thr, DUK_STRIDX_ERR_CREATE);
#endif
}
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
#endif /* DUK_USE_AUGMENT_ERROR_CREATE */
/*
* Augment an error at throw time; allow a user error handler (if defined)
@ -583,6 +597,6 @@ DUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *th
DUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) {
#if defined(DUK_USE_ERRTHROW)
duk__err_augment_user(thr, DUK_STRIDX_ERR_THROW);
#endif /* DUK_USE_ERRTHROW */
#endif /* DUK_USE_ERRTHROW */
}
#endif /* DUK_USE_AUGMENT_ERROR_THROW */
#endif /* DUK_USE_AUGMENT_ERROR_THROW */

18
src-input/duk_error_longjmp.c

@ -47,8 +47,10 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
DUK_ASSERT(thr->heap != NULL);
DUK_DD(DUK_DDPRINT("longjmp error: type=%d iserror=%d value1=%!T value2=%!T",
(int) thr->heap->lj.type, (int) thr->heap->lj.iserror,
&thr->heap->lj.value1, &thr->heap->lj.value2));
(int) thr->heap->lj.type,
(int) thr->heap->lj.iserror,
&thr->heap->lj.value1,
&thr->heap->lj.value2));
/* Prevent finalizer execution during error handling. All error
* handling sites will process pending finalizers once error handling
@ -66,11 +68,11 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
DUK_ASSERT_LJSTATE_SET(thr->heap);
thr->heap->pf_prevent_count++;
DUK_ASSERT(thr->heap->pf_prevent_count != 0); /* Wrap. */
DUK_ASSERT(thr->heap->pf_prevent_count != 0); /* Wrap. */
#if defined(DUK_USE_ASSERTIONS)
/* XXX: set this immediately when longjmp state is set */
DUK_ASSERT(thr->heap->error_not_allowed == 0); /* Detect error within critical section. */
DUK_ASSERT(thr->heap->error_not_allowed == 0); /* Detect error within critical section. */
thr->heap->error_not_allowed = 1;
#endif
@ -82,8 +84,10 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
*/
if (!thr->heap->lj.jmpbuf_ptr) {
DUK_D(DUK_DPRINT("uncaught error: type=%d iserror=%d value1=%!T value2=%!T",
(int) thr->heap->lj.type, (int) thr->heap->lj.iserror,
&thr->heap->lj.value1, &thr->heap->lj.value2));
(int) thr->heap->lj.type,
(int) thr->heap->lj.iserror,
&thr->heap->lj.value1,
&thr->heap->lj.value2));
#if defined(DUK_USE_PREFER_SIZE)
duk__uncaught_minimal(thr);
@ -94,7 +98,7 @@ DUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {
}
#if defined(DUK_USE_CPP_EXCEPTIONS)
throw duk_internal_exception(); /* dummy */
throw duk_internal_exception(); /* dummy */
#else
DUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb);
#endif

58
src-input/duk_error_macros.c

@ -4,31 +4,43 @@
#include "duk_internal.h"
#define DUK__ERRFMT_BUFSIZE 256 /* size for formatting buffers */
#define DUK__ERRFMT_BUFSIZE 256 /* size for formatting buffers */
#if defined(DUK_USE_VERBOSE_ERRORS)
DUK_INTERNAL DUK_COLD void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...) {
DUK_INTERNAL DUK_COLD void duk_err_handle_error_fmt(duk_hthread *thr,
const char *filename,
duk_uint_t line_and_code,
const char *fmt,
...) {
va_list ap;
char msg[DUK__ERRFMT_BUFSIZE];
va_start(ap, fmt);
(void) DUK_VSNPRINTF(msg, sizeof(msg), fmt, ap);
msg[sizeof(msg) - 1] = (char) 0;
duk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));
va_end(ap); /* dead code, but ensures portability (see Linux man page notes) */
duk_err_create_and_throw(thr,
(duk_errcode_t) (line_and_code >> 24),
msg,
filename,
(duk_int_t) (line_and_code & 0x00ffffffL));
va_end(ap); /* dead code, but ensures portability (see Linux man page notes) */
}
DUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg) {
duk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));
duk_err_create_and_throw(thr,
(duk_errcode_t) (line_and_code >> 24),
msg,
filename,
(duk_int_t) (line_and_code & 0x00ffffffL));
}
#else /* DUK_USE_VERBOSE_ERRORS */
#else /* DUK_USE_VERBOSE_ERRORS */
DUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) {
duk_err_create_and_throw(thr, code);
}
#endif /* DUK_USE_VERBOSE_ERRORS */
#endif /* DUK_USE_VERBOSE_ERRORS */
/*
* Error throwing helpers
@ -36,14 +48,34 @@ DUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t
#if defined(DUK_USE_VERBOSE_ERRORS)
#if defined(DUK_USE_PARANOID_ERRORS)
DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {
DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)",
expect_name, duk_get_type_name(thr, idx), (long) idx);
DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr,
const char *filename,
duk_int_t linenumber,
duk_idx_t idx,
const char *expect_name) {
DUK_ERROR_RAW_FMT3(thr,
filename,
linenumber,
DUK_ERR_TYPE_ERROR,
"%s required, found %s (stack index %ld)",
expect_name,
duk_get_type_name(thr, idx),
(long) idx);
}
#else
DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {
DUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, "%s required, found %s (stack index %ld)",
expect_name, duk_push_string_readable(thr, idx), (long) idx);
DUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr,
const char *filename,
duk_int_t linenumber,
duk_idx_t idx,
const char *expect_name) {
DUK_ERROR_RAW_FMT3(thr,
filename,
linenumber,
DUK_ERR_TYPE_ERROR,
"%s required, found %s (stack index %ld)",
expect_name,
duk_push_string_readable(thr, idx),
(long) idx);
}
#endif
DUK_INTERNAL DUK_COLD void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) {

15
src-input/duk_error_misc.c

@ -26,14 +26,14 @@ DUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {
for (act = thr->callstack_curr; act != NULL; act = act->parent) {
for (cat = act->cat; cat != NULL; cat = cat->parent) {
if (DUK_CAT_HAS_CATCH_ENABLED(cat)) {
return 1; /* all we need to know */
return 1; /* all we need to know */
}
}
}
}
return 0;
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */
#endif /* DUK_USE_DEBUGGER_SUPPORT */
/*
* Get prototype object for an integer error code.
@ -83,11 +83,10 @@ DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {
* config options.
*/
if (!duk_debug_is_attached(thr->heap) ||
thr->heap->dbg_processing ||
thr->heap->lj.type != DUK_LJ_TYPE_THROW ||
if (!duk_debug_is_attached(thr->heap) || thr->heap->dbg_processing || thr->heap->lj.type != DUK_LJ_TYPE_THROW ||
thr->heap->creating_error) {
DUK_D(DUK_DPRINT("skip debugger error integration; not attached, debugger processing, not THROW, or error thrown while creating error"));
DUK_D(DUK_DPRINT("skip debugger error integration; not attached, debugger processing, not THROW, or error thrown "
"while creating error"));
return;
}
@ -115,7 +114,7 @@ DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {
/* Store and reset longjmp state. */
DUK_ASSERT_LJSTATE_SET(thr->heap);
DUK_TVAL_DECREF_NORZ(thr, tv_obj);
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2)); /* Always for THROW type. */
DUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2)); /* Always for THROW type. */
DUK_TVAL_SET_UNDEFINED(tv_obj);
thr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;
DUK_ASSERT_LJSTATE_UNSET(thr->heap);
@ -150,7 +149,7 @@ DUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {
duk_pop(thr);
}
#endif /* DUK_USE_DEBUGGER_SUPPORT */
#endif /* DUK_USE_DEBUGGER_SUPPORT */
/*
* Helpers for setting up heap longjmp state.

31
src-input/duk_error_throw.c

@ -21,14 +21,20 @@
*/
#if defined(DUK_USE_VERBOSE_ERRORS)
DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) {
DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr,
duk_errcode_t code,
const char *msg,
const char *filename,
duk_int_t line) {
#else
DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {
#endif
#if defined(DUK_USE_VERBOSE_ERRORS)
DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld",
(long) code, (const char *) msg,
(const char *) filename, (long) line));
(long) code,
(const char *) msg,
(const char *) filename,
(long) line));
#else
DUK_DD(DUK_DDPRINT("duk_err_create_and_throw(): code=%ld", (long) code));
#endif
@ -88,18 +94,9 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
* use 'msg' as a format string directly.
*/
#if defined(DUK_USE_VERBOSE_ERRORS)
duk_push_error_object_raw(thr,
code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
filename,
line,
"%s",
(const char *) msg);
duk_push_error_object_raw(thr, code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, filename, line, "%s", (const char *) msg);
#else
duk_push_error_object_raw(thr,
code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,
NULL,
0,
NULL);
duk_push_error_object_raw(thr, code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE, NULL, 0, NULL);
#endif
/* Note that an alloc error may happen during error augmentation.
@ -109,8 +106,7 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
* avoiding it for alloc errors (this differs from Duktape 1.x).
*/
#if defined(DUK_USE_AUGMENT_ERROR_THROW)
DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT (before throw augment)",
(duk_tval *) duk_get_tval(thr, -1)));
DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT (before throw augment)", (duk_tval *) duk_get_tval(thr, -1)));
duk_err_augment_error_throw(thr);
#endif
@ -133,7 +129,8 @@ DUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code)
*/
DUK_DDD(DUK_DDDPRINT("THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)",
(duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2));
(duk_tval *) &thr->heap->lj.value1,
(duk_tval *) &thr->heap->lj.value2));
duk_err_longjmp(thr);
DUK_UNREACHABLE();

Loading…
Cancel
Save