diff --git a/src/duk_bi_array.c b/src/duk_bi_array.c index 717ecf53..bfb8a0f9 100644 --- a/src/duk_bi_array.c +++ b/src/duk_bi_array.c @@ -734,7 +734,7 @@ duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) { if (act_start < 0) { act_start = len + act_start; } - DUK_ASSERT(act_start >= 0 && act_start <= len); + DUK_ASSERT(act_start >= 0 && act_start <= (duk_int_t) len); #ifdef DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT if (have_delcount) { @@ -751,8 +751,8 @@ duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx) { } #endif - DUK_ASSERT(del_count >= 0 && del_count <= len - act_start); - DUK_ASSERT(del_count + act_start <= len); + DUK_ASSERT(del_count >= 0 && del_count <= (duk_int_t) len - act_start); + DUK_ASSERT(del_count + act_start <= (duk_int_t) len); duk_push_array(ctx); diff --git a/src/duk_features.h.in b/src/duk_features.h.in index f4729796..0b90db2c 100644 --- a/src/duk_features.h.in +++ b/src/duk_features.h.in @@ -875,25 +875,35 @@ typedef size_t duk_size_t; typedef ptrdiff_t duk_ptrdiff_t; /* The best type for an "all around int" in Duktape internals is "at least - * 32 bit signed integer" which is fastest. Same for unsigned type. - */ + * 32 bit signed integer" which is most convenient. Same for unsigned type. + * Prefer 'int' when large enough, as it is almost always a convenient type. + */ +#if defined(UINT_MAX) && (UINT_MAX >= 0xffffffffUL) +typedef int duk_int_t; +typedef unsigned int duk_uint_t; +#define DUK_INT_MIN INT_MIN +#define DUK_INT_MAX INT_MAX +#define DUK_UINT_MIN 0 +#define DUK_UINT_MAX UINT_MAX +#else typedef duk_int_fast32_t duk_int_t; typedef duk_uint_fast32_t duk_uint_t; #define DUK_INT_MIN DUK_INT_FAST32_MIN #define DUK_INT_MAX DUK_INT_FAST32_MAX #define DUK_UINT_MIN DUK_UINT_FAST32_MIN #define DUK_UINT_MAX DUK_UINT_FAST32_MAX +#endif /* Same as 'duk_int_t' but guaranteed to be a 'fast' variant if this * distinction matters for the CPU. These types are used mainly in the * executor where it might really matter. */ -typedef duk_int_t duk_int_fast_t; -typedef duk_uint_t duk_uint_fast_t; -#define DUK_INT_FAST_MIN DUK_INT_MIN -#define DUK_INT_FAST_MAX DUK_INT_MAX -#define DUK_UINT_FAST_MIN DUK_UINT_MIN -#define DUK_UINT_FAST_MAX DUK_UINT_MAX +typedef duk_int_fast32_t duk_int_fast_t; +typedef duk_uint_fast32_t duk_uint_fast_t; +#define DUK_INT_FAST_MIN DUK_INT_FAST32_MIN +#define DUK_INT_FAST_MAX DUK_INT_FAST32_MAX +#define DUK_UINT_FAST_MIN DUK_UINT_FAST32_MIN +#define DUK_UINT_FAST_MAX DUK_UINT_FAST32_MAX /* Small integers (16 bits or more) can fall back to the 'int' type, but * have a typedef so they are marked "small" explicitly. @@ -943,8 +953,8 @@ typedef duk_int_t duk_errcode_t; * ensure duk_uint32_t casts back and forth nicely. Almost everything * else uses the signed one. */ -typedef duk_int_fast32_t duk_codepoint_t; -typedef duk_uint_fast32_t duk_ucodepoint_t; +typedef duk_int_t duk_codepoint_t; +typedef duk_uint_t duk_ucodepoint_t; /* IEEE double typedef. */ typedef double duk_double_t; diff --git a/src/duk_heap_alloc.c b/src/duk_heap_alloc.c index 14370c8b..949772cb 100644 --- a/src/duk_heap_alloc.c +++ b/src/duk_heap_alloc.c @@ -432,11 +432,24 @@ static void duk__dump_type_sizes(void) { DUK__DUMPSZ(duk_intptr_t); DUK__DUMPSZ(duk_uintmax_t); DUK__DUMPSZ(duk_intmax_t); + DUK__DUMPSZ(duk_double_t); + + /* important chosen base types */ + DUK__DUMPSZ(duk_int_t); + DUK__DUMPSZ(duk_uint_t); + DUK__DUMPSZ(duk_int_fast_t); + DUK__DUMPSZ(duk_uint_fast_t); DUK__DUMPSZ(duk_small_int_t); DUK__DUMPSZ(duk_small_uint_t); + DUK__DUMPSZ(duk_small_int_fast_t); + DUK__DUMPSZ(duk_small_uint_fast_t); + + /* some derived types */ DUK__DUMPSZ(duk_codepoint_t); DUK__DUMPSZ(duk_ucodepoint_t); - DUK__DUMPSZ(duk_double_t); + DUK__DUMPSZ(duk_idx_t); + DUK__DUMPSZ(duk_errcode_t); + DUK__DUMPSZ(duk_uarridx_t); /* tval */ DUK__DUMPSZ(duk_double_union); diff --git a/src/duk_hstring_misc.c b/src/duk_hstring_misc.c index 72aa4880..0672ecd4 100644 --- a/src/duk_hstring_misc.c +++ b/src/duk_hstring_misc.c @@ -13,7 +13,7 @@ duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, DUK_ASSERT(thr != NULL); DUK_ASSERT(h != NULL); DUK_ASSERT_DISABLE(pos >= 0); /* unsigned */ - DUK_ASSERT(pos < (duk_int_t) DUK_HSTRING_GET_CHARLEN(h)); + DUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h)); boff = duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos); DUK_DDD(DUK_DDDPRINT("charCodeAt: pos=%ld -> boff=%ld, str=%!O", diff --git a/website/buildsite.py b/website/buildsite.py index 9759c491..0917579a 100644 --- a/website/buildsite.py +++ b/website/buildsite.py @@ -216,16 +216,16 @@ def parseApiDoc(filename): return parts # C99: these are used if available -type_repl_c99 = [ - ['duk_int_t', 'int_fast32_t' ], - ['duk_uint_t', 'uint_fast32_t' ], +type_repl_c99_32bit = [ + ['duk_int_t', 'int' ], + ['duk_uint_t', 'unsigned int' ], ['duk_int32_t', 'int32_t' ], ['duk_uint32_t', 'uint32_t' ], ['duk_uint16_t', 'uint16_t' ], - ['duk_idx_t', 'int_fast32_t' ], - ['duk_uarridx_t', 'uint_fast32_t' ], - ['duk_codepoint_t', 'int_fast32_t' ], - ['duk_errcode_t', 'int_fast32_t' ], + ['duk_idx_t', 'int' ], + ['duk_uarridx_t', 'unsigned int' ], + ['duk_codepoint_t', 'int' ], + ['duk_errcode_t', 'int' ], ['duk_bool_t', 'int' ], ['duk_ret_t', 'int' ], ['duk_size_t', 'size_t' ], @@ -290,7 +290,7 @@ def processApiDoc(parts, funcname, testrefs, used_tags): alt_typing_legacy32 = [] alt_typing_legacy16 = [] for i in p: - alt_typing_c99.append(substitutePrototypeTypes(i, type_repl_c99)) + alt_typing_c99.append(substitutePrototypeTypes(i, type_repl_c99_32bit)) alt_typing_legacy32.append(substitutePrototypeTypes(i, type_repl_legacy32)) alt_typing_legacy16.append(substitutePrototypeTypes(i, type_repl_legacy16)) # Long tooltips are a bad idea in most browsers, so just put the C99 typing there for now @@ -300,7 +300,7 @@ def processApiDoc(parts, funcname, testrefs, used_tags): # 'Legacy 16-bit: ' + '\n'.join(alt_typing_legacy16) + '\n' # '">') res.append('
')
 		for i in p:
 			res.append(htmlEscape(i))
diff --git a/website/guide/ctypes.html b/website/guide/ctypes.html
index c136bc61..4ce4bc45 100644
--- a/website/guide/ctypes.html
+++ b/website/guide/ctypes.html
@@ -106,7 +106,8 @@ about type bit counts and such don't hold.

duk_idx_t). The concrete type used by the compiler depends on your platform and compiler. When hovering over a prototype in the API documentation the tool tip will show what concrete types are used when -C99/C++11 types are available.

+C99/C++11 types are available and the platform int is at least +32 bits wide (which is nowadays almost always the case).

The following table summarizes a few central typedefs and what the concrete type selected will be in various (example) environments. The @@ -116,16 +117,16 @@ and scanf() casts for portable formatting/scanning.

- - - + + + - + @@ -134,7 +135,7 @@ and scanf() casts for portable formatting/scanning.

- + @@ -170,7 +171,7 @@ and scanf() casts for portable formatting/scanning.

- + @@ -179,7 +180,7 @@ and scanf() casts for portable formatting/scanning.

- + @@ -188,7 +189,7 @@ and scanf() casts for portable formatting/scanning.

- + @@ -197,7 +198,7 @@ and scanf() casts for portable formatting/scanning.

- + @@ -268,9 +269,14 @@ least the following variations are seen:

As can be seen, no built-in C type would be appropriate, so type detection is needed. Duktape detects and defines duk_int_t type for these -purposes (at least 32 bits wide, fast integer). Normally it is mapped to the -C99 type int_fast32_t but if that's not available, Duktape uses -platform specific detection.

+purposes (at least 32 bits wide, convenient to the CPU). Normally it is mapped +to int if Duktape can reliably detect that int is 32 +bits or wider. When this is not the case, int_fast32_t is used +if C99 types are available; if C99 is not available, Duktape uses platform +specific detection to arrive at an appropriate type. The duk_uint_t +is the same but unsigned. Most other types in the API (such as duk_idx_t) +are mapped to duk_(u)int_t but this may change in the future +if necessary.

Other special types are also needed. For instance, exactly N bits wide integers are also needed to ensure proper overflow behavior in some cases.

@@ -283,7 +289,7 @@ partially standardized (e.g. %d is used for an int, regardless of its bit size), but custom codes are sometimes used.

When using type wrappers, the correct format code depends on type detection. -For instance, duk_int_t is mapped to a fast integer type which is +For instance, duk_int_t is mapped to a convenient integer type which is at least 32 bits wide. On one platform the underlying type might be int (format specifier %d) and on another it might be long (format specifier %ld). Calling code cannot safely use such a value

Duktape typeC99/C++11Legacy 32-bitLegacy 16-bitC99/C++11 32-bit intLegacy 32-bit intLegacy 16-bit int printf scanf Notes
duk_int_tint_fast32_tint int long %ld
long
duk_uint_tuint_fast32_tunsigned int unsigned int unsigned long %lu
unsigned long
duk_idx_tint_fast32_tint int long %ld
long
duk_uarridx_tuint_fast32_tunsigned int unsigned int unsigned long %lu
unsigned long
duk_codepoint_tint_fast32_tint int long %ld
long
duk_errcode_tint_fast32_tint int long %ld
long