Browse Source

Merge branch 'bcc-fixes'

pull/9/head
Sami Vaarala 11 years ago
parent
commit
2916660e76
  1. 147
      doc/code-issues.txt
  2. 6
      src/duk_api.c
  3. 3
      src/duk_api_logging.c
  4. 2
      src/duk_bi_duktape.c
  5. 3
      src/duk_bi_json.c
  6. 33
      src/duk_bi_math.c
  7. 2
      src/duk_bi_string.c
  8. 97
      src/duk_features.h.in
  9. 2
      src/duk_heap_alloc.c
  10. 2
      src/duk_heap_markandsweep.c
  11. 4
      src/duk_heap_refcount.c
  12. 38
      src/duk_hobject_props.c
  13. 6
      src/duk_js_executor.c
  14. 2
      src/duk_replacements.c
  15. 5
      src/genbuiltins.py
  16. 7
      website/guide/portability.html

147
doc/code-issues.txt

@ -147,6 +147,34 @@ Be careful especially of assertions, debug prints, and other macros::
DUK_UNREF(y); DUK_UNREF(y);
int flags = 0; /* problem: DUK_UNREF() */ int flags = 0; /* problem: DUK_UNREF() */
Note that even **disabled** debug prints break the variable declaration
part because disabled debug prints are replaced with ``do {} while (0)``
(this is intentional to flush out this kind of errors even in release
builds)::
{
int x;
DUK_DDD(DUK_DDDPRINT("debug print"));
int y; /* error here */
x = 123;
...
}
The fix is::
{
int x;
int y;
DUK_DDD(DUK_DDDPRINT("debug print"));
x = 123;
...
}
Include guards Include guards
-------------- --------------
@ -626,6 +654,118 @@ EBCDIC
See separate section below. See separate section below.
Portability issues on very old compilers
========================================
Initialization of auto arrays
-----------------------------
Some old compilers (such as bcc) refuse to compile the following (error
message is something along the lines of: initialization of auto arrays
is illegal)::
int myarray[] = { 123, 234 };
or even::
int myarray[2] = { 123, 234 };
Apparently the following would be legal::
static int myarray[2] = { 123, 234 };
The workaround is to use a static array or initialize explicitly::
int myarray[2];
myarray[0] = 123;
myarray[1] = 234;
Initializer is too complicated (bcc)
------------------------------------
BCC complains about "initializer is too complicated" when a function pointer
array contains casts::
...
(duk_c_function) my_function,
...
This works::
...
my_function,
...
Non-integral selector in switch (bcc)
-------------------------------------
For some reason BCC fails to compile switch statements where the value is
obtained with a macro such as::
switch (DUK_DEC_OP(ins)) {
...
}
This is probably caused by the fact that ``DUK_DEC_OP(ins)`` is a 32-bit value
while BCC's integer type is 16 bits. Switch argument needs to be ``int``, so
one needs to::
switch ((int) DUK_DEC_OP(ins)) {
...
}
Or perhaps (using type wrappers)::
switch ((duk_small_int_t) DUK_DEC_OP(ins)) {
...
}
Division by zero is a compile error
-----------------------------------
Attempting to create NaN or infinity values with expressions like ``0/0`` and
``1/0`` are treated as compile errors by some compilers (such as BCC) while
others will just replace them with an incorrect value (e.g. VBCC replaces them
with zero). Run-time computed NaN / infinity values are needed on such platforms.
ULL integer constants may cause an error
----------------------------------------
The following may cause a compilation error (e.g. BCC)::
#if defined(ULONG_MAX) && (ULONG_MAX == 18446744073709551615ULL)
The error happens even if ``ULONG_MAX`` is not defined. Instead, this needs
to be restructured in one of several ways. For instance, old compilers can be
rejected explicitly::
#if defined(DUK_F_BCC)
/* cannot check ULONG_MAX */
#else
#if defined(ULONG_MAX) && (ULONG_MAX == 18446744073709551615ULL)
/* ... */
#endif
#endif
The important point is that the old compiler cannot process the preprocessor
line containing the integer constant; if it processes even part of the line,
it may choke on a syntax error.
Comments inside macro arguments may cause an error (BCC)
--------------------------------------------------------
The following causes an error on BCC::
DUK_ASSERT(FOO || /* foo happens */
BAR);
The comment causes BCC to produce an error like "incorrect number of macro
arguments". The fix is to remove the comment from inside the macro::
DUK_ASSERT(FOO ||
BAR);
Character values in char literals and strings, EBCDIC Character values in char literals and strings, EBCDIC
===================================================== =====================================================
@ -839,3 +979,10 @@ clang
----- -----
Clang has some issues with union aliasing. See ``misc/clang_aliasing.c``. Clang has some issues with union aliasing. See ``misc/clang_aliasing.c``.
bcc
---
BCC is not a realistic compilation target at the moment but serves as a nice
"torture target". Various issues have been documented above in portability
issues.

6
src/duk_api.c

