• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/include/ucode/types.h

  1 /*
  2  * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
  3  *
  4  * Permission to use, copy, modify, and/or distribute this software for any
  5  * purpose with or without fee is hereby granted, provided that the above
  6  * copyright notice and this permission notice appear in all copies.
  7  *
  8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15  */
 16 
 17 #ifndef UCODE_TYPES_H
 18 #define UCODE_TYPES_H
 19 
 20 #include <stdbool.h>
 21 #include <stdint.h>
 22 #include <regex.h>
 23 #include <json-c/json.h>
 24 
 25 #include "util.h"
 26 
 27 
 28 /* Value types and generic value header */
 29 
 30 typedef enum uc_type {
 31         UC_NULL,
 32         UC_INTEGER,
 33         UC_BOOLEAN,
 34         UC_STRING,
 35         UC_DOUBLE,
 36         UC_ARRAY,
 37         UC_OBJECT,
 38         UC_REGEXP,
 39         UC_CFUNCTION,
 40         UC_CLOSURE,
 41         UC_UPVALUE,
 42         UC_RESOURCE,
 43         UC_PROGRAM,
 44         UC_SOURCE
 45 } uc_type_t;
 46 
 47 typedef struct uc_value {
 48         uint32_t type:4;
 49         uint32_t mark:1;
 50         uint32_t u64:1;
 51         uint32_t refcount:26;
 52 } uc_value_t;
 53 
 54 
 55 /* Constant list defintions */
 56 
 57 typedef struct {
 58         size_t isize;
 59         size_t dsize;
 60         uint64_t *index;
 61         char *data;
 62 } uc_value_list_t;
 63 
 64 
 65 /* Source buffer defintions */
 66 
 67 uc_declare_vector(uc_lineinfo_t, uint8_t);
 68 
 69 typedef struct {
 70         uc_value_t header;
 71         char *filename, *runpath, *buffer;
 72         FILE *fp;
 73         size_t off;
 74         uc_lineinfo_t lineinfo;
 75 } uc_source_t;
 76 
 77 
 78 /* Bytecode chunk defintions */
 79 
 80 typedef struct {
 81         size_t from, to, target, slot;
 82 } uc_ehrange_t;
 83 
 84 typedef struct {
 85         size_t from, to, slot, nameidx;
 86 } uc_varrange_t;
 87 
 88 uc_declare_vector(uc_ehranges_t, uc_ehrange_t);
 89 uc_declare_vector(uc_variables_t, uc_varrange_t);
 90 uc_declare_vector(uc_offsetinfo_t, uint8_t);
 91 
 92 typedef struct {
 93         size_t count;
 94         uint8_t *entries;
 95         uc_ehranges_t ehranges;
 96         struct {
 97                 uc_variables_t variables;
 98                 uc_value_list_t varnames;
 99                 uc_offsetinfo_t offsets;
100         } debuginfo;
101 } uc_chunk_t;
102 
103 
104 /* Value type structures */
105 
106 typedef struct uc_weakref {
107         struct uc_weakref *prev;
108         struct uc_weakref *next;
109 } uc_weakref_t;
110 
111 typedef struct uc_function {
112         uc_weakref_t progref;
113         bool arrow, vararg, strict;
114         size_t nargs;
115         size_t nupvals;
116         size_t srcpos;
117         uc_chunk_t chunk;
118         struct uc_program *program;
119         char name[];
120 } uc_function_t;
121 
122 typedef struct {
123         uc_value_t header;
124         double dbl;
125 } uc_double_t;
126 
127 typedef struct {
128         uc_value_t header;
129         union {
130                 int64_t s64;
131                 uint64_t u64;
132         } i;
133 } uc_integer_t;
134 
135 typedef struct {
136         uc_value_t header;
137         size_t length;
138         char str[];
139 } uc_string_t;
140 
141 typedef struct {
142         uc_value_t header;
143         uc_weakref_t ref;
144         size_t count;
145         uc_value_t *proto;
146         uc_value_t **entries;
147 } uc_array_t;
148 
149 typedef struct {
150         uc_value_t header;
151         uc_weakref_t ref;
152         uc_value_t *proto;
153         struct lh_table *table;
154 } uc_object_t;
155 
156 typedef struct {
157         uc_value_t header;
158         regex_t regexp;
159         bool icase, newline, global;
160         char source[];
161 } uc_regexp_t;
162 
163 typedef struct uc_upval_tref {
164         uc_value_t header;
165         size_t slot;
166         bool closed;
167         uc_value_t *value;
168         struct uc_upval_tref *next;
169 } uc_upvalref_t;
170 
171 typedef struct {
172         uc_value_t header;
173         uc_weakref_t ref;
174         bool is_arrow;
175         uc_function_t *function;
176         uc_upvalref_t **upvals;
177 } uc_closure_t;
178 
179 typedef struct uc_vm uc_vm_t;
180 typedef uc_value_t *(*uc_cfn_ptr_t)(uc_vm_t *, size_t);
181 
182 typedef struct {
183         uc_value_t header;
184         uc_cfn_ptr_t cfn;
185         char name[];
186 } uc_cfunction_t;
187 
188 typedef struct {
189         const char *name;
190         uc_value_t *proto;
191         void (*free)(void *);
192 } uc_resource_type_t;
193 
194 typedef struct {
195         uc_value_t header;
196         uc_resource_type_t *type;
197         void *data;
198 } uc_resource_t;
199 
200 uc_declare_vector(uc_resource_types_t, uc_resource_type_t *);
201 
202 
203 /* Program structure definitions */
204 
205 typedef struct uc_program {
206         uc_value_t header;
207         uc_value_list_t constants;
208         uc_weakref_t functions;
209         uc_source_t *source;
210 } uc_program_t;
211 
212 
213 /* Parser definitions */
214 
215 typedef struct {
216         bool lstrip_blocks;
217         bool trim_blocks;
218         bool strict_declarations;
219         bool raw_mode;
220 } uc_parse_config_t;
221 
222 
223 /* VM definitions */
224 
225 typedef enum {
226         EXCEPTION_NONE,
227         EXCEPTION_SYNTAX,
228         EXCEPTION_RUNTIME,
229         EXCEPTION_TYPE,
230         EXCEPTION_REFERENCE,
231         EXCEPTION_USER,
232         EXCEPTION_EXIT
233 } uc_exception_type_t;
234 
235 typedef struct {
236         uc_exception_type_t type;
237         uc_value_t *stacktrace;
238         char *message;
239 } uc_exception_t;
240 
241 typedef struct {
242         uint8_t *ip;
243         uc_closure_t *closure;
244         uc_cfunction_t *cfunction;
245         size_t stackframe;
246         uc_value_t *ctx;
247         bool mcall, strict;
248 } uc_callframe_t;
249 
250 uc_declare_vector(uc_callframes_t, uc_callframe_t);
251 uc_declare_vector(uc_stack_t, uc_value_t *);
252 
253 typedef struct printbuf uc_stringbuf_t;
254 
255 typedef void (uc_exception_handler_t)(uc_vm_t *, uc_exception_t *);
256 
257 struct uc_vm {
258         uc_stack_t stack;
259         uc_exception_t exception;
260         uc_callframes_t callframes;
261         uc_upvalref_t *open_upvals;
262         uc_parse_config_t *config;
263         uc_value_t *globals;
264         uc_value_t *registry;
265         uc_source_t *sources;
266         uc_weakref_t values;
267         uc_resource_types_t restypes;
268         union {
269                 uint32_t u32;
270                 int32_t s32;
271                 uint16_t u16;
272                 int16_t s16;
273                 uint8_t u8;
274                 int8_t s8;
275         } arg;
276         size_t spread_values;
277         uint8_t trace;
278         uc_stringbuf_t *strbuf;
279         uc_exception_handler_t *exhandler;
280         FILE *output;
281 };
282 
283 
284 /* Value API */
285 
286 void ucv_free(uc_value_t *, bool);
287 void ucv_put(uc_value_t *);
288 
289 void ucv_unref(uc_weakref_t *);
290 void ucv_ref(uc_weakref_t *, uc_weakref_t *);
291 
292 uc_value_t *ucv_get(uc_value_t *uv);
293 
294 uc_type_t ucv_type(uc_value_t *);
295 const char *ucv_typename(uc_value_t *);
296 
297 uc_value_t *ucv_boolean_new(bool);
298 bool ucv_boolean_get(uc_value_t *);
299 
300 uc_value_t *ucv_string_new(const char *);
301 uc_value_t *ucv_string_new_length(const char *, size_t);
302 size_t ucv_string_length(uc_value_t *);
303 
304 char *_ucv_string_get(uc_value_t **);
305 #define ucv_string_get(uv) _ucv_string_get((uc_value_t **)&uv)
306 
307 uc_stringbuf_t *ucv_stringbuf_new(void);
308 uc_value_t *ucv_stringbuf_finish(uc_stringbuf_t *);
309 
310 void _ucv_stringbuf_append(uc_stringbuf_t *, const char *, size_t);
311 
312 #define _ucv_is_literal(str) ("" str)
313 #define ucv_stringbuf_append(buf, str) _ucv_stringbuf_append(buf, _ucv_is_literal(str), sizeof(str) - 1)
314 #define ucv_stringbuf_addstr(buf, str, len) _ucv_stringbuf_append(buf, str, len)
315 #define ucv_stringbuf_printf(buf, fmt, ...) sprintbuf(buf, fmt, __VA_ARGS__)
316 
317 uc_value_t *ucv_int64_new(int64_t);
318 uc_value_t *ucv_uint64_new(uint64_t);
319 int64_t ucv_int64_get(uc_value_t *);
320 uint64_t ucv_uint64_get(uc_value_t *);
321 
322 uc_value_t *ucv_double_new(double);
323 double ucv_double_get(uc_value_t *);
324 
325 uc_value_t *ucv_array_new(uc_vm_t *);
326 uc_value_t *ucv_array_new_length(uc_vm_t *, size_t);
327 uc_value_t *ucv_array_get(uc_value_t *, size_t);
328 uc_value_t *ucv_array_pop(uc_value_t *);
329 uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *);
330 uc_value_t *ucv_array_shift(uc_value_t *);
331 uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *);
332 void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *));
333 bool ucv_array_delete(uc_value_t *, size_t, size_t);
334 bool ucv_array_set(uc_value_t *, size_t, uc_value_t *);
335 size_t ucv_array_length(uc_value_t *);
336 
337 uc_value_t *ucv_object_new(uc_vm_t *);
338 uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *);
339 bool ucv_object_add(uc_value_t *, const char *, uc_value_t *);
340 bool ucv_object_delete(uc_value_t *, const char *);
341 size_t ucv_object_length(uc_value_t *);
342 
343 #define ucv_object_foreach(obj, key, val)                                                                                                               \
344         char *key = NULL;                                                                                                                                                       \
345         uc_value_t *val = NULL;                                                                                                                                         \
346         struct lh_entry *entry##key;                                                                                                                            \
347         struct lh_entry *entry_next##key = NULL;                                                                                                        \
348         for (entry##key = (ucv_type(obj) == UC_OBJECT) ? ((uc_object_t *)obj)->table->head : NULL;      \
349              (entry##key ? (key = (char *)lh_entry_k(entry##key),                                                                       \
350                             val = (uc_value_t *)lh_entry_v(entry##key),                                                         \
351                             entry_next##key = entry##key->next, entry##key)                                                     \
352                          : 0);                                                                                                                                          \
353              entry##key = entry_next##key)
354 
355 uc_value_t *ucv_cfunction_new(const char *, uc_cfn_ptr_t);
356 
357 uc_value_t *ucv_closure_new(uc_vm_t *, uc_function_t *, bool);
358 
359 uc_resource_type_t *ucv_resource_type_add(uc_vm_t *, const char *, uc_value_t *, void (*)(void *));
360 uc_resource_type_t *ucv_resource_type_lookup(uc_vm_t *, const char *);
361 
362 uc_value_t *ucv_resource_new(uc_resource_type_t *, void *);
363 void **ucv_resource_dataptr(uc_value_t *, const char *);
364 
365 uc_value_t *ucv_regexp_new(const char *, bool, bool, bool, char **);
366 
367 uc_value_t *ucv_upvalref_new(size_t);
368 
369 uc_value_t *ucv_prototype_get(uc_value_t *);
370 bool ucv_prototype_set(uc_value_t *, uc_value_t *);
371 
372 uc_value_t *ucv_property_get(uc_value_t *, const char *);
373 
374 uc_value_t *ucv_from_json(uc_vm_t *, json_object *);
375 json_object *ucv_to_json(uc_value_t *);
376 
377 char *ucv_to_string(uc_vm_t *, uc_value_t *);
378 char *ucv_to_jsonstring_formatted(uc_vm_t *, uc_value_t *, char, size_t);
379 void ucv_to_stringbuf_formatted(uc_vm_t *, uc_stringbuf_t *, uc_value_t *, size_t, char, size_t);
380 
381 #define ucv_to_jsonstring(vm, val) ucv_to_jsonstring_formatted(vm, val, '\1', 0)
382 #define ucv_to_stringbuf(vm, buf, val, json) ucv_to_stringbuf_formatted(vm, buf, val, 0, json ? '\1' : '\0', 0)
383 
384 uc_type_t ucv_cast_number(uc_value_t *, int64_t *, double *);
385 
386 uc_value_t *ucv_to_number(uc_value_t *);
387 
388 static inline double
389 ucv_to_double(uc_value_t *v)
390 {
391         uc_value_t *nv;
392         double d;
393 
394         nv = ucv_to_number(v);
395         d = ucv_double_get(nv);
396         ucv_put(nv);
397 
398         return d;
399 }
400 
401 static inline int64_t
402 ucv_to_integer(uc_value_t *v)
403 {
404         uc_value_t *nv;
405         int64_t n;
406 
407         nv = ucv_to_number(v);
408         n = ucv_int64_get(nv);
409         ucv_put(nv);
410 
411         return n;
412 }
413 
414 static inline uint64_t
415 ucv_to_unsigned(uc_value_t *v)
416 {
417         uc_value_t *nv;
418         uint64_t u;
419 
420         nv = ucv_to_number(v);
421         u = ucv_uint64_get(nv);
422         ucv_put(nv);
423 
424         return u;
425 }
426 
427 static inline bool
428 ucv_is_callable(uc_value_t *uv)
429 {
430         switch (ucv_type(uv)) {
431         case UC_CLOSURE:
432         case UC_CFUNCTION:
433                 return true;
434 
435         default:
436                 return false;
437         }
438 }
439 
440 static inline bool
441 ucv_is_arrowfn(uc_value_t *uv)
442 {
443         uc_closure_t *closure = (uc_closure_t *)uv;
444 
445         return (ucv_type(uv) == UC_CLOSURE && closure->is_arrow);
446 }
447 
448 static inline bool
449 ucv_is_u64(uc_value_t *uv)
450 {
451         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64 == true);
452 }
453 
454 static inline bool
455 ucv_is_scalar(uc_value_t *uv)
456 {
457         switch (ucv_type(uv)) {
458         case UC_NULL:
459         case UC_BOOLEAN:
460         case UC_DOUBLE:
461         case UC_INTEGER:
462         case UC_STRING:
463                 return true;
464 
465         default:
466                 return false;
467         }
468 }
469 
470 bool ucv_is_equal(uc_value_t *, uc_value_t *);
471 bool ucv_is_truish(uc_value_t *);
472 
473 bool ucv_compare(int, uc_value_t *, uc_value_t *, int *);
474 
475 uc_value_t *ucv_key_get(uc_vm_t *, uc_value_t *, uc_value_t *);
476 uc_value_t *ucv_key_set(uc_vm_t *, uc_value_t *, uc_value_t *, uc_value_t *);
477 bool ucv_key_delete(uc_vm_t *, uc_value_t *, uc_value_t *);
478 
479 
480 static inline bool
481 ucv_is_marked(uc_value_t *uv)
482 {
483         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->mark == true);
484 }
485 
486 static inline void
487 ucv_set_mark(uc_value_t *uv)
488 {
489         if (((uintptr_t)uv & 3) == 0 && uv != NULL)
490                 uv->mark = true;
491 }
492 
493 static inline void
494 ucv_clear_mark(uc_value_t *uv)
495 {
496         if (((uintptr_t)uv & 3) == 0 && uv != NULL)
497                 uv->mark = false;
498 }
499 
500 void ucv_gc(uc_vm_t *);
501 
502 void ucv_freeall(uc_vm_t *);
503 
504 #endif /* UCODE_TYPES_H */
505 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt