Make compiler independent of script.
diff --git a/lib/bcc/Script.cpp b/lib/bcc/Script.cpp
new file mode 100644
index 0000000..7a1706a
--- /dev/null
+++ b/lib/bcc/Script.cpp
@@ -0,0 +1,212 @@
+/*
+ * copyright 2010, the android open source project
+ *
+ * licensed under the apache license, version 2.0 (the "license");
+ * you may not use this file except in compliance with the license.
+ * you may obtain a copy of the license at
+ *
+ *     http://www.apache.org/licenses/license-2.0
+ *
+ * unless required by applicable law or agreed to in writing, software
+ * distributed under the license is distributed on an "as is" basis,
+ * without warranties or conditions of any kind, either express or implied.
+ * see the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+#define LOG_TAG "bcc"
+#include <cutils/log.h>
+
+#include "Script.h"
+
+#include "ScriptCompiled.h"
+
+#include <new>
+
+namespace bcc {
+
+Script::~Script() {
+  if (mStatus == ScriptStatus::Compiled) {
+    delete mCompiled;
+  }
+}
+
+
+int Script::readBC(const char *bitcode,
+                   size_t bitcodeSize,
+                   long bitcodeFileModTime,
+                   long bitcodeFileCRC32,
+                   const BCCchar *resName,
+                   const BCCchar *cacheDir) {
+  if (mStatus != ScriptStatus::Unknown) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return 1;
+  }
+
+  mCompiled = new (nothrow) ScriptCompiled(this);
+
+  if (!mCompiled) {
+    mErrorCode = BCC_OUT_OF_MEMORY;
+    return 1;
+  }
+
+  mStatus = ScriptStatus::Compiled;
+
+  if (mpExtSymbolLookupFn) {
+    mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
+                                      mpExtSymbolLookupFnContext);
+  }
+
+  return mCompiled->readBC(bitcode, bitcodeSize,
+                           bitcodeFileModTime, bitcodeFileCRC32,
+                           resName, cacheDir);
+}
+
+
+int Script::readModule(llvm::Module *module) {
+  if (mStatus != ScriptStatus::Unknown) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return 1;
+  }
+
+  mCompiled = new (nothrow) ScriptCompiled(this);
+
+  if (!mCompiled) {
+    mErrorCode = BCC_OUT_OF_MEMORY;
+    return 1;
+  }
+
+  mStatus = ScriptStatus::Compiled;
+
+  if (mpExtSymbolLookupFn) {
+    mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
+                                      mpExtSymbolLookupFnContext);
+  }
+
+  return mCompiled->readModule(module);
+}
+
+
+int Script::linkBC(const char *bitcode, size_t bitcodeSize) {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return 1;
+  }
+
+  return mCompiled->linkBC(bitcode, bitcodeSize);
+}
+
+
+int Script::loadCacheFile() {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return 1;
+  }
+
+  return mCompiled->loadCacheFile();
+}
+
+
+int Script::compile() {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return 1;
+  }
+
+  return mCompiled->compile();
+}
+
+
+char const *Script::getCompilerErrorMessage() {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return NULL;
+  }
+
+  return mCompiled->getCompilerErrorMessage();
+}
+
+
+void *Script::lookup(const char *name) {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return NULL;
+  }
+
+  return mCompiled->lookup(name);
+}
+
+
+void Script::getExportVars(BCCsizei *actualVarCount,
+                           BCCsizei maxVarCount,
+                           BCCvoid **vars) {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return;
+  }
+
+  mCompiled->getExportVars(actualVarCount, maxVarCount, vars);
+}
+
+
+void Script::getExportFuncs(BCCsizei *actualFuncCount,
+                            BCCsizei maxFuncCount,
+                            BCCvoid **funcs) {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return;
+  }
+
+  mCompiled->getExportFuncs(actualFuncCount, maxFuncCount, funcs);
+}
+
+
+void Script::getPragmas(BCCsizei *actualStringCount,
+                        BCCsizei maxStringCount,
+                        BCCchar **strings) {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return;
+  }
+
+  mCompiled->getPragmas(actualStringCount, maxStringCount, strings);
+}
+
+
+void Script::getFunctions(BCCsizei *actualFunctionCount,
+                          BCCsizei maxFunctionCount,
+                          BCCchar **functions) {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return;
+  }
+
+  mCompiled->getFunctions(actualFunctionCount, maxFunctionCount, functions);
+}
+
+
+void Script::getFunctionBinary(BCCchar *function,
+                               BCCvoid **base,
+                               BCCsizei *length) {
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return;
+  }
+
+  mCompiled->getFunctionBinary(function, base, length);
+}
+
+
+void Script::registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
+  mpExtSymbolLookupFn = pFn;
+  mpExtSymbolLookupFnContext = pContext;
+
+  if (mStatus != ScriptStatus::Compiled) {
+    mErrorCode = BCC_INVALID_OPERATION;
+    return;
+  }
+
+  mCompiled->registerSymbolCallback(pFn, pContext);
+}
+
+} // namespace bcc
diff --git a/lib/bcc/Script.h b/lib/bcc/Script.h
index a22bd74..3e5f74e 100644
--- a/lib/bcc/Script.h
+++ b/lib/bcc/Script.h
@@ -17,8 +17,6 @@
 #ifndef BCC_SCRIPT_H
 #define BCC_SCRIPT_H
 
-#include "Compiler.h"
-
 #include <bcc/bcc.h>
 
 namespace llvm {
@@ -26,99 +24,79 @@
 }
 
 namespace bcc {
+  class ScriptCompiled;
+  class ScriptCached;
+
+  namespace ScriptStatus {
+    enum StatusType {
+      Unknown,
+      Compiled,
+      //Cached,
+    };
+  }
 
   class Script {
   private:
     BCCenum mErrorCode;
 
-    Compiler mCompiler;
+    ScriptStatus::StatusType mStatus;
+
+    union {
+      ScriptCompiled *mCompiled;
+      ScriptCached *mCached;
+    };
+
+    BCCSymbolLookupFn mpExtSymbolLookupFn;
+    BCCvoid *mpExtSymbolLookupFnContext;
 
   public:
-    Script() {
-      mErrorCode = BCC_NO_ERROR;
+    Script() : mErrorCode(BCC_NO_ERROR), mStatus(ScriptStatus::Unknown) {
     }
 
-    ~Script() {
-    }
-
-    //////////////////////////////////////////////////////////////////////////
-    // Part I. Compiler
-    //////////////////////////////////////////////////////////////////////////
+    ~Script();
 
     int readBC(const char *bitcode,
                size_t bitcodeSize,
                long bitcodeFileModTime,
                long bitcodeFileCRC32,
                const BCCchar *resName,
-               const BCCchar *cacheDir) {
-      return mCompiler.readBC(bitcode, bitcodeSize,
-                              bitcodeFileModTime, bitcodeFileCRC32,
-                              resName, cacheDir);
-    }
+               const BCCchar *cacheDir);
 
-    int linkBC(const char *bitcode, size_t bitcodeSize) {
-      return mCompiler.linkBC(bitcode, bitcodeSize);
-    }
+    int linkBC(const char *bitcode, size_t bitcodeSize);
 
-    int loadCacheFile() {
-      return mCompiler.loadCacheFile();
-    }
+    int loadCacheFile();
 
-    int compile() {
-      return mCompiler.compile();
-    }
+    int compile();
 
-    char const *getCompilerErrorMessage() {
-      return mCompiler.getErrorMessage();
-    }
+    char const *getCompilerErrorMessage();
 
-    void *lookup(const char *name) {
-      return mCompiler.lookup(name);
-    }
+    void *lookup(const char *name);
 
     void getExportVars(BCCsizei *actualVarCount,
                        BCCsizei maxVarCount,
-                       BCCvoid **vars) {
-      mCompiler.getExportVars(actualVarCount, maxVarCount, vars);
-    }
+                       BCCvoid **vars);
 
     void getExportFuncs(BCCsizei *actualFuncCount,
                         BCCsizei maxFuncCount,
-                        BCCvoid **funcs) {
-      mCompiler.getExportFuncs(actualFuncCount, maxFuncCount, funcs);
-    }
+                        BCCvoid **funcs);
 
     void getPragmas(BCCsizei *actualStringCount,
                     BCCsizei maxStringCount,
-                    BCCchar **strings) {
-      mCompiler.getPragmas(actualStringCount, maxStringCount, strings);
-    }
+                    BCCchar **strings);
 
     void getFunctions(BCCsizei *actualFunctionCount,
                       BCCsizei maxFunctionCount,
-                      BCCchar **functions) {
-      mCompiler.getFunctions(actualFunctionCount, maxFunctionCount, functions);
-    }
+                      BCCchar **functions);
 
     void getFunctionBinary(BCCchar *function,
                            BCCvoid **base,
-                           BCCsizei *length) {
-      mCompiler.getFunctionBinary(function, base, length);
-    }
+                           BCCsizei *length);
 
-    void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
-      mCompiler.registerSymbolCallback(pFn, pContext);
-    }
+    void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext);
 
-    int readModule(llvm::Module *module) {
-      return mCompiler.readModule(module);
-    }
+    int readModule(llvm::Module *module);
 
 
-    //////////////////////////////////////////////////////////////////////////
-    // Error handling
-    //////////////////////////////////////////////////////////////////////////
-
     void setError(BCCenum error) {
       if (mErrorCode == BCC_NO_ERROR && error != BCC_NO_ERROR) {
         mErrorCode = error;
diff --git a/lib/bcc/ScriptCompiled.h b/lib/bcc/ScriptCompiled.h
new file mode 100644
index 0000000..03b1fcd
--- /dev/null
+++ b/lib/bcc/ScriptCompiled.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BCC_SCRIPTCOMPILED_H
+#define BCC_SCRIPTCOMPILED_H
+
+#include "Compiler.h"
+
+#include <bcc/bcc.h>
+
+namespace llvm {
+  class Module;
+}
+
+namespace bcc {
+  class Script;
+
+  class ScriptCompiled {
+  private:
+    Script *mpOwner;
+
+    Compiler mCompiler;
+
+  public:
+    ScriptCompiled(Script *owner) : mpOwner(owner) {
+    }
+
+    int readBC(const char *bitcode,
+               size_t bitcodeSize,
+               long bitcodeFileModTime,
+               long bitcodeFileCRC32,
+               const BCCchar *resName,
+               const BCCchar *cacheDir) {
+      return mCompiler.readBC(bitcode, bitcodeSize,
+                              bitcodeFileModTime, bitcodeFileCRC32,
+                              resName, cacheDir);
+    }
+
+    int linkBC(const char *bitcode, size_t bitcodeSize) {
+      return mCompiler.linkBC(bitcode, bitcodeSize);
+    }
+
+    int loadCacheFile() {
+      return mCompiler.loadCacheFile();
+    }
+
+    int compile() {
+      return mCompiler.compile();
+    }
+
+    char const *getCompilerErrorMessage() {
+      return mCompiler.getErrorMessage();
+    }
+
+    void *lookup(const char *name) {
+      return mCompiler.lookup(name);
+    }
+
+    void getExportVars(BCCsizei *actualVarCount,
+                       BCCsizei maxVarCount,
+                       BCCvoid **vars) {
+      mCompiler.getExportVars(actualVarCount, maxVarCount, vars);
+    }
+
+    void getExportFuncs(BCCsizei *actualFuncCount,
+                        BCCsizei maxFuncCount,
+                        BCCvoid **funcs) {
+      mCompiler.getExportFuncs(actualFuncCount, maxFuncCount, funcs);
+    }
+
+    void getPragmas(BCCsizei *actualStringCount,
+                    BCCsizei maxStringCount,
+                    BCCchar **strings) {
+      mCompiler.getPragmas(actualStringCount, maxStringCount, strings);
+    }
+
+    void getFunctions(BCCsizei *actualFunctionCount,
+                      BCCsizei maxFunctionCount,
+                      BCCchar **functions) {
+      mCompiler.getFunctions(actualFunctionCount, maxFunctionCount, functions);
+    }
+
+    void getFunctionBinary(BCCchar *function,
+                           BCCvoid **base,
+                           BCCsizei *length) {
+      mCompiler.getFunctionBinary(function, base, length);
+    }
+
+    void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
+      mCompiler.registerSymbolCallback(pFn, pContext);
+    }
+
+    int readModule(llvm::Module *module) {
+      return mCompiler.readModule(module);
+    }
+  };
+
+} // namespace bcc
+
+#endif // BCC_SCRIPTCOMPILED_H