1 /*
2    AngelCode Scripting Library
3    Copyright (c) 2003-2018 Andreas Jonsson
4 
5    This software is provided 'as-is', without any express or implied
6    warranty. In no event will the authors be held liable for any
7    damages arising from the use of this software.
8 
9    Permission is granted to anyone to use this software for any
10    purpose, including commercial applications, and to alter it and
11    redistribute it freely, subject to the following restrictions:
12 
13    1. The origin of this software must not be misrepresented; you
14       must not claim that you wrote the original software. If you use
15       this software in a product, an acknowledgment in the product
16       documentation would be appreciated but is not required.
17 
18    2. Altered source versions must be plainly marked as such, and
19       must not be misrepresented as being the original software.
20 
21    3. This notice may not be removed or altered from any source
22       distribution.
23 
24    The original version of this library can be located at:
25    http://www.angelcode.com/angelscript/
26 
27    Andreas Jonsson
28    andreas@angelcode.com
29 */
30 
31 
32 //
33 // as_bytecode.h
34 //
35 // A class for constructing the final byte code
36 //
37 
38 
39 
40 #ifndef AS_BYTECODE_H
41 #define AS_BYTECODE_H
42 
43 #include "as_config.h"
44 
45 #ifndef AS_NO_COMPILER
46 
47 #include "as_array.h"
48 
49 BEGIN_AS_NAMESPACE
50 
51 #define BYTECODE_SIZE  4
52 #define MAX_DATA_SIZE  8
53 #define MAX_INSTR_SIZE (BYTECODE_SIZE+MAX_DATA_SIZE)
54 
55 class asCScriptEngine;
56 class asCScriptFunction;
57 class asCByteInstruction;
58 
59 class asCByteCode
60 {
61 public:
62 	asCByteCode(asCScriptEngine *engine);
63 	~asCByteCode();
64 
65 	void ClearAll();
66 
67 	int GetSize();
68 
69 	void Finalize(const asCArray<int> &tempVariableOffsets);
70 
71 	void Optimize();
72 	void OptimizeLocally(const asCArray<int> &tempVariableOffsets);
73 	void ExtractLineNumbers();
74 	void ExtractObjectVariableInfo(asCScriptFunction *outFunc);
75 	void ExtractTryCatchInfo(asCScriptFunction *outFunc);
76 	int  ResolveJumpAddresses();
77 	int  FindLabel(int label, asCByteInstruction *from, asCByteInstruction **dest, int *positionDelta);
78 
79 	void AddPath(asCArray<asCByteInstruction *> &paths, asCByteInstruction *instr, int stackSize);
80 
81 	void Output(asDWORD *array);
82 	void AddCode(asCByteCode *bc);
83 
84 	void PostProcess();
85 
86 #ifdef AS_DEBUG
87 	void DebugOutput(const char *name, asCScriptFunction *func);
88 #endif
89 
90 	int  GetLastInstr();
91 	int  RemoveLastInstr();
92 	asDWORD GetLastInstrValueDW();
93 
94 	void InsertIfNotExists(asCArray<int> &vars, int var);
95 	void GetVarsUsed(asCArray<int> &vars);
96 	bool IsVarUsed(int offset);
97 	void ExchangeVar(int oldOffset, int newOffset);
98 	bool IsSimpleExpression();
99 
100 	void Label(short label);
101 	void Line(int line, int column, int scriptIdx);
102 	void ObjInfo(int offset, int info);
103 	void Block(bool start);
104 	void TryBlock(short catchLabel);
105 
106 	void VarDecl(int varDeclIdx);
107 	void Call(asEBCInstr bc, int funcID, int pop);
108 	void CallPtr(asEBCInstr bc, int funcPtrVar, int pop);
109 	void Alloc(asEBCInstr bc, void *objID, int funcID, int pop);
110 	void Ret(int pop);
111 	void JmpP(int var, asDWORD max);
112 
113 	int InsertFirstInstrDWORD(asEBCInstr bc, asDWORD param);
114 	int InsertFirstInstrQWORD(asEBCInstr bc, asQWORD param);
115 	int Instr(asEBCInstr bc);
116 	int InstrQWORD(asEBCInstr bc, asQWORD param);
117 	int InstrDOUBLE(asEBCInstr bc, double param);
118 	int InstrPTR(asEBCInstr bc, void *param);
119 	int InstrDWORD(asEBCInstr bc, asDWORD param);
120 	int InstrWORD(asEBCInstr bc, asWORD param);
121 	int InstrSHORT(asEBCInstr bc, short param);
122 	int InstrFLOAT(asEBCInstr bc, float param);
123 	int InstrINT(asEBCInstr bc, int param);
124 	int InstrW_W_W(asEBCInstr bc, int a, int b, int c);
125 	int InstrSHORT_B(asEBCInstr bc, short a, asBYTE b);
126 	int InstrSHORT_W(asEBCInstr bc, short a, asWORD b);
127 	int InstrSHORT_DW(asEBCInstr bc, short a, asDWORD b);
128 	int InstrSHORT_QW(asEBCInstr bc, short a, asQWORD b);
129 	int InstrW_DW(asEBCInstr bc, asWORD a, asDWORD b);
130 	int InstrW_QW(asEBCInstr bc, asWORD a, asQWORD b);
131 	int InstrW_PTR(asEBCInstr bc, short a, void *param);
132 	int InstrW_FLOAT(asEBCInstr bc, asWORD a, float b);
133 	int InstrW_W(asEBCInstr bc, int w, int b);
134 	int InstrSHORT_DW_DW(asEBCInstr bc, short a, asDWORD b, asDWORD c);
135 
GetEngine()136 	asCScriptEngine *GetEngine() const { return engine; };
137 
138 	asCArray<int> lineNumbers;
139 	asCArray<int> sectionIdxs;
140 	int largestStackUsed;
141 
142 protected:
143 	// Assignments are not allowed
144 	void operator=(const asCByteCode &) {}
145 
146 	// Helpers for Optimize
147 	bool CanBeSwapped(asCByteInstruction *curr);
148 	asCByteInstruction *ChangeFirstDeleteNext(asCByteInstruction *curr, asEBCInstr bc);
149 	asCByteInstruction *DeleteFirstChangeNext(asCByteInstruction *curr, asEBCInstr bc);
150 	asCByteInstruction *DeleteInstruction(asCByteInstruction *instr);
151 	void RemoveInstruction(asCByteInstruction *instr);
152 	asCByteInstruction *GoBack(asCByteInstruction *curr);
153 	asCByteInstruction *GoForward(asCByteInstruction *curr);
154 	void InsertBefore(asCByteInstruction *before, asCByteInstruction *instr);
155 	bool RemoveUnusedValue(asCByteInstruction *curr, asCByteInstruction **next);
156 	bool IsTemporary(int offset);
157 	bool IsTempRegUsed(asCByteInstruction *curr);
158 	bool IsTempVarRead(asCByteInstruction *curr, int offset);
159 	bool PostponeInitOfTemp(asCByteInstruction *curr, asCByteInstruction **next);
160 	bool IsTempVarReadByInstr(asCByteInstruction *curr, int var);
161 	bool IsTempVarOverwrittenByInstr(asCByteInstruction *curr, int var);
162 	bool IsInstrJmpOrLabel(asCByteInstruction *curr);
163 
164 	int AddInstruction();
165 	int AddInstructionFirst();
166 
167 	asCByteInstruction *first;
168 	asCByteInstruction *last;
169 
170 	const asCArray<int> *temporaryVariables;
171 
172 	asCScriptEngine *engine;
173 };
174 
175 class asCByteInstruction
176 {
177 public:
178 	asCByteInstruction();
179 
180 	void AddAfter(asCByteInstruction *nextCode);
181 	void AddBefore(asCByteInstruction *nextCode);
182 	void Remove();
183 
184 	int  GetSize();
185 	int  GetStackIncrease();
186 
187 	asCByteInstruction *next;
188 	asCByteInstruction *prev;
189 
190 	asEBCInstr op;
191 	asQWORD arg;
192 	short wArg[3];
193 	int size;
194 	int stackInc;
195 
196 	// Testing
197 	bool marked;
198 	int  stackSize;
199 };
200 
201 END_AS_NAMESPACE
202 
203 #endif // AS_NO_COMPILER
204 
205 #endif
206