11#ifndef bytecode_compiler_H
22#define bytecode_compiler_H
33
4+ #include < variant>
45#include < clasp/core/common.h>
56#include < clasp/core/compPackage.fwd.h>
67
@@ -54,6 +55,14 @@ class LexicalVarInfo_O : public VarInfo_O {
5455 }
5556};
5657
58+ struct LexicalVarInfoV {
59+ LexicalVarInfoV (LexicalVarInfo_sp info) : _info(info) {};
60+ // Because we mutate infos, and store them in lexenvs, we have to
61+ // allocate them. This wrapper is just for var_info_v purposes.
62+ LexicalVarInfo_sp _info;
63+ LexicalVarInfo_sp info () const { return _info; }
64+ };
65+
5766FORWARD (SpecialVarInfo);
5867class SpecialVarInfo_O : public VarInfo_O {
5968 LISP_CLASS (comp, CompPkg, SpecialVarInfo_O, " SpecialVarInfo" , VarInfo_O);
@@ -74,6 +83,13 @@ class SpecialVarInfo_O : public VarInfo_O {
7483 CL_DEFMETHOD bool globalp () const { return this ->_globalp ; }
7584};
7685
86+ struct SpecialVarInfoV {
87+ SpecialVarInfoV (bool globalp) : _globalp(globalp) {};
88+ SpecialVarInfoV (SpecialVarInfo_sp info) : _globalp(info->globalp ()) {};
89+ bool _globalp;
90+ bool globalp () const { return _globalp; }
91+ };
92+
7793FORWARD (SymbolMacroVarInfo);
7894class SymbolMacroVarInfo_O : public VarInfo_O {
7995 LISP_CLASS (comp, CompPkg, SymbolMacroVarInfo_O, " SymbolMacroVarInfo" , VarInfo_O);
@@ -91,6 +107,13 @@ class SymbolMacroVarInfo_O : public VarInfo_O {
91107 CL_DEFMETHOD Function_sp expander () const { return this ->_expander ; }
92108};
93109
110+ struct SymbolMacroVarInfoV {
111+ SymbolMacroVarInfoV (Function_sp expander) : _expander(expander) {};
112+ SymbolMacroVarInfoV (SymbolMacroVarInfo_sp info) : _expander(info->expander ()) {};
113+ Function_sp _expander;
114+ Function_sp expander () const { return _expander; }
115+ };
116+
94117FORWARD (ConstantVarInfo);
95118class ConstantVarInfo_O : public VarInfo_O {
96119 LISP_CLASS (comp, CompPkg, ConstantVarInfo_O, " ConstantVarInfo" , VarInfo_O);
@@ -107,6 +130,19 @@ class ConstantVarInfo_O : public VarInfo_O {
107130 CL_DEFMETHOD T_sp value () const { return this ->_value ; }
108131};
109132
133+ struct ConstantVarInfoV {
134+ ConstantVarInfoV (T_sp value) : _value(value) {};
135+ ConstantVarInfoV (ConstantVarInfo_sp info) : _value(info->value ()) {};
136+ T_sp _value;
137+ T_sp value () const { return _value; }
138+ };
139+
140+ // non-heaped infos, to avoid consing. see var_info_v.
141+ // We use this thing instead of monostate for clarity.
142+ struct NoVarInfoV {};
143+
144+ typedef std::variant<NoVarInfoV, LexicalVarInfoV, SpecialVarInfoV, SymbolMacroVarInfoV, ConstantVarInfoV> VarInfoV;
145+
110146FORWARD (FunInfo);
111147class FunInfo_O : public General_O {
112148 LISP_ABSTRACT_CLASS (comp, CompPkg, FunInfo_O, " FunInfo" , General_O);
@@ -131,6 +167,13 @@ class GlobalFunInfo_O : public FunInfo_O {
131167 CL_DEFMETHOD T_sp cmexpander () const { return this ->_cmexpander ; }
132168};
133169
170+ struct GlobalFunInfoV {
171+ GlobalFunInfoV (T_sp cmexpander) : _cmexpander(cmexpander) {};
172+ GlobalFunInfoV (GlobalFunInfo_sp info) : _cmexpander(info->cmexpander ()) {};
173+ T_sp _cmexpander;
174+ T_sp cmexpander () const { return _cmexpander; }
175+ };
176+
134177FORWARD (LocalFunInfo);
135178class LocalFunInfo_O : public FunInfo_O {
136179 LISP_CLASS (comp, CompPkg, LocalFunInfo_O, " LocalFunInfo" , FunInfo_O);
@@ -147,6 +190,12 @@ class LocalFunInfo_O : public FunInfo_O {
147190 CL_DEFMETHOD T_sp funVar () const { return this ->fun_var ; }
148191};
149192
193+ struct LocalFunInfoV {
194+ LocalFunInfoV (LocalFunInfo_sp info) : _info(info) {};
195+ LocalFunInfo_sp _info;
196+ LocalFunInfo_sp info () const { return _info; }
197+ };
198+
150199// We have separate global and local macro classes because it is sometimes
151200// important to know that a binding is local - for example, a local binding
152201// shadows a global setf expander.
@@ -167,6 +216,13 @@ class GlobalMacroInfo_O : public FunInfo_O {
167216 CL_DEFMETHOD Function_sp expander () const { return this ->_expander ; }
168217};
169218
219+ struct GlobalMacroInfoV {
220+ GlobalMacroInfoV (Function_sp expander) : _expander(expander) {};
221+ GlobalMacroInfoV (GlobalMacroInfo_sp info) : _expander(info->expander ()) {};
222+ Function_sp _expander;
223+ Function_sp expander () const { return _expander; }
224+ };
225+
170226FORWARD (LocalMacroInfo);
171227class LocalMacroInfo_O : public FunInfo_O {
172228 LISP_CLASS (comp, CompPkg, LocalMacroInfo_O, " LocalMacroInfo" , FunInfo_O);
@@ -183,8 +239,19 @@ class LocalMacroInfo_O : public FunInfo_O {
183239 CL_DEFMETHOD Function_sp expander () const { return this ->_expander ; }
184240};
185241
242+ struct LocalMacroInfoV {
243+ LocalMacroInfoV (Function_sp expander) : _expander(expander) {};
244+ LocalMacroInfoV (LocalMacroInfo_sp info) : _expander(info->expander ()) {};
245+ Function_sp _expander;
246+ Function_sp expander () const { return _expander; }
247+ };
248+
249+ struct NoFunInfoV {};
250+
251+ typedef std::variant<NoFunInfoV, GlobalFunInfoV, LocalFunInfoV, GlobalMacroInfoV, LocalMacroInfoV> FunInfoV;
252+
186253FORWARD (Lexenv);
187- FORWARD ( Context);
254+ class Context ; // forward decl
188255class Lexenv_O : public General_O {
189256 LISP_CLASS (comp, CompPkg, Lexenv_O, " Lexenv" , General_O);
190257public:
@@ -219,7 +286,9 @@ class Lexenv_O : public General_O {
219286 * environment. The max local count in the current function is also
220287 * updated.
221288 */
222- CL_DEFMETHOD Lexenv_sp bind_vars (List_sp vars, Context_sp context);
289+ Lexenv_sp bind_vars (List_sp vars, const Context context);
290+ // Ditto but with just one.
291+ Lexenv_sp bind1var (Symbol_sp var, const Context context);
223292 // Add VARS as special in ENV.
224293 CL_DEFMETHOD Lexenv_sp add_specials (List_sp vars);
225294 // Add FUNCTION NAMES as notinline in ENV.
@@ -246,74 +315,67 @@ class Lexenv_O : public General_O {
246315
247316// Context contains information about what the current form needs
248317// to know about what it is enclosed by.
318+ // Because they are only ever passed "down" and used within the
319+ // compiler, they are POD rather than Lisp objects, to save some time
320+ // on consing and GC.
321+ // (Profiling has shown that the compiler spends a lot of time consing.)
249322FORWARD (Label);
250323FORWARD (Cfunction);
251324FORWARD (Module);
252- class Context_O : public General_O {
253- LISP_CLASS (comp, CompPkg, Context_O, " Context" , General_O);
325+ class Context {
254326public:
255- T_sp _receiving;
327+ int _receiving;
256328 List_sp _dynenv;
257329 T_sp _cfunction;
258330public:
259- Context_O (T_sp receiving, T_sp dynenv, T_sp cfunction)
331+ Context ( int receiving, T_sp dynenv, T_sp cfunction)
260332 : _receiving(receiving), _dynenv(dynenv), _cfunction(cfunction) {}
261- CL_LISPIFY_NAME (Context/make)
262- CL_DEF_CLASS_METHOD
263- static Context_sp make (T_sp receiving, T_sp dynenv, T_sp cfunction) {
264- return gctools::GC<Context_O>::allocate<gctools::RuntimeStage>(receiving, dynenv, cfunction);
265- }
266- CL_LISPIFY_NAME (context/receiving)
267- CL_DEFMETHOD T_sp receiving () { return this ->_receiving ; }
268- CL_LISPIFY_NAME (context/dynenv)
269- CL_DEFMETHOD List_sp dynenv () { return this ->_dynenv ; }
270- CL_DEFMETHOD Cfunction_sp cfunction () {
333+ // Sub constructors
334+ Context (const Context& parent, int receiving)
335+ : _receiving(receiving), _dynenv(parent.dynenv()),
336+ _cfunction (parent.cfunction()) {}
337+ // Plop the de on the front.
338+ Context (const Context& parent, T_sp de)
339+ : _receiving(parent.receiving()),
340+ _dynenv(Cons_O::create(de, parent.dynenv())),
341+ _cfunction(parent.cfunction()) {}
342+ int receiving () const { return this ->_receiving ; }
343+ List_sp dynenv () const { return this ->_dynenv ; }
344+ Cfunction_sp cfunction () const {
271345 return gc::As<Cfunction_sp>(this ->_cfunction );
272346 }
273- CL_DEFMETHOD Module_sp module ();
274- public:
275- // Make a new context that's like this one but with a possibly-different
276- // RECEIVING.
277- CL_DEFMETHOD Context_sp sub (T_sp receiving) {
278- return Context_O::make (receiving, this ->_dynenv , this ->_cfunction );
279- }
280- // Make a new context that's like this one but with the given thing
281- // plopped on the dynenv.
282- CL_DEFMETHOD Context_sp subde (T_sp de) {
283- return Context_O::make (this ->_receiving , Cons_O::create (de, this ->_dynenv ),
284- this ->_cfunction );
285- }
286- CL_DEFMETHOD size_t literal_index (T_sp literal);
287- CL_DEFMETHOD size_t new_literal_index (T_sp literal);
288- CL_DEFMETHOD size_t closure_index (T_sp info);
289- CL_DEFMETHOD void assemble0 (uint8_t opcode);
290- CL_DEFMETHOD void assemble1 (uint8_t opcode, size_t operand1);
291- CL_DEFMETHOD void assemble2 (uint8_t opcode,
292- size_t operand1, size_t operand2);
347+ Module_sp module () const ;
348+ public:
349+ size_t literal_index (T_sp literal) const ;
350+ size_t new_literal_index (T_sp literal) const ;
351+ size_t closure_index (T_sp info) const ;
352+ void assemble0 (uint8_t opcode) const ;
353+ void assemble1 (uint8_t opcode, size_t operand1) const ;
354+ void assemble2 (uint8_t opcode, size_t operand1, size_t operand2) const ;
293355 void emit_control_label (Label_sp,
294- uint8_t opcode8, uint8_t opcode16, uint8_t opcode24);
295- CL_DEFMETHOD void emit_jump (Label_sp label);
296- CL_DEFMETHOD void emit_jump_if (Label_sp label);
297- CL_DEFMETHOD void emit_entry_or_save_sp (LexicalVarInfo_sp info);
298- CL_DEFMETHOD void emit_ref_or_restore_sp (LexicalVarInfo_sp info);
299- CL_DEFMETHOD void emit_exit (Label_sp label);
300- CL_DEFMETHOD void emit_exit_or_jump (LexicalVarInfo_sp info, Label_sp label);
301- CL_DEFMETHOD void maybe_emit_entry_close (LexicalVarInfo_sp info);
302- CL_DEFMETHOD void emit_catch (Label_sp label);
303- CL_DEFMETHOD void emit_jump_if_supplied (Label_sp label, size_t indx);
304- CL_DEFMETHOD void reference_lexical_info (LexicalVarInfo_sp info);
305- CL_DEFMETHOD void maybe_emit_make_cell (LexicalVarInfo_sp info);
306- CL_DEFMETHOD void maybe_emit_cell_ref (LexicalVarInfo_sp info);
307- CL_DEFMETHOD void maybe_emit_encage (LexicalVarInfo_sp info);
308- CL_DEFMETHOD void emit_lexical_set (LexicalVarInfo_sp info);
309- CL_DEFMETHOD void emit_parse_key_args (size_t max_count, size_t key_count,
310- size_t key_start, size_t indx,
311- bool aokp);
312- CL_DEFMETHOD void emit_bind (size_t count, size_t offset);
313- CL_DEFMETHOD void emit_call (size_t argcount);
314- CL_DEFMETHOD void emit_mv_call ();
315- CL_DEFMETHOD void emit_special_bind (Symbol_sp sym);
316- CL_DEFMETHOD void emit_unbind (size_t count);
356+ uint8_t opcode8, uint8_t opcode16, uint8_t opcode24) const ;
357+ void emit_jump (Label_sp label) const ;
358+ void emit_jump_if (Label_sp label) const ;
359+ void emit_entry_or_save_sp (LexicalVarInfo_sp info) const ;
360+ void emit_ref_or_restore_sp (LexicalVarInfo_sp info) const ;
361+ void emit_exit (Label_sp label) const ;
362+ void emit_exit_or_jump (LexicalVarInfo_sp info, Label_sp label) const ;
363+ void maybe_emit_entry_close (LexicalVarInfo_sp info) const ;
364+ void emit_catch (Label_sp label) const ;
365+ void emit_jump_if_supplied (Label_sp label, size_t indx) const ;
366+ void reference_lexical_info (LexicalVarInfo_sp info) const ;
367+ void maybe_emit_make_cell (LexicalVarInfo_sp info) const ;
368+ void maybe_emit_cell_ref (LexicalVarInfo_sp info) const ;
369+ void maybe_emit_encage (LexicalVarInfo_sp info) const ;
370+ void emit_lexical_set (LexicalVarInfo_sp info) const ;
371+ void emit_parse_key_args (size_t max_count, size_t key_count,
372+ size_t key_start, size_t indx,
373+ bool aokp) const ;
374+ void emit_bind (size_t count, size_t offset) const ;
375+ void emit_call (size_t argcount) const ;
376+ void emit_mv_call () const ;
377+ void emit_special_bind (Symbol_sp sym) const ;
378+ void emit_unbind (size_t count) const ;
317379};
318380
319381FORWARD (Annotation);
@@ -374,7 +436,7 @@ class Label_O : public Annotation_O {
374436 return gctools::GC<Label_O>::allocate<gctools::RuntimeStage>();
375437 }
376438public:
377- CL_DEFMETHOD void contextualize (Context_sp context);
439+ void contextualize (const Context context);
378440};
379441
380442FORWARD (Fixup);
@@ -399,7 +461,7 @@ class Fixup_O : public Annotation_O {
399461public:
400462 // Mark the fixup in the instruction stream during assembly.
401463 // FIXME: This name sucks, but emit_fixup seems wayy too confusing.
402- CL_DEFMETHOD void contextualize (Context_sp context);
464+ void contextualize (const Context context);
403465 // Compute the final size (in bytes) for the fixed up code.
404466 CL_DEFMETHOD virtual size_t resize () = 0;
405467 // Emit the final code into the bytecode vector.
0 commit comments