blob: 7e8e10d7d5e51c8d95a6f258885e2421b3a7efc0 [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"
Logan474cbd22011-01-31 01:47:44 +080031#include "SourceInfo.h"
Logancf3e5212010-12-29 01:44:55 +080032
Logan89eb47f2011-01-07 10:45:16 +080033#include <errno.h>
Logan474cbd22011-01-31 01:47:44 +080034#include <sys/stat.h>
35#include <sys/types.h>
Logancf3e5212010-12-29 01:44:55 +080036
Logan89eb47f2011-01-07 10:45:16 +080037#include <new>
38#include <string.h>
Logan033f46e2011-01-06 05:51:24 +080039#include <cutils/properties.h>
40
Logan89eb47f2011-01-07 10:45:16 +080041
Loganecf4cbd2011-01-06 05:34:11 +080042namespace {
43
Logan033f46e2011-01-06 05:51:24 +080044bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080045 char buf[PROPERTY_VALUE_MAX];
46 property_get(str, buf, "0");
47 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080048}
49
Loganecf4cbd2011-01-06 05:34:11 +080050} // namespace anonymous
51
Logancf3e5212010-12-29 01:44:55 +080052namespace bcc {
53
54Script::~Script() {
Logan35849002011-01-15 07:30:43 +080055 switch (mStatus) {
56 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080057 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080058 break;
59
60#if USE_CACHE
61 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080062 delete mCached;
Logan35849002011-01-15 07:30:43 +080063 break;
64#endif
65
66 default:
67 break;
Logancf3e5212010-12-29 01:44:55 +080068 }
Logan474cbd22011-01-31 01:47:44 +080069
70 for (size_t i = 0; i < 2; ++i) {
71 delete mSourceList[i];
72 }
Logancf3e5212010-12-29 01:44:55 +080073}
74
75
Logan474cbd22011-01-31 01:47:44 +080076int Script::addSourceBC(size_t idx,
77 char const *resName,
78 const char *bitcode,
79 size_t bitcodeSize,
80 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +080081 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +080082 mErrorCode = BCC_INVALID_OPERATION;
Logan474cbd22011-01-31 01:47:44 +080083 LOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +080084 return 1;
85 }
86
Logan474cbd22011-01-31 01:47:44 +080087 if (!bitcode) {
88 mErrorCode = BCC_INVALID_VALUE;
89 LOGE("Invalid argument: bitcode = NULL\n");
90 return 1;
91 }
92
93 mSourceList[idx] = SourceInfo::createFromBuffer(resName,
94 bitcode, bitcodeSize,
95 flags);
96
97 if (!mSourceList[idx]) {
98 mErrorCode = BCC_OUT_OF_MEMORY;
99 LOGE("Out of memory while adding source bitcode\n");
100 return 1;
101 }
102
Loganecf4cbd2011-01-06 05:34:11 +0800103 return 0;
Logancf3e5212010-12-29 01:44:55 +0800104}
105
106
Logan474cbd22011-01-31 01:47:44 +0800107int Script::addSourceModule(size_t idx,
108 llvm::Module *module,
109 unsigned long flags) {
Logancf3e5212010-12-29 01:44:55 +0800110 if (mStatus != ScriptStatus::Unknown) {
111 mErrorCode = BCC_INVALID_OPERATION;
Logan474cbd22011-01-31 01:47:44 +0800112 LOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800113 return 1;
114 }
115
Logan474cbd22011-01-31 01:47:44 +0800116 if (!module) {
117 mErrorCode = BCC_INVALID_VALUE;
118 LOGE("Invalid argument: module = NULL\n");
119 return 1;
120 }
121
122 mSourceList[idx] = SourceInfo::createFromModule(module, flags);
123
124 if (!mSourceList[idx]) {
125 mErrorCode = BCC_OUT_OF_MEMORY;
126 LOGE("Out of memory when add source module\n");
127 return 1;
128 }
129
Loganecf4cbd2011-01-06 05:34:11 +0800130 return 0;
Logancf3e5212010-12-29 01:44:55 +0800131}
132
133
Logan474cbd22011-01-31 01:47:44 +0800134int Script::addSourceFile(size_t idx,
135 char const *path,
136 unsigned long flags) {
Logan3133c412011-01-06 06:15:40 +0800137 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800138 mErrorCode = BCC_INVALID_OPERATION;
Logan474cbd22011-01-31 01:47:44 +0800139 LOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800140 return 1;
141 }
142
Logan474cbd22011-01-31 01:47:44 +0800143 if (!path) {
144 mErrorCode = BCC_INVALID_VALUE;
145 LOGE("Invalid argument: path = NULL\n");
146 return 1;
147 }
148
149 struct stat sb;
150 if (stat(path, &sb) != 0) {
151 mErrorCode = BCC_INVALID_VALUE;
152 LOGE("File not found: %s\n", path);
153 return 1;
154 }
155
156 mSourceList[idx] = SourceInfo::createFromFile(path, flags);
157
158 if (!mSourceList[idx]) {
159 mErrorCode = BCC_OUT_OF_MEMORY;
160 LOGE("Out of memory while adding source file\n");
161 return 1;
162 }
163
Logan3133c412011-01-06 06:15:40 +0800164 return 0;
Logancf3e5212010-12-29 01:44:55 +0800165}
166
167
Loganf340bf72011-01-14 17:51:40 +0800168int Script::prepareExecutable(char const *cachePath, unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800169 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800170 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +0800171 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800172 return 1;
173 }
174
Logan35849002011-01-15 07:30:43 +0800175#if USE_CACHE
Loganecf4cbd2011-01-06 05:34:11 +0800176 // Load Cache File
Loganf340bf72011-01-14 17:51:40 +0800177 mCachePath = cachePath;
178 if (cachePath && internalLoadCache() == 0) {
Logan033f46e2011-01-06 05:51:24 +0800179 return 0;
180 }
Logan35849002011-01-15 07:30:43 +0800181#endif
Loganecf4cbd2011-01-06 05:34:11 +0800182
Logan033f46e2011-01-06 05:51:24 +0800183 return internalCompile();
184}
185
186
Logan35849002011-01-15 07:30:43 +0800187#if USE_CACHE
Logan033f46e2011-01-06 05:51:24 +0800188int Script::internalLoadCache() {
189 if (getBooleanProp("debug.bcc.nocache")) {
190 // Android system environment property disable the cache mechanism by
191 // setting "debug.bcc.nocache". So we will not load the cache file any
192 // way.
193 return 1;
194 }
195
Loganf340bf72011-01-14 17:51:40 +0800196 if (!mCachePath) {
197 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800198 // we don't know where to open the cache file.
199 return 1;
Logan033f46e2011-01-06 05:51:24 +0800200 }
Logan04329712011-01-06 06:10:57 +0800201
202 FileHandle file;
203
Loganf340bf72011-01-14 17:51:40 +0800204 if (file.open(mCachePath, OpenMode::Read) < 0) {
Logan04329712011-01-06 06:10:57 +0800205 // Unable to open the cache file in read mode.
206 return 1;
207 }
208
Logane7eb7732011-01-07 07:11:56 +0800209 CacheReader reader;
Logan04329712011-01-06 06:10:57 +0800210
Logan9a5f8682011-01-07 06:09:57 +0800211 // Dependencies
Logan35849002011-01-15 07:30:43 +0800212#if USE_LIBBCC_SHA1SUM
Logan9a5f8682011-01-07 06:09:57 +0800213 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800214#endif
215
Logan9a5f8682011-01-07 06:09:57 +0800216 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
217
Logan474cbd22011-01-31 01:47:44 +0800218 for (size_t i = 0; i < 2; ++i) {
219 if (mSourceList[i]) {
220 mSourceList[i]->introDependency(reader);
221 }
Logan9a5f8682011-01-07 06:09:57 +0800222 }
223
224 // Read cache file
Logane7eb7732011-01-07 07:11:56 +0800225 ScriptCached *cached = reader.readCacheFile(&file, this);
Logan04329712011-01-06 06:10:57 +0800226 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800227 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800228 return 1;
229 }
230
231 mCached = cached;
232 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800233
Loganf3c83ce2011-01-07 06:36:33 +0800234 // Dirty hack for libRS.
235 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800236 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800237 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
238 }
239
Loganf7f0ac52011-01-07 03:53:43 +0800240 return 0;
Logan033f46e2011-01-06 05:51:24 +0800241}
Logan35849002011-01-15 07:30:43 +0800242#endif
Logan033f46e2011-01-06 05:51:24 +0800243
244
245int Script::internalCompile() {
246 // Create the ScriptCompiled object
Loganecf4cbd2011-01-06 05:34:11 +0800247 mCompiled = new (nothrow) ScriptCompiled(this);
248
249 if (!mCompiled) {
250 mErrorCode = BCC_OUT_OF_MEMORY;
251 LOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
252 return 1;
253 }
254
255 mStatus = ScriptStatus::Compiled;
256
Logan033f46e2011-01-06 05:51:24 +0800257 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800258 if (mpExtSymbolLookupFn) {
259 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
260 mpExtSymbolLookupFnContext);
261 }
262
Logan474cbd22011-01-31 01:47:44 +0800263 // Parse Bitcode File (if necessary)
264 for (size_t i = 0; i < 2; ++i) {
265 if (mSourceList[i] && mSourceList[i]->prepareModule(mCompiled) != 0) {
266 LOGE("Unable to parse bitcode for source[%lu]\n", (unsigned long)i);
Logan033f46e2011-01-06 05:51:24 +0800267 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800268 }
Logan474cbd22011-01-31 01:47:44 +0800269 }
270
271 // Set the main source module
272 if (!mSourceList[0] || !mSourceList[0]->getModule()) {
273 LOGE("Source bitcode is not setted.\n");
274 return 1;
275 }
276
277 if (mCompiled->readModule(mSourceList[0]->takeModule()) != 0) {
278 LOGE("Unable to read source module\n");
279 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800280 }
281
Logan3133c412011-01-06 06:15:40 +0800282 // Link the source module with the library module
Logan474cbd22011-01-31 01:47:44 +0800283 if (mSourceList[1]) {
284 if (mCompiled->linkModule(mSourceList[1]->takeModule()) != 0) {
285 LOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800286 return 1;
287 }
288 }
Loganecf4cbd2011-01-06 05:34:11 +0800289
Logan3133c412011-01-06 06:15:40 +0800290 // Compile and JIT the code
Logan04329712011-01-06 06:10:57 +0800291 if (mCompiled->compile() != 0) {
Logan65719812011-01-07 11:17:14 +0800292 LOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800293 return 1;
294 }
295
Logan35849002011-01-15 07:30:43 +0800296#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800297 // Note: If we re-compile the script because the cached context slot not
298 // available, then we don't have to write the cache.
299
300 // Note: If the address of the context is not in the context slot, then
301 // we don't have to cache it.
302
Logan42598052011-01-26 22:41:13 +0800303 if (mCachePath &&
Logan1dc63142011-02-25 17:14:51 +0800304 !mIsContextSlotNotAvail &&
305 ContextManager::get().isManagingContext(getContext()) &&
Logan42598052011-01-26 22:41:13 +0800306 !getBooleanProp("debug.bcc.nocache")) {
307
Logan89eb47f2011-01-07 10:45:16 +0800308 FileHandle file;
Logan04329712011-01-06 06:10:57 +0800309
Jeff Brown937a0bc2011-01-26 23:20:14 -0800310 // Remove the file if it already exists before writing the new file.
311 // The old file may still be mapped elsewhere in memory and we do not want
312 // to modify its contents. (The same script may be running concurrently in
313 // the same process or a different process!)
314 ::unlink(mCachePath);
315
Loganf340bf72011-01-14 17:51:40 +0800316 if (file.open(mCachePath, OpenMode::Write) >= 0) {
Logan04329712011-01-06 06:10:57 +0800317 CacheWriter writer;
Logana27a83f2011-01-07 10:25:48 +0800318
Logana2e15af2011-01-07 11:46:08 +0800319 // Dependencies
Logan35849002011-01-15 07:30:43 +0800320#if USE_LIBBCC_SHA1SUM
Logana2e15af2011-01-07 11:46:08 +0800321 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800322#endif
Logana2e15af2011-01-07 11:46:08 +0800323 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
324
Logan474cbd22011-01-31 01:47:44 +0800325 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800326 if (mSourceList[i]) {
327 mSourceList[i]->introDependency(writer);
328 }
Logana2e15af2011-01-07 11:46:08 +0800329 }
330
Logana27a83f2011-01-07 10:25:48 +0800331 // libRS is threadable dirty hack
332 // TODO: This should be removed in the future
333 uint32_t libRS_threadable = 0;
334 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800335 libRS_threadable =
336 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
337 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800338 }
339
Logan89eb47f2011-01-07 10:45:16 +0800340 if (!writer.writeCacheFile(&file, this, libRS_threadable)) {
341 file.truncate();
342 file.close();
Logana27a83f2011-01-07 10:25:48 +0800343
Loganf340bf72011-01-14 17:51:40 +0800344 if (unlink(mCachePath) != 0) {
Logan89eb47f2011-01-07 10:45:16 +0800345 LOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Loganf340bf72011-01-14 17:51:40 +0800346 mCachePath, strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800347 }
348 }
349 }
Logan04329712011-01-06 06:10:57 +0800350 }
Logan35849002011-01-15 07:30:43 +0800351#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800352
353 return 0;
Logancf3e5212010-12-29 01:44:55 +0800354}
355
356
357char const *Script::getCompilerErrorMessage() {
358 if (mStatus != ScriptStatus::Compiled) {
359 mErrorCode = BCC_INVALID_OPERATION;
360 return NULL;
361 }
362
363 return mCompiled->getCompilerErrorMessage();
364}
365
366
367void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800368 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800369 case ScriptStatus::Compiled: return mCompiled->lookup(name);
Logan35849002011-01-15 07:30:43 +0800370#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800371 case ScriptStatus::Cached: return mCached->lookup(name);
Logan35849002011-01-15 07:30:43 +0800372#endif
Logan89eb47f2011-01-07 10:45:16 +0800373
374 default:
Logancf3e5212010-12-29 01:44:55 +0800375 mErrorCode = BCC_INVALID_OPERATION;
376 return NULL;
377 }
Logancf3e5212010-12-29 01:44:55 +0800378}
379
380
Loganbe79ada2011-01-13 01:33:45 +0800381size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800382 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800383 case ScriptStatus::Compiled: return mCompiled->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800384#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800385 case ScriptStatus::Cached: return mCached->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800386#endif
Loganbe79ada2011-01-13 01:33:45 +0800387 default: return 0;
388 }
389}
390
391
392size_t Script::getExportFuncCount() const {
393 switch (mStatus) {
394 case ScriptStatus::Compiled: return mCompiled->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800395#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800396 case ScriptStatus::Cached: return mCached->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800397#endif
Loganbe79ada2011-01-13 01:33:45 +0800398 default: return 0;
399 }
400}
401
402
403size_t Script::getPragmaCount() const {
404 switch (mStatus) {
405 case ScriptStatus::Compiled: return mCompiled->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800406#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800407 case ScriptStatus::Cached: return mCached->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800408#endif
Loganbe79ada2011-01-13 01:33:45 +0800409 default: return 0;
410 }
411}
412
413
414size_t Script::getFuncCount() const {
415 switch (mStatus) {
416 case ScriptStatus::Compiled: return mCompiled->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800417#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800418 case ScriptStatus::Cached: return mCached->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800419#endif
Loganbe79ada2011-01-13 01:33:45 +0800420 default: return 0;
421 }
422}
423
424
Stephen Hines071288a2011-01-27 14:38:26 -0800425size_t Script::getObjectSlotCount() const {
426 switch (mStatus) {
427 case ScriptStatus::Compiled: return mCompiled->getObjectSlotCount();
428#if USE_CACHE
429 case ScriptStatus::Cached: return mCached->getObjectSlotCount();
430#endif
431 default: return 0;
432 }
433}
434
435
Loganbe79ada2011-01-13 01:33:45 +0800436void Script::getExportVarList(size_t varListSize, void **varList) {
437 switch (mStatus) {
438#define DELEGATE(STATUS) \
439 case ScriptStatus::STATUS: \
440 m##STATUS->getExportVarList(varListSize, varList); \
Logan89eb47f2011-01-07 10:45:16 +0800441 break;
Logancf3e5212010-12-29 01:44:55 +0800442
Logan35849002011-01-15 07:30:43 +0800443#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800444 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800445#endif
446
Loganbe79ada2011-01-13 01:33:45 +0800447 DELEGATE(Compiled);
448#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800449
450 default:
451 mErrorCode = BCC_INVALID_OPERATION;
452 }
Logancf3e5212010-12-29 01:44:55 +0800453}
454
455
Loganbe79ada2011-01-13 01:33:45 +0800456void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800457 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800458#define DELEGATE(STATUS) \
459 case ScriptStatus::STATUS: \
460 m##STATUS->getExportFuncList(funcListSize, funcList); \
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
475
Loganbe79ada2011-01-13 01:33:45 +0800476void Script::getPragmaList(size_t pragmaListSize,
477 char const **keyList,
478 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800479 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800480#define DELEGATE(STATUS) \
481 case ScriptStatus::STATUS: \
482 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
Logan89eb47f2011-01-07 10:45:16 +0800483 break;
Logancf3e5212010-12-29 01:44:55 +0800484
Logan35849002011-01-15 07:30:43 +0800485#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800486 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800487#endif
488
Loganbe79ada2011-01-13 01:33:45 +0800489 DELEGATE(Compiled);
490#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800491
492 default:
493 mErrorCode = BCC_INVALID_OPERATION;
494 }
Logancf3e5212010-12-29 01:44:55 +0800495}
496
497
Loganf340bf72011-01-14 17:51:40 +0800498void Script::getFuncInfoList(size_t funcInfoListSize,
499 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800500 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800501#define DELEGATE(STATUS) \
502 case ScriptStatus::STATUS: \
Stephen Hines071288a2011-01-27 14:38:26 -0800503 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
Logan89eb47f2011-01-07 10:45:16 +0800504 break;
Logancf3e5212010-12-29 01:44:55 +0800505
Logan35849002011-01-15 07:30:43 +0800506#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800507 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800508#endif
509
Loganbe79ada2011-01-13 01:33:45 +0800510 DELEGATE(Compiled);
511#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800512
513 default:
514 mErrorCode = BCC_INVALID_OPERATION;
515 }
Logancf3e5212010-12-29 01:44:55 +0800516}
517
Stephen Hines071288a2011-01-27 14:38:26 -0800518
519void Script::getObjectSlotList(size_t objectSlotListSize,
520 uint32_t *objectSlotList) {
521 switch (mStatus) {
522#define DELEGATE(STATUS) \
523 case ScriptStatus::STATUS: \
524 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
525 break;
526
527#if USE_CACHE
528 DELEGATE(Cached);
529#endif
530
531 DELEGATE(Compiled);
532#undef DELEGATE
533
534 default:
535 mErrorCode = BCC_INVALID_OPERATION;
536 }
537}
538
539
Logana27a83f2011-01-07 10:25:48 +0800540char *Script::getContext() {
541 switch (mStatus) {
Logan35849002011-01-15 07:30:43 +0800542#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800543 case ScriptStatus::Cached: return mCached->getContext();
Logan35849002011-01-15 07:30:43 +0800544#endif
Loganbe79ada2011-01-13 01:33:45 +0800545 case ScriptStatus::Compiled: return mCompiled->getContext();
Logana27a83f2011-01-07 10:25:48 +0800546
547 default:
548 mErrorCode = BCC_INVALID_OPERATION;
Logan02286cb2011-01-07 00:30:47 +0800549 return NULL;
550 }
Logan02286cb2011-01-07 00:30:47 +0800551}
552
Logancf3e5212010-12-29 01:44:55 +0800553
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800554int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800555 mpExtSymbolLookupFn = pFn;
556 mpExtSymbolLookupFnContext = pContext;
557
Logan7d2219f2011-01-06 06:19:25 +0800558 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800559 mErrorCode = BCC_INVALID_OPERATION;
Logan7d2219f2011-01-06 06:19:25 +0800560 LOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800561 return 1;
Logancf3e5212010-12-29 01:44:55 +0800562 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800563 return 0;
Logancf3e5212010-12-29 01:44:55 +0800564}
565
566} // namespace bcc