Browse Source

Changes to compile CBOR extra as built-in

* Add minimal CBOR config options.

* Add 'CBOR' built-in YAML metadata.

* Add a public C API for CBOR.

* Remove examples/cmdline support for extras/cbor, use built-in CBOR
  instead.

* Makefile, dist/tools changes.

* Rewrite CBOR extra to use Duktape internal helpers, also some related
  refactoring.
pull/2163/head
Sami Vaarala 5 years ago
parent
commit
98a5be265c
  1. 9
      Makefile
  2. 9
      config/config-options/DUK_USE_CBOR_BUILTIN.yaml
  3. 10
      config/config-options/DUK_USE_CBOR_SUPPORT.yaml
  4. 2
      config/examples/low_memory.yaml
  5. 2
      config/examples/low_memory_strip.yaml
  6. 3
      config/tags.yaml
  7. 11
      examples/cmdline/duk_cmdline.c
  8. 31
      src-input/builtins.yaml
  9. 80
      src-input/duk_api_bytecode.c
  10. 8
      src-input/duk_bi_buffer.c
  11. 1039
      src-input/duk_bi_cbor.c
  12. 4
      src-input/duk_bi_json.c
  13. 39
      src-input/duk_fltunion.h
  14. 1
      src-input/duk_internal.h
  15. 1
      src-input/duk_unicode.h
  16. 84
      src-input/duk_unicode_support.c
  17. 93
      src-input/duk_util.h
  18. 92
      src-input/duk_util_bufwriter.c
  19. 84
      src-input/duk_util_double.c
  20. 148
      src-input/duk_util_memrw.c
  21. 2
      src-input/duktape.h.in
  22. 4
      tools/configure.py
  23. 3
      util/dist.py

9
Makefile

@ -62,8 +62,7 @@ DUKTAPE_CMDLINE_SOURCES = \
extras/print-alert/duk_print_alert.c \
extras/console/duk_console.c \
extras/logging/duk_logging.c \
extras/module-duktape/duk_module_duktape.c \
extras/cbor/duk_cbor.c
extras/module-duktape/duk_module_duktape.c
ifdef SYSTEMROOT # Windows
DUKTAPE_CMDLINE_SOURCES += examples/debug-trans-socket/duk_trans_socket_windows.c
else
@ -109,7 +108,6 @@ CCOPTS_SHARED += -DDUK_CMDLINE_PRINTALERT_SUPPORT
CCOPTS_SHARED += -DDUK_CMDLINE_CONSOLE_SUPPORT
CCOPTS_SHARED += -DDUK_CMDLINE_LOGGING_SUPPORT
CCOPTS_SHARED += -DDUK_CMDLINE_MODULE_SUPPORT
CCOPTS_SHARED += -DDUK_CMDLINE_CBOR_SUPPORT
ifdef SYSTEMROOT # Windows
# Skip fancy (linenoise)
else
@ -146,7 +144,6 @@ CCOPTS_SHARED += -I./extras/print-alert
CCOPTS_SHARED += -I./extras/console
CCOPTS_SHARED += -I./extras/logging
CCOPTS_SHARED += -I./extras/module-duktape
CCOPTS_SHARED += -I./extras/cbor
#CCOPTS_SHARED += -m32 # force 32-bit compilation on a 64-bit host
#CCOPTS_SHARED += -mx32 # force X32 compilation on a 64-bit host
#CCOPTS_SHARED += -fstack-usage # enable manually, then e.g. $ make clean duk; python util/pretty_stack_usage.py duktape.su
@ -168,9 +165,9 @@ CLANG_CCOPTS_NONDEBUG += -Wcomma
GXXOPTS_SHARED = -pedantic -ansi -std=c++11 -fstrict-aliasing -Wall -Wextra -Wunused-result -Wunused-function
GXXOPTS_SHARED += -DDUK_CMDLINE_PRINTALERT_SUPPORT
GXXOPTS_NONDEBUG = $(GXXOPTS_SHARED) -Os -fomit-frame-pointer
GXXOPTS_NONDEBUG += -I./examples/alloc-logging -I./examples/alloc-torture -I./examples/alloc-hybrid -I./extras/print-alert -I./extras/console -I./extras/logging -I./extras/module-duktape -I./extras/cbor
GXXOPTS_NONDEBUG += -I./examples/alloc-logging -I./examples/alloc-torture -I./examples/alloc-hybrid -I./extras/print-alert -I./extras/console -I./extras/logging -I./extras/module-duktape
GXXOPTS_DEBUG = $(GXXOPTS_SHARED) -O0 -g -ggdb
GXXOPTS_DEBUG += -I./examples/alloc-logging -I./examples/alloc-torture -I./examples/alloc-hybrid -I./extras/print-alert -I./extras/console -I./extras/logging -I./extras/module-duktape -I./extras/cbor
GXXOPTS_DEBUG += -I./examples/alloc-logging -I./examples/alloc-torture -I./examples/alloc-hybrid -I./extras/print-alert -I./extras/console -I./extras/logging -I./extras/module-duktape
CCOPTS_DUKLOW = -m32
CCOPTS_DUKLOW += -flto -fno-asynchronous-unwind-tables -ffunction-sections -Wl,--gc-sections

9
config/config-options/DUK_USE_CBOR_BUILTIN.yaml

@ -0,0 +1,9 @@
define: DUK_USE_CBOR_BUILTIN
introduced: 2.5.0
default: true
tags:
- codec
- cbor
- experimental
description: >
Provide a CBOR built-in with CBOR.encode() and CBOR.decode() functions.

10
config/config-options/DUK_USE_CBOR_SUPPORT.yaml

@ -0,0 +1,10 @@
define: DUK_USE_CBOR_SUPPORT
introduced: 2.5.0
default: true
tags:
- codec
- cbor
- experimental
description: >
Include CBOR support. When disabled, CBOR functions in the C API (and the
CBOR built-in, if enabled) will throw an error.