@ -1383,11 +1383,15 @@ static int duk__defaultvalue_coerce_attempt(duk_context *ctx, int index, int fun
void duk_to_defaultvalue(duk_context *ctx, int index, int hint) { void duk_to_defaultvalue(duk_context *ctx, int index, int hint) {
duk_hthread *thr = (duk_hthread *) ctx; duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *obj; duk_hobject *obj;
int coercers[] = { DUK_STRIDX_VALUE_OF, DUK_STRIDX_TO_STRING }; /* inline initializer for coercers[] is not allowed by old compilers like BCC */
int coercers[2];
DUK_ASSERT(ctx != NULL); DUK_ASSERT(ctx != NULL);
DUK_ASSERT(thr != NULL); DUK_ASSERT(thr != NULL);
coercers[0] = DUK_STRIDX_VALUE_OF;
coercers[1] = DUK_STRIDX_TO_STRING;
index = duk_require_normalize_index(ctx, index); index = duk_require_normalize_index(ctx, index);
if (!duk_is_object(ctx, index)) { if (!duk_is_object(ctx, index)) {

3
src/duk_api_logging.c

@ -15,7 +15,8 @@ void duk_log(duk_context *ctx, int level, const char *fmt, ...) {
duk_hthread *thr = (duk_hthread *) ctx; duk_hthread *thr = (duk_hthread *) ctx;
va_list ap; va_list ap;
char buf[DUK__LOGFMT_BUFSIZE]; char buf[DUK__LOGFMT_BUFSIZE];
duk_uint16_t stridx_logfunc[6] = { /* stridx_logfunc[] must be static to allow initializer with old compilers like BCC */
static const duk_uint16_t stridx_logfunc[6] = {
DUK_STRIDX_LC_TRACE, DUK_STRIDX_LC_DEBUG, DUK_STRIDX_LC_INFO, DUK_STRIDX_LC_TRACE, DUK_STRIDX_LC_DEBUG, DUK_STRIDX_LC_INFO,
DUK_STRIDX_LC_WARN, DUK_STRIDX_LC_ERROR, DUK_STRIDX_LC_FATAL DUK_STRIDX_LC_WARN, DUK_STRIDX_LC_ERROR, DUK_STRIDX_LC_FATAL
}; };

2
src/duk_bi_duktape.c

@ -49,7 +49,7 @@ duk_ret_t duk_bi_duktape_object_info(duk_context *ctx) {
/* heaphdr size and additional allocation size, followed by /* heaphdr size and additional allocation size, followed by
* type specific stuff (with varying value count) * type specific stuff (with varying value count)
*/ */
switch (DUK_HEAPHDR_GET_TYPE(h)) { switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {
case DUK_HTYPE_STRING: { case DUK_HTYPE_STRING: {
duk_hstring *h_str = (duk_hstring *) h; duk_hstring *h_str = (duk_hstring *) h;
duk_push_int(ctx, (int) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1)); duk_push_int(ctx, (int) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1));

3
src/duk_bi_json.c

@ -1860,7 +1860,8 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
if (duk_is_number(ctx, idx_space)) { if (duk_is_number(ctx, idx_space)) {
double d; double d;
int nspace; int nspace;
char spaces[10] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; /* FIXME:helper */ /* spaces[] must be static to allow initializer with old compilers like BCC */
static const char spaces[10] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; /* FIXME:helper */
/* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */ /* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */
/* FIXME: get_clamped_int; double arithmetic is expensive */ /* FIXME: get_clamped_int; double arithmetic is expensive */

33
src/duk_bi_math.c

@ -4,6 +4,8 @@
#include "duk_internal.h" #include "duk_internal.h"
#if defined(DUK_USE_MATH_BUILTIN)
/* /*
* Use static helpers which can work with math.h functions matching * Use static helpers which can work with math.h functions matching
* the following signatures. This is not portable if any of these math * the following signatures. This is not portable if any of these math
@ -248,3 +250,34 @@ duk_ret_t duk_bi_math_object_random(duk_context *ctx) {
duk_push_number(ctx, (duk_double_t) duk_util_tinyrandom_get_double((duk_hthread *) ctx)); duk_push_number(ctx, (duk_double_t) duk_util_tinyrandom_get_double((duk_hthread *) ctx));
return 1; return 1;
} }
#else /* DUK_USE_MATH_BUILTIN */
/* A stubbed built-in is useful for e.g. compilation torture testing with BCC. */
duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx) {
DUK_UNREF(ctx);
return DUK_RET_UNIMPLEMENTED_ERROR;
}
duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx) {
DUK_UNREF(ctx);
return DUK_RET_UNIMPLEMENTED_ERROR;
}
duk_ret_t duk_bi_math_object_max(duk_context *ctx) {
DUK_UNREF(ctx);
return DUK_RET_UNIMPLEMENTED_ERROR;
}
duk_ret_t duk_bi_math_object_min(duk_context *ctx) {
DUK_UNREF(ctx);
return DUK_RET_UNIMPLEMENTED_ERROR;
}
duk_ret_t duk_bi_math_object_random(duk_context *ctx) {
DUK_UNREF(ctx);
return DUK_RET_UNIMPLEMENTED_ERROR;
}
#endif /* DUK_USE_MATH_BUILTIN */

2
src/duk_bi_string.c

@ -655,7 +655,7 @@ duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx) {
} }
ch2 = r[0]; ch2 = r[0];
switch (ch2) { switch ((duk_small_int_t) ch2) {
case (duk_int_t) '$': { case (duk_int_t) '$': {
ch1 = (1 << 8) + (duk_int_t) '$'; ch1 = (1 << 8) + (duk_int_t) '$';
goto repl_write; goto repl_write;

97
src/duk_features.h.in

@ -223,7 +223,7 @@ static __inline__ unsigned long long duk_rdtsc(void) {
#define DUK_F_GCC #define DUK_F_GCC
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
/* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */ /* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */
#define DUK_F_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #define DUK_F_GCC_VERSION (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)
#else #else
#error cannot figure out gcc version #error cannot figure out gcc version
#endif #endif
@ -244,6 +244,23 @@ static __inline__ unsigned long long duk_rdtsc(void) {
#define DUK_F_MINGW #define DUK_F_MINGW
#endif #endif
/* BCC (Bruce's C compiler): this is a "torture target" for compilation */
#if defined(__BCC__) || defined(__BCC_VERSION__)
#define DUK_F_BCC
#endif
#if defined(__VBCC__)
#define DUK_F_VBCC
#endif
#if defined(DUK_F_BCC)
/* preprocessor does not understand ULL constants (12345ULL) so we can't
* evaluate any expressions with them (e.g. BCC).
*/
#else
#define DUK_F_ULL_CONSTS
#endif
/* /*
* Platform detection, system includes, Date provider selection. * Platform detection, system includes, Date provider selection.
* *
@ -293,7 +310,7 @@ static __inline__ unsigned long long duk_rdtsc(void) {
#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE) #if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE)
/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */ /* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */
#define _XOPEN_SOURCE 600 #define _XOPEN_SOURCE 600
#define _POSIX_C_SOURCE 200112 #define _POSIX_C_SOURCE 200112L
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
@ -389,7 +406,11 @@ static __inline__ unsigned long long duk_rdtsc(void) {
#define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_PRS_STRPTIME
#define DUK_USE_DATE_FMT_STRFTIME #define DUK_USE_DATE_FMT_STRFTIME
#include <sys/types.h> #include <sys/types.h>
#if defined(DUK_F_BCC)
/* no endian.h */
#else
#include <endian.h> #include <endian.h>
#endif /* DUK_F_BCC */
#include <limits.h> #include <limits.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
@ -413,7 +434,11 @@ static __inline__ unsigned long long duk_rdtsc(void) {
#define DUK_USE_DATE_PRS_STRPTIME #define DUK_USE_DATE_PRS_STRPTIME
#define DUK_USE_DATE_FMT_STRFTIME #define DUK_USE_DATE_FMT_STRFTIME
#include <sys/types.h> #include <sys/types.h>
#if defined(DUK_F_BCC)
/* no endian.h */
#else
#include <endian.h> #include <endian.h>
#endif /* DUK_F_BCC */
#include <limits.h> #include <limits.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
@ -427,10 +452,10 @@ static __inline__ unsigned long long duk_rdtsc(void) {
#include <stdarg.h> /* varargs */ #include <stdarg.h> /* varargs */
#include <setjmp.h> #include <setjmp.h>
#include <stddef.h> /* e.g. ptrdiff_t */ #include <stddef.h> /* e.g. ptrdiff_t */
#ifdef DUK_F_TOS #if defined(DUK_F_TOS) || defined(DUK_F_BCC)
/*FIXME*/ /* stdint.h not available */
#else #else
/* XXX: technically C99 (C++11) but found in many systems */ /* technically C99 (C++11) but found in many systems */
#include <stdint.h> #include <stdint.h>
#endif #endif
#include <math.h> #include <math.h>
@ -466,7 +491,7 @@ static __inline__ unsigned long long duk_rdtsc(void) {
* format characters need to be changed. * format characters need to be changed.
*/ */
#if defined(INT_MAX) #if defined(INT_MAX)
#if INT_MAX < 2147483647 #if INT_MAX < 2147483647L
#error INT_MAX too small, expected int to be 32 bits at least #error INT_MAX too small, expected int to be 32 bits at least
#endif #endif
#else #else
@ -484,8 +509,11 @@ static __inline__ unsigned long long duk_rdtsc(void) {
#error cannot check complement of two #error cannot check complement of two
#endif #endif
/* Pointer size determination based on architecture. */ /* Pointer size determination based on architecture.
* XXX: unsure about BCC correctness.
*/
#if defined(DUK_F_X86) || defined(DUK_F_X32) || \ #if defined(DUK_F_X86) || defined(DUK_F_X32) || \
defined(DUK_F_BCC) || \
(defined(__WORDSIZE) && (__WORDSIZE == 32)) (defined(__WORDSIZE) && (__WORDSIZE == 32))
#define DUK_F_32BIT_PTRS #define DUK_F_32BIT_PTRS
#elif defined(DUK_F_X64) || \ #elif defined(DUK_F_X64) || \
@ -498,7 +526,7 @@ static __inline__ unsigned long long duk_rdtsc(void) {
/* Intermediate define for 'have inttypes.h' */ /* Intermediate define for 'have inttypes.h' */
#undef DUK_F_HAVE_INTTYPES #undef DUK_F_HAVE_INTTYPES
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!(defined(DUK_F_AMIGAOS) && defined(__VBCC__)) !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC))
/* vbcc + AmigaOS has C99 but no inttypes.h */ /* vbcc + AmigaOS has C99 but no inttypes.h */
#define DUK_F_HAVE_INTTYPES #define DUK_F_HAVE_INTTYPES
#elif defined(__cplusplus) && (__cplusplus >= 201103L) #elif defined(__cplusplus) && (__cplusplus >= 201103L)
@ -645,21 +673,25 @@ typedef signed long duk_int32_t;
#error cannot detect 32-bit type #error cannot detect 32-bit type
#endif #endif
#define DUK_F_HAVE_64BIT #undef DUK_F_HAVE_64BIT
#if defined(DUK_F_ULL_CONSTS)
#if defined(ULONG_MAX) && (ULONG_MAX == 18446744073709551615ULL) #if defined(ULONG_MAX) && (ULONG_MAX == 18446744073709551615ULL)
#define DUK_F_HAVE_64BIT
typedef unsigned long duk_uint64_t; typedef unsigned long duk_uint64_t;
typedef signed long duk_int64_t; typedef signed long duk_int64_t;
#elif defined(ULLONG_MAX) && (ULLONG_MAX == 18446744073709551615ULL) #elif defined(ULLONG_MAX) && (ULLONG_MAX == 18446744073709551615ULL)
#define DUK_F_HAVE_64BIT
typedef unsigned long long duk_uint64_t; typedef unsigned long long duk_uint64_t;
typedef signed long long duk_int64_t; typedef signed long long duk_int64_t;
#elif defined(DUK_F_MINGW) || defined(DUK_F_MSVC) #elif defined(DUK_F_MINGW) || defined(DUK_F_MSVC)
/* Both MinGW and MSVC have a 64-bit type. */ /* Both MinGW and MSVC have a 64-bit type. */
#define DUK_F_HAVE_64BIT
typedef unsigned long duk_uint64_t; typedef unsigned long duk_uint64_t;
typedef signed long duk_int64_t; typedef signed long duk_int64_t;
#else #else
/* cannot detect 64-bit type, not always needed so don't error */ /* cannot detect 64-bit type, not always needed so don't error */
#undef DUK_F_HAVE_64BIT
#endif #endif
#endif /* DUK_F_ULL_CONSTS */
typedef duk_uint8_t duk_uint_least8_t; typedef duk_uint8_t duk_uint_least8_t;
typedef duk_int8_t duk_int_least8_t; typedef duk_int8_t duk_int_least8_t;
@ -673,8 +705,13 @@ typedef duk_uint16_t duk_uint_fast16_t;
typedef duk_int16_t duk_int_fast16_t; typedef duk_int16_t duk_int_fast16_t;
typedef duk_uint32_t duk_uint_fast32_t; typedef duk_uint32_t duk_uint_fast32_t;
typedef duk_int32_t duk_int_fast32_t; typedef duk_int32_t duk_int_fast32_t;
#if defined(DUK_F_HAVE_64BIT)
typedef duk_int64_t duk_intmax_t;
typedef duk_uint64_t duk_uintmax_t;
#else
typedef duk_int32_t duk_intmax_t; typedef duk_int32_t duk_intmax_t;
typedef duk_uint32_t duk_uintmax_t; typedef duk_uint32_t duk_uintmax_t;
#endif
/* This detection is not very reliable. */ /* This detection is not very reliable. */
#if defined(DUK_F_32BIT_PTRS) #if defined(DUK_F_32BIT_PTRS)
@ -687,10 +724,6 @@ typedef duk_uint64_t duk_uintptr_t;
#error cannot determine intptr type #error cannot determine intptr type
#endif #endif
/* Pretend that maximum int is 32 bits. */
typedef duk_uint32_t duk_uintmax_t;
typedef duk_int32_t duk_intmax_t;
#define DUK_UINT8_MIN 0UL #define DUK_UINT8_MIN 0UL
#define DUK_UINT8_MAX 0xffUL #define DUK_UINT8_MAX 0xffUL
#define DUK_INT8_MIN (-0x80L) #define DUK_INT8_MIN (-0x80L)
@ -727,6 +760,7 @@ typedef duk_int32_t duk_intmax_t;
#define DUK_UINT_FAST32_MAX 0xffffffffUL #define DUK_UINT_FAST32_MAX 0xffffffffUL
#define DUK_INT_FAST32_MIN (-0x80000000L) #define DUK_INT_FAST32_MIN (-0x80000000L)
#define DUK_INT_FAST32_MAX 0x7fffffffL #define DUK_INT_FAST32_MAX 0x7fffffffL
#if defined(DUK_F_HAVE_64BIT)
#define DUK_UINT64_MIN 0ULL #define DUK_UINT64_MIN 0ULL
#define DUK_UINT64_MAX 0xffffffffffffffffULL #define DUK_UINT64_MAX 0xffffffffffffffffULL
#define DUK_INT64_MIN (-0x8000000000000000LL) #define DUK_INT64_MIN (-0x8000000000000000LL)
@ -739,6 +773,7 @@ typedef duk_int32_t duk_intmax_t;
#define DUK_UINT_FAST64_MAX 0xffffffffffffffffULL #define DUK_UINT_FAST64_MAX 0xffffffffffffffffULL
#define DUK_INT_FAST64_MIN (-0x8000000000000000LL) #define DUK_INT_FAST64_MIN (-0x8000000000000000LL)
#define DUK_INT_FAST64_MAX 0x7fffffffffffffffULL #define DUK_INT_FAST64_MAX 0x7fffffffffffffffULL
#endif
#define DUK_UINTPTR_MIN 0UL #define DUK_UINTPTR_MIN 0UL
#define DUK_UINTPTR_MAX 0xffffffffUL #define DUK_UINTPTR_MAX 0xffffffffUL
#define DUK_INTPTR_MIN (-0x80000000L) #define DUK_INTPTR_MIN (-0x80000000L)
@ -834,7 +869,7 @@ typedef double duk_double_t;
* unless they are known to be unreliable. For instance, 64-bit types are * unless they are known to be unreliable. For instance, 64-bit types are
* available on VBCC but seem to misbehave. * available on VBCC but seem to misbehave.
*/ */
#if defined(DUK_F_HAVE_64BIT) && !defined(__VBCC__) #if defined(DUK_F_HAVE_64BIT) && !defined(DUK_F_VBCC)
#define DUK_USE_64BIT_OPS #define DUK_USE_64BIT_OPS
#else #else
#undef DUK_USE_64BIT_OPS #undef DUK_USE_64BIT_OPS
@ -861,7 +896,8 @@ typedef double duk_double_t;
#define DUK_USE_ALIGN_4 #define DUK_USE_ALIGN_4
#elif defined(DUK_F_MIPS) #elif defined(DUK_F_MIPS)
#define DUK_USE_ALIGN_4 #define DUK_USE_ALIGN_4
#elif defined(DUK_F_X86) || defined(DUK_F_X32) || defined(DUK_F_X64) #elif defined(DUK_F_X86) || defined(DUK_F_X32) || defined(DUK_F_X64) || \
defined(DUK_F_BCC)
#define DUK_USE_UNALIGNED_ACCESSES_POSSIBLE #define DUK_USE_UNALIGNED_ACCESSES_POSSIBLE
#else #else
/* unknown, use safe default */ /* unknown, use safe default */
@ -1102,6 +1138,11 @@ typedef double duk_double_t;
#endif #endif
#endif #endif
/* Bruce's C Compiler (BCC), assume we're on x86. */
#if !defined(DUK_F_BYTEORDER) && defined(DUK_F_BCC)
#define DUK_F_BYTEORDER 1
#endif
/* Check whether or not byte order detection worked based on the intermediate /* Check whether or not byte order detection worked based on the intermediate
* define, and define final values. If detection failed, #error out. * define, and define final values. If detection failed, #error out.
*/ */
@ -1174,7 +1215,7 @@ typedef double duk_double_t;
#define DUK_DOUBLE_INFINITY (__builtin_inf()) #define DUK_DOUBLE_INFINITY (__builtin_inf())
#elif defined(INFINITY) #elif defined(INFINITY)
#define DUK_DOUBLE_INFINITY ((double) INFINITY) #define DUK_DOUBLE_INFINITY ((double) INFINITY)
#elif !defined(__VBCC__) && !defined(_MSC_VER) #elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC)
#define DUK_DOUBLE_INFINITY (1.0 / 0.0) #define DUK_DOUBLE_INFINITY (1.0 / 0.0)
#else #else
/* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity. /* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity.
@ -1189,7 +1230,7 @@ extern double duk_computed_infinity;
#undef DUK_USE_COMPUTED_NAN #undef DUK_USE_COMPUTED_NAN
#if defined(NAN) #if defined(NAN)
#define DUK_DOUBLE_NAN NAN #define DUK_DOUBLE_NAN NAN
#elif !defined(__VBCC__) && !defined(_MSC_VER) #elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC)
#define DUK_DOUBLE_NAN (0.0 / 0.0) #define DUK_DOUBLE_NAN (0.0 / 0.0)
#else #else
/* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN. /* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN.
@ -1218,7 +1259,7 @@ extern double duk_computed_nan;
defined(FP_SUBNORMAL) && defined(FP_NORMAL)) defined(FP_SUBNORMAL) && defined(FP_NORMAL))
/* missing some obvious constants */ /* missing some obvious constants */
#define DUK_F_USE_REPL_ALL #define DUK_F_USE_REPL_ALL
#elif defined(DUK_F_AMIGAOS) && defined(__VBCC__) #elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)
/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue) */ /* VBCC is missing the built-ins even in C99 mode (perhaps a header issue) */
#define DUK_F_USE_REPL_ALL #define DUK_F_USE_REPL_ALL
#elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG) #elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG)
@ -1268,7 +1309,7 @@ extern double duk_computed_nan;
*/ */
#if defined(DUK_F_C99) && \ #if defined(DUK_F_C99) && \
!defined(__UCLIBC__) /* uclibc may be missing these */ && \ !defined(__UCLIBC__) /* uclibc may be missing these */ && \
!(defined(DUK_F_AMIGAOS) && defined(__VBCC__)) /* vbcc + AmigaOS may be missing these */ !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)) /* vbcc + AmigaOS may be missing these */
#define DUK_USE_MATH_FMIN #define DUK_USE_MATH_FMIN
#define DUK_USE_MATH_FMAX #define DUK_USE_MATH_FMAX
#define DUK_USE_MATH_ROUND #define DUK_USE_MATH_ROUND
@ -1449,13 +1490,13 @@ typedef FILE duk_file;
* http://clang.llvm.org/docs/LanguageExtensions.html * http://clang.llvm.org/docs/LanguageExtensions.html
*/ */
#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500) #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L)
/* since gcc-2.5 */ /* since gcc-2.5 */
#define DUK_NORETURN(decl) decl __attribute__((noreturn)) #define DUK_NORETURN(decl) decl __attribute__((noreturn))
#elif defined(__clang__) #elif defined(__clang__)
/* syntax same as gcc */ /* syntax same as gcc */
#define DUK_NORETURN(decl) decl __attribute__((noreturn)) #define DUK_NORETURN(decl) decl __attribute__((noreturn))
#elif defined(_MSC_VER) #elif defined(DUK_F_MSVC)
/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */ /* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */
#define DUK_NORETURN(decl) __declspec(noreturn) decl #define DUK_NORETURN(decl) __declspec(noreturn) decl
#else #else
@ -1473,7 +1514,7 @@ typedef FILE duk_file;
* http://clang.llvm.org/docs/LanguageExtensions.html * http://clang.llvm.org/docs/LanguageExtensions.html
*/ */
#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500) #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)
/* since gcc-4.5 */ /* since gcc-4.5 */
#define DUK_UNREACHABLE() do { __builtin_unreachable(); } while(0) #define DUK_UNREACHABLE() do { __builtin_unreachable(); } while(0)
#elif defined(__clang__) && defined(__has_builtin) #elif defined(__clang__) && defined(__has_builtin)
@ -1522,7 +1563,7 @@ typedef FILE duk_file;
#endif #endif
#if defined(DUK_USE_BRANCH_HINTS) #if defined(DUK_USE_BRANCH_HINTS)
#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERISON >= 40500) #if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERISON >= 40500L)
/* GCC: test not very accurate; enable only in relatively recent builds /* GCC: test not very accurate; enable only in relatively recent builds
* because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html) * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html)
*/ */
@ -1551,7 +1592,7 @@ typedef FILE duk_file;
#define DUK_LINE_MACRO __LINE__ #define DUK_LINE_MACRO __LINE__
#if !defined(__VBCC__) && !defined(_MSC_VER) #if !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC)
#define DUK_FUNC_MACRO __func__ #define DUK_FUNC_MACRO __func__
#else #else
#define DUK_FUNC_MACRO "unknown" #define DUK_FUNC_MACRO "unknown"
@ -1738,6 +1779,12 @@ typedef FILE duk_file;
* Ecmascript features / compliance options * Ecmascript features / compliance options
*/ */
#if defined(DUK_F_BCC)
/* Math built-in is stubbed out on BCC to allow compiler torture testing. */
#else
#define DUK_USE_MATH_BUILTIN
#endif
#define DUK_USE_REGEXP_SUPPORT #define DUK_USE_REGEXP_SUPPORT
#if defined(DUK_OPT_NO_REGEXP_SUPPORT) #if defined(DUK_OPT_NO_REGEXP_SUPPORT)
#undef DUK_USE_REGEXP_SUPPORT #undef DUK_USE_REGEXP_SUPPORT

2
src/duk_heap_alloc.c

@ -69,7 +69,7 @@ void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {
DUK_DDD(DUK_DDDPRINT("free heaphdr %p, htype %d", (void *) hdr, (int) DUK_HEAPHDR_GET_TYPE(hdr))); DUK_DDD(DUK_DDDPRINT("free heaphdr %p, htype %d", (void *) hdr, (int) DUK_HEAPHDR_GET_TYPE(hdr)));
switch (DUK_HEAPHDR_GET_TYPE(hdr)) { switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(hdr)) {
case DUK_HTYPE_STRING: case DUK_HTYPE_STRING:
/* no inner refs to free */ /* no inner refs to free */
break; break;

2
src/duk_heap_markandsweep.c

@ -156,7 +156,7 @@ static void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {
heap->mark_and_sweep_recursion_depth++; heap->mark_and_sweep_recursion_depth++;
switch (DUK_HEAPHDR_GET_TYPE(h)) { switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {
case DUK_HTYPE_STRING: case DUK_HTYPE_STRING:
duk__mark_hstring(heap, (duk_hstring *) h); duk__mark_hstring(heap, (duk_hstring *) h);
break; break;

4
src/duk_heap_refcount.c

@ -144,7 +144,7 @@ static void duk__refcount_finalize_hobject(duk_hthread *thr, duk_hobject *h) {
void duk_heap_refcount_finalize_heaphdr(duk_hthread *thr, duk_heaphdr *hdr) { void duk_heap_refcount_finalize_heaphdr(duk_hthread *thr, duk_heaphdr *hdr) {
DUK_ASSERT(hdr); DUK_ASSERT(hdr);
switch (DUK_HEAPHDR_GET_TYPE(hdr)) { switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(hdr)) {
case DUK_HTYPE_OBJECT: case DUK_HTYPE_OBJECT:
duk__refcount_finalize_hobject(thr, (duk_hobject *) hdr); duk__refcount_finalize_hobject(thr, (duk_hobject *) hdr);
break; break;
@ -421,7 +421,7 @@ void duk_heap_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h) {
} }
#endif #endif
switch (DUK_HEAPHDR_GET_TYPE(h)) { switch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {
case DUK_HTYPE_STRING: case DUK_HTYPE_STRING:
/* /*
* Strings have no internal references but do have "weak" * Strings have no internal references but do have "weak"

38
src/duk_hobject_props.c

@ -1984,6 +1984,8 @@ int duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {
if (duk__get_own_property_desc_raw(thr, h_target, key, arr_idx, &desc, 1 /*push_value*/)) { if (duk__get_own_property_desc_raw(thr, h_target, key, arr_idx, &desc, 1 /*push_value*/)) {
duk_tval *tv_hook = duk_require_tval(ctx, -3); /* value from hook */ duk_tval *tv_hook = duk_require_tval(ctx, -3); /* value from hook */
duk_tval *tv_targ = duk_require_tval(ctx, -1); /* value from target */ duk_tval *tv_targ = duk_require_tval(ctx, -1); /* value from target */
int datadesc_reject;
int accdesc_reject;
DUK_DDD(DUK_DDDPRINT("proxy 'get': target has matching property %!O, check for " DUK_DDD(DUK_DDDPRINT("proxy 'get': target has matching property %!O, check for "
"conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08x, " "conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08x, "
@ -1991,14 +1993,14 @@ int duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {
key, tv_hook, tv_targ, (int) desc.flags, key, tv_hook, tv_targ, (int) desc.flags,
(void *) desc.get, (void *) desc.set)); (void *) desc.get, (void *) desc.set));
int datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
!(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) && !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&
!duk_js_samevalue(tv_hook, tv_targ); !duk_js_samevalue(tv_hook, tv_targ);
int accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
!(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
(desc.get == NULL) && (desc.get == NULL) &&
!DUK_TVAL_IS_UNDEFINED(tv_hook); !DUK_TVAL_IS_UNDEFINED(tv_hook);
if (datadesc_reject || accdesc_reject) { if (datadesc_reject || accdesc_reject) {
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "proxy get rejected"); DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "proxy get rejected");
} }
@ -2769,6 +2771,8 @@ int duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, du
if (duk__get_own_property_desc_raw(thr, h_target, key, arr_idx, &desc, 1 /*push_value*/)) { if (duk__get_own_property_desc_raw(thr, h_target, key, arr_idx, &desc, 1 /*push_value*/)) {
duk_tval *tv_targ = duk_require_tval(ctx, -1); duk_tval *tv_targ = duk_require_tval(ctx, -1);
int datadesc_reject;
int accdesc_reject;
DUK_DDD(DUK_DDDPRINT("proxy 'set': target has matching property %!O, check for " DUK_DDD(DUK_DDDPRINT("proxy 'set': target has matching property %!O, check for "
"conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08x, " "conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08x, "
@ -2776,13 +2780,13 @@ int duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, du
key, tv_val, tv_targ, (int) desc.flags, key, tv_val, tv_targ, (int) desc.flags,
(void *) desc.get, (void *) desc.set)); (void *) desc.get, (void *) desc.set));
int datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && datadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
!(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) && !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&
!duk_js_samevalue(tv_val, tv_targ); !duk_js_samevalue(tv_val, tv_targ);
int accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) && accdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&
!(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&
(desc.set == NULL); (desc.set == NULL);
if (datadesc_reject || accdesc_reject) { if (datadesc_reject || accdesc_reject) {
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "proxy set rejected"); DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "proxy set rejected");
} }
@ -3606,12 +3610,14 @@ int duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, in
DUK_ASSERT(key != NULL); DUK_ASSERT(key != NULL);
if (duk__get_own_property_desc_raw(thr, h_target, key, arr_idx, &desc, 0 /*push_value*/)) { if (duk__get_own_property_desc_raw(thr, h_target, key, arr_idx, &desc, 0 /*push_value*/)) {
int desc_reject;
DUK_DDD(DUK_DDDPRINT("proxy 'deleteProperty': target has matching property %!O, check for " DUK_DDD(DUK_DDDPRINT("proxy 'deleteProperty': target has matching property %!O, check for "
"conflicting property; desc.flags=0x%08x, " "conflicting property; desc.flags=0x%08x, "
"desc.get=%p, desc.set=%p", "desc.get=%p, desc.set=%p",
key, (int) desc.flags, (void *) desc.get, (void *) desc.set)); key, (int) desc.flags, (void *) desc.get, (void *) desc.set));
int desc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE); desc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE);
if (desc_reject) { if (desc_reject) {
/* unconditional */ /* unconditional */
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "proxy deleteProperty rejected"); DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "proxy deleteProperty rejected");

6
src/duk_js_executor.c

@ -756,8 +756,8 @@ static int duk__handle_longjmp(duk_hthread *thr,
DUK_HOBJECT_IS_COMPILEDFUNCTION((resumee->callstack + resumee->callstack_top - 2)->func))); /* an Ecmascript function */ DUK_HOBJECT_IS_COMPILEDFUNCTION((resumee->callstack + resumee->callstack_top - 2)->func))); /* an Ecmascript function */
DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED || DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||
(resumee->callstack + resumee->callstack_top - 2)->idx_retval >= 0); /* waiting for a value */ (resumee->callstack + resumee->callstack_top - 2)->idx_retval >= 0); /* waiting for a value */
DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE || /* INACTIVE: no activation, single function value on valstack */ DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE ||
resumee->callstack_top == 0); resumee->callstack_top == 0); /* INACTIVE: no activation, single function value on valstack */
DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE || DUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE ||
(resumee->valstack_top == resumee->valstack + 1 && (resumee->valstack_top == resumee->valstack + 1 &&
DUK_TVAL_IS_OBJECT(resumee->valstack_top - 1) && DUK_TVAL_IS_OBJECT(resumee->valstack_top - 1) &&
@ -1656,7 +1656,7 @@ void duk_js_execute_bytecode(duk_hthread *entry_thread) {
ins = bcode[act->pc++]; ins = bcode[act->pc++];
switch (DUK_DEC_OP(ins)) { switch ((duk_small_int_t) DUK_DEC_OP(ins)) {
case DUK_OP_LDREG: { case DUK_OP_LDREG: {
int t; int t;

2
src/duk_replacements.c

@ -6,6 +6,8 @@
* mimics the standard prototypes. * mimics the standard prototypes.
*/ */
#include "duk_internal.h"
#ifdef DUK_USE_COMPUTED_NAN #ifdef DUK_USE_COMPUTED_NAN
double duk_computed_nan; double duk_computed_nan;
#endif #endif

5
src/genbuiltins.py

@ -1443,7 +1443,10 @@ class GenBuiltins:
genc.emitLine('/* native functions: %d */' % len(self.native_func_list)) genc.emitLine('/* native functions: %d */' % len(self.native_func_list))
genc.emitLine('const duk_c_function duk_bi_native_functions[] = {') genc.emitLine('const duk_c_function duk_bi_native_functions[] = {')
for i in self.native_func_list: for i in self.native_func_list:
genc.emitLine('\t(duk_c_function) %s,' % i) # The function pointer cast here makes BCC complain about
# "initializer too complicated", so omit the cast.
#genc.emitLine('\t(duk_c_function) %s,' % i)
genc.emitLine('\t%s,' % i)
genc.emitLine('};') genc.emitLine('};')
def generateDefineNames(self, id): def generateDefineNames(self, id):

7
website/guide/portability.html

@ -177,6 +177,13 @@ detail below the table.</p>
32-bit Java. Tested with <a href="http://adobe-flash.github.io/crossbridge/">CrossBridge</a> 32-bit Java. Tested with <a href="http://adobe-flash.github.io/crossbridge/">CrossBridge</a>
1.0.1 on 64-bit Windows 7.</td> 1.0.1 on 64-bit Windows 7.</td>
</tr> </tr>
<tr>
<td>Linux</td>
<td>BCC<br />(Bruce's C compiler)</td>
<td>i386</td>
<td><code>-3</code> and <code>-ansi</code> required; compiles but doesn't link. This is an
old compiler useful for portability torture tests (for instance 16-bit integers).</td>
</tr>
</tbody> </tbody>
</table> </table>

Loading…
Cancel
Save