blob: 23fe9cf9ebf840581c14f60bfee6e3f7a8f1b538 [file] [log] [blame]
Logancf3e5212010-12-29 01:44:55 +08001/*
2 * copyright 2010, the android open source project
3 *
4 * licensed under the apache license, version 2.0 (the "license");
5 * you may not use this file except in compliance with the license.
6 * you may obtain a copy of the license at
7 *
8 * http://www.apache.org/licenses/license-2.0
9 *
10 * unless required by applicable law or agreed to in writing, software
11 * distributed under the license is distributed on an "as is" basis,
12 * without warranties or conditions of any kind, either express or implied.
13 * see the license for the specific language governing permissions and
14 * limitations under the license.
15 */
16
17#define LOG_TAG "bcc"
18#include <cutils/log.h>
19
20#include "Script.h"
21
Logan35849002011-01-15 07:30:43 +080022#include "Config.h"
23
Loganf7f0ac52011-01-07 03:53:43 +080024#include "CacheReader.h"
Logan89eb47f2011-01-07 10:45:16 +080025#include "CacheWriter.h"
Logan42598052011-01-26 22:41:13 +080026#include "ContextManager.h"
Logan04329712011-01-06 06:10:57 +080027#include "FileHandle.h"
Logancf3e5212010-12-29 01:44:55 +080028#include "ScriptCompiled.h"
Logan9a5f8682011-01-07 06:09:57 +080029#include "ScriptCached.h"
30#include "Sha1Helper.h"
Logancf3e5212010-12-29 01:44:55 +080031
Logan89eb47f2011-01-07 10:45:16 +080032#include <errno.h>
Logancf3e5212010-12-29 01:44:55 +080033
Logan89eb47f2011-01-07 10:45:16 +080034#include <new>
35#include <string.h>
Logan033f46e2011-01-06 05:51:24 +080036#include <cutils/properties.h>
37
Logan89eb47f2011-01-07 10:45:16 +080038
Loganecf4cbd2011-01-06 05:34:11 +080039namespace {
40
Logan033f46e2011-01-06 05:51:24 +080041bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080042 char buf[PROPERTY_VALUE_MAX];
43 property_get(str, buf, "0");
44 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080045}
46
Loganecf4cbd2011-01-06 05:34:11 +080047} // namespace anonymous
48
Logancf3e5212010-12-29 01:44:55 +080049namespace bcc {
50
51Script::~Script() {
Logan35849002011-01-15 07:30:43 +080052 switch (mStatus) {
53 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080054 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080055 break;
56
57#if USE_CACHE
58 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080059 delete mCached;
Logan35849002011-01-15 07:30:43 +080060 break;
61#endif
62
63 default:
64 break;
Logancf3e5212010-12-29 01:44:55 +080065 }
66}
67
68
Loganf340bf72011-01-14 17:51:40 +080069int Script::readBC(char const *resName,
70 const char *bitcode,
Logancf3e5212010-12-29 01:44:55 +080071 size_t bitcodeSize,
Loganf340bf72011-01-14 17:51:40 +080072 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +080073 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +080074 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +080075 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +080076 return 1;
77 }
78
Loganecf4cbd2011-01-06 05:34:11 +080079 sourceBC = bitcode;
80 sourceResName = resName;
81 sourceSize = bitcodeSize;
Loganecf4cbd2011-01-06 05:34:11 +080082 return 0;
Logancf3e5212010-12-29 01:44:55 +080083}
84
85
Loganf340bf72011-01-14 17:51:40 +080086int Script::readModule(char const *resName,
87 llvm::Module *module,
88 unsigned long flags) {
Logancf3e5212010-12-29 01:44:55 +080089 if (mStatus != ScriptStatus::Unknown) {
90 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +080091 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +080092 return 1;
93 }
94
Loganecf4cbd2011-01-06 05:34:11 +080095 sourceModule = module;
96 return 0;
Logancf3e5212010-12-29 01:44:55 +080097}
98
99
Loganf340bf72011-01-14 17:51:40 +0800100int Script::linkBC(char const *resName,
101 const char *bitcode,
102 size_t bitcodeSize,
103 unsigned long flags) {
Logan3133c412011-01-06 06:15:40 +0800104 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800105 mErrorCode = BCC_INVALID_OPERATION;
Logan3133c412011-01-06 06:15:40 +0800106 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800107 return 1;
108 }
109
Logan3133c412011-01-06 06:15:40 +0800110 libraryBC = bitcode;
111 librarySize = bitcodeSize;
112 return 0;
Logancf3e5212010-12-29 01:44:55 +0800113}
114
115
Loganf340bf72011-01-14 17:51:40 +0800116int Script::prepareExecutable(char const *cachePath, unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800117 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800118 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +0800119 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800120 return 1;
121 }
122
Logan35849002011-01-15 07:30:43 +0800123#if USE_CACHE
Loganecf4cbd2011-01-06 05:34:11 +0800124 // Load Cache File
Loganf340bf72011-01-14 17:51:40 +0800125 mCachePath = cachePath;
126 if (cachePath && internalLoadCache() == 0) {
Logan033f46e2011-01-06 05:51:24 +0800127 return 0;
128 }
Logan35849002011-01-15 07:30:43 +0800129#endif
Loganecf4cbd2011-01-06 05:34:11 +0800130
Logan033f46e2011-01-06 05:51:24 +0800131 return internalCompile();
132}
133
134
Logan35849002011-01-15 07:30:43 +0800135#if USE_CACHE
Logan033f46e2011-01-06 05:51:24 +0800136int Script::internalLoadCache() {
137 if (getBooleanProp("debug.bcc.nocache")) {
138 // Android system environment property disable the cache mechanism by
139 // setting "debug.bcc.nocache". So we will not load the cache file any
140 // way.
141 return 1;
142 }
143
Loganf340bf72011-01-14 17:51:40 +0800144 if (!mCachePath) {
145 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800146 // we don't know where to open the cache file.
147 return 1;
Logan033f46e2011-01-06 05:51:24 +0800148 }
Logan04329712011-01-06 06:10:57 +0800149
Loganf340bf72011-01-14 17:51:40 +0800150 // If we are going to use the cache file. We have to calculate sha1sum
151 // first (no matter we can open the file now or not.)
Logana2e15af2011-01-07 11:46:08 +0800152 if (sourceBC) {
Logana2e15af2011-01-07 11:46:08 +0800153 calcSHA1(sourceSHA1, sourceBC, sourceSize);
154 }
155
Loganf340bf72011-01-14 17:51:40 +0800156 //if (libraryBC) {
157 // calcSHA1(librarySHA1, libraryBC, librarySize);
158 //}
159
Logan04329712011-01-06 06:10:57 +0800160 FileHandle file;
161
Loganf340bf72011-01-14 17:51:40 +0800162 if (file.open(mCachePath, OpenMode::Read) < 0) {
Logan04329712011-01-06 06:10:57 +0800163 // Unable to open the cache file in read mode.
164 return 1;
165 }
166
Logane7eb7732011-01-07 07:11:56 +0800167 CacheReader reader;
Logan04329712011-01-06 06:10:57 +0800168
Logan9a5f8682011-01-07 06:09:57 +0800169 // Dependencies
Logan35849002011-01-15 07:30:43 +0800170#if USE_LIBBCC_SHA1SUM
Logan9a5f8682011-01-07 06:09:57 +0800171 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800172#endif
173
Logan9a5f8682011-01-07 06:09:57 +0800174 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
175
176 if (sourceBC) {
Logan9a5f8682011-01-07 06:09:57 +0800177 reader.addDependency(BCC_APK_RESOURCE, sourceResName, sourceSHA1);
178 }
179
Loganf340bf72011-01-14 17:51:40 +0800180 //if (libraryBC) {
181 // reader.addDependency(BCC_APK_RESOURCE, libraryResName, librarySHA1);
182 //}
183
Logan9a5f8682011-01-07 06:09:57 +0800184 // Read cache file
Logane7eb7732011-01-07 07:11:56 +0800185 ScriptCached *cached = reader.readCacheFile(&file, this);
Logan04329712011-01-06 06:10:57 +0800186 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800187 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800188 return 1;
189 }
190
191 mCached = cached;
192 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800193
Loganf3c83ce2011-01-07 06:36:33 +0800194 // Dirty hack for libRS.
195 // TODO(all): This dirty hack should be removed in the future.
196 if (cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
197 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
198 }
199
Loganf7f0ac52011-01-07 03:53:43 +0800200 return 0;
Logan033f46e2011-01-06 05:51:24 +0800201}
Logan35849002011-01-15 07:30:43 +0800202#endif
Logan033f46e2011-01-06 05:51:24 +0800203
204
205int Script::internalCompile() {
206 // Create the ScriptCompiled object
Loganecf4cbd2011-01-06 05:34:11 +0800207 mCompiled = new (nothrow) ScriptCompiled(this);
208
209 if (!mCompiled) {
210 mErrorCode = BCC_OUT_OF_MEMORY;
211 LOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
212 return 1;
213 }
214
215 mStatus = ScriptStatus::Compiled;
216
Logan033f46e2011-01-06 05:51:24 +0800217 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800218 if (mpExtSymbolLookupFn) {
219 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
220 mpExtSymbolLookupFnContext);
221 }
222
Logan033f46e2011-01-06 05:51:24 +0800223 // Setup the source bitcode / module
Loganecf4cbd2011-01-06 05:34:11 +0800224 if (sourceBC) {
Loganf340bf72011-01-14 17:51:40 +0800225 if (mCompiled->readBC(sourceResName, sourceBC, sourceSize, 0) != 0) {
Logan65719812011-01-07 11:17:14 +0800226 LOGE("Unable to readBC, bitcode=%p, size=%lu\n",
227 sourceBC, (unsigned long)sourceSize);
Logan033f46e2011-01-06 05:51:24 +0800228 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800229 }
Shih-wei Liaoefbd0ed2011-01-07 06:36:25 -0800230 LOGI("Load sourceBC\n");
Loganecf4cbd2011-01-06 05:34:11 +0800231 } else if (sourceModule) {
Loganf340bf72011-01-14 17:51:40 +0800232 if (mCompiled->readModule(NULL, sourceModule, 0) != 0) {
Logan033f46e2011-01-06 05:51:24 +0800233 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800234 }
Shih-wei Liaoefbd0ed2011-01-07 06:36:25 -0800235 LOGI("Load sourceModule\n");
Loganecf4cbd2011-01-06 05:34:11 +0800236 }
237
Logan3133c412011-01-06 06:15:40 +0800238 // Link the source module with the library module
Shih-wei Liao74fbea72011-01-16 15:38:59 -0800239 if (librarySize == 1 /* link against file */ ||
240 libraryBC /* link against buffer */) {
Loganf340bf72011-01-14 17:51:40 +0800241 if (mCompiled->linkBC(NULL, libraryBC, librarySize, 0) != 0) {
Logan04329712011-01-06 06:10:57 +0800242 return 1;
243 }
Logan65719812011-01-07 11:17:14 +0800244
Shih-wei Liao39ebe2c2011-01-28 11:22:32 -0800245 LOGI("Load Library\n");
Logan04329712011-01-06 06:10:57 +0800246 }
Loganecf4cbd2011-01-06 05:34:11 +0800247
Logan3133c412011-01-06 06:15:40 +0800248 // Compile and JIT the code
Logan04329712011-01-06 06:10:57 +0800249 if (mCompiled->compile() != 0) {
Logan65719812011-01-07 11:17:14 +0800250 LOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800251 return 1;
252 }
253
Logan35849002011-01-15 07:30:43 +0800254#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800255 // Note: If we re-compile the script because the cached context slot not
256 // available, then we don't have to write the cache.
257
258 // Note: If the address of the context is not in the context slot, then
259 // we don't have to cache it.
260
261 char *addr = getContext();
262
263 if (mCachePath &&
264 !mIsContextSlotNotAvail && getSlotIndexFromAddress(addr) >= 0 &&
265 !getBooleanProp("debug.bcc.nocache")) {
266
Logan89eb47f2011-01-07 10:45:16 +0800267 FileHandle file;
Logan04329712011-01-06 06:10:57 +0800268
Jeff Brown937a0bc2011-01-26 23:20:14 -0800269 // Remove the file if it already exists before writing the new file.
270 // The old file may still be mapped elsewhere in memory and we do not want
271 // to modify its contents. (The same script may be running concurrently in
272 // the same process or a different process!)
273 ::unlink(mCachePath);
274
Loganf340bf72011-01-14 17:51:40 +0800275 if (file.open(mCachePath, OpenMode::Write) >= 0) {
Logan04329712011-01-06 06:10:57 +0800276 CacheWriter writer;
Logana27a83f2011-01-07 10:25:48 +0800277
Logana2e15af2011-01-07 11:46:08 +0800278 // Dependencies
Logan35849002011-01-15 07:30:43 +0800279#if USE_LIBBCC_SHA1SUM
Logana2e15af2011-01-07 11:46:08 +0800280 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800281#endif
Logana2e15af2011-01-07 11:46:08 +0800282 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
283
284 if (sourceBC) {
285 writer.addDependency(BCC_APK_RESOURCE, sourceResName, sourceSHA1);
286 }
287
Logana27a83f2011-01-07 10:25:48 +0800288 // libRS is threadable dirty hack
289 // TODO: This should be removed in the future
290 uint32_t libRS_threadable = 0;
291 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800292 libRS_threadable =
293 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
294 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800295 }
296
Logan89eb47f2011-01-07 10:45:16 +0800297 if (!writer.writeCacheFile(&file, this, libRS_threadable)) {
298 file.truncate();
299 file.close();
Logana27a83f2011-01-07 10:25:48 +0800300
Loganf340bf72011-01-14 17:51:40 +0800301 if (unlink(mCachePath) != 0) {
Logan89eb47f2011-01-07 10:45:16 +0800302 LOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Loganf340bf72011-01-14 17:51:40 +0800303 mCachePath, strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800304 }
305 }
306 }
Logan04329712011-01-06 06:10:57 +0800307 }
Logan35849002011-01-15 07:30:43 +0800308#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800309
310 return 0;
Logancf3e5212010-12-29 01:44:55 +0800311}
312
313
314char const *Script::getCompilerErrorMessage() {
315 if (mStatus != ScriptStatus::Compiled) {
316 mErrorCode = BCC_INVALID_OPERATION;
317 return NULL;
318 }
319
320 return mCompiled->getCompilerErrorMessage();
321}
322
323
324void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800325 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800326 case ScriptStatus::Compiled: return mCompiled->lookup(name);
Logan35849002011-01-15 07:30:43 +0800327#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800328 case ScriptStatus::Cached: return mCached->lookup(name);
Logan35849002011-01-15 07:30:43 +0800329#endif
Logan89eb47f2011-01-07 10:45:16 +0800330
331 default:
Logancf3e5212010-12-29 01:44:55 +0800332 mErrorCode = BCC_INVALID_OPERATION;
333 return NULL;
334 }
Logancf3e5212010-12-29 01:44:55 +0800335}
336
337
Loganbe79ada2011-01-13 01:33:45 +0800338size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800339 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800340 case ScriptStatus::Compiled: return mCompiled->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800341#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800342 case ScriptStatus::Cached: return mCached->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800343#endif
Loganbe79ada2011-01-13 01:33:45 +0800344 default: return 0;
345 }
346}
347
348
349size_t Script::getExportFuncCount() const {
350 switch (mStatus) {
351 case ScriptStatus::Compiled: return mCompiled->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800352#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800353 case ScriptStatus::Cached: return mCached->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800354#endif
Loganbe79ada2011-01-13 01:33:45 +0800355 default: return 0;
356 }
357}
358
359
360size_t Script::getPragmaCount() const {
361 switch (mStatus) {
362 case ScriptStatus::Compiled: return mCompiled->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800363#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800364 case ScriptStatus::Cached: return mCached->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800365#endif
Loganbe79ada2011-01-13 01:33:45 +0800366 default: return 0;
367 }
368}
369
370
371size_t Script::getFuncCount() const {
372 switch (mStatus) {
373 case ScriptStatus::Compiled: return mCompiled->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800374#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800375 case ScriptStatus::Cached: return mCached->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800376#endif
Loganbe79ada2011-01-13 01:33:45 +0800377 default: return 0;
378 }
379}
380
381
Stephen Hines071288a2011-01-27 14:38:26 -0800382size_t Script::getObjectSlotCount() const {
383 switch (mStatus) {
384 case ScriptStatus::Compiled: return mCompiled->getObjectSlotCount();
385#if USE_CACHE
386 case ScriptStatus::Cached: return mCached->getObjectSlotCount();
387#endif
388 default: return 0;
389 }
390}
391
392
Loganbe79ada2011-01-13 01:33:45 +0800393void Script::getExportVarList(size_t varListSize, void **varList) {
394 switch (mStatus) {
395#define DELEGATE(STATUS) \
396 case ScriptStatus::STATUS: \
397 m##STATUS->getExportVarList(varListSize, varList); \
Logan89eb47f2011-01-07 10:45:16 +0800398 break;
Logancf3e5212010-12-29 01:44:55 +0800399
Logan35849002011-01-15 07:30:43 +0800400#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800401 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800402#endif
403
Loganbe79ada2011-01-13 01:33:45 +0800404 DELEGATE(Compiled);
405#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800406
407 default:
408 mErrorCode = BCC_INVALID_OPERATION;
409 }
Logancf3e5212010-12-29 01:44:55 +0800410}
411
412
Loganbe79ada2011-01-13 01:33:45 +0800413void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800414 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800415#define DELEGATE(STATUS) \
416 case ScriptStatus::STATUS: \
417 m##STATUS->getExportFuncList(funcListSize, funcList); \
Logan89eb47f2011-01-07 10:45:16 +0800418 break;
Logancf3e5212010-12-29 01:44:55 +0800419
Logan35849002011-01-15 07:30:43 +0800420#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800421 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800422#endif
423
Loganbe79ada2011-01-13 01:33:45 +0800424 DELEGATE(Compiled);
425#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800426
427 default:
428 mErrorCode = BCC_INVALID_OPERATION;
429 }
Logancf3e5212010-12-29 01:44:55 +0800430}
431
432
Loganbe79ada2011-01-13 01:33:45 +0800433void Script::getPragmaList(size_t pragmaListSize,
434 char const **keyList,
435 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800436 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800437#define DELEGATE(STATUS) \
438 case ScriptStatus::STATUS: \
439 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
Logan89eb47f2011-01-07 10:45:16 +0800440 break;
Logancf3e5212010-12-29 01:44:55 +0800441
Logan35849002011-01-15 07:30:43 +0800442#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800443 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800444#endif
445
Loganbe79ada2011-01-13 01:33:45 +0800446 DELEGATE(Compiled);
447#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800448
449 default:
450 mErrorCode = BCC_INVALID_OPERATION;
451 }
Logancf3e5212010-12-29 01:44:55 +0800452}
453
454
Loganf340bf72011-01-14 17:51:40 +0800455void Script::getFuncInfoList(size_t funcInfoListSize,
456 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800457 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800458#define DELEGATE(STATUS) \
459 case ScriptStatus::STATUS: \
Stephen Hines071288a2011-01-27 14:38:26 -0800460 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
Logan89eb47f2011-01-07 10:45:16 +0800461 break;
Logancf3e5212010-12-29 01:44:55 +0800462
Logan35849002011-01-15 07:30:43 +0800463#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800464 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800465#endif
466
Loganbe79ada2011-01-13 01:33:45 +0800467 DELEGATE(Compiled);
468#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800469
470 default:
471 mErrorCode = BCC_INVALID_OPERATION;
472 }
Logancf3e5212010-12-29 01:44:55 +0800473}
474
Stephen Hines071288a2011-01-27 14:38:26 -0800475
476void Script::getObjectSlotList(size_t objectSlotListSize,
477 uint32_t *objectSlotList) {
478 switch (mStatus) {
479#define DELEGATE(STATUS) \
480 case ScriptStatus::STATUS: \
481 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
482 break;
483
484#if USE_CACHE
485 DELEGATE(Cached);
486#endif
487
488 DELEGATE(Compiled);
489#undef DELEGATE
490
491 default:
492 mErrorCode = BCC_INVALID_OPERATION;
493 }
494}
495
496
Logana27a83f2011-01-07 10:25:48 +0800497char *Script::getContext() {
498 switch (mStatus) {
Logan35849002011-01-15 07:30:43 +0800499#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800500 case ScriptStatus::Cached: return mCached->getContext();
Logan35849002011-01-15 07:30:43 +0800501#endif
Loganbe79ada2011-01-13 01:33:45 +0800502 case ScriptStatus::Compiled: return mCompiled->getContext();
Logana27a83f2011-01-07 10:25:48 +0800503
504 default:
505 mErrorCode = BCC_INVALID_OPERATION;
Logan02286cb2011-01-07 00:30:47 +0800506 return NULL;
507 }
Logan02286cb2011-01-07 00:30:47 +0800508}
509
Logancf3e5212010-12-29 01:44:55 +0800510
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800511int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800512 mpExtSymbolLookupFn = pFn;
513 mpExtSymbolLookupFnContext = pContext;
514
Logan7d2219f2011-01-06 06:19:25 +0800515 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800516 mErrorCode = BCC_INVALID_OPERATION;
Logan7d2219f2011-01-06 06:19:25 +0800517 LOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800518 return 1;
Logancf3e5212010-12-29 01:44:55 +0800519 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800520 return 0;
Logancf3e5212010-12-29 01:44:55 +0800521}
522
523} // namespace bcc