2
config/examples/low_memory.yaml

@ -152,3 +152,5 @@ DUK_USE_HTML_COMMENTS: false
DUK_USE_SHEBANG_COMMENTS: false
DUK_USE_REFLECT_BUILTIN: false
DUK_USE_SYMBOL_BUILTIN: false
DUK_USE_CBOR_SUPPORT: false
DUK_USE_CBOR_BUILTIN: false

2
config/examples/low_memory_strip.yaml

@ -45,3 +45,5 @@ DUK_USE_ENCODING_BUILTINS: false
DUK_USE_REFLECT_BUILTIN: false
DUK_USE_JSON_SUPPORT: false # also disables JSON support for C API
DUK_USE_GLOBAL_BUILTIN: false
DUK_USE_CBOR_SUPPORT: false
DUK_USE_CBOR_BUILTIN: false

3
config/tags.yaml

@ -89,6 +89,9 @@ torture:
Development time options to stress test corner case handling by e.g.
causing a garbage collection on every allocation.
cbor:
title: CBOR
codec:
title: Codecs

11
examples/cmdline/duk_cmdline.c

@ -13,9 +13,6 @@
* - To enable Duktape.Logger, define DUK_CMDLINE_LOGGING_SUPPORT
* and add extras/logging/duk_logging.c to compilation.
*
* - To enable CBOR, define DUK_CMDLINE_CBOR_SUPPORT and add
* extras/cbor/duk_cbor.c to compilation.
*
* - To enable Duktape 1.x module loading support (require(),
* Duktape.modSearch() etc), define DUK_CMDLINE_MODULE_SUPPORT and add
* extras/module-duktape/duk_module_duktape.c to compilation.
@ -77,9 +74,6 @@
#if defined(DUK_CMDLINE_MODULE_SUPPORT)
#include "duk_module_duktape.h"
#endif
#if defined(DUK_CMDLINE_CBOR_SUPPORT)
#include "duk_cbor.h"
#endif
#if defined(DUK_CMDLINE_FILEIO)
#include <errno.h>
#endif
@ -1163,11 +1157,6 @@ static duk_context *create_duktape_heap(int alloc_provider, int debugger, int lo
duk_module_duktape_init(ctx);
#endif
/* Register CBOR. */
#if defined(DUK_CMDLINE_CBOR_SUPPORT)
duk_cbor_init(ctx, 0 /*flags*/);
#endif
/* Trivial readFile/writeFile bindings for testing. */
#if defined(DUK_CMDLINE_FILEIO)
duk_push_c_function(ctx, fileio_read_file, 1 /*nargs*/);

31
src-input/builtins.yaml

@ -283,6 +283,13 @@ objects:
id: bi_json
present_if: DUK_USE_JSON_BUILTIN
# CBOR
- key: "CBOR"
value:
type: object
id: bi_cbor
present_if: DUK_USE_CBOR_BUILTIN
# Duktape specific
- key: "Duktape"
value:
@ -5341,6 +5348,30 @@ objects:
varargs: false
nodejs_buffer: true
#
# CBOR
#
- id: bi_cbor
class: Object
internal_prototype: bi_object_prototype
bidx: false
present_if: DUK_USE_CBOR_BUILTIN
properties:
- key: "encode"
value:
type: function
native: duk_bi_cbor_encode
length: 1
attributes: "wc"
- key: "decode"
value:
type: function
native: duk_bi_cbor_decode
length: 1
attributes: "wc"
#
# Encoding API
#

80
src-input/duk_api_bytecode.c

@ -24,20 +24,20 @@
* Dump/load helpers, xxx_raw() helpers do no buffer checks
*/
DUK_LOCAL duk_uint8_t *duk__load_string_raw(duk_hthread *thr, duk_uint8_t *p) {
DUK_LOCAL const duk_uint8_t *duk__load_string_raw(duk_hthread *thr, const duk_uint8_t *p) {
duk_uint32_t len;
len = DUK_RAW_READ_U32_BE(p);
len = DUK_RAW_READINC_U32_BE(p);
duk_push_lstring(thr, (const char *) p, len);
p += len;
return p;
}
DUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, duk_uint8_t *p) {
DUK_LOCAL const duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, const duk_uint8_t *p) {
duk_uint32_t len;
duk_uint8_t *buf;
len = DUK_RAW_READ_U32_BE(p);
len = DUK_RAW_READINC_U32_BE(p);
buf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);
DUK_ASSERT(buf != NULL);
duk_memcpy((void *) buf, (const void *) p, (size_t) len);
@ -54,7 +54,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) {
len = DUK_HSTRING_GET_BYTELEN(h);
DUK_ASSERT(len <= 0xffffffffUL); /* string limits */
tmp32 = (duk_uint32_t) len;
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
duk_memcpy((void *) p,
(const void *) DUK_HSTRING_GET_DATA(h),
len);
@ -73,7 +73,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_hbuffer_raw(duk_hthread *thr, duk_uint8_t *p, d
len = DUK_HBUFFER_GET_SIZE(h);
DUK_ASSERT(len <= 0xffffffffUL); /* buffer limits */
tmp32 = (duk_uint32_t) len;
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
/* When len == 0, buffer data pointer may be NULL. */
duk_memcpy_unsafe((void *) p,
(const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),
@ -113,7 +113,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, d
p = duk__dump_hbuffer_raw(thr, p, h_buf);
} else {
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_RAW_WRITE_U32_BE(p, 0);
DUK_RAW_WRITEINC_U32_BE(p, 0);
}
return p;
}
@ -129,7 +129,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, d
val = def_value;
}
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_RAW_WRITE_U32_BE(p, val);
DUK_RAW_WRITEINC_U32_BE(p, val);
return p;
}
@ -167,11 +167,11 @@ DUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bu
DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL); /* ensures no overflow */
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(key) + 4U, p);
p = duk__dump_hstring_raw(p, key);
DUK_RAW_WRITE_U32_BE(p, val);
DUK_RAW_WRITEINC_U32_BE(p, val);
}
}
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_RAW_WRITE_U32_BE(p, 0); /* end of _Varmap */
DUK_RAW_WRITEINC_U32_BE(p, 0); /* end of _Varmap */
return p;
}
@ -190,7 +190,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_b
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_ASSERT(h->length != DUK__NO_FORMALS); /* limits */
DUK_RAW_WRITE_U32_BE(p, h->length);
DUK_RAW_WRITEINC_U32_BE(p, h->length);
for (i = 0; i < h->length; i++) {
duk_tval *tv_val;
@ -211,7 +211,7 @@ DUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_b
} else {
DUK_DD(DUK_DDPRINT("dumping function without _Formals, emit marker to indicate missing _Formals"));
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);
DUK_RAW_WRITE_U32_BE(p, DUK__NO_FORMALS); /* marker: no formals */
DUK_RAW_WRITEINC_U32_BE(p, DUK__NO_FORMALS); /* marker: no formals */
}
return p;
}
@ -251,27 +251,27 @@ static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bu
/* Fixed header info. */
tmp32 = count_instr;
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
tmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func);
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
tmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func);
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
tmp16 = func->nregs;
DUK_RAW_WRITE_U16_BE(p, tmp16);
DUK_RAW_WRITEINC_U16_BE(p, tmp16);
tmp16 = func->nargs;
DUK_RAW_WRITE_U16_BE(p, tmp16);
DUK_RAW_WRITEINC_U16_BE(p, tmp16);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
tmp32 = func->start_line;
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
tmp32 = func->end_line;
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
#else
DUK_RAW_WRITE_U32_BE(p, 0);
DUK_RAW_WRITE_U32_BE(p, 0);
DUK_RAW_WRITEINC_U32_BE(p, 0);
DUK_RAW_WRITEINC_U32_BE(p, 0);
#endif
tmp32 = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) func); /* masks flags, only duk_hobject flags */
tmp32 &= ~(DUK_HOBJECT_FLAG_HAVE_FINALIZER); /* finalizer flag is lost */
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
/* Bytecode instructions: endian conversion needed unless
* platform is big endian.
@ -285,7 +285,7 @@ static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bu
#else
while (ins != ins_end) {
tmp32 = (duk_uint32_t) (*ins);
DUK_RAW_WRITE_U32_BE(p, tmp32);
DUK_RAW_WRITEINC_U32_BE(p, tmp32);
ins++;
}
#endif
@ -310,7 +310,7 @@ static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bu
p = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 8U, p);
*p++ = DUK__SER_NUMBER;
d = DUK_TVAL_GET_NUMBER(tv);
DUK_RAW_WRITE_DOUBLE_BE(p, d);
DUK_RAW_WRITEINC_DOUBLE_BE(p, d);
}
tv++;
}
@ -371,7 +371,7 @@ static duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bu
DUK_ASSERT((duk_size_t) (p_end - p) >= (duk_size_t) (n)); \
} while (0)
static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t *p_end) {
static const duk_uint8_t *duk__load_func(duk_hthread *thr, const duk_uint8_t *p, const duk_uint8_t *p_end) {
duk_hcompfunc *h_fun;
duk_hbuffer *h_data;
duk_size_t data_size;
@ -398,9 +398,9 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
DUK_DD(DUK_DDPRINT("loading function, p=%p, p_end=%p", (void *) p, (void *) p_end));
DUK__ASSERT_LEFT(3 * 4);
count_instr = DUK_RAW_READ_U32_BE(p);
count_const = DUK_RAW_READ_U32_BE(p);
count_funcs = DUK_RAW_READ_U32_BE(p);
count_instr = DUK_RAW_READINC_U32_BE(p);
count_const = DUK_RAW_READINC_U32_BE(p);
count_funcs = DUK_RAW_READINC_U32_BE(p);
data_size = sizeof(duk_tval) * count_const +
sizeof(duk_hobject *) * count_funcs +
@ -428,17 +428,17 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
DUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, h_fun) == NULL);
DUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);
h_fun->nregs = DUK_RAW_READ_U16_BE(p);
h_fun->nargs = DUK_RAW_READ_U16_BE(p);
h_fun->nregs = DUK_RAW_READINC_U16_BE(p);
h_fun->nargs = DUK_RAW_READINC_U16_BE(p);
#if defined(DUK_USE_DEBUGGER_SUPPORT)
h_fun->start_line = DUK_RAW_READ_U32_BE(p);
h_fun->end_line = DUK_RAW_READ_U32_BE(p);
h_fun->start_line = DUK_RAW_READINC_U32_BE(p);
h_fun->end_line = DUK_RAW_READINC_U32_BE(p);
#else
p += 8; /* skip line info */
#endif
/* duk_hcompfunc flags; quite version specific */
tmp32 = DUK_RAW_READ_U32_BE(p);
tmp32 = DUK_RAW_READINC_U32_BE(p);
DUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32); /* masks flags to only change duk_hobject flags */
/* standard prototype (no need to set here, already set) */
@ -474,7 +474,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
#else
q = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;
for (n = count_instr; n > 0; n--) {
*((duk_instr_t *) (void *) q) = DUK_RAW_READ_U32_BE(p);
*((duk_instr_t *) (void *) q) = DUK_RAW_READINC_U32_BE(p);
q += sizeof(duk_instr_t);
}
#endif
@ -482,7 +482,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
/* Load constants onto value stack but don't yet copy to buffer. */
for (n = count_const; n > 0; n--) {
DUK__ASSERT_LEFT(1);
const_type = DUK_RAW_READ_U8(p);
const_type = DUK_RAW_READINC_U8(p);
switch (const_type) {
case DUK__SER_STRING: {
p = duk__load_string_raw(thr, p);
@ -495,7 +495,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
duk_tval tv_tmp;
duk_double_t val;
DUK__ASSERT_LEFT(8);
val = DUK_RAW_READ_DOUBLE_BE(p);
val = DUK_RAW_READINC_DOUBLE_BE(p);
DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val);
duk_push_tval(thr, &tv_tmp);
break;
@ -562,7 +562,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
duk_set_top(thr, idx_base + 1);
/* Setup function properties. */
tmp32 = DUK_RAW_READ_U32_BE(p);
tmp32 = DUK_RAW_READINC_U32_BE(p);
duk_push_u32(thr, tmp32);
duk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
@ -642,7 +642,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
duk_pop(thr);
break;
}
tmp32 = DUK_RAW_READ_U32_BE(p);
tmp32 = DUK_RAW_READINC_U32_BE(p);
duk_push_u32(thr, tmp32);
duk_put_prop(thr, -3);
}
@ -652,7 +652,7 @@ static duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t
/* _Formals may have been missing in the original function, which is
* handled using a marker length.
*/
arr_limit = DUK_RAW_READ_U32_BE(p);
arr_limit = DUK_RAW_READINC_U32_BE(p);
if (arr_limit != DUK__NO_FORMALS) {
duk_push_bare_array(thr); /* _Formals */
for (arr_idx = 0; arr_idx < arr_limit; arr_idx++) {
@ -706,7 +706,7 @@ DUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {
}
DUK_EXTERNAL void duk_load_function(duk_hthread *thr) {
duk_uint8_t *p_buf, *p, *p_end;
const duk_uint8_t *p_buf, *p, *p_end;
duk_size_t sz;
DUK_ASSERT_API_ENTRY(thr);

8
src-input/duk_bi_buffer.c

@ -2268,7 +2268,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
duk_small_int_t magic_bigendian;
duk_small_int_t magic_signed;
duk_small_int_t magic_typedarray;
duk_small_int_t endswap;
duk_small_uint_t endswap;
duk_hbufobj *h_this;
duk_bool_t no_assert;
duk_int_t offset_signed;
@ -2320,7 +2320,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {
DUK_DDD(DUK_DDDPRINT("readfield, buffer_length=%ld, offset=%ld, no_assert=%d, "
"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, "
"endswap=%d",
"endswap=%u",
(long) buffer_length, (long) offset, (int) no_assert,
(unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),
(int) (magic_signed >> 4), (int) endswap));
@ -2527,7 +2527,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {
duk_small_int_t magic_bigendian;
duk_small_int_t magic_signed;
duk_small_int_t magic_typedarray;
duk_small_int_t endswap;
duk_small_uint_t endswap;
duk_hbufobj *h_this;
duk_bool_t no_assert;
duk_int_t offset_signed;
@ -2598,7 +2598,7 @@ DUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {
DUK_DDD(DUK_DDDPRINT("writefield, value=%!T, buffer_length=%ld, offset=%ld, no_assert=%d, "
"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, "
"endswap=%d",
"endswap=%u",
duk_get_tval(thr, 0), (long) buffer_length, (long) offset, (int) no_assert,
(unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),
(int) (magic_signed >> 4), (int) endswap));

1039
src-input/duk_bi_cbor.c

File diff suppressed because it is too large

4
src-input/duk_bi_json.c

@ -379,7 +379,7 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u
return 1; /* syntax error */
}
DUK_RAW_WRITE_XUTF8(*ext_p, cp);
DUK_RAW_WRITEINC_XUTF8(*ext_p, cp);
return 0;
}
@ -1323,7 +1323,7 @@ DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_st
q = duk__emit_esc_auto_fast(js_ctx, cp, q);
} else {
/* as is */
DUK_RAW_WRITE_XUTF8(q, cp);
DUK_RAW_WRITEINC_XUTF8(q, cp);
}
}
}

39
src-input/duk_fltunion.h

@ -0,0 +1,39 @@
/*
* Union to access IEEE float memory representation.
*/
#if !defined(DUK_FLTUNION_H_INCLUDED)
#define DUK_FLTUNION_H_INCLUDED
#include "duk_internal.h"
union duk_float_union {
float f;
duk_uint32_t ui[1];
duk_uint16_t us[2];
duk_uint8_t uc[4];
};
typedef union duk_float_union duk_float_union;
#if defined(DUK_USE_DOUBLE_LE) || defined(DUK_USE_DOUBLE_ME)
#define DUK_FLT_IDX_UI0 0
#define DUK_FLT_IDX_US0 1
#define DUK_FLT_IDX_US1 0
#define DUK_FLT_IDX_UC0 3
#define DUK_FLT_IDX_UC1 2
#define DUK_FLT_IDX_UC2 1
#define DUK_FLT_IDX_UC3 0
#elif defined(DUK_USE_DOUBLE_BE)
#define DUK_FLT_IDX_UI0 0
#define DUK_FLT_IDX_US0 0
#define DUK_FLT_IDX_US1 1
#define DUK_FLT_IDX_UC0 0
#define DUK_FLT_IDX_UC1 1
#define DUK_FLT_IDX_UC2 2
#define DUK_FLT_IDX_UC3 3
#else
#error internal error
#endif
#endif /* DUK_FLTUNION_H_INCLUDED */

1
src-input/duk_internal.h

@ -35,6 +35,7 @@
*/
#include "duk_dblunion.h"
#include "duk_fltunion.h"
#include "duk_replacements.h"
#include "duk_jmpbuf.h"
#include "duk_exception.h"

1
src-input/duk_unicode.h

@ -235,6 +235,7 @@ DUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp,
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp);
DUK_INTERNAL_DECL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end);
DUK_INTERNAL_DECL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen);
DUK_INTERNAL_DECL duk_bool_t duk_unicode_is_utf8_compatible(const duk_uint8_t *buf, duk_size_t len);
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp);
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp);
DUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp);

