Be a bit more explicit about uses of the struct hack.

This commit is contained in:
Bob Nystrom 2015-01-23 10:38:12 -08:00
parent cda727a18d
commit 94080a0e96
3 changed files with 36 additions and 24 deletions

View File

@ -27,7 +27,7 @@
// Enabling this speeds up the main dispatch loop a bit, but requires compiler // Enabling this speeds up the main dispatch loop a bit, but requires compiler
// support. // support.
// //
// Defaults to on. // Defaults to on on supported compilers.
#ifndef WREN_COMPUTED_GOTO #ifndef WREN_COMPUTED_GOTO
#ifdef _MSC_VER #ifdef _MSC_VER
// No computed gotos in Visual Studio. // No computed gotos in Visual Studio.
@ -94,6 +94,23 @@
// field index*. // field index*.
#define MAX_FIELDS 255 #define MAX_FIELDS 255
// The Microsoft compiler does not support the "inline" modifier when compiling
// as plain C.
#if defined( _MSC_VER ) && !defined(__cplusplus)
#define inline _inline
#endif
// This is used to clearly mark flexible-sized arrays that appear at the end of
// some dynamically-allocated structs, known as the "struct hack".
#if __STDC_VERSION__ >= 199901L
// In C99, a flexible array member is just "[]".
#define FLEXIBLE_ARRAY
#else
// Elsewhere, use a zero-sized array. It's technically undefined behavior, but
// works reliably in most known compilers.
#define FLEXIBLE_ARRAY 0
#endif
// Assertions are used to validate program invariants. They indicate things the // Assertions are used to validate program invariants. They indicate things the
// program expects to be true about its internal state during execution. If an // program expects to be true about its internal state during execution. If an
// assertion fails, there is a bug in Wren. // assertion fails, there is a bug in Wren.
@ -104,26 +121,26 @@
#include <stdio.h> #include <stdio.h>
#define ASSERT(condition, message) \ #define ASSERT(condition, message) \
do \ do \
{ \
if (!(condition)) \
{ \ { \
fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \ if (!(condition)) \
__FILE__, __LINE__, __func__, message); \ { \
abort(); \ fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \
__FILE__, __LINE__, __func__, message); \
abort(); \
} \
} \ } \
} \ while(0)
while(0)
// Assertion to indicate that the given point in the code should never be // Assertion to indicate that the given point in the code should never be
// reached. // reached.
#define UNREACHABLE() \ #define UNREACHABLE() \
do \ do \
{ \ { \
fprintf(stderr, "This line should not be reached.\n"); \ fprintf(stderr, "This line should not be reached.\n"); \
abort(); \ abort(); \
} \ } \
while (0) while (0)
#else #else
@ -132,10 +149,4 @@
#endif #endif
// The Microsoft compiler does not sport the "inline" modifier when
// compiling in plain-C
#if defined( _MSC_VER ) && !defined(__cplusplus)
#define inline _inline
#endif
#endif #endif

View File

@ -2808,6 +2808,7 @@ void definition(Compiler* compiler)
classDefinition(compiler); classDefinition(compiler);
return; return;
} }
if (match(compiler, TOKEN_VAR)) { if (match(compiler, TOKEN_VAR)) {
variableDefinition(compiler); variableDefinition(compiler);
return; return;

View File

@ -112,7 +112,7 @@ typedef struct
Obj obj; Obj obj;
// Does not include the null terminator. // Does not include the null terminator.
int length; int length;
char value[0]; char value[FLEXIBLE_ARRAY];
} ObjString; } ObjString;
// The dynamically allocated data structure for a variable that has been used // The dynamically allocated data structure for a variable that has been used
@ -260,7 +260,7 @@ typedef struct
ObjFn* fn; ObjFn* fn;
// The upvalues this function has closed over. // The upvalues this function has closed over.
Upvalue* upvalues[0]; Upvalue* upvalues[FLEXIBLE_ARRAY];
} ObjClosure; } ObjClosure;
typedef enum typedef enum
@ -323,7 +323,7 @@ struct sObjClass
typedef struct typedef struct
{ {
Obj obj; Obj obj;
Value fields[0]; Value fields[FLEXIBLE_ARRAY];
} ObjInstance; } ObjInstance;
typedef struct typedef struct