aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/lscript/lscript_compile/lscript_bytecode.cpp')
-rw-r--r--linden/indra/lscript/lscript_compile/lscript_bytecode.cpp318
1 files changed, 318 insertions, 0 deletions
diff --git a/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp b/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
new file mode 100644
index 0000000..6d18a1a
--- /dev/null
+++ b/linden/indra/lscript/lscript_compile/lscript_bytecode.cpp
@@ -0,0 +1,318 @@
1/**
2 * @file lscript_bytecode.cpp
3 * @brief classes to build actual bytecode
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "lscript_bytecode.h"
31#include "lscript_error.h"
32
33#if defined(_MSC_VER)
34# pragma warning(disable: 4102) // 'yy_more' : unreferenced label
35# pragma warning(disable: 4702) // unreachable code
36#endif
37
38LLScriptJumpTable::LLScriptJumpTable()
39{
40}
41
42LLScriptJumpTable::~LLScriptJumpTable()
43{
44 mLabelMap.deleteAllData();
45 mJumpMap.deleteAllData();
46}
47
48void LLScriptJumpTable::addLabel(char *name, S32 offset)
49{
50 char *temp = gScopeStringTable->addString(name);
51 mLabelMap[temp] = new S32(offset);
52}
53
54void LLScriptJumpTable::addJump(char *name, S32 offset)
55{
56 char *temp = gScopeStringTable->addString(name);
57 mJumpMap[temp] = new S32(offset);
58}
59
60
61LLScriptByteCodeChunk::LLScriptByteCodeChunk(BOOL b_need_jumps)
62: mCodeChunk(NULL), mCurrentOffset(0), mJumpTable(NULL)
63{
64 if (b_need_jumps)
65 {
66 mJumpTable = new LLScriptJumpTable();
67 }
68}
69
70LLScriptByteCodeChunk::~LLScriptByteCodeChunk()
71{
72 delete [] mCodeChunk;
73 delete mJumpTable;
74}
75
76void LLScriptByteCodeChunk::addByte(U8 byte)
77{
78 if (mCodeChunk)
79 {
80 U8 *temp = new U8[mCurrentOffset + 1];
81 memcpy(temp, mCodeChunk, mCurrentOffset);
82 delete [] mCodeChunk;
83 mCodeChunk = temp;
84 }
85 else
86 {
87 mCodeChunk = new U8[1];
88 }
89 *(mCodeChunk + mCurrentOffset++) = byte;
90}
91
92void LLScriptByteCodeChunk::addU16(U16 data)
93{
94 U8 temp[2];
95 S32 offset = 0;
96 u162bytestream(temp, offset, data);
97 addBytes(temp, 2);
98}
99
100void LLScriptByteCodeChunk::addBytes(U8 *bytes, S32 size)
101{
102 if (mCodeChunk)
103 {
104 U8 *temp = new U8[mCurrentOffset + size];
105 memcpy(temp, mCodeChunk, mCurrentOffset);
106 delete [] mCodeChunk;
107 mCodeChunk = temp;
108 }
109 else
110 {
111 mCodeChunk = new U8[size];
112 }
113 memcpy(mCodeChunk + mCurrentOffset, bytes, size);
114 mCurrentOffset += size;
115}
116
117void LLScriptByteCodeChunk::addBytes(char *bytes, S32 size)
118{
119 if (mCodeChunk)
120 {
121 U8 *temp = new U8[mCurrentOffset + size];
122 memcpy(temp, mCodeChunk, mCurrentOffset);
123 delete [] mCodeChunk;
124 mCodeChunk = temp;
125 }
126 else
127 {
128 mCodeChunk = new U8[size];
129 }
130 memcpy(mCodeChunk + mCurrentOffset, bytes, size);
131 mCurrentOffset += size;
132}
133
134void LLScriptByteCodeChunk::addBytes(S32 size)
135{
136 if (mCodeChunk)
137 {
138 U8 *temp = new U8[mCurrentOffset + size];
139 memcpy(temp, mCodeChunk, mCurrentOffset);
140 delete [] mCodeChunk;
141 mCodeChunk = temp;
142 }
143 else
144 {
145 mCodeChunk = new U8[size];
146 }
147 memset(mCodeChunk + mCurrentOffset, 0, size);
148 mCurrentOffset += size;
149}
150
151void LLScriptByteCodeChunk::addBytesDontInc(S32 size)
152{
153 if (mCodeChunk)
154 {
155 U8 *temp = new U8[mCurrentOffset + size];
156 memcpy(temp, mCodeChunk, mCurrentOffset);
157 delete [] mCodeChunk;
158 mCodeChunk = temp;
159 }
160 else
161 {
162 mCodeChunk = new U8[size];
163 }
164 memset(mCodeChunk + mCurrentOffset, 0, size);
165}
166
167void LLScriptByteCodeChunk::addInteger(S32 value)
168{
169 U8 temp[4];
170 S32 offset = 0;
171 integer2bytestream(temp, offset, value);
172 addBytes(temp, 4);
173}
174
175void LLScriptByteCodeChunk::addFloat(F32 value)
176{
177 U8 temp[4];
178 S32 offset = 0;
179 float2bytestream(temp, offset, value);
180 addBytes(temp, 4);
181}
182
183void LLScriptByteCodeChunk::addLabel(char *name)
184{
185 if (mJumpTable)
186 {
187 mJumpTable->addLabel(name, mCurrentOffset);
188 }
189}
190
191void LLScriptByteCodeChunk::addJump(char *name)
192{
193 if (mJumpTable)
194 {
195 mJumpTable->addJump(name, mCurrentOffset);
196 }
197}
198
199// format is Byte 0: jump op code Byte 1 - 4: offset
200// the jump position points to Byte 5, so we need to add the data at
201// offset - 4, offset - 3, offset - 2, and offset - 1
202
203// offset is label - jump
204
205void LLScriptByteCodeChunk::connectJumps()
206{
207 char *jump;
208 S32 offset, jumppos;
209
210 if (mJumpTable)
211 {
212 for (jump = mJumpTable->mJumpMap.getFirstKey();
213 jump;
214 jump = mJumpTable->mJumpMap.getNextKey())
215 {
216 jumppos = *mJumpTable->mJumpMap[jump];
217 offset = *mJumpTable->mLabelMap[jump] - jumppos;
218 jumppos = jumppos - 4;
219 integer2bytestream(mCodeChunk, jumppos, offset);
220 }
221 }
222}
223
224LLScriptScriptCodeChunk::LLScriptScriptCodeChunk(S32 total_size)
225: mTotalSize(total_size), mCompleteCode(NULL)
226{
227 mRegisters = new LLScriptByteCodeChunk(FALSE);
228 mGlobalVariables = new LLScriptByteCodeChunk(FALSE);
229 mGlobalFunctions = new LLScriptByteCodeChunk(FALSE);
230 mStates = new LLScriptByteCodeChunk(FALSE);
231 mHeap = new LLScriptByteCodeChunk(FALSE);
232}
233
234LLScriptScriptCodeChunk::~LLScriptScriptCodeChunk()
235{
236 delete mRegisters;
237 delete mGlobalVariables;
238 delete mGlobalFunctions;
239 delete mStates;
240 delete mHeap;
241 delete [] mCompleteCode;
242}
243
244void LLScriptScriptCodeChunk::build(FILE *efp, FILE *bcfp)
245{
246 S32 code_data_size = mRegisters->mCurrentOffset +
247 mGlobalVariables->mCurrentOffset +
248 mGlobalFunctions->mCurrentOffset +
249 mStates->mCurrentOffset +
250 mHeap->mCurrentOffset;
251
252 S32 offset = 0;
253
254 if (code_data_size < mTotalSize)
255 {
256 mCompleteCode = new U8[mTotalSize];
257 memset(mCompleteCode, 0, mTotalSize);
258
259 memcpy(mCompleteCode, mRegisters->mCodeChunk, mRegisters->mCurrentOffset);
260 offset += mRegisters->mCurrentOffset;
261
262 set_register(mCompleteCode, LREG_IP, 0);
263 set_register(mCompleteCode, LREG_VN, LSL2_VERSION_NUMBER);
264 set_event_register(mCompleteCode, LREG_IE, 0, LSL2_CURRENT_MAJOR_VERSION);
265 set_register(mCompleteCode, LREG_BP, mTotalSize - 1);
266 set_register(mCompleteCode, LREG_SP, mTotalSize - 1);
267
268 set_register(mCompleteCode, LREG_GVR, offset);
269
270 memcpy(mCompleteCode + offset, mGlobalVariables->mCodeChunk, mGlobalVariables->mCurrentOffset);
271 offset += mGlobalVariables->mCurrentOffset;
272
273 set_register(mCompleteCode, LREG_GFR, offset);
274
275 memcpy(mCompleteCode + offset, mGlobalFunctions->mCodeChunk, mGlobalFunctions->mCurrentOffset);
276 offset += mGlobalFunctions->mCurrentOffset;
277
278 set_register(mCompleteCode, LREG_SR, offset);
279 // zero is, by definition the default state
280 set_register(mCompleteCode, LREG_CS, 0);
281 set_register(mCompleteCode, LREG_NS, 0);
282 set_event_register(mCompleteCode, LREG_CE, LSCRIPTStateBitField[LSTT_STATE_ENTRY], LSL2_CURRENT_MAJOR_VERSION);
283 S32 default_state_offset = 0;
284 if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
285 {
286 default_state_offset = 8;
287 }
288 else
289 {
290 default_state_offset = 4;
291 }
292 set_event_register(mCompleteCode, LREG_ER, bytestream2u64(mStates->mCodeChunk, default_state_offset), LSL2_CURRENT_MAJOR_VERSION);
293
294 memcpy(mCompleteCode + offset, mStates->mCodeChunk, mStates->mCurrentOffset);
295 offset += mStates->mCurrentOffset;
296
297 set_register(mCompleteCode, LREG_HR, offset);
298
299 memcpy(mCompleteCode + offset, mHeap->mCodeChunk, mHeap->mCurrentOffset);
300 offset += mHeap->mCurrentOffset;
301
302 set_register(mCompleteCode, LREG_HP, offset);
303 set_register(mCompleteCode, LREG_FR, 0);
304 set_register(mCompleteCode, LREG_SLR, 0);
305 set_register(mCompleteCode, LREG_ESR, 0);
306 set_register(mCompleteCode, LREG_PR, 0);
307 set_register(mCompleteCode, LREG_TM, mTotalSize);
308
309
310 fwrite(mCompleteCode, 1, mTotalSize, bcfp);
311 }
312 else
313 {
314 gErrorToText.writeError(efp, 0, 0, LSERROR_ASSEMBLE_OUT_OF_MEMORY);
315 }
316}
317
318LLScriptScriptCodeChunk *gScriptCodeChunk;