forked from cesanta/v7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinternal.h
320 lines (263 loc) · 8.22 KB
/
internal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
#ifndef V7_INTERNAL_H_INCLUDED
#define V7_INTERNAL_H_INCLUDED
#include "license.h"
/* Check whether we're compiling in an environment with no filesystem */
#if defined(ARDUINO) && (ARDUINO == 106)
#define V7_NO_FS
#endif
/*
* In some compilers (watcom) NAN == NAN (and other comparisons) don't follow
* the rules of IEEE 754. Since we don't know a priori which compilers
* will generate correct code, we disable the fallback on selected platforms.
* TODO(mkm): selectively disable on clang/gcc once we test this out.
*/
#define V7_BROKEN_NAN
#ifdef __GNUC__
#define NORETURN __attribute__((noreturn))
#define UNUSED __attribute__((unused))
#else
#define NORETURN
#define UNUSED
#endif
/*
* DO NOT SUBMIT: remove this when adding support
* for predefined strings as roots
*/
#define V7_DISABLE_PREDEFINED_STRINGS
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
/* Public API. Implemented in api.c */
#include "../v7.h"
#ifdef V7_WINDOWS
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#define isnan(x) _isnan(x)
#define isinf(x) (!_finite(x))
#define __unused
typedef __int64 int64_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef unsigned long uintptr_t;
#define __func__ ""
#else
#include <stdint.h>
#endif
#include "v7_features.h"
/* Private API */
#include "utf.h"
#include "mbuf.h"
#include "tokenizer.h"
#include "slre.h"
#include "varint.h"
#include "ast.h"
#include "parser.h"
#include "mm.h"
/* Max captures for String.replace() */
#define V7_RE_MAX_REPL_SUB 255
/* MSVC6 doesn't have standard C math constants defined */
#ifndef M_E
#define M_E 2.71828182845904523536028747135266250
#endif
#ifndef M_LOG2E
#define M_LOG2E 1.44269504088896340735992468100189214
#endif
#ifndef M_LOG10E
#define M_LOG10E 0.434294481903251827651128918916605082
#endif
#ifndef M_LN2
#define M_LN2 0.693147180559945309417232121458176568
#endif
#ifndef M_LN10
#define M_LN10 2.30258509299404568401799145468436421
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
#ifndef M_SQRT2
#define M_SQRT2 1.41421356237309504880168872420969808
#endif
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.707106781186547524400844362104849039
#endif
#ifndef NAN
extern double _v7_nan;
#define HAS_V7_NAN
#define NAN (_v7_nan)
#endif
#ifndef INFINITY
extern double _v7_infinity;
#define HAS_V7_INFINITY
#define INFINITY (_v7_infinity)
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
/* TODO(lsm): move VM definitions to vm.h */
#ifndef VM_H_INCLUDED
#define V7_VALUE_DEFINED
typedef uint64_t val_t;
#endif
/*
* JavaScript value is either a primitive, or an object.
* There are 5 primitive types: Undefined, Null, Boolean, Number, String.
* Non-primitive type is an Object type. There are several classes of Objects,
* see description of `struct v7_object` below for more details.
* This enumeration combines types and object classes in one enumeration.
* NOTE(lsm): compile with `-fshort-enums` to reduce sizeof(enum v7_type) to 1.
*/
enum v7_type {
/* Primitive types */
V7_TYPE_UNDEFINED,
V7_TYPE_NULL,
V7_TYPE_BOOLEAN,
V7_TYPE_NUMBER,
V7_TYPE_STRING,
V7_TYPE_FOREIGN,
V7_TYPE_CFUNCTION,
/* Different classes of Object type */
V7_TYPE_GENERIC_OBJECT,
V7_TYPE_BOOLEAN_OBJECT,
V7_TYPE_STRING_OBJECT,
V7_TYPE_NUMBER_OBJECT,
V7_TYPE_FUNCTION_OBJECT,
V7_TYPE_CFUNCTION_OBJECT,
V7_TYPE_REGEXP_OBJECT,
V7_TYPE_ARRAY_OBJECT,
V7_TYPE_DATE_OBJECT,
V7_TYPE_ERROR_OBJECT,
V7_TYPE_MAX_OBJECT_TYPE,
V7_NUM_TYPES
};
enum cached_strings {
PREDEFINED_STR_LENGTH,
PREDEFINED_STR_PROTOTYPE,
PREDEFINED_STR_CONSTRUCTOR,
PREDEFINED_STR_ARGUMENTS,
PREDEFINED_STR_MAX
};
enum error_ctor {
TYPE_ERROR,
SYNTAX_ERROR,
REFERENCE_ERROR,
INTERNAL_ERROR,
RANGE_ERROR,
ERROR_CTOR_MAX
};
#include "vm.h"
struct v7 {
val_t global_object;
val_t this_object;
val_t object_prototype;
val_t array_prototype;
val_t boolean_prototype;
val_t error_prototype;
val_t string_prototype;
val_t regexp_prototype;
val_t number_prototype;
val_t date_prototype;
val_t function_prototype;
/*
* Stack of execution contexts.
* Each execution context object in the call stack has hidden properties:
* * "_p": Parent context (for closures)
* * "_e": Exception environment
*
* Hidden properties have V7_PROPERTY_HIDDEN flag set.
* Execution contexts should be allocated on heap, because they might not be
* on a call stack but still referenced (closures).
*/
val_t call_stack;
struct mbuf owned_strings; /* Sequence of (varint len, char data[]) */
struct mbuf foreign_strings; /* Sequence of (varint len, char *data) */
struct mbuf tmp_stack; /* Stack of val_t* elements, used as root set */
struct gc_arena object_arena;
struct gc_arena function_arena;
struct gc_arena property_arena;
int strict_mode; /* true if currently in strict mode */
val_t error_objects[ERROR_CTOR_MAX];
val_t thrown_error;
char error_msg[60]; /* Exception message */
int creating_exception; /* Avoids reentrant exception creation */
#if defined(__cplusplus)
::jmp_buf jmp_buf;
::jmp_buf label_jmp_buf;
#else
jmp_buf jmp_buf; /* Exception environment for v7_exec() */
jmp_buf label_jmp_buf; /* Target for non local (labeled) breaks */
#endif
char *label; /* Inner label */
size_t label_len; /* Inner label length */
int lab_cont; /* True if re-entering a loop with labeled continue */
struct mbuf json_visited_stack; /* Detecting cycle in to_json */
/* Parser state */
struct v7_pstate pstate; /* Parsing state */
enum v7_tok cur_tok; /* Current token */
const char *tok; /* Parsed terminal token (ident, number, string) */
unsigned long tok_len; /* Length of the parsed terminal token */
size_t last_var_node; /* Offset of last var node or function/script node */
int after_newline; /* True if the cur_tok starts a new line */
double cur_tok_dbl; /* When tokenizing, parser stores TOK_NUMBER here */
/* TODO(mkm): remove when AST are GC-ed */
struct mbuf allocated_asts;
val_t predefined_strings[PREDEFINED_STR_MAX];
/* singleton, pointer because of amalgamation */
struct v7_property *cur_dense_prop;
};
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#endif
#define V7_STATIC_ASSERT(COND, MSG) \
typedef char static_assertion_##MSG[2 * (!!(COND)) - 1]
#ifndef NDEBUG
#define V7_CHECK(v7, COND) \
do { \
if (!(COND)) \
throw_exception(v7, INTERNAL_ERROR, "%s line %d: %s", __func__, \
__LINE__, #COND); \
} while (0)
#else
#define V7_CHECK(v7, COND) \
do { \
if (!(COND)) throw_exception(v7, INTERNAL_ERROR, "line %d", __LINE__); \
} while (0)
#endif
#define TRACE_VAL(v7, val) \
do { \
char buf[200], *p = v7_to_json(v7, val, buf, sizeof(buf)); \
printf("%s %d: [%s]\n", __func__, __LINE__, p); \
if (p != buf) free(p); \
} while (0)
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
V7_PRIVATE void throw_value(struct v7 *, val_t) NORETURN;
V7_PRIVATE void throw_exception(struct v7 *, enum error_ctor, const char *,
...) NORETURN;
V7_PRIVATE size_t unescape(const char *s, size_t len, char *to);
V7_PRIVATE void init_js_stdlib(struct v7 *);
V7_PRIVATE val_t Regex_ctor(struct v7 *v7, val_t this_obj, val_t args);
V7_PRIVATE val_t rx_exec(struct v7 *v7, val_t rx, val_t str, int lind);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* V7_INTERNAL_H_INCLUDED */