]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/code.h
canvas::Layout: support for contents margins.
[simgear.git] / simgear / nasal / code.h
1 #ifndef _CODE_H
2 #define _CODE_H
3
4 #include <setjmp.h>
5 #include "nasal.h"
6 #include "data.h"
7
8 #define MAX_STACK_DEPTH 512
9 #define MAX_RECURSION 128
10 #define MAX_MARK_DEPTH 128
11
12 // Number of objects (per pool per thread) asked for using naGC_get().
13 // The idea is that contexts can "cache" allocations to prevent thread
14 // contention on the global pools.  But in practice this interacts
15 // very badly with small subcontext calls, which grab huge numbers of
16 // cached objects and don't use them, causing far more collections
17 // than necessary.  Just leave it at 1 pending a rework of the
18 // collector synchronization.
19 #define OBJ_CACHE_SZ 1
20
21 enum {    
22     OP_NOT, OP_MUL, OP_PLUS, OP_MINUS, OP_DIV, OP_NEG, OP_CAT, OP_LT, OP_LTE,
23     OP_GT, OP_GTE, OP_EQ, OP_NEQ, OP_EACH, OP_JMP, OP_JMPLOOP, OP_JIFNOTPOP,
24     OP_JIFEND, OP_FCALL, OP_MCALL, OP_RETURN, OP_PUSHCONST, OP_PUSHONE,
25     OP_PUSHZERO, OP_PUSHNIL, OP_POP, OP_DUP, OP_XCHG, OP_INSERT, OP_EXTRACT,
26     OP_MEMBER, OP_SETMEMBER, OP_LOCAL, OP_SETLOCAL, OP_NEWVEC, OP_VAPPEND,
27     OP_NEWHASH, OP_HAPPEND, OP_MARK, OP_UNMARK, OP_BREAK, OP_SETSYM, OP_DUP2,
28     OP_INDEX, OP_BREAK2, OP_PUSHEND, OP_JIFTRUE, OP_JIFNOT, OP_FCALLH,
29     OP_MCALLH, OP_XCHG2, OP_UNPACK, OP_SLICE, OP_SLICE2, OP_BIT_AND, OP_BIT_OR,
30     OP_BIT_XOR, OP_BIT_NEG
31 };
32
33 struct Frame {
34     naRef func; // naFunc object
35     naRef locals; // local per-call namespace
36     int ip; // instruction pointer into code
37     int bp; // opStack pointer to start of frame
38 };
39
40 struct Globals {
41     // Garbage collecting allocators:
42     struct naPool pools[NUM_NASAL_TYPES];
43     int allocCount;
44
45     // Dead blocks waiting to be freed when it is safe
46     void** deadBlocks;
47     int deadsz;
48     int ndead;
49     
50     // Threading stuff
51     int nThreads;
52     int waitCount;
53     int needGC;
54     int bottleneck;
55     void* sem;
56     void* lock;
57
58     // Constants
59     naRef meRef;
60     naRef argRef;
61     naRef parentsRef;
62
63     // A hash of symbol names
64     naRef symbols;
65
66     // Vector/hash containing objects which should not be freed by the gc
67     // TODO do we need a separate vector and hash?
68     naRef save;
69     naRef save_hash;
70     int next_gc_key;
71
72     struct Context* freeContexts;
73     struct Context* allContexts;
74 };
75
76 struct Context {
77     // Stack(s)
78     struct Frame fStack[MAX_RECURSION];
79     int fTop;
80     naRef opStack[MAX_STACK_DEPTH];
81     int opFrame; // like Frame::bp, but for C functions
82     int opTop;
83     int markStack[MAX_MARK_DEPTH];
84     int markTop;
85
86     // Free object lists, cached from the global GC
87     struct naObj** free[NUM_NASAL_TYPES];
88     int nfree[NUM_NASAL_TYPES];
89
90     // GC-findable reference point for objects that may live on the
91     // processor ("real") stack during execution.  naNew() places them
92     // here, and clears the array each instruction
93     struct naObj** temps;
94     int ntemps;
95     int tempsz;
96
97     // Error handling
98     jmp_buf jumpHandle;
99     char error[128];
100     naRef dieArg;
101
102     // Sub-call lists
103     struct Context* callParent;
104     struct Context* callChild;
105
106     // Linked list pointers in globals
107     struct Context* nextFree;
108     struct Context* nextAll;
109
110     void* userData;
111 };
112
113 #define globals nasal_globals
114 extern struct Globals* globals;
115
116 // Threading low-level functions
117 void* naNewLock();
118 void naFreeLock(void* lock);
119 void naLock(void* lock);
120 void naUnlock(void* lock);
121 void* naNewSem();
122 void naFreeSem(void* sem);
123 void naSemDown(void* sem);
124 void naSemUp(void* sem, int count);
125
126 void naCheckBottleneck();
127
128 #define LOCK() naLock(globals->lock)
129 #define UNLOCK() naUnlock(globals->lock)
130
131 #endif // _CODE_H