Re-added support for reference arguments.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of SourcePawn.
6 * SourcePawn is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
11 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * SourcePawn. If not, see http://www.gnu.org/licenses/.
18 #ifndef _include_sp2_hir_h_
19 #define _include_sp2_hir_h_
22 #include "../PoolAllocator.h"
23 #include "../Opcodes.h"
34 /* Special LValue types */ \
43 // Forward declarations.
44 #define _(name) class H##name;
52 class HIR : public PoolObject
56 #define _(name) k##name,
63 HIR(AstNode *node, Type *type)
72 AstNode *node() const {
76 virtual bool isLValue() const {
80 virtual HOp op() const = 0;
81 virtual void accept(HIRVisitor *visitor) = 0;
84 bool is##name() const { \
85 return op() == k##name; \
87 H##name *to##name() { \
89 return reinterpret_cast<H##name *>(this); \
96 return reinterpret_cast<HLValue *>(this);
101 ScopedRoot<Type> type_;
104 class BytecodeEmitter;
110 virtual void visit##name(H##name *hir) { \
117 typedef PoolList<HIR *> HIRList;
119 #define DEFINE_HIR(name) \
120 virtual HOp op() const { \
123 virtual void accept(HIRVisitor *visitor) { \
124 visitor->visit##name(this); \
127 class HInteger : public HIR
130 HInteger(AstNode *node, Type *type, int value)
145 class HConvert : public HIR
148 HConvert(AstNode *node, Type *type, Opcode op, HIR *in)
156 Opcode opcode() const {
168 class HLValue : public HIR
171 HLValue(AstNode *node, Type *type)
176 // Pushes a reference to the LValue on the stack.
177 virtual void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_) = 0;
179 // Duplicates a stack reference.
180 virtual void hold(BytecodeEmitter &emitter_) = 0;
182 // Reorders the stack for a post-increment operation:
183 // REF VAL -> VAL REF VAL
184 virtual void swapAndPick(BytecodeEmitter &emitter_) = 0;
186 // Given a stack layout of the form:
190 // Emits a store to the reference.
191 virtual void store(BytecodeEmitter &emitter_) = 0;
192 virtual void load(BytecodeEmitter &emitter_) = 0;
194 // Try to make a direct reference, if semantics allow it. False if the
195 // caller must allocate a reference to the stack.
196 virtual bool ref(BytecodeEmitter &emitter_) = 0;
198 bool isLValue() const {
203 class HLocal : public HLValue
206 HLocal(AstNode *node, VariableSymbol *sym);
210 // Pushes a reference to the LValue on the stack.
211 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
212 void hold(BytecodeEmitter &emitter_);
213 void swapAndPick(BytecodeEmitter &emitter_);
214 void store(BytecodeEmitter &emitter_);
215 void load(BytecodeEmitter &emitter_);
216 bool ref(BytecodeEmitter &emitter_);
218 VariableSymbol *sym() const {
223 VariableSymbol *sym_;
226 class HIndex : public HLValue
229 HIndex(AstNode *node, Type *type, HIR *left, HIR *right)
230 : HLValue(node, type),
238 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
239 void hold(BytecodeEmitter &emitter_);
240 void swapAndPick(BytecodeEmitter &emitter_);
241 void store(BytecodeEmitter &emitter_);
242 void load(BytecodeEmitter &emitter_);
243 bool ref(BytecodeEmitter &emitter_);
250 class HGlobal : public HLValue
253 HGlobal(AstNode *node, Symbol *sym)
254 : HLValue(node, sym->type()),
261 void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
262 void hold(BytecodeEmitter &emitter_);
263 void swapAndPick(BytecodeEmitter &emitter_);
264 void store(BytecodeEmitter &emitter_);
265 void load(BytecodeEmitter &emitter_);
266 bool ref(BytecodeEmitter &emitter_);
268 Symbol *sym() const {
276 class HBinary : public HIR
279 HBinary(AstNode *node, Type *type, TokenKind token, HIR *left, HIR *right)
288 TokenKind token() const {
304 class HFloat : public HIR
307 HFloat(AstNode *node, Type *type, float value)
314 float value() const {
322 class HStore : public HIR
325 HStore(AstNode *node, HLValue *lval, HIR *rval)
326 : HIR(node, lval->type()),
333 HStore(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
334 : HIR(node, lval->type()),
343 HLValue *lval() const {
349 TokenKind kind() const {
359 class HPostIncDec : public HIR
362 HPostIncDec(AstNode *node, TokenKind kind, HLValue *lval, HIR *rval)
363 : HIR(node, lval->type()),
370 DEFINE_HIR(PostIncDec);
372 HLValue *lval() const {
378 TokenKind kind() const {
388 class HCall : public HIR
391 HCall(AstNode *node, Type *type, HIR *callee, HIRList *args)
400 HIR *callee() const {
403 HIRList *args() const {
412 class HToRef : public HIR
415 HToRef(AstNode *node, Type *type, HIR *in)
433 void EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir);
437 #endif // _include_sp2_hir_h_