forked from svaarala/duktape
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathduk_hcompiledfunction.h
More file actions
174 lines (149 loc) · 5.94 KB
/
Copy pathduk_hcompiledfunction.h
File metadata and controls
174 lines (149 loc) · 5.94 KB
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
/*
* Heap compiled function (Ecmascript function) representation.
*
* There is a single data buffer containing the Ecmascript function's
* bytecode, constants, and inner functions.
*/
#ifndef DUK_HCOMPILEDFUNCTION_H_INCLUDED
#define DUK_HCOMPILEDFUNCTION_H_INCLUDED
/*
* Accessor macros for function specific data areas
*/
/* Note: assumes 'data' is always a fixed buffer */
#define DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE(h) \
DUK_HBUFFER_FIXED_GET_DATA_PTR((duk_hbuffer_fixed *) (h)->data)
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(h) \
((duk_tval *) DUK_HCOMPILEDFUNCTION_GET_BUFFER_BASE((h)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(h) \
((h)->funcs)
#define DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(h) \
((h)->bytecode)
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(h) \
((duk_tval *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE((h)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(h) \
((duk_hobject **) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE((h)))
#define DUK_HCOMPILEDFUNCTION_GET_CODE_END(h) \
((duk_instr_t *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((duk_hbuffer_fixed *) (h)->data) + \
DUK_HBUFFER_GET_SIZE((h)->data)))
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE(h) \
( \
(duk_size_t) \
( \
((duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_END((h))) - \
((duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE((h))) \
) \
)
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE(h) \
( \
(duk_size_t) \
( \
((duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_END((h))) - \
((duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE((h))) \
) \
)
#define DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE(h) \
( \
(duk_size_t) \
( \
((duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_END((h))) - \
((duk_uint8_t *) DUK_HCOMPILEDFUNCTION_GET_CODE_BASE((h))) \
) \
)
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_COUNT(h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CONSTS_SIZE((h)) / sizeof(duk_tval)))
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_COUNT(h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_FUNCS_SIZE((h)) / sizeof(duk_hobject *)))
#define DUK_HCOMPILEDFUNCTION_GET_CODE_COUNT(h) \
((duk_size_t) (DUK_HCOMPILEDFUNCTION_GET_CODE_SIZE((h)) / sizeof(duk_instr_t)))
/*
* Main struct
*/
struct duk_hcompiledfunction {
/* shared object part */
duk_hobject obj;
/*
* Pointers to function data area for faster access. Function
* data is a buffer shared between all closures of the same
* "template" function. The data buffer is always fixed (non-
* dynamic, hence stable), with a layout as follows:
*
* constants (duk_tval)
* inner functions (duk_hobject *)
* bytecode (duk_instr_t)
*
* Note: bytecode end address can be computed from 'data' buffer
* size. It is not strictly necessary functionally, assuming
* bytecode never jumps outside its allocated area. However,
* it's a safety/robustness feature for avoiding the chance of
* executing random data as bytecode due to a compiler error.
*
* Note: values in the data buffer must be incref'd (they will
* be decref'd on release) for every compiledfunction referring
* to the 'data' element.
*/
duk_hbuffer *data; /* data area, fixed allocation, stable data ptrs */
/* no need for constants pointer */
duk_hobject **funcs;
duk_instr_t *bytecode;
/*
* 'nregs' registers are allocated on function entry, at most 'nargs'
* are initialized to arguments, and the rest to undefined. Arguments
* above 'nregs' are not mapped to registers. All registers in the
* active stack range must be initialized because they are GC reachable.
* 'nargs' is needed so that if the function is given more than 'nargs'
* arguments, the additional arguments do not 'clobber' registers
* beyond 'nregs' which must be consistently initialized to undefined.
*
* Usually there is no need to know which registers are mapped to
* local variables. Registers may be allocated to variable in any
* way (even including gaps). However, a register-variable mapping
* must be the same for the duration of the function execution and
* the register cannot be used for anything else.
*
* When looking up variables by name, the '_Varmap' map is used.
* When an activation closes, registers mapped to arguments are
* copied into the environment record based on the same map. The
* reverse map (from register to variable) is not currently needed
* at run time, except for debugging, so it is not maintained.
*/
duk_uint16_t nregs; /* regs to allocate */
duk_uint16_t nargs; /* number of arguments allocated to regs */
/*
* Additional control information is placed into the object itself
* as internal properties to avoid unnecessary fields for the
* majority of functions. The compiler tries to omit internal
* control fields when possible.
*
* Function templates:
*
* {
* name: "func", // declaration, named function expressions
* fileName: <debug info for creating nice errors>
* _Varmap: { "arg1": 0, "arg2": 1, "varname": 2 },
* _Formals: [ "arg1", "arg2" ],
* _Source: "function func(arg1, arg2) { ... }",
* _Pc2line: <debug info for pc-to-line mapping>,
* }
*
* Function instances:
*
* {
* length: 2,
* prototype: { constructor: <func> },
* caller: <thrower>,
* arguments: <thrower>,
* name: "func", // declaration, named function expressions
* fileName: <debug info for creating nice errors>
* _Varmap: { "arg1": 0, "arg2": 1, "varname": 2 },
* _Formals: [ "arg1", "arg2" ],
* _Source: "function func(arg1, arg2) { ... }",
* _Pc2line: <debug info for pc-to-line mapping>,
* _Varenv: <variable environment of closure>,
* _Lexenv: <lexical environment of closure (if differs from _Varenv)>
* }
*
* More detailed description of these properties can be found
* in the documentation.
*/
};
#endif /* DUK_HCOMPILEDFUNCTION_H_INCLUDED */