blob: 0e20d9eaded86ef867accc26f6526af6fd3ab180 [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"
Logan04329712011-01-06 06:10:57 +080026#include "FileHandle.h"
Logancf3e5212010-12-29 01:44:55 +080027#include "ScriptCompiled.h"
Logan9a5f8682011-01-07 06:09:57 +080028#include "ScriptCached.h"
29#include "Sha1Helper.h"
Logancf3e5212010-12-29 01:44:55 +080030
Logan89eb47f2011-01-07 10:45:16 +080031#include <errno.h>
Logancf3e5212010-12-29 01:44:55 +080032
Logan89eb47f2011-01-07 10:45:16 +080033#include <new>
34#include <string.h>
Logan033f46e2011-01-06 05:51:24 +080035#include <cutils/properties.h>
36
Logan89eb47f2011-01-07 10:45:16 +080037
Loganecf4cbd2011-01-06 05:34:11 +080038namespace {
39
Logan033f46e2011-01-06 05:51:24 +080040bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080041 char buf[PROPERTY_VALUE_MAX];
42 property_get(str, buf, "0");
43 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080044}
45
Loganecf4cbd2011-01-06 05:34:11 +080046} // namespace anonymous
47
Logancf3e5212010-12-29 01:44:55 +080048namespace bcc {
49
50Script::~Script() {
Logan35849002011-01-15 07:30:43 +080051 switch (mStatus) {
52 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080053 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080054 break;
55
56#if USE_CACHE
57 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080058 delete mCached;
Logan35849002011-01-15 07:30:43 +080059 break;
60#endif
61
62 default:
63 break;
Logancf3e5212010-12-29 01:44:55 +080064 }
65}
66
67
Loganf340bf72011-01-14 17:51:40 +080068int Script::readBC(char const *resName,
69 const char *bitcode,
Logancf3e5212010-12-29 01:44:55 +080070 size_t bitcodeSize,
Loganf340bf72011-01-14 17:51:40 +080071 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +080072 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +080073 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +080074 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +080075 return 1;
76 }
77
Loganecf4cbd2011-01-06 05:34:11 +080078 sourceBC = bitcode;
79 sourceResName = resName;
80 sourceSize = bitcodeSize;
Loganecf4cbd2011-01-06 05:34:11 +080081 return 0;
Logancf3e5212010-12-29 01:44:55 +080082}
83
84
Loganf340bf72011-01-14 17:51:40 +080085int Script::readModule(char const *resName,
86 llvm::Module *module,
87 unsigned long flags) {
Logancf3e5212010-12-29 01:44:55 +080088 if (mStatus != ScriptStatus::Unknown) {
89 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +080090 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +080091 return 1;
92 }
93
Loganecf4cbd2011-01-06 05:34:11 +080094 sourceModule = module;
95 return 0;
Logancf3e5212010-12-29 01:44:55 +080096}
97
98
Loganf340bf72011-01-14 17:51:40 +080099int Script::linkBC(char const *resName,
100 const char *bitcode,
101 size_t bitcodeSize,
102 unsigned long flags) {
Logan3133c412011-01-06 06:15:40 +0800103 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800104 mErrorCode = BCC_INVALID_OPERATION;
Logan3133c412011-01-06 06:15:40 +0800105 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800106 return 1;
107 }
108
Logan3133c412011-01-06 06:15:40 +0800109 libraryBC = bitcode;
110 librarySize = bitcodeSize;
111 return 0;
Logancf3e5212010-12-29 01:44:55 +0800112}
113
114
Loganf340bf72011-01-14 17:51:40 +0800115int Script::prepareExecutable(char const *cachePath, unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800116 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800117 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +0800118 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800119 return 1;
120 }
121
Logan35849002011-01-15 07:30:43 +0800122#if USE_CACHE
Loganecf4cbd2011-01-06 05:34:11 +0800123 // Load Cache File
Loganf340bf72011-01-14 17:51:40 +0800124 mCachePath = cachePath;
125 if (cachePath && internalLoadCache() == 0) {
Logan033f46e2011-01-06 05:51:24 +0800126 return 0;
127 }
Logan35849002011-01-15 07:30:43 +0800128#endif
Loganecf4cbd2011-01-06 05:34:11 +0800129
Logan033f46e2011-01-06 05:51:24 +0800130 return internalCompile();
131}
132
133
Logan35849002011-01-15 07:30:43 +0800134#if USE_CACHE
Logan033f46e2011-01-06 05:51:24 +0800135int Script::internalLoadCache() {
136 if (getBooleanProp("debug.bcc.nocache")) {
137 // Android system environment property disable the cache mechanism by
138 // setting "debug.bcc.nocache". So we will not load the cache file any
139 // way.
140 return 1;
141 }
142
Loganf340bf72011-01-14 17:51:40 +0800143 if (!mCachePath) {
144 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800145 // we don't know where to open the cache file.
146 return 1;
Logan033f46e2011-01-06 05:51:24 +0800147 }
Logan04329712011-01-06 06:10:57 +0800148
Loganf340bf72011-01-14 17:51:40 +0800149 // If we are going to use the cache file. We have to calculate sha1sum
150 // first (no matter we can open the file now or not.)
Logana2e15af2011-01-07 11:46:08 +0800151 if (sourceBC) {
Logana2e15af2011-01-07 11:46:08 +0800152 calcSHA1(sourceSHA1, sourceBC, sourceSize);
153 }
154
Loganf340bf72011-01-14 17:51:40 +0800155 //if (libraryBC) {
156 // calcSHA1(librarySHA1, libraryBC, librarySize);
157 //}
158
Logan04329712011-01-06 06:10:57 +0800159 FileHandle file;
160
Loganf340bf72011-01-14 17:51:40 +0800161 if (file.open(mCachePath, OpenMode::Read) < 0) {
Logan04329712011-01-06 06:10:57 +0800162 // Unable to open the cache file in read mode.
163 return 1;
164 }
165
Logane7eb7732011-01-07 07:11:56 +0800166 CacheReader reader;
Logan04329712011-01-06 06:10:57 +0800167
Logan9a5f8682011-01-07 06:09:57 +0800168 // Dependencies
Logan35849002011-01-15 07:30:43 +0800169#if USE_LIBBCC_SHA1SUM
Logan9a5f8682011-01-07 06:09:57 +0800170 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800171#endif
172
Logan9a5f8682011-01-07 06:09:57 +0800173 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
174
175 if (sourceBC) {
Logan9a5f8682011-01-07 06:09:57 +0800176 reader.addDependency(BCC_APK_RESOURCE, sourceResName, sourceSHA1);
177 }
178
Loganf340bf72011-01-14 17:51:40 +0800179 //if (libraryBC) {
180 // reader.addDependency(BCC_APK_RESOURCE, libraryResName, librarySHA1);
181 //}
182
Logan9a5f8682011-01-07 06:09:57 +0800183 // Read cache file
Logane7eb7732011-01-07 07:11:56 +0800184 ScriptCached *cached = reader.readCacheFile(&file, this);
Logan04329712011-01-06 06:10:57 +0800185 if (!cached) {
186 return 1;
187 }
188
189 mCached = cached;
190 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800191
Loganf3c83ce2011-01-07 06:36:33 +0800192 // Dirty hack for libRS.
193 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800194 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800195 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
196 }
197
Loganf7f0ac52011-01-07 03:53:43 +0800198 return 0;
Logan033f46e2011-01-06 05:51:24 +0800199}
Logan35849002011-01-15 07:30:43 +0800200#endif
Logan033f46e2011-01-06 05:51:24 +0800201
202
203int Script::internalCompile() {
204 // Create the ScriptCompiled object
Loganecf4cbd2011-01-06 05:34:11 +0800205 mCompiled = new (nothrow) ScriptCompiled(this);
206
207 if (!mCompiled) {
208 mErrorCode = BCC_OUT_OF_MEMORY;
209 LOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
210 return 1;
211 }
212
213 mStatus = ScriptStatus::Compiled;
214
Logan033f46e2011-01-06 05:51:24 +0800215 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800216 if (mpExtSymbolLookupFn) {
217 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
218 mpExtSymbolLookupFnContext);
219 }
220
Logan033f46e2011-01-06 05:51:24 +0800221 // Setup the source bitcode / module
Loganecf4cbd2011-01-06 05:34:11 +0800222 if (sourceBC) {
Loganf340bf72011-01-14 17:51:40 +0800223 if (mCompiled->readBC(sourceResName, sourceBC, sourceSize, 0) != 0) {
Logan65719812011-01-07 11:17:14 +0800224 LOGE("Unable to readBC, bitcode=%p, size=%lu\n",
225 sourceBC, (unsigned long)sourceSize);
Logan033f46e2011-01-06 05:51:24 +0800226 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800227 }
Shih-wei Liaoefbd0ed2011-01-07 06:36:25 -0800228 LOGI("Load sourceBC\n");
Loganecf4cbd2011-01-06 05:34:11 +0800229 } else if (sourceModule) {
Loganf340bf72011-01-14 17:51:40 +0800230 if (mCompiled->readModule(NULL, sourceModule, 0) != 0) {
Logan033f46e2011-01-06 05:51:24 +0800231 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800232 }
Shih-wei Liaoefbd0ed2011-01-07 06:36:25 -0800233 LOGI("Load sourceModule\n");
Loganecf4cbd2011-01-06 05:34:11 +0800234 }
235
Logan3133c412011-01-06 06:15:40 +0800236 // Link the source module with the library module
Shih-wei Liao74fbea72011-01-16 15:38:59 -0800237 if (librarySize == 1 /* link against file */ ||
238 libraryBC /* link against buffer */) {
Loganf340bf72011-01-14 17:51:40 +0800239 if (mCompiled->linkBC(NULL, libraryBC, librarySize, 0) != 0) {
Logan04329712011-01-06 06:10:57 +0800240 return 1;
241 }
Logan65719812011-01-07 11:17:14 +0800242
Shih-wei Liao39ebe2c2011-01-28 11:22:32 -0800243 LOGI("Load Library\n");
Logan04329712011-01-06 06:10:57 +0800244 }
Loganecf4cbd2011-01-06 05:34:11 +0800245
Logan3133c412011-01-06 06:15:40 +0800246 // Compile and JIT the code
Logan04329712011-01-06 06:10:57 +0800247 if (mCompiled->compile() != 0) {
Logan65719812011-01-07 11:17:14 +0800248 LOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800249 return 1;
250 }
251
Logan35849002011-01-15 07:30:43 +0800252#if USE_CACHE
Logan04329712011-01-06 06:10:57 +0800253 // TODO(logan): Write the cache out
Loganf340bf72011-01-14 17:51:40 +0800254 if (mCachePath && !getBooleanProp("debug.bcc.nocache")) {
Logan89eb47f2011-01-07 10:45:16 +0800255 FileHandle file;
Logan04329712011-01-06 06:10:57 +0800256
Jeff Brown937a0bc2011-01-26 23:20:14 -0800257 // Remove the file if it already exists before writing the new file.
258 // The old file may still be mapped elsewhere in memory and we do not want
259 // to modify its contents. (The same script may be running concurrently in
260 // the same process or a different process!)
261 ::unlink(mCachePath);
262
Loganf340bf72011-01-14 17:51:40 +0800263 if (file.open(mCachePath, OpenMode::Write) >= 0) {
Logan04329712011-01-06 06:10:57 +0800264 CacheWriter writer;
Logana27a83f2011-01-07 10:25:48 +0800265
Logana2e15af2011-01-07 11:46:08 +0800266 // Dependencies
Logan35849002011-01-15 07:30:43 +0800267#if USE_LIBBCC_SHA1SUM
Logana2e15af2011-01-07 11:46:08 +0800268 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800269#endif
Logana2e15af2011-01-07 11:46:08 +0800270 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
271
272 if (sourceBC) {
273 writer.addDependency(BCC_APK_RESOURCE, sourceResName, sourceSHA1);
274 }
275
Logana27a83f2011-01-07 10:25:48 +0800276 // libRS is threadable dirty hack
277 // TODO: This should be removed in the future
278 uint32_t libRS_threadable = 0;
279 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800280 libRS_threadable =
281 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
282 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800283 }
284
Logan89eb47f2011-01-07 10:45:16 +0800285 if (!writer.writeCacheFile(&file, this, libRS_threadable)) {
286 file.truncate();
287 file.close();
Logana27a83f2011-01-07 10:25:48 +0800288
Loganf340bf72011-01-14 17:51:40 +0800289 if (unlink(mCachePath) != 0) {
Logan89eb47f2011-01-07 10:45:16 +0800290 LOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Loganf340bf72011-01-14 17:51:40 +0800291 mCachePath, strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800292 }
293 }
294 }
Logan04329712011-01-06 06:10:57 +0800295 }
Logan35849002011-01-15 07:30:43 +0800296#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800297
298 return 0;
Logancf3e5212010-12-29 01:44:55 +0800299}
300
301
302char const *Script::getCompilerErrorMessage() {
303 if (mStatus != ScriptStatus::Compiled) {
304 mErrorCode = BCC_INVALID_OPERATION;
305 return NULL;
306 }
307
308 return mCompiled->getCompilerErrorMessage();
309}
310
311
312void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800313 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800314 case ScriptStatus::Compiled: return mCompiled->lookup(name);
Logan35849002011-01-15 07:30:43 +0800315#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800316 case ScriptStatus::Cached: return mCached->lookup(name);
Logan35849002011-01-15 07:30:43 +0800317#endif
Logan89eb47f2011-01-07 10:45:16 +0800318
319 default:
Logancf3e5212010-12-29 01:44:55 +0800320 mErrorCode = BCC_INVALID_OPERATION;
321 return NULL;
322 }
Logancf3e5212010-12-29 01:44:55 +0800323}
324
325
Loganbe79ada2011-01-13 01:33:45 +0800326size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800327 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800328 case ScriptStatus::Compiled: return mCompiled->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800329#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800330 case ScriptStatus::Cached: return mCached->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800331#endif
Loganbe79ada2011-01-13 01:33:45 +0800332 default: return 0;
333 }
334}
335
336
337size_t Script::getExportFuncCount() const {
338 switch (mStatus) {
339 case ScriptStatus::Compiled: return mCompiled->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800340#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800341 case ScriptStatus::Cached: return mCached->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800342#endif
Loganbe79ada2011-01-13 01:33:45 +0800343 default: return 0;
344 }
345}
346
347
348size_t Script::getPragmaCount() const {
349 switch (mStatus) {
350 case ScriptStatus::Compiled: return mCompiled->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800351#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800352 case ScriptStatus::Cached: return mCached->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800353#endif
Loganbe79ada2011-01-13 01:33:45 +0800354 default: return 0;
355 }
356}
357
358
359size_t Script::getFuncCount() const {
360 switch (mStatus) {
361 case ScriptStatus::Compiled: return mCompiled->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800362#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800363 case ScriptStatus::Cached: return mCached->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800364#endif
Loganbe79ada2011-01-13 01:33:45 +0800365 default: return 0;
366 }
367}
368
369
Stephen Hines071288a2011-01-27 14:38:26 -0800370size_t Script::getObjectSlotCount() const {
371 switch (mStatus) {
372 case ScriptStatus::Compiled: return mCompiled->getObjectSlotCount();
373#if USE_CACHE
374 case ScriptStatus::Cached: return mCached->getObjectSlotCount();
375#endif
376 default: return 0;
377 }
378}
379
380
Loganbe79ada2011-01-13 01:33:45 +0800381void Script::getExportVarList(size_t varListSize, void **varList) {
382 switch (mStatus) {
383#define DELEGATE(STATUS) \
384 case ScriptStatus::STATUS: \
385 m##STATUS->getExportVarList(varListSize, varList); \
Logan89eb47f2011-01-07 10:45:16 +0800386 break;
Logancf3e5212010-12-29 01:44:55 +0800387
Logan35849002011-01-15 07:30:43 +0800388#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800389 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800390#endif
391
Loganbe79ada2011-01-13 01:33:45 +0800392 DELEGATE(Compiled);
393#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800394
395 default:
396 mErrorCode = BCC_INVALID_OPERATION;
397 }
Logancf3e5212010-12-29 01:44:55 +0800398}
399
400
Loganbe79ada2011-01-13 01:33:45 +0800401void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800402 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800403#define DELEGATE(STATUS) \
404 case ScriptStatus::STATUS: \
405 m##STATUS->getExportFuncList(funcListSize, funcList); \
Logan89eb47f2011-01-07 10:45:16 +0800406 break;
Logancf3e5212010-12-29 01:44:55 +0800407
Logan35849002011-01-15 07:30:43 +0800408#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800409 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800410#endif
411
Loganbe79ada2011-01-13 01:33:45 +0800412 DELEGATE(Compiled);
413#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800414
415 default:
416 mErrorCode = BCC_INVALID_OPERATION;
417 }
Logancf3e5212010-12-29 01:44:55 +0800418}
419
420
Loganbe79ada2011-01-13 01:33:45 +0800421void Script::getPragmaList(size_t pragmaListSize,
422 char const **keyList,
423 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800424 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800425#define DELEGATE(STATUS) \
426 case ScriptStatus::STATUS: \
427 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
Logan89eb47f2011-01-07 10:45:16 +0800428 break;
Logancf3e5212010-12-29 01:44:55 +0800429
Logan35849002011-01-15 07:30:43 +0800430#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800431 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800432#endif
433
Loganbe79ada2011-01-13 01:33:45 +0800434 DELEGATE(Compiled);
435#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800436
437 default:
438 mErrorCode = BCC_INVALID_OPERATION;
439 }
Logancf3e5212010-12-29 01:44:55 +0800440}
441
442
Loganf340bf72011-01-14 17:51:40 +0800443void Script::getFuncInfoList(size_t funcInfoListSize,
444 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800445 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800446#define DELEGATE(STATUS) \
447 case ScriptStatus::STATUS: \
Stephen Hines071288a2011-01-27 14:38:26 -0800448 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
Logan89eb47f2011-01-07 10:45:16 +0800449 break;
Logancf3e5212010-12-29 01:44:55 +0800450
Logan35849002011-01-15 07:30:43 +0800451#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800452 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800453#endif
454
Loganbe79ada2011-01-13 01:33:45 +0800455 DELEGATE(Compiled);
456#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800457
458 default:
459 mErrorCode = BCC_INVALID_OPERATION;
460 }
Logancf3e5212010-12-29 01:44:55 +0800461}
462
Stephen Hines071288a2011-01-27 14:38:26 -0800463
464void Script::getObjectSlotList(size_t objectSlotListSize,
465 uint32_t *objectSlotList) {
466 switch (mStatus) {
467#define DELEGATE(STATUS) \
468 case ScriptStatus::STATUS: \
469 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
470 break;
471
472#if USE_CACHE
473 DELEGATE(Cached);
474#endif
475
476 DELEGATE(Compiled);
477#undef DELEGATE
478
479 default:
480 mErrorCode = BCC_INVALID_OPERATION;
481 }
482}
483
484
Logana27a83f2011-01-07 10:25:48 +0800485char *Script::getContext() {
486 switch (mStatus) {
Logan35849002011-01-15 07:30:43 +0800487#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800488 case ScriptStatus::Cached: return mCached->getContext();
Logan35849002011-01-15 07:30:43 +0800489#endif
Loganbe79ada2011-01-13 01:33:45 +0800490 case ScriptStatus::Compiled: return mCompiled->getContext();
Logana27a83f2011-01-07 10:25:48 +0800491
492 default:
493 mErrorCode = BCC_INVALID_OPERATION;
Logan02286cb2011-01-07 00:30:47 +0800494 return NULL;
495 }
Logan02286cb2011-01-07 00:30:47 +0800496}
497
Logancf3e5212010-12-29 01:44:55 +0800498
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800499int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800500 mpExtSymbolLookupFn = pFn;
501 mpExtSymbolLookupFnContext = pContext;
502
Logan7d2219f2011-01-06 06:19:25 +0800503 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800504 mErrorCode = BCC_INVALID_OPERATION;
Logan7d2219f2011-01-06 06:19:25 +0800505 LOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800506 return 1;
Logancf3e5212010-12-29 01:44:55 +0800507 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800508 return 0;
Logancf3e5212010-12-29 01:44:55 +0800509}
510
511} // namespace bcc