84
src-input/duk_unicode_support.c

@ -397,6 +397,90 @@ DUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *d
}
#endif /* DUK_USE_PREFER_SIZE */
/* Check whether a string is UTF-8 compatible or not. */
DUK_INTERNAL duk_bool_t duk_unicode_is_utf8_compatible(const duk_uint8_t *buf, duk_size_t len) {
duk_size_t i = 0;
#if !defined(DUK_USE_PREFER_SIZE)
duk_size_t len_safe;
#endif
/* Many practical strings are ASCII only, so use a fast path check
* to check chunks of bytes at once with minimal branch cost.
*/
#if !defined(DUK_USE_PREFER_SIZE)
len_safe = len & ~0x03UL;
for (; i < len_safe; i += 4) {
duk_uint8_t t = buf[i] | buf[i + 1] | buf[i + 2] | buf[i + 3];
if (DUK_UNLIKELY((t & 0x80U) != 0U)) {
/* At least one byte was outside 0x00-0x7f, break
* out to slow path (and remain there).
*
* XXX: We could also deal with the problem character
* and resume fast path later.
*/
break;
}
}
#endif
for (; i < len;) {
duk_uint8_t t;
duk_size_t left;
duk_size_t ncont;
duk_uint32_t cp;
duk_uint32_t mincp;
t = buf[i++];
if (DUK_LIKELY((t & 0x80U) == 0U)) {
/* Fast path, ASCII. */
continue;
}
/* Non-ASCII start byte, slow path.
*
* 10xx xxxx -> continuation byte
* 110x xxxx + 1*CONT -> [0x80, 0x7ff]
* 1110 xxxx + 2*CONT -> [0x800, 0xffff], must reject [0xd800,0xdfff]
* 1111 0xxx + 3*CONT -> [0x10000, 0x10ffff]
*/
left = len - i;
if (t <= 0xdfU) { /* 1101 1111 = 0xdf */
if (t <= 0xbfU) { /* 1011 1111 = 0xbf */
return 0;
}
ncont = 1;
mincp = 0x80UL;
cp = t & 0x1fU;
} else if (t <= 0xefU) { /* 1110 1111 = 0xef */
ncont = 2;
mincp = 0x800UL;
cp = t & 0x0fU;
} else if (t <= 0xf7U) { /* 1111 0111 = 0xf7 */
ncont = 3;
mincp = 0x10000UL;
cp = t & 0x07U;
} else {
return 0;
}
if (left < ncont) {
return 0;
}
while (ncont > 0U) {
t = buf[i++];
if ((t & 0xc0U) != 0x80U) { /* 10xx xxxx */
return 0;
}
cp = (cp << 6) + (t & 0x3fU);
ncont--;
}
if (cp < mincp || cp > 0x10ffffUL || (cp >= 0xd800UL && cp <= 0xdfffUL)) {
return 0;
}
}
return 1;
}
/*
* Unicode range matcher
*

93
src-input/duk_util.h

@ -67,40 +67,49 @@ struct duk_bitencoder_ctx {
/*
* Raw write/read macros for big endian, unaligned basic values.
* Caller ensures there's enough space. The macros update the pointer
* argument automatically on resizes. The idiom seems a bit odd, but
* leads to compact code.
* Caller ensures there's enough space. The INC macro variants
* update the pointer argument automatically.
*/
#define DUK_RAW_WRITE_U8(ptr,val) do { \
*(ptr) = (duk_uint8_t) (val); \
} while (0)
#define DUK_RAW_WRITE_U16_BE(ptr,val) duk_raw_write_u16_be((ptr), (duk_uint16_t) (val))
#define DUK_RAW_WRITE_U32_BE(ptr,val) duk_raw_write_u32_be((ptr), (duk_uint32_t) (val))
#define DUK_RAW_WRITE_FLOAT_BE(ptr,val) duk_raw_write_float_be((ptr), (duk_float_t) (val))
#define DUK_RAW_WRITE_DOUBLE_BE(ptr,val) duk_raw_write_double_be((ptr), (duk_double_t) (val))
#define DUK_RAW_WRITE_XUTF8(ptr,val) duk_raw_write_xutf8((ptr), (duk_ucodepoint_t) (val))
#define DUK_RAW_WRITEINC_U8(ptr,val) do { \
*(ptr)++ = (duk_uint8_t) (val); \
} while (0)
#define DUK_RAW_WRITE_U16_BE(ptr,val) duk_raw_write_u16_be(&(ptr), (duk_uint16_t) (val))
#define DUK_RAW_WRITE_U32_BE(ptr,val) duk_raw_write_u32_be(&(ptr), (duk_uint32_t) (val))
#define DUK_RAW_WRITE_DOUBLE_BE(ptr,val) duk_raw_write_double_be(&(ptr), (duk_double_t) (val))
#define DUK_RAW_WRITE_XUTF8(ptr,val) do { \
/* 'ptr' is evaluated both as LHS and RHS. */ \
duk_uint8_t *duk__ptr; \
duk_small_int_t duk__len; \
duk__ptr = (duk_uint8_t *) (ptr); \
duk__len = duk_unicode_encode_xutf8((duk_ucodepoint_t) (val), duk__ptr); \
duk__ptr += duk__len; \
(ptr) = duk__ptr; \
} while (0)
#define DUK_RAW_WRITE_CESU8(ptr,val) do { \
/* 'ptr' is evaluated both as LHS and RHS. */ \
duk_uint8_t *duk__ptr; \
duk_small_int_t duk__len; \
duk__ptr = (duk_uint8_t *) (ptr); \
duk__len = duk_unicode_encode_cesu8((duk_ucodepoint_t) (val), duk__ptr); \
duk__ptr += duk__len; \
(ptr) = duk__ptr; \
} while (0)
#define DUK_RAW_READ_U8(ptr) ((duk_uint8_t) (*(ptr)++))
#define DUK_RAW_READ_U16_BE(ptr) duk_raw_read_u16_be(&(ptr));
#define DUK_RAW_READ_U32_BE(ptr) duk_raw_read_u32_be(&(ptr));
#define DUK_RAW_READ_DOUBLE_BE(ptr) duk_raw_read_double_be(&(ptr));
#define DUK_RAW_WRITEINC_U16_BE(ptr,val) duk_raw_writeinc_u16_be(&(ptr), (duk_uint16_t) (val))
#define DUK_RAW_WRITEINC_U32_BE(ptr,val) duk_raw_writeinc_u32_be(&(ptr), (duk_uint32_t) (val))
#define DUK_RAW_WRITEINC_FLOAT_BE(ptr,val) duk_raw_writeinc_float_be(&(ptr), (duk_float_t) (val))
#define DUK_RAW_WRITEINC_DOUBLE_BE(ptr,val) duk_raw_writeinc_double_be(&(ptr), (duk_double_t) (val))
#define DUK_RAW_WRITEINC_XUTF8(ptr,val) duk_raw_writeinc_xutf8(&(ptr), (duk_ucodepoint_t) (val))
#define DUK_RAW_WRITEINC_CESU8(ptr,val) duk_raw_writeinc_cesu8(&(ptr), (duk_ucodepoint_t) (val))
#define DUK_RAW_READ_U8(ptr) ((duk_uint8_t) (*(ptr)))
#define DUK_RAW_READ_U16_BE(ptr) duk_raw_read_u16_be((ptr));
#define DUK_RAW_READ_U32_BE(ptr) duk_raw_read_u32_be((ptr));
#define DUK_RAW_READ_DOUBLE_BE(ptr) duk_raw_read_double_be((ptr));
#define DUK_RAW_READINC_U8(ptr) ((duk_uint8_t) (*(ptr)++))
#define DUK_RAW_READINC_U16_BE(ptr) duk_raw_readinc_u16_be(&(ptr));
#define DUK_RAW_READINC_U32_BE(ptr) duk_raw_readinc_u32_be(&(ptr));
#define DUK_RAW_READINC_DOUBLE_BE(ptr) duk_raw_readinc_double_be(&(ptr));
/*
* Double and float byte order operations.
*/
DUK_INTERNAL_DECL void duk_dblunion_host_to_little(duk_double_union *u);
DUK_INTERNAL_DECL void duk_dblunion_little_to_host(duk_double_union *u);
DUK_INTERNAL_DECL void duk_dblunion_host_to_big(duk_double_union *u);
DUK_INTERNAL_DECL void duk_dblunion_big_to_host(duk_double_union *u);
DUK_INTERNAL_DECL void duk_fltunion_host_to_big(duk_float_union *u);
DUK_INTERNAL_DECL void duk_fltunion_big_to_host(duk_float_union *u);
/*
* Buffer writer (dynamic buffer only)
@ -529,12 +538,26 @@ DUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_b
DUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);
/* No duk_bw_remove_ensure_slice(), functionality would be identical. */
DUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p);
DUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p);
DUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p);
DUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val);
DUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val);
DUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val);
DUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(const duk_uint8_t *p);
DUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(const duk_uint8_t *p);
DUK_INTERNAL_DECL duk_float_t duk_raw_read_float_be(const duk_uint8_t *p);
DUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(const duk_uint8_t *p);
DUK_INTERNAL_DECL duk_uint16_t duk_raw_readinc_u16_be(const duk_uint8_t **p);
DUK_INTERNAL_DECL duk_uint32_t duk_raw_readinc_u32_be(const duk_uint8_t **p);
DUK_INTERNAL_DECL duk_float_t duk_raw_readinc_float_be(const duk_uint8_t **p);
DUK_INTERNAL_DECL duk_double_t duk_raw_readinc_double_be(const duk_uint8_t **p);
DUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t *p, duk_uint16_t val);
DUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t *p, duk_uint32_t val);
DUK_INTERNAL_DECL void duk_raw_write_float_be(duk_uint8_t *p, duk_float_t val);
DUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t *p, duk_double_t val);
DUK_INTERNAL_DECL duk_small_int_t duk_raw_write_xutf8(duk_uint8_t *p, duk_ucodepoint_t val);
DUK_INTERNAL_DECL duk_small_int_t duk_raw_write_cesu8(duk_uint8_t *p, duk_ucodepoint_t val);
DUK_INTERNAL_DECL void duk_raw_writeinc_u16_be(duk_uint8_t **p, duk_uint16_t val);
DUK_INTERNAL_DECL void duk_raw_writeinc_u32_be(duk_uint8_t **p, duk_uint32_t val);
DUK_INTERNAL_DECL void duk_raw_writeinc_float_be(duk_uint8_t **p, duk_float_t val);
DUK_INTERNAL_DECL void duk_raw_writeinc_double_be(duk_uint8_t **p, duk_double_t val);
DUK_INTERNAL_DECL void duk_raw_writeinc_xutf8(duk_uint8_t **p, duk_ucodepoint_t val);
DUK_INTERNAL_DECL void duk_raw_writeinc_cesu8(duk_uint8_t **p, duk_ucodepoint_t val);
#if defined(DUK_USE_DEBUGGER_SUPPORT) /* For now only needed by the debugger. */
DUK_INTERNAL_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len);

92
src-input/duk_util_bufwriter.c

@ -266,98 +266,6 @@ DUK_INTERNAL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *b
bw->p -= len;
}
/*
* Macro support functions for reading/writing raw data.
*
* These are done using mempcy to ensure they're valid even for unaligned
* reads/writes on platforms where alignment counts. On x86 at least gcc
* is able to compile these into a bswap+mov. "Always inline" is used to
* ensure these macros compile to minimal code.
*
* Not really bufwriter related, but currently used together.
*/
DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p) {
union {
duk_uint8_t b[2];
duk_uint16_t x;
} u;
duk_memcpy((void *) u.b, (const void *) (*p), (size_t) 2);
u.x = DUK_NTOH16(u.x);
*p += 2;
return u.x;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p) {
union {
duk_uint8_t b[4];
duk_uint32_t x;
} u;
duk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);
u.x = DUK_NTOH32(u.x);
*p += 4;
return u.x;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t **p) {
duk_double_union du;
union {
duk_uint8_t b[4];
duk_uint32_t x;
} u;
duk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);
u.x = DUK_NTOH32(u.x);
du.ui[DUK_DBL_IDX_UI0] = u.x;
duk_memcpy((void *) u.b, (const void *) (*p + 4), (size_t) 4);
u.x = DUK_NTOH32(u.x);
du.ui[DUK_DBL_IDX_UI1] = u.x;
*p += 8;
return du.d;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val) {
union {
duk_uint8_t b[2];
duk_uint16_t x;
} u;
u.x = DUK_HTON16(val);
duk_memcpy((void *) (*p), (const void *) u.b, (size_t) 2);
*p += 2;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val) {
union {
duk_uint8_t b[4];
duk_uint32_t x;
} u;
u.x = DUK_HTON32(val);
duk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);
*p += 4;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val) {
duk_double_union du;
union {
duk_uint8_t b[4];
duk_uint32_t x;
} u;
du.d = val;
u.x = du.ui[DUK_DBL_IDX_UI0];
u.x = DUK_HTON32(u.x);
duk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);
u.x = du.ui[DUK_DBL_IDX_UI1];
u.x = DUK_HTON32(u.x);
duk_memcpy((void *) (*p + 4), (const void *) u.b, (size_t) 4);
*p += 8;
}
/*
* Assertion helpers
*/

84
src-input/duk_util_double.c

@ -232,3 +232,87 @@ DUK_INTERNAL DUK_INLINE duk_double_t duk_double_div(duk_double_t x, duk_double_t
return x / y;
}
/* Double and float byteorder changes. */
DUK_INTERNAL DUK_INLINE void duk_dblunion_host_to_little(duk_double_union *u) {
#if defined(DUK_USE_DOUBLE_LE)
/* HGFEDCBA -> HGFEDCBA */
DUK_UNREF(u);
#elif defined(DUK_USE_DOUBLE_ME)
duk_uint32_t a, b;
/* DCBAHGFE -> HGFEDCBA */
a = u->ui[0];
b = u->ui[1];
u->ui[0] = b;
u->ui[1] = a;
#elif defined(DUK_USE_DOUBLE_BE)
/* ABCDEFGH -> HGFEDCBA */
#if defined(DUK_USE_64BIT_OPS)
u->ull[0] = DUK_BSWAP64(u->ull[0]);
#else
duk_uint32_t a, b;
a = u->ui[0];
b = u->ui[1];
u->ui[0] = DUK_BSWAP32(b);
u->ui[1] = DUK_BSWAP32(a);
#endif
#else
#error internal error
#endif
}
DUK_INTERNAL DUK_INLINE void duk_dblunion_little_to_host(duk_double_union *u) {
duk_dblunion_host_to_little(u);
}
DUK_INTERNAL DUK_INLINE void duk_dblunion_host_to_big(duk_double_union *u) {
#if defined(DUK_USE_DOUBLE_LE)
/* HGFEDCBA -> ABCDEFGH */
#if defined(DUK_USE_64BIT_OPS)
u->ull[0] = DUK_BSWAP64(u->ull[0]);
#else
duk_uint32_t a, b;
a = u->ui[0];
b = u->ui[1];
u->ui[0] = DUK_BSWAP32(b);
u->ui[1] = DUK_BSWAP32(a);
#endif
#elif defined(DUK_USE_DOUBLE_ME)
duk_uint32_t a, b;
/* DCBAHGFE -> ABCDEFGH */
a = u->ui[0];
b = u->ui[1];
u->ui[0] = DUK_BSWAP32(a);
u->ui[1] = DUK_BSWAP32(b);
#elif defined(DUK_USE_DOUBLE_BE)
/* ABCDEFGH -> ABCDEFGH */
DUK_UNREF(u);
#else
#error internal error
#endif
}
DUK_INTERNAL DUK_INLINE void duk_dblunion_big_to_host(duk_double_union *u) {
duk_dblunion_host_to_big(u);
}
DUK_INTERNAL DUK_INLINE void duk_fltunion_host_to_big(duk_float_union *u) {
#if defined(DUK_USE_DOUBLE_LE) || defined(DUK_USE_DOUBLE_ME)
/* DCBA -> ABCD */
u->ui[0] = DUK_BSWAP32(u->ui[0]);
#elif defined(DUK_USE_DOUBLE_BE)
/* ABCD -> ABCD */
DUK_UNREF(u);
#else
#error internal error
#endif
}
DUK_INTERNAL DUK_INLINE void duk_fltunion_big_to_host(duk_float_union *u) {
duk_fltunion_host_to_big(u);
}

148
src-input/duk_util_memrw.c

@ -0,0 +1,148 @@
/*
* Macro support functions for reading/writing raw data.
*
* These are done using memcpy to ensure they're valid even for unaligned
* reads/writes on platforms where alignment counts. On x86 at least gcc
* is able to compile these into a bswap+mov. "Always inline" is used to
* ensure these macros compile to minimal code.
*/
#include "duk_internal.h"
union duk__u16_union {
duk_uint8_t b[2];
duk_uint16_t x;
};
typedef union duk__u16_union duk__u16_union;
union duk__u32_union {
duk_uint8_t b[4];
duk_uint32_t x;
};
typedef union duk__u32_union duk__u32_union;
#if defined(DUK_USE_64BIT_OPS)
union duk__u64_union {
duk_uint8_t b[8];
duk_uint64_t x;
};
typedef union duk__u64_union duk__u64_union;
#endif
DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(const duk_uint8_t *p) {
duk__u16_union u;
duk_memcpy((void *) u.b, (const void *) p, (size_t) 2);
u.x = DUK_NTOH16(u.x);
return u.x;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(const duk_uint8_t *p) {
duk__u32_union u;
duk_memcpy((void *) u.b, (const void *) p, (size_t) 4);
u.x = DUK_NTOH32(u.x);
return u.x;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_float_t duk_raw_read_float_be(const duk_uint8_t *p) {
duk_float_union fu;
duk_memcpy((void *) fu.uc, (const void *) p, (size_t) 4);
duk_fltunion_big_to_host(&fu);
return fu.f;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(const duk_uint8_t *p) {
duk_double_union du;
duk_memcpy((void *) du.uc, (const void *) p, (size_t) 8);
duk_dblunion_big_to_host(&du);
return du.d;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_readinc_u16_be(const duk_uint8_t **p) {
duk_uint16_t res = duk_raw_read_u16_be(*p);
*p += 2;
return res;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_readinc_u32_be(const duk_uint8_t **p) {
duk_uint32_t res = duk_raw_read_u32_be(*p);
*p += 4;
return res;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_float_t duk_raw_readinc_float_be(const duk_uint8_t **p) {
duk_float_t res = duk_raw_read_float_be(*p);
*p += 4;
return res;
}
DUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_readinc_double_be(const duk_uint8_t **p) {
duk_double_t res = duk_raw_read_double_be(*p);
*p += 8;
return res;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t *p, duk_uint16_t val) {
duk__u16_union u;
u.x = DUK_HTON16(val);
duk_memcpy((void *) p, (const void *) u.b, (size_t) 2);
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t *p, duk_uint32_t val) {
duk__u32_union u;
u.x = DUK_HTON32(val);
duk_memcpy((void *) p, (const void *) u.b, (size_t) 4);
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_float_be(duk_uint8_t *p, duk_float_t val) {
duk_float_union fu;
fu.f = val;
duk_fltunion_host_to_big(&fu);
duk_memcpy((void *) p, (const void *) fu.uc, (size_t) 4);
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t *p, duk_double_t val) {
duk_double_union du;
du.d = val;
duk_dblunion_host_to_big(&du);
duk_memcpy((void *) p, (const void *) du.uc, (size_t) 8);
}
DUK_INTERNAL duk_small_int_t duk_raw_write_xutf8(duk_uint8_t *p, duk_ucodepoint_t val) {
duk_small_int_t len = duk_unicode_encode_xutf8(val, p);
return len;
}
DUK_INTERNAL duk_small_int_t duk_raw_write_cesu8(duk_uint8_t *p, duk_ucodepoint_t val) {
duk_small_int_t len = duk_unicode_encode_cesu8(val, p);
return len;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_u16_be(duk_uint8_t **p, duk_uint16_t val) {
duk_raw_write_u16_be(*p, val);
*p += 2;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_u32_be(duk_uint8_t **p, duk_uint32_t val) {
duk_raw_write_u32_be(*p, val);
*p += 4;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_float_be(duk_uint8_t **p, duk_float_t val) {
duk_raw_write_float_be(*p, val);
*p += 4;
}
DUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_writeinc_double_be(duk_uint8_t **p, duk_double_t val) {
duk_raw_write_double_be(*p, val);
*p += 8;
}
DUK_INTERNAL void duk_raw_writeinc_xutf8(duk_uint8_t **p, duk_ucodepoint_t val) {
duk_small_int_t len = duk_unicode_encode_xutf8(val, *p);
*p += len;
}
DUK_INTERNAL void duk_raw_writeinc_cesu8(duk_uint8_t **p, duk_ucodepoint_t val) {
duk_small_int_t len = duk_unicode_encode_cesu8(val, *p);
*p += len;
}

2
src-input/duktape.h.in

@ -895,6 +895,8 @@ DUK_EXTERNAL_DECL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL void duk_hex_decode(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL void duk_json_decode(duk_context *ctx, duk_idx_t idx);
DUK_EXTERNAL_DECL void duk_cbor_encode(duk_context *ctx, duk_idx_t idx, duk_uint_t encode_flags);
DUK_EXTERNAL_DECL void duk_cbor_decode(duk_context *ctx, duk_idx_t idx, duk_uint_t decode_flags);
DUK_EXTERNAL_DECL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx);

4
tools/configure.py

@ -412,6 +412,7 @@ def main():
'duk_bi_array.c',
'duk_bi_boolean.c',
'duk_bi_buffer.c',
'duk_bi_cbor.c',
'duk_bi_date.c',
'duk_bi_date_unix.c',
'duk_bi_date_windows.c',
@ -448,6 +449,7 @@ def main():
'duk_error_macros.c',
'duk_error_misc.c',
'duk_error_throw.c',
'duk_fltunion.h',
'duk_forwdecl.h',
'duk_harray.h',
'duk_hboundfunc.h',
@ -524,6 +526,7 @@ def main():
'duk_util_double.c',
'duk_util_cast.c',
'duk_util_memory.c',
'duk_util_memrw.c',
'duk_util_misc.c',
'duk_selftest.c',
'duk_selftest.h',
@ -925,6 +928,7 @@ def main():
'duk_builtins.c',
'duk_error_macros.c',
'duk_unicode_support.c',
'duk_util_memrw.c',
'duk_util_misc.c',
'duk_hobject_class.c'
]

3
util/dist.py

@ -320,6 +320,7 @@ def main():
'duk_bi_array.c',
'duk_bi_boolean.c',
'duk_bi_buffer.c',
'duk_bi_cbor.c',
'duk_bi_date.c',
'duk_bi_date_unix.c',
'duk_bi_date_windows.c',
@ -357,6 +358,7 @@ def main():
'duk_error_misc.c',
'duk_error_throw.c',
'duk_exception.h',
'duk_fltunion.h',
'duk_forwdecl.h',
'duk_harray.h',
'duk_hboundfunc.h',
@ -438,6 +440,7 @@ def main():
'duk_util_double.c',
'duk_util_cast.c',
'duk_util_memory.c',
'duk_util_memrw.c',
'duk_util_misc.c',
'strings.yaml',
'SpecialCasing.txt',

Loading…
Cancel
Save