Browse Source

Merge branch 'duk-int-tweak'

pull/30/head
Sami Vaarala 10 years ago
parent
commit
2a52f29ce3
  1. 6
      src/duk_bi_array.c
  2. 30
      src/duk_features.h.in
  3. 15
      src/duk_heap_alloc.c
  4. 2
      src/duk_hstring_misc.c
  5. 18
      website/buildsite.py
  6. 34
      website/guide/ctypes.html

6
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);

30
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;

15
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);

2
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",

18
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('<pre class="c-code" title="' +
'C99/C++11: ' + '\n'.join(alt_typing_c99) +
'C99/C++11 (32-bit): ' + '\n'.join(alt_typing_c99) +
'">')
for i in p:
res.append(htmlEscape(i))

34
website/guide/ctypes.html

@ -106,7 +106,8 @@ about type bit counts and such don't hold.</p>
<code>duk_idx_t</code>). 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.</p>
C99/C++11 types are available and the platform <code>int</code> is at least
32 bits wide (which is nowadays almost always the case).</p>
<p>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 <code>scanf()</code> casts for portable formatting/scanning.</p>
<table>
<tr>
<th>Duktape type</th>
<th>C99/C++11</th>
<th>Legacy 32-bit</th>
<th>Legacy 16-bit</th>
<th>C99/C++11 32-bit int</th>
<th>Legacy 32-bit int</th>
<th>Legacy 16-bit int</th>
<th><code>printf</code></th>
<th><code>scanf</code></th>
<th>Notes</th>
</tr>
<tr>
<td>duk_int_t</td>
<td>int_fast32_t</td>
<td>int</td>
<td>int</td>
<td>long</td>
<td>%ld<br />long</td>
@ -134,7 +135,7 @@ and <code>scanf()</code> casts for portable formatting/scanning.</p>
</tr>
<tr>
<td>duk_uint_t</td>
<td>uint_fast32_t</td>
<td>unsigned int</td>
<td>unsigned int</td>
<td>unsigned long</td>
<td>%lu<br />unsigned long</td>
@ -170,7 +171,7 @@ and <code>scanf()</code> casts for portable formatting/scanning.</p>
</tr>
<tr>
<td>duk_idx_t</td>
<td>int_fast32_t</td>
<td>int</td>
<td>int</td>
<td>long</td>
<td>%ld<br />long</td>
@ -179,7 +180,7 @@ and <code>scanf()</code> casts for portable formatting/scanning.</p>
</tr>
<tr>
<td>duk_uarridx_t</td>
<td>uint_fast32_t</td>
<td>unsigned int</td>
<td>unsigned int</td>
<td>unsigned long</td>
<td>%lu<br />unsigned long</td>
@ -188,7 +189,7 @@ and <code>scanf()</code> casts for portable formatting/scanning.</p>
</tr>
<tr>
<td>duk_codepoint_t</td>
<td>int_fast32_t</td>
<td>int</td>
<td>int</td>
<td>long</td>
<td>%ld<br />long</td>
@ -197,7 +198,7 @@ and <code>scanf()</code> casts for portable formatting/scanning.</p>
</tr>
<tr>
<td>duk_errcode_t</td>
<td>int_fast32_t</td>
<td>int</td>
<td>int</td>
<td>long</td>
<td>%ld<br />long</td>
@ -268,9 +269,14 @@ least the following variations are seen:</p>
<p>As can be seen, no built-in C type would be appropriate, so type detection
is needed. Duktape detects and defines <code>duk_int_t</code> type for these
purposes (at least 32 bits wide, fast integer). Normally it is mapped to the
C99 type <code>int_fast32_t</code> but if that's not available, Duktape uses
platform specific detection.</p>
purposes (at least 32 bits wide, convenient to the CPU). Normally it is mapped
to <code>int</code> if Duktape can reliably detect that <code>int</code> is 32
bits or wider. When this is not the case, <code>int_fast32_t</code> is used
if C99 types are available; if C99 is not available, Duktape uses platform
specific detection to arrive at an appropriate type. The <code>duk_uint_t</code>
is the same but unsigned. Most other types in the API (such as <code>duk_idx_t</code>)
are mapped to <code>duk_(u)int_t</code> but this may change in the future
if necessary.</p>
<p>Other special types are also needed. For instance, exactly N bits wide
integers are also needed to ensure proper overflow behavior in some cases.</p>
@ -283,7 +289,7 @@ partially standardized (e.g. <code>%d</code> is used for an <code>int</code>,
regardless of its bit size), but custom codes are sometimes used.</p>
<p>When using type wrappers, the correct format code depends on type detection.
For instance, <code>duk_int_t</code> is mapped to a fast integer type which is
For instance, <code>duk_int_t</code> is mapped to a convenient integer type which is
at least 32 bits wide. On one platform the underlying type might be <code>int</code>
(format specifier <code>%d</code>) and on another it might be <code>long</code>
(format specifier <code>%ld</code>). Calling code cannot safely use such a value

Loading…
Cancel
Save