blob: cc9801a5927f171f71a44718aef3e71aab7c330f [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
Logancf3e5212010-12-29 01:44:55 +080017#include "Script.h"
18
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
20
Loganf7f0ac52011-01-07 03:53:43 +080021#include "CacheReader.h"
Logan89eb47f2011-01-07 10:45:16 +080022#include "CacheWriter.h"
Logan42598052011-01-26 22:41:13 +080023#include "ContextManager.h"
Logan4dcd6792011-02-28 05:12:00 +080024#include "DebugHelper.h"
Logan04329712011-01-06 06:10:57 +080025#include "FileHandle.h"
Logancf3e5212010-12-29 01:44:55 +080026#include "ScriptCompiled.h"
Logan9a5f8682011-01-07 06:09:57 +080027#include "ScriptCached.h"
28#include "Sha1Helper.h"
Logan474cbd22011-01-31 01:47:44 +080029#include "SourceInfo.h"
Logancf3e5212010-12-29 01:44:55 +080030
Logan89eb47f2011-01-07 10:45:16 +080031#include <errno.h>
Logan474cbd22011-01-31 01:47:44 +080032#include <sys/stat.h>
33#include <sys/types.h>
Logancf3e5212010-12-29 01:44:55 +080034
Logan89eb47f2011-01-07 10:45:16 +080035#include <new>
36#include <string.h>
Logan033f46e2011-01-06 05:51:24 +080037#include <cutils/properties.h>
38
Logan89eb47f2011-01-07 10:45:16 +080039
Loganecf4cbd2011-01-06 05:34:11 +080040namespace {
41
Logan033f46e2011-01-06 05:51:24 +080042bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080043 char buf[PROPERTY_VALUE_MAX];
44 property_get(str, buf, "0");
45 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080046}
47
Loganecf4cbd2011-01-06 05:34:11 +080048} // namespace anonymous
49
Logancf3e5212010-12-29 01:44:55 +080050namespace bcc {
51
52Script::~Script() {
Logan35849002011-01-15 07:30:43 +080053 switch (mStatus) {
54 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080055 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080056 break;
57
58#if USE_CACHE
59 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080060 delete mCached;
Logan35849002011-01-15 07:30:43 +080061 break;
62#endif
63
64 default:
65 break;
Logancf3e5212010-12-29 01:44:55 +080066 }
Logan474cbd22011-01-31 01:47:44 +080067
68 for (size_t i = 0; i < 2; ++i) {
69 delete mSourceList[i];
70 }
Logancf3e5212010-12-29 01:44:55 +080071}
72
73
Logan474cbd22011-01-31 01:47:44 +080074int Script::addSourceBC(size_t idx,
75 char const *resName,
76 const char *bitcode,
77 size_t bitcodeSize,
78 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +080079 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +080080 mErrorCode = BCC_INVALID_OPERATION;
Logan474cbd22011-01-31 01:47:44 +080081 LOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +080082 return 1;
83 }
84
Logan474cbd22011-01-31 01:47:44 +080085 if (!bitcode) {
86 mErrorCode = BCC_INVALID_VALUE;
87 LOGE("Invalid argument: bitcode = NULL\n");
88 return 1;
89 }
90
91 mSourceList[idx] = SourceInfo::createFromBuffer(resName,
92 bitcode, bitcodeSize,
93 flags);
94
95 if (!mSourceList[idx]) {
96 mErrorCode = BCC_OUT_OF_MEMORY;
97 LOGE("Out of memory while adding source bitcode\n");
98 return 1;
99 }
100
Loganecf4cbd2011-01-06 05:34:11 +0800101 return 0;
Logancf3e5212010-12-29 01:44:55 +0800102}
103
104
Logan474cbd22011-01-31 01:47:44 +0800105int Script::addSourceModule(size_t idx,
106 llvm::Module *module,
107 unsigned long flags) {
Logancf3e5212010-12-29 01:44:55 +0800108 if (mStatus != ScriptStatus::Unknown) {
109 mErrorCode = BCC_INVALID_OPERATION;
Logan474cbd22011-01-31 01:47:44 +0800110 LOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800111 return 1;
112 }
113
Logan474cbd22011-01-31 01:47:44 +0800114 if (!module) {
115 mErrorCode = BCC_INVALID_VALUE;
116 LOGE("Invalid argument: module = NULL\n");
117 return 1;
118 }
119
120 mSourceList[idx] = SourceInfo::createFromModule(module, flags);
121
122 if (!mSourceList[idx]) {
123 mErrorCode = BCC_OUT_OF_MEMORY;
124 LOGE("Out of memory when add source module\n");
125 return 1;
126 }
127
Loganecf4cbd2011-01-06 05:34:11 +0800128 return 0;
Logancf3e5212010-12-29 01:44:55 +0800129}
130
131
Logan474cbd22011-01-31 01:47:44 +0800132int Script::addSourceFile(size_t idx,
133 char const *path,
134 unsigned long flags) {
Logan3133c412011-01-06 06:15:40 +0800135 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800136 mErrorCode = BCC_INVALID_OPERATION;
Logan474cbd22011-01-31 01:47:44 +0800137 LOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800138 return 1;
139 }
140
Logan474cbd22011-01-31 01:47:44 +0800141 if (!path) {
142 mErrorCode = BCC_INVALID_VALUE;
143 LOGE("Invalid argument: path = NULL\n");
144 return 1;
145 }
146
147 struct stat sb;
148 if (stat(path, &sb) != 0) {
149 mErrorCode = BCC_INVALID_VALUE;
150 LOGE("File not found: %s\n", path);
151 return 1;
152 }
153
154 mSourceList[idx] = SourceInfo::createFromFile(path, flags);
155
156 if (!mSourceList[idx]) {
157 mErrorCode = BCC_OUT_OF_MEMORY;
158 LOGE("Out of memory while adding source file\n");
159 return 1;
160 }
161
Logan3133c412011-01-06 06:15:40 +0800162 return 0;
Logancf3e5212010-12-29 01:44:55 +0800163}
164
165
Loganf340bf72011-01-14 17:51:40 +0800166int Script::prepareExecutable(char const *cachePath, unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800167 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800168 mErrorCode = BCC_INVALID_OPERATION;
Loganecf4cbd2011-01-06 05:34:11 +0800169 LOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800170 return 1;
171 }
172
Logan35849002011-01-15 07:30:43 +0800173#if USE_CACHE
Loganecf4cbd2011-01-06 05:34:11 +0800174 // Load Cache File
Loganf340bf72011-01-14 17:51:40 +0800175 mCachePath = cachePath;
176 if (cachePath && internalLoadCache() == 0) {
Logan033f46e2011-01-06 05:51:24 +0800177 return 0;
178 }
Logan35849002011-01-15 07:30:43 +0800179#endif
Loganecf4cbd2011-01-06 05:34:11 +0800180
Stephen Hines27b35102011-05-11 17:58:48 -0700181 int status = internalCompile();
182 if (status != 0) {
183 LOGE("LLVM error message: %s\n", getCompilerErrorMessage());
184 }
185 return status;
Logan033f46e2011-01-06 05:51:24 +0800186}
187
188
Logan35849002011-01-15 07:30:43 +0800189#if USE_CACHE
Logan033f46e2011-01-06 05:51:24 +0800190int Script::internalLoadCache() {
191 if (getBooleanProp("debug.bcc.nocache")) {
192 // Android system environment property disable the cache mechanism by
193 // setting "debug.bcc.nocache". So we will not load the cache file any
194 // way.
195 return 1;
196 }
197
Loganf340bf72011-01-14 17:51:40 +0800198 if (!mCachePath) {
199 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800200 // we don't know where to open the cache file.
201 return 1;
Logan033f46e2011-01-06 05:51:24 +0800202 }
Logan04329712011-01-06 06:10:57 +0800203
204 FileHandle file;
205
Loganf340bf72011-01-14 17:51:40 +0800206 if (file.open(mCachePath, OpenMode::Read) < 0) {
Logan04329712011-01-06 06:10:57 +0800207 // Unable to open the cache file in read mode.
208 return 1;
209 }
210
Logane7eb7732011-01-07 07:11:56 +0800211 CacheReader reader;
Logan04329712011-01-06 06:10:57 +0800212
Logan9a5f8682011-01-07 06:09:57 +0800213 // Dependencies
Logan35849002011-01-15 07:30:43 +0800214#if USE_LIBBCC_SHA1SUM
Logan9a5f8682011-01-07 06:09:57 +0800215 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800216#endif
217
Logan9a5f8682011-01-07 06:09:57 +0800218 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
219
Logan474cbd22011-01-31 01:47:44 +0800220 for (size_t i = 0; i < 2; ++i) {
221 if (mSourceList[i]) {
222 mSourceList[i]->introDependency(reader);
223 }
Logan9a5f8682011-01-07 06:09:57 +0800224 }
225
226 // Read cache file
Logane7eb7732011-01-07 07:11:56 +0800227 ScriptCached *cached = reader.readCacheFile(&file, this);
Logan04329712011-01-06 06:10:57 +0800228 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800229 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800230 return 1;
231 }
232
233 mCached = cached;
234 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800235
Loganf3c83ce2011-01-07 06:36:33 +0800236 // Dirty hack for libRS.
237 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800238 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800239 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
240 }
241
Loganf7f0ac52011-01-07 03:53:43 +0800242 return 0;
Logan033f46e2011-01-06 05:51:24 +0800243}
Logan35849002011-01-15 07:30:43 +0800244#endif
Logan033f46e2011-01-06 05:51:24 +0800245
246
247int Script::internalCompile() {
248 // Create the ScriptCompiled object
Loganecf4cbd2011-01-06 05:34:11 +0800249 mCompiled = new (nothrow) ScriptCompiled(this);
250
251 if (!mCompiled) {
252 mErrorCode = BCC_OUT_OF_MEMORY;
253 LOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
254 return 1;
255 }
256
257 mStatus = ScriptStatus::Compiled;
258
Logan033f46e2011-01-06 05:51:24 +0800259 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800260 if (mpExtSymbolLookupFn) {
261 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
262 mpExtSymbolLookupFnContext);
263 }
264
Logan474cbd22011-01-31 01:47:44 +0800265 // Parse Bitcode File (if necessary)
266 for (size_t i = 0; i < 2; ++i) {
267 if (mSourceList[i] && mSourceList[i]->prepareModule(mCompiled) != 0) {
268 LOGE("Unable to parse bitcode for source[%lu]\n", (unsigned long)i);
Logan033f46e2011-01-06 05:51:24 +0800269 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800270 }
Logan474cbd22011-01-31 01:47:44 +0800271 }
272
273 // Set the main source module
274 if (!mSourceList[0] || !mSourceList[0]->getModule()) {
275 LOGE("Source bitcode is not setted.\n");
276 return 1;
277 }
278
279 if (mCompiled->readModule(mSourceList[0]->takeModule()) != 0) {
280 LOGE("Unable to read source module\n");
281 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800282 }
283
Logan3133c412011-01-06 06:15:40 +0800284 // Link the source module with the library module
Logan474cbd22011-01-31 01:47:44 +0800285 if (mSourceList[1]) {
286 if (mCompiled->linkModule(mSourceList[1]->takeModule()) != 0) {
287 LOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800288 return 1;
289 }
290 }
Loganecf4cbd2011-01-06 05:34:11 +0800291
Logan3133c412011-01-06 06:15:40 +0800292 // Compile and JIT the code
Logan04329712011-01-06 06:10:57 +0800293 if (mCompiled->compile() != 0) {
Logan65719812011-01-07 11:17:14 +0800294 LOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800295 return 1;
296 }
297
Logan35849002011-01-15 07:30:43 +0800298#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800299 // Note: If we re-compile the script because the cached context slot not
300 // available, then we don't have to write the cache.
301
302 // Note: If the address of the context is not in the context slot, then
303 // we don't have to cache it.
304
Logan42598052011-01-26 22:41:13 +0800305 if (mCachePath &&
Logan1dc63142011-02-25 17:14:51 +0800306 !mIsContextSlotNotAvail &&
307 ContextManager::get().isManagingContext(getContext()) &&
Logan42598052011-01-26 22:41:13 +0800308 !getBooleanProp("debug.bcc.nocache")) {
309
Logan89eb47f2011-01-07 10:45:16 +0800310 FileHandle file;
Logan04329712011-01-06 06:10:57 +0800311
Jeff Brown937a0bc2011-01-26 23:20:14 -0800312 // Remove the file if it already exists before writing the new file.
313 // The old file may still be mapped elsewhere in memory and we do not want
314 // to modify its contents. (The same script may be running concurrently in
315 // the same process or a different process!)
316 ::unlink(mCachePath);
317
Loganf340bf72011-01-14 17:51:40 +0800318 if (file.open(mCachePath, OpenMode::Write) >= 0) {
Logan04329712011-01-06 06:10:57 +0800319 CacheWriter writer;
Logana27a83f2011-01-07 10:25:48 +0800320
Logana2e15af2011-01-07 11:46:08 +0800321 // Dependencies
Logan35849002011-01-15 07:30:43 +0800322#if USE_LIBBCC_SHA1SUM
Logana2e15af2011-01-07 11:46:08 +0800323 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC, sha1LibBCC);
Logane1323992011-01-12 04:47:13 +0800324#endif
Logana2e15af2011-01-07 11:46:08 +0800325 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
326
Logan474cbd22011-01-31 01:47:44 +0800327 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800328 if (mSourceList[i]) {
329 mSourceList[i]->introDependency(writer);
330 }
Logana2e15af2011-01-07 11:46:08 +0800331 }
332
Logana27a83f2011-01-07 10:25:48 +0800333 // libRS is threadable dirty hack
334 // TODO: This should be removed in the future
335 uint32_t libRS_threadable = 0;
336 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800337 libRS_threadable =
338 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
339 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800340 }
341
Logan89eb47f2011-01-07 10:45:16 +0800342 if (!writer.writeCacheFile(&file, this, libRS_threadable)) {
343 file.truncate();
344 file.close();
Logana27a83f2011-01-07 10:25:48 +0800345
Loganf340bf72011-01-14 17:51:40 +0800346 if (unlink(mCachePath) != 0) {
Logan89eb47f2011-01-07 10:45:16 +0800347 LOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Loganf340bf72011-01-14 17:51:40 +0800348 mCachePath, strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800349 }
350 }
351 }
Logan04329712011-01-06 06:10:57 +0800352 }
Logan35849002011-01-15 07:30:43 +0800353#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800354
355 return 0;
Logancf3e5212010-12-29 01:44:55 +0800356}
357
358
359char const *Script::getCompilerErrorMessage() {
360 if (mStatus != ScriptStatus::Compiled) {
361 mErrorCode = BCC_INVALID_OPERATION;
362 return NULL;
363 }
364
365 return mCompiled->getCompilerErrorMessage();
366}
367
368
369void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800370 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800371 case ScriptStatus::Compiled: return mCompiled->lookup(name);
Logan35849002011-01-15 07:30:43 +0800372#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800373 case ScriptStatus::Cached: return mCached->lookup(name);
Logan35849002011-01-15 07:30:43 +0800374#endif
Logan89eb47f2011-01-07 10:45:16 +0800375
376 default:
Logancf3e5212010-12-29 01:44:55 +0800377 mErrorCode = BCC_INVALID_OPERATION;
378 return NULL;
379 }
Logancf3e5212010-12-29 01:44:55 +0800380}
381
382
Loganbe79ada2011-01-13 01:33:45 +0800383size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800384 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800385 case ScriptStatus::Compiled: return mCompiled->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800386#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800387 case ScriptStatus::Cached: return mCached->getExportVarCount();
Logan35849002011-01-15 07:30:43 +0800388#endif
Loganbe79ada2011-01-13 01:33:45 +0800389 default: return 0;
390 }
391}
392
393
394size_t Script::getExportFuncCount() const {
395 switch (mStatus) {
396 case ScriptStatus::Compiled: return mCompiled->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800397#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800398 case ScriptStatus::Cached: return mCached->getExportFuncCount();
Logan35849002011-01-15 07:30:43 +0800399#endif
Loganbe79ada2011-01-13 01:33:45 +0800400 default: return 0;
401 }
402}
403
404
405size_t Script::getPragmaCount() const {
406 switch (mStatus) {
407 case ScriptStatus::Compiled: return mCompiled->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800408#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800409 case ScriptStatus::Cached: return mCached->getPragmaCount();
Logan35849002011-01-15 07:30:43 +0800410#endif
Loganbe79ada2011-01-13 01:33:45 +0800411 default: return 0;
412 }
413}
414
415
416size_t Script::getFuncCount() const {
417 switch (mStatus) {
418 case ScriptStatus::Compiled: return mCompiled->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800419#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800420 case ScriptStatus::Cached: return mCached->getFuncCount();
Logan35849002011-01-15 07:30:43 +0800421#endif
Loganbe79ada2011-01-13 01:33:45 +0800422 default: return 0;
423 }
424}
425
426
Stephen Hines071288a2011-01-27 14:38:26 -0800427size_t Script::getObjectSlotCount() const {
428 switch (mStatus) {
429 case ScriptStatus::Compiled: return mCompiled->getObjectSlotCount();
430#if USE_CACHE
431 case ScriptStatus::Cached: return mCached->getObjectSlotCount();
432#endif
433 default: return 0;
434 }
435}
436
437
Loganbe79ada2011-01-13 01:33:45 +0800438void Script::getExportVarList(size_t varListSize, void **varList) {
439 switch (mStatus) {
440#define DELEGATE(STATUS) \
441 case ScriptStatus::STATUS: \
442 m##STATUS->getExportVarList(varListSize, varList); \
Logan89eb47f2011-01-07 10:45:16 +0800443 break;
Logancf3e5212010-12-29 01:44:55 +0800444
Logan35849002011-01-15 07:30:43 +0800445#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800446 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800447#endif
448
Loganbe79ada2011-01-13 01:33:45 +0800449 DELEGATE(Compiled);
450#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800451
452 default:
453 mErrorCode = BCC_INVALID_OPERATION;
454 }
Logancf3e5212010-12-29 01:44:55 +0800455}
456
457
Loganbe79ada2011-01-13 01:33:45 +0800458void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800459 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800460#define DELEGATE(STATUS) \
461 case ScriptStatus::STATUS: \
462 m##STATUS->getExportFuncList(funcListSize, funcList); \
Logan89eb47f2011-01-07 10:45:16 +0800463 break;
Logancf3e5212010-12-29 01:44:55 +0800464
Logan35849002011-01-15 07:30:43 +0800465#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800466 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800467#endif
468
Loganbe79ada2011-01-13 01:33:45 +0800469 DELEGATE(Compiled);
470#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800471
472 default:
473 mErrorCode = BCC_INVALID_OPERATION;
474 }
Logancf3e5212010-12-29 01:44:55 +0800475}
476
477
Loganbe79ada2011-01-13 01:33:45 +0800478void Script::getPragmaList(size_t pragmaListSize,
479 char const **keyList,
480 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800481 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800482#define DELEGATE(STATUS) \
483 case ScriptStatus::STATUS: \
484 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
Logan89eb47f2011-01-07 10:45:16 +0800485 break;
Logancf3e5212010-12-29 01:44:55 +0800486
Logan35849002011-01-15 07:30:43 +0800487#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800488 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800489#endif
490
Loganbe79ada2011-01-13 01:33:45 +0800491 DELEGATE(Compiled);
492#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800493
494 default:
495 mErrorCode = BCC_INVALID_OPERATION;
496 }
Logancf3e5212010-12-29 01:44:55 +0800497}
498
499
Loganf340bf72011-01-14 17:51:40 +0800500void Script::getFuncInfoList(size_t funcInfoListSize,
501 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800502 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800503#define DELEGATE(STATUS) \
504 case ScriptStatus::STATUS: \
Stephen Hines071288a2011-01-27 14:38:26 -0800505 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
Logan89eb47f2011-01-07 10:45:16 +0800506 break;
Logancf3e5212010-12-29 01:44:55 +0800507
Logan35849002011-01-15 07:30:43 +0800508#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800509 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800510#endif
511
Loganbe79ada2011-01-13 01:33:45 +0800512 DELEGATE(Compiled);
513#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800514
515 default:
516 mErrorCode = BCC_INVALID_OPERATION;
517 }
Logancf3e5212010-12-29 01:44:55 +0800518}
519
Stephen Hines071288a2011-01-27 14:38:26 -0800520
521void Script::getObjectSlotList(size_t objectSlotListSize,
522 uint32_t *objectSlotList) {
523 switch (mStatus) {
524#define DELEGATE(STATUS) \
525 case ScriptStatus::STATUS: \
526 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
527 break;
528
529#if USE_CACHE
530 DELEGATE(Cached);
531#endif
532
533 DELEGATE(Compiled);
534#undef DELEGATE
535
536 default:
537 mErrorCode = BCC_INVALID_OPERATION;
538 }
539}
540
541
Logana27a83f2011-01-07 10:25:48 +0800542char *Script::getContext() {
543 switch (mStatus) {
Logan35849002011-01-15 07:30:43 +0800544#if USE_CACHE
Loganbe79ada2011-01-13 01:33:45 +0800545 case ScriptStatus::Cached: return mCached->getContext();
Logan35849002011-01-15 07:30:43 +0800546#endif
Loganbe79ada2011-01-13 01:33:45 +0800547 case ScriptStatus::Compiled: return mCompiled->getContext();
Logana27a83f2011-01-07 10:25:48 +0800548
549 default:
550 mErrorCode = BCC_INVALID_OPERATION;
Logan02286cb2011-01-07 00:30:47 +0800551 return NULL;
552 }
Logan02286cb2011-01-07 00:30:47 +0800553}
554
Logancf3e5212010-12-29 01:44:55 +0800555
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800556int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800557 mpExtSymbolLookupFn = pFn;
558 mpExtSymbolLookupFnContext = pContext;
559
Logan7d2219f2011-01-06 06:19:25 +0800560 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800561 mErrorCode = BCC_INVALID_OPERATION;
Logan7d2219f2011-01-06 06:19:25 +0800562 LOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800563 return 1;
Logancf3e5212010-12-29 01:44:55 +0800564 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800565 return 0;
Logancf3e5212010-12-29 01:44:55 +0800566}
567
568} // namespace bcc