Generating stub code for registering a jni function at runtime.
On ARM and x86. Added a unit test.
Change-Id: I6b1ee09ad18295108f406ce21d73555796ecbba6
diff --git a/src/stub_x86.cc b/src/stub_x86.cc
new file mode 100644
index 0000000..bddfc6c
--- /dev/null
+++ b/src/stub_x86.cc
@@ -0,0 +1,47 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "assembler_x86.h"
+#include "jni_internal.h"
+#include "object.h"
+
+#define __ assembler->
+
+namespace art {
+namespace x86 {
+
+ByteArray* CreateJniStub() {
+ UniquePtr<X86Assembler> assembler( static_cast<X86Assembler*>(Assembler::Create(kX86)) );
+
+ // Pad stack to ensure 16-byte alignment
+ __ pushl(Immediate(0));
+ __ pushl(Immediate(0));
+ __ pushl(Immediate(0));
+ __ fs()->movl(ECX, Address::Absolute(Thread::SelfOffset()));
+ __ pushl(ECX); // Thread*
+
+ __ Call(reinterpret_cast<int32_t>(&FindNativeMethod), X86ManagedRegister::FromCpuRegister(ECX));
+
+ __ addl(ESP, Immediate(16));
+
+ Label no_native_code_found; // forward declaration
+ __ cmpl(EAX, Immediate(0));
+ __ j(kEqual, &no_native_code_found);
+
+ __ jmp(EAX); // Tail call into native code
+
+ __ Bind(&no_native_code_found);
+ __ ret(); // return to caller to handle exception
+
+ assembler->EmitSlowPaths();
+
+ size_t cs = assembler->CodeSize();
+ ByteArray* jni_stub = ByteArray::Alloc(cs);
+ CHECK(jni_stub != NULL);
+ MemoryRegion code(jni_stub->GetData(), jni_stub->GetLength());
+ assembler->FinalizeInstructions(code);
+
+ return jni_stub;
+}
+
+} // namespace x86
+} // namespace art