Working ClassLoader
Change-Id: Ia1122165e47f846a1d4506111849f830d9f14c1b
diff --git a/src/dalvik_system_DexFile.cc b/src/dalvik_system_DexFile.cc
index 3c373d5..977abc8 100644
--- a/src/dalvik_system_DexFile.cc
+++ b/src/dalvik_system_DexFile.cc
@@ -14,7 +14,11 @@
* limitations under the License.
*/
+#include "class_loader.h"
+#include "class_linker.h"
+#include "dex_file.h"
#include "logging.h"
+#include "runtime.h"
#include "ScopedUtfChars.h"
#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
@@ -80,20 +84,61 @@
if (env->ExceptionOccurred()) {
return 0;
}
- UNIMPLEMENTED(WARNING) << sourceName.c_str();
- return 0;
+ const DexFile* dex_file = DexFile::Open(sourceName.c_str(), "");
+ if (dex_file == NULL) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "unable to open DEX file: %s",
+ sourceName.c_str());
+ return NULL;
+ }
+ return static_cast<jint>(reinterpret_cast<uintptr_t>(dex_file));
+}
+
+static const DexFile* toDexFile(JNIEnv* env, int dex_file_address) {
+ const DexFile* dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(dex_file_address));
+ if ((dex_file == NULL)) {
+ jniThrowNullPointerException(env, "dex_file == null");
+ }
+ return dex_file;
}
void DexFile_closeDexFile(JNIEnv* env, jclass, jint cookie) {
- UNIMPLEMENTED(WARNING);
+ const DexFile* dex_file = toDexFile(env, cookie);
+ if (dex_file == NULL) {
+ return;
+ }
+ if (Runtime::Current()->GetClassLinker()->IsDexFileRegistered(*dex_file)) {
+ return;
+ }
+ delete dex_file;
}
jclass DexFile_defineClass(JNIEnv* env, jclass, jstring javaName, jobject javaLoader, jint cookie) {
- UNIMPLEMENTED(ERROR);
- return NULL;
+ const DexFile* dex_file = toDexFile(env, cookie);
+ if (dex_file == NULL) {
+ return NULL;
+ }
+ String* name = Decode<String*>(env, javaName);
+ const char* class_name = name->ToModifiedUtf8().c_str();
+ const std::string descriptor = DotToDescriptor(class_name);
+ const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor);
+ if (dex_class_def == NULL) {
+ jniThrowExceptionFmt(env, "Ljava/lang/NoClassDefFoundError;", "Class %s not found", class_name);
+ return NULL;
+ }
+
+ Object* class_loader_object = Decode<Object*>(env, javaLoader);
+ ClassLoader* class_loader = down_cast<ClassLoader*>(class_loader_object);
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ class_linker->RegisterDexFile(*dex_file);
+ Class* result = class_linker->DefineClass(descriptor, class_loader, *dex_file, *dex_class_def);
+ return AddLocalReference<jclass>(env, result);
}
jobjectArray DexFile_getClassNameList(JNIEnv* env, jclass, jint cookie) {
+ const DexFile* dex_file = toDexFile(env, cookie);
+ if (dex_file == NULL) {
+ return NULL;
+ }
UNIMPLEMENTED(ERROR);
return NULL;
}