2014-04-21 02:14:48 +00:00
|
|
|
/* Copyright (c) 2008-2014, Avian Contributors
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
2013-02-27 20:25:50 +00:00
|
|
|
#include "avian/machine.h"
|
|
|
|
#include "avian/classpath-common.h"
|
|
|
|
#include "avian/util.h"
|
|
|
|
#include "avian/process.h"
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <io.h>
|
|
|
|
#include <direct.h>
|
|
|
|
#include <share.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#undef interface
|
|
|
|
|
|
|
|
#define CLOSE _close
|
|
|
|
#define READ _read
|
|
|
|
#define WRITE _write
|
|
|
|
#define FSTAT _fstat
|
|
|
|
#define STAT _stat
|
|
|
|
#define LSEEK _lseek
|
|
|
|
|
|
|
|
#define S_ISSOCK(x) false
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define S_ISREG(x) ((x) | _S_IFREG)
|
|
|
|
#define S_ISDIR(x) ((x) | _S_IFDIR)
|
|
|
|
#define S_IRUSR _S_IREAD
|
|
|
|
#define S_IWUSR _S_IWRITE
|
|
|
|
#else
|
|
|
|
#define OPEN _open
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define O_RDONLY _O_RDONLY
|
|
|
|
|
|
|
|
#if (defined AVIAN_OPENJDK_SRC) \
|
|
|
|
|| ((defined __x86_64__) && (defined __MINGW32__))
|
|
|
|
#define EXPORT(x) x
|
|
|
|
#else
|
|
|
|
#define EXPORT(x) _##x
|
|
|
|
#endif
|
2010-11-07 04:21:19 +00:00
|
|
|
|
|
|
|
typedef int socklen_t;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#define RTLD_DEFAULT 0
|
2010-12-02 03:05:22 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#else // not PLATFORM_WINDOWS
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sched.h>
|
|
|
|
#include <dlfcn.h>
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#define OPEN open
|
|
|
|
#define CLOSE close
|
|
|
|
#define READ read
|
|
|
|
#define WRITE write
|
|
|
|
#define STAT stat
|
|
|
|
#define FSTAT fstat
|
|
|
|
#define LSEEK lseek
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#define EXPORT(x) x
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#endif // not PLATFORM_WINDOWS
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2012-03-13 14:26:51 +00:00
|
|
|
#define JVM_EEXIST -100
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
using namespace vm;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2014-07-11 15:50:18 +00:00
|
|
|
inline int OPEN(string_t path, int mask, int mode)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int fd;
|
2010-09-10 21:05:29 +00:00
|
|
|
if (_wsopen_s(&fd, path, mask, _SH_DENYNO, mode) == 0) {
|
2014-07-11 15:50:18 +00:00
|
|
|
return fd;
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
return -1;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace local {
|
|
|
|
|
2011-04-10 03:17:15 +00:00
|
|
|
const int JMM_VERSION_1_0 = 0x20010000;
|
|
|
|
|
|
|
|
struct jmmOptionalSupport {
|
|
|
|
unsigned isLowMemoryDetectionSupported : 1;
|
|
|
|
unsigned isCompilationTimeMonitoringSupported : 1;
|
|
|
|
unsigned isThreadContentionMonitoringSupported : 1;
|
|
|
|
unsigned isCurrentThreadCpuTimeSupported : 1;
|
|
|
|
unsigned isOtherThreadCpuTimeSupported : 1;
|
|
|
|
unsigned isBootClassPathSupported : 1;
|
|
|
|
unsigned isObjectMonitorUsageSupported : 1;
|
|
|
|
unsigned isSynchronizerUsageSupported : 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef unsigned jmmLongAttribute;
|
|
|
|
typedef unsigned jmmBoolAttribute;
|
|
|
|
typedef unsigned jmmStatisticType;
|
|
|
|
typedef unsigned jmmThresholdType;
|
|
|
|
typedef unsigned jmmVMGlobalType;
|
|
|
|
typedef unsigned jmmVMGlobalOrigin;
|
|
|
|
|
|
|
|
struct jmmVMGlobal {
|
|
|
|
jstring name;
|
|
|
|
jvalue value;
|
|
|
|
jmmVMGlobalType type;
|
|
|
|
jmmVMGlobalOrigin origin;
|
|
|
|
unsigned writeable : 1;
|
|
|
|
unsigned external : 1;
|
|
|
|
unsigned reserved : 30;
|
|
|
|
void* reserved1;
|
|
|
|
void* reserved2;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct jmmExtAttributeInfo {
|
|
|
|
const char* name;
|
|
|
|
char type;
|
|
|
|
const char* description;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct jmmGCStat {
|
|
|
|
jlong gc_index;
|
|
|
|
jlong start_time;
|
|
|
|
jlong end_time;
|
|
|
|
jobjectArray usage_before_gc;
|
|
|
|
jobjectArray usage_after_gc;
|
|
|
|
jint gc_ext_attribute_values_size;
|
|
|
|
jvalue* gc_ext_attribute_values;
|
|
|
|
jint num_gc_ext_attributes;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct JmmInterface {
|
|
|
|
void* reserved1;
|
|
|
|
void* reserved2;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* GetVersion)(JNIEnv*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* GetOptionalSupport)(JNIEnv*, jmmOptionalSupport*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobject(JNICALL* GetInputArguments)(JNIEnv*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* GetThreadInfo)(JNIEnv*, jlongArray, jint, jobjectArray);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray(JNICALL* GetInputArgumentArray)(JNIEnv*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray(JNICALL* GetMemoryPools)(JNIEnv*, jobject);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray(JNICALL* GetMemoryManagers)(JNIEnv*, jobject);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobject(JNICALL* GetMemoryPoolUsage)(JNIEnv*, jobject);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobject(JNICALL* GetPeakMemoryPoolUsage)(JNIEnv*, jobject);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
|
|
|
void* reserved4;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobject(JNICALL* GetMemoryUsage)(JNIEnv*, jboolean);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jlong(JNICALL* GetLongAttribute)(JNIEnv*, jobject, jmmLongAttribute);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jboolean(JNICALL* GetBoolAttribute)(JNIEnv*, jmmBoolAttribute);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jboolean(JNICALL* SetBoolAttribute)(JNIEnv*, jmmBoolAttribute, jboolean);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* GetLongAttributes)(JNIEnv*,
|
|
|
|
jobject,
|
|
|
|
jmmLongAttribute*,
|
|
|
|
jint,
|
|
|
|
jlong*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray(JNICALL* FindCircularBlockedThreads)(JNIEnv*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jlong(JNICALL* GetThreadCpuTime)(JNIEnv*, jlong);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray(JNICALL* GetVMGlobalNames)(JNIEnv*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* GetVMGlobals)(JNIEnv*, jobjectArray, jmmVMGlobal*, jint);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* GetInternalThreadTimes)(JNIEnv*, jobjectArray, jlongArray);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jboolean(JNICALL* ResetStatistic)(JNIEnv*, jvalue, jmmStatisticType);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void(JNICALL* SetPoolSensor)(JNIEnv*, jobject, jmmThresholdType, jobject);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jlong(JNICALL* SetPoolThreshold)(JNIEnv*, jobject, jmmThresholdType, jlong);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobject(JNICALL* GetPoolCollectionUsage)(JNIEnv*, jobject);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* GetGCExtAttributeInfo)(JNIEnv*,
|
|
|
|
jobject,
|
|
|
|
jmmExtAttributeInfo*,
|
|
|
|
jint);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void(JNICALL* GetLastGCStat)(JNIEnv*, jobject, jmmGCStat*);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jlong(JNICALL* GetThreadCpuTimeWithKind)(JNIEnv*, jlong, jboolean);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
|
|
|
void* reserved5;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint(JNICALL* DumpHeap0)(JNIEnv*, jstring, jboolean);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray(JNICALL* FindDeadlocks)(JNIEnv*, jboolean);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void(JNICALL* SetVMGlobal)(JNIEnv*, jstring, jvalue);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
|
|
|
void* reserved6;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray(JNICALL* DumpThreads)(JNIEnv*, jlongArray, jboolean, jboolean);
|
2011-04-10 03:17:15 +00:00
|
|
|
};
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
const unsigned InterfaceVersion = 4;
|
2010-09-14 16:49:41 +00:00
|
|
|
const unsigned PageSize = 4 * 1024;
|
2013-10-27 14:36:32 +00:00
|
|
|
#ifdef AVIAN_OPENJDK_SRC
|
2010-11-05 19:18:28 +00:00
|
|
|
const int VirtualFileBase = 1000000000;
|
2013-10-27 14:36:32 +00:00
|
|
|
#endif
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
Machine* globalMachine;
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
const char* primitiveName(Thread* t, GcClass* c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
if (c == primitiveClass(t, 'V')) {
|
|
|
|
return "void";
|
|
|
|
} else if (c == primitiveClass(t, 'Z')) {
|
|
|
|
return "boolean";
|
|
|
|
} else if (c == primitiveClass(t, 'B')) {
|
|
|
|
return "byte";
|
|
|
|
} else if (c == primitiveClass(t, 'C')) {
|
|
|
|
return "char";
|
|
|
|
} else if (c == primitiveClass(t, 'S')) {
|
|
|
|
return "short";
|
|
|
|
} else if (c == primitiveClass(t, 'I')) {
|
|
|
|
return "int";
|
|
|
|
} else if (c == primitiveClass(t, 'F')) {
|
|
|
|
return "float";
|
|
|
|
} else if (c == primitiveClass(t, 'J')) {
|
|
|
|
return "long";
|
|
|
|
} else if (c == primitiveClass(t, 'D')) {
|
|
|
|
return "double";
|
|
|
|
} else {
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcByteArray* getClassName(Thread* t, GcClass* c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-05-29 04:17:25 +00:00
|
|
|
if (c->name() == 0) {
|
|
|
|
if (c->vmFlags() & PrimitiveFlag) {
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, c);
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcByteArray* name = makeByteArray(t, primitiveName(t, c));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
c->setName(t, name);
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
return c->name();
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcString* makeClassNameString(Thread* t, GcByteArray* name)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, s, name->length());
|
2014-07-11 15:47:57 +00:00
|
|
|
replace('/',
|
|
|
|
'.',
|
|
|
|
RUNTIME_ARRAY_BODY(s),
|
2014-06-27 00:17:46 +00:00
|
|
|
reinterpret_cast<char*>(name->body().begin()));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-02-22 21:20:09 +00:00
|
|
|
return makeString(t, "%s", RUNTIME_ARRAY_BODY(s));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object makeJmethod(Thread* t, GcMethod* vmMethod, int index = -1);
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object makeJconstructor(Thread* t, GcMethod* vmMethod, int index = -1);
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object makeJfield(Thread* t, GcField* vmField, int index = -1);
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2013-07-03 20:33:46 +00:00
|
|
|
#ifdef AVIAN_OPENJDK_SRC
|
2014-07-11 15:50:18 +00:00
|
|
|
void interceptFileOperations(Thread*, bool);
|
2013-07-03 20:33:46 +00:00
|
|
|
#endif
|
2010-11-04 17:02:09 +00:00
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
class MyClasspath : public Classpath {
|
|
|
|
public:
|
2014-07-11 15:50:18 +00:00
|
|
|
MyClasspath(System* s,
|
|
|
|
Allocator* allocator,
|
|
|
|
const char* javaHome,
|
|
|
|
const char* embedPrefix)
|
|
|
|
: allocator(allocator), ranNetOnLoad(0), ranManagementOnLoad(0)
|
2010-09-20 23:31:23 +00:00
|
|
|
{
|
|
|
|
class StringBuilder {
|
|
|
|
public:
|
2014-07-11 15:50:18 +00:00
|
|
|
StringBuilder(System* s, Allocator* allocator)
|
|
|
|
: s(s),
|
|
|
|
allocator(allocator),
|
|
|
|
bufferSize(1024),
|
|
|
|
buffer(static_cast<char*>(allocator->allocate(bufferSize))),
|
|
|
|
offset(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ensure(unsigned capacity)
|
|
|
|
{
|
2012-10-03 15:43:51 +00:00
|
|
|
if (capacity > bufferSize) {
|
|
|
|
unsigned size = max(bufferSize * 2, capacity);
|
|
|
|
char* b = static_cast<char*>(allocator->allocate(size));
|
|
|
|
|
|
|
|
if (offset) {
|
|
|
|
memcpy(b, buffer, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
allocator->free(buffer, bufferSize);
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
buffer = b;
|
|
|
|
bufferSize = size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void append(const char* append)
|
|
|
|
{
|
2010-09-20 23:31:23 +00:00
|
|
|
unsigned length = strlen(append);
|
2012-10-03 15:43:51 +00:00
|
|
|
ensure(offset + length + 1);
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
strncpy(buffer + offset, append, length + 1);
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
offset += length;
|
2010-09-20 23:31:23 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void append(char c)
|
|
|
|
{
|
2012-10-03 15:43:51 +00:00
|
|
|
ensure(2);
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
buffer[offset] = c;
|
|
|
|
buffer[offset + 1] = 0;
|
2010-09-20 23:31:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
++offset;
|
2010-09-20 23:31:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
System* s;
|
2012-10-03 15:43:51 +00:00
|
|
|
Allocator* allocator;
|
|
|
|
unsigned bufferSize;
|
|
|
|
char* buffer;
|
|
|
|
unsigned offset;
|
|
|
|
} sb(s, allocator);
|
2010-09-20 23:31:23 +00:00
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
unsigned javaHomeOffset = sb.offset;
|
2010-09-20 23:31:23 +00:00
|
|
|
sb.append(javaHome);
|
|
|
|
sb.append('\0');
|
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
unsigned classpathOffset = sb.offset;
|
2010-11-26 19:41:31 +00:00
|
|
|
sb.append(AVIAN_CLASSPATH);
|
2010-10-24 17:49:12 +00:00
|
|
|
sb.append(s->pathSeparator());
|
2010-09-20 23:31:23 +00:00
|
|
|
sb.append(javaHome);
|
2010-09-21 00:38:38 +00:00
|
|
|
sb.append("/lib/rt.jar");
|
2010-09-20 23:31:23 +00:00
|
|
|
sb.append(s->pathSeparator());
|
|
|
|
sb.append(javaHome);
|
2010-09-21 00:38:38 +00:00
|
|
|
sb.append("/lib/jsse.jar");
|
2010-09-20 23:31:23 +00:00
|
|
|
sb.append(s->pathSeparator());
|
|
|
|
sb.append(javaHome);
|
2010-09-21 00:38:38 +00:00
|
|
|
sb.append("/lib/jce.jar");
|
2010-09-20 23:31:23 +00:00
|
|
|
sb.append(s->pathSeparator());
|
|
|
|
sb.append(javaHome);
|
2011-03-04 23:55:31 +00:00
|
|
|
sb.append("/lib/ext/sunjce_provider.jar");
|
|
|
|
sb.append(s->pathSeparator());
|
|
|
|
sb.append(javaHome);
|
2010-09-21 00:38:38 +00:00
|
|
|
sb.append("/lib/resources.jar");
|
2010-09-20 23:31:23 +00:00
|
|
|
sb.append('\0');
|
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
unsigned libraryPathOffset = sb.offset;
|
2010-09-20 23:31:23 +00:00
|
|
|
sb.append(javaHome);
|
2010-11-07 17:08:04 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2014-07-11 15:50:18 +00:00
|
|
|
#define LIB_DIR "/bin"
|
2012-03-16 17:01:20 +00:00
|
|
|
#elif defined __APPLE__
|
2014-07-11 15:50:18 +00:00
|
|
|
#define LIB_DIR "/lib"
|
2010-11-07 17:08:04 +00:00
|
|
|
#elif defined ARCH_x86_64
|
2014-07-11 15:50:18 +00:00
|
|
|
#define LIB_DIR "/lib/amd64"
|
2012-08-04 13:31:54 +00:00
|
|
|
#elif defined ARCH_arm
|
2014-07-11 15:50:18 +00:00
|
|
|
#define LIB_DIR "/lib/arm"
|
2010-09-20 23:31:23 +00:00
|
|
|
#else
|
2014-07-11 15:50:18 +00:00
|
|
|
// todo: handle other architectures
|
|
|
|
#define LIB_DIR "/lib/i386"
|
2010-09-20 23:31:23 +00:00
|
|
|
#endif
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2013-01-25 15:07:47 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
sb.append(LIB_DIR);
|
|
|
|
#else
|
2012-12-20 19:25:13 +00:00
|
|
|
sb.append(LIB_DIR ":");
|
|
|
|
sb.append(javaHome);
|
|
|
|
sb.append(LIB_DIR "/xawt");
|
2013-01-25 15:07:47 +00:00
|
|
|
#endif
|
2010-11-04 17:02:09 +00:00
|
|
|
sb.append('\0');
|
2012-10-03 15:43:51 +00:00
|
|
|
|
|
|
|
unsigned tzMappingsOffset = sb.offset;
|
2010-11-07 19:24:40 +00:00
|
|
|
sb.append(javaHome);
|
|
|
|
sb.append("/lib/tzmappings");
|
2012-10-03 15:43:51 +00:00
|
|
|
this->tzMappingsLength = sb.offset - tzMappingsOffset;
|
2010-11-07 19:24:40 +00:00
|
|
|
sb.append('\0');
|
2010-11-05 19:18:28 +00:00
|
|
|
|
2012-10-03 15:43:51 +00:00
|
|
|
unsigned embedPrefixOffset = sb.offset;
|
2010-11-05 19:18:28 +00:00
|
|
|
sb.append(embedPrefix);
|
2012-10-03 15:43:51 +00:00
|
|
|
this->embedPrefixLength = sb.offset - embedPrefixOffset;
|
|
|
|
|
|
|
|
this->javaHome = sb.buffer + javaHomeOffset;
|
|
|
|
this->classpath = sb.buffer + classpathOffset;
|
|
|
|
this->libraryPath = sb.buffer + libraryPathOffset;
|
|
|
|
this->tzMappings = sb.buffer + tzMappingsOffset;
|
|
|
|
this->embedPrefix = sb.buffer + embedPrefixOffset;
|
|
|
|
this->buffer = sb.buffer;
|
|
|
|
this->bufferSize = sb.bufferSize;
|
2010-09-20 23:31:23 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual GcJclass* makeJclass(Thread* t, GcClass* class_)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-09-14 16:49:41 +00:00
|
|
|
PROTECT(t, class_);
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcString* name = makeClassNameString(t, getClassName(t, class_));
|
2012-03-11 22:26:46 +00:00
|
|
|
PROTECT(t, name);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcJclass* c
|
|
|
|
= reinterpret_cast<GcJclass*>(allocate(t, GcJclass::FixedSize, true));
|
2014-07-02 21:11:27 +00:00
|
|
|
setObjectClass(t, c, type(t, GcJclass::Type));
|
2014-06-26 02:17:27 +00:00
|
|
|
c->setName(t, name);
|
|
|
|
c->setVmClass(t, class_);
|
2012-03-11 22:26:46 +00:00
|
|
|
|
|
|
|
return c;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual GcString* makeString(Thread* t,
|
|
|
|
object oarray,
|
|
|
|
int32_t offset,
|
|
|
|
int32_t length)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
if (objectClass(t, oarray) == type(t, GcByteArray::Type)) {
|
|
|
|
GcByteArray* array = cast<GcByteArray>(t, oarray);
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, array);
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
GcCharArray* charArray = makeCharArray(t, length);
|
2010-09-10 21:05:29 +00:00
|
|
|
for (int i = 0; i < length; ++i) {
|
2014-06-27 00:17:46 +00:00
|
|
|
if (array->body()[offset + i] & 0x80) {
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* constructor = resolveMethod(t,
|
|
|
|
type(t, GcString::Type),
|
|
|
|
"<init>",
|
|
|
|
"([BIILjava/lang/String;)V");
|
2013-04-10 00:44:54 +00:00
|
|
|
PROTECT(t, constructor);
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcString* utf8 = vm::makeString(t, "UTF8");
|
2013-04-10 00:44:54 +00:00
|
|
|
PROTECT(t, utf8);
|
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
object s = makeNew(t, type(t, GcString::Type));
|
2013-04-10 00:44:54 +00:00
|
|
|
PROTECT(t, s);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->processor->invoke(
|
|
|
|
t, constructor, s, array, offset, length, utf8);
|
2013-04-10 00:44:54 +00:00
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
return cast<GcString>(t, s);
|
2013-04-10 00:44:54 +00:00
|
|
|
}
|
2013-02-03 21:09:29 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
charArray->body()[i] = array->body()[offset + i];
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
oarray = charArray;
|
2011-03-18 03:42:15 +00:00
|
|
|
} else {
|
2014-06-27 00:17:46 +00:00
|
|
|
expect(t, objectClass(t, oarray) == type(t, GcCharArray::Type));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
2011-03-18 03:42:15 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
return vm::makeString(t, oarray, offset, length, 0);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual GcThread* makeThread(Thread* t, Thread* parent)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
const unsigned MaxPriority = 10;
|
|
|
|
const unsigned NormalPriority = 5;
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcThreadGroup* group;
|
2010-09-10 21:05:29 +00:00
|
|
|
if (parent) {
|
2014-06-28 23:24:24 +00:00
|
|
|
group = parent->javaThread->group();
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
group = reinterpret_cast<GcThreadGroup*>(
|
|
|
|
allocate(t, GcThreadGroup::FixedSize, true));
|
2014-07-02 21:11:27 +00:00
|
|
|
setObjectClass(t, group, type(t, GcThreadGroup::Type));
|
2014-06-28 23:24:24 +00:00
|
|
|
group->maxPriority() = MaxPriority;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
2010-11-27 23:27:30 +00:00
|
|
|
|
|
|
|
PROTECT(t, group);
|
2014-06-28 23:24:24 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcThread* thread
|
|
|
|
= reinterpret_cast<GcThread*>(allocate(t, GcThread::FixedSize, true));
|
2014-07-02 21:11:27 +00:00
|
|
|
setObjectClass(t, thread, type(t, GcThread::Type));
|
2014-06-28 23:24:24 +00:00
|
|
|
thread->priority() = NormalPriority;
|
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
thread->setGroup(t, group);
|
2014-06-28 23:24:24 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
thread->setContextClassLoader(t, roots(t)->appLoader());
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-11-27 23:27:30 +00:00
|
|
|
PROTECT(t, thread);
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcJobject* blockerLock = makeJobject(t);
|
2014-07-02 21:11:27 +00:00
|
|
|
thread->setBlockerLock(t, blockerLock);
|
2011-04-01 00:58:59 +00:00
|
|
|
|
2010-11-27 23:27:30 +00:00
|
|
|
const unsigned BufferSize = 256;
|
|
|
|
char buffer[BufferSize];
|
|
|
|
unsigned length = vm::snprintf(buffer, BufferSize, "Thread-%p", thread);
|
2014-06-28 23:24:24 +00:00
|
|
|
GcCharArray* name = makeCharArray(t, length);
|
2010-11-27 23:27:30 +00:00
|
|
|
for (unsigned i = 0; i < length; ++i) {
|
2014-06-28 23:24:24 +00:00
|
|
|
name->body()[i] = buffer[i];
|
2010-11-27 23:27:30 +00:00
|
|
|
}
|
2014-06-26 02:17:27 +00:00
|
|
|
thread->setName(t, name);
|
2010-11-27 23:27:30 +00:00
|
|
|
|
2010-11-05 21:34:28 +00:00
|
|
|
return thread;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual object makeJMethod(Thread* t, GcMethod* vmMethod)
|
2012-12-19 19:39:33 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, vmMethod);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return vmMethod->name()->body()[0] == '<' ? makeJconstructor(t, vmMethod)
|
|
|
|
: makeJmethod(t, vmMethod);
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual GcMethod* getVMMethod(Thread* t, object jmethod)
|
2012-12-19 19:39:33 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
return cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
objectClass(t, jmethod) == type(t, GcJmethod::Type)
|
|
|
|
? cast<GcArray>(t,
|
|
|
|
cast<GcJmethod>(t, jmethod)
|
|
|
|
->clazz()
|
|
|
|
->vmClass()
|
|
|
|
->methodTable())
|
|
|
|
->body()[cast<GcJmethod>(t, jmethod)->slot()]
|
|
|
|
: cast<GcArray>(t,
|
|
|
|
cast<GcJconstructor>(t, jmethod)
|
|
|
|
->clazz()
|
|
|
|
->vmClass()
|
|
|
|
->methodTable())
|
|
|
|
->body()[cast<GcJconstructor>(t, jmethod)->slot()]);
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual object makeJField(Thread* t, GcField* vmField)
|
2012-12-19 19:39:33 +00:00
|
|
|
{
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeJfield(t, vmField);
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual GcField* getVMField(Thread* t, GcJfield* jfield)
|
2012-12-19 19:39:33 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
return cast<GcField>(
|
|
|
|
t,
|
|
|
|
cast<GcArray>(t, jfield->clazz()->vmClass()->fieldTable())
|
|
|
|
->body()[jfield->slot()]);
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void clearInterrupted(Thread* t)
|
2012-05-02 17:41:36 +00:00
|
|
|
{
|
2013-05-01 04:53:56 +00:00
|
|
|
vm::clearInterrupted(t);
|
2012-05-02 17:41:36 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void runThread(Thread* t)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2013-02-03 22:18:32 +00:00
|
|
|
// force monitor creation so we don't get an OutOfMemory error
|
|
|
|
// later when we try to acquire it:
|
2014-07-02 21:11:27 +00:00
|
|
|
objectMonitor(t, t->javaThread, true);
|
2013-02-03 22:18:32 +00:00
|
|
|
|
|
|
|
THREAD_RESOURCE0(t, {
|
2014-07-11 15:50:18 +00:00
|
|
|
vm::acquire(t, t->javaThread);
|
2014-08-20 15:49:00 +00:00
|
|
|
t->clearFlag(Thread::ActiveFlag);
|
2014-07-11 15:50:18 +00:00
|
|
|
vm::notifyAll(t, t->javaThread);
|
|
|
|
vm::release(t, t->javaThread);
|
2013-03-05 16:06:19 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
GcThrowable* e = t->exception;
|
|
|
|
PROTECT(t, e);
|
2013-03-15 19:28:01 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
t->exception = 0;
|
2013-03-15 19:28:01 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->processor->invoke(t,
|
|
|
|
cast<GcMethod>(t, roots(t)->threadTerminated()),
|
|
|
|
t->javaThread->group(),
|
|
|
|
t->javaThread);
|
2013-03-15 19:28:01 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
t->exception = e;
|
2013-02-03 22:18:32 +00:00
|
|
|
});
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* method = resolveMethod(
|
|
|
|
t, roots(t)->bootLoader(), "java/lang/Thread", "run", "()V");
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
t->m->processor->invoke(t, method, t->javaThread);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual void resolveNative(Thread* t, GcMethod* method)
|
2011-04-10 17:26:44 +00:00
|
|
|
{
|
2012-08-06 01:31:20 +00:00
|
|
|
if (strcmp(reinterpret_cast<const int8_t*>("sun/font/SunFontManager"),
|
2014-06-21 04:16:33 +00:00
|
|
|
method->class_()->name()->body().begin()) == 0
|
2011-04-10 17:26:44 +00:00
|
|
|
and strcmp(reinterpret_cast<const int8_t*>("initIDs"),
|
2014-06-21 04:16:33 +00:00
|
|
|
method->name()->body().begin()) == 0
|
2011-04-10 17:26:44 +00:00
|
|
|
and strcmp(reinterpret_cast<const int8_t*>("()V"),
|
2014-07-11 15:47:57 +00:00
|
|
|
method->spec()->body().begin()) == 0) {
|
2011-04-10 17:26:44 +00:00
|
|
|
PROTECT(t, method);
|
|
|
|
|
|
|
|
expect(t, loadLibrary(t, libraryPath, "fontmanager", true, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
vm::resolveNative(t, method);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void interceptMethods(Thread* t UNUSED)
|
2013-03-15 19:28:01 +00:00
|
|
|
{
|
|
|
|
#ifdef AVIAN_OPENJDK_SRC
|
|
|
|
interceptFileOperations(t, false);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void preBoot(Thread*)
|
2013-02-22 21:41:24 +00:00
|
|
|
{
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
2014-04-12 01:38:11 +00:00
|
|
|
virtual bool mayInitClasses()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void boot(Thread* t)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
globalMachine = t->m;
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
resolveSystemClass(
|
|
|
|
t, roots(t)->bootLoader(), type(t, GcClassLoader::Type)->name());
|
2010-12-06 00:40:50 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* method = resolveMethod(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"java/lang/ThreadGroup",
|
|
|
|
"threadTerminated",
|
|
|
|
"(Ljava/lang/Thread;)V");
|
2014-06-30 01:44:41 +00:00
|
|
|
// sequence point, for gc (don't recombine statements)
|
2014-07-02 21:11:27 +00:00
|
|
|
roots(t)->setThreadTerminated(t, method);
|
2013-03-05 16:06:19 +00:00
|
|
|
|
2010-11-04 17:02:09 +00:00
|
|
|
#ifdef AVIAN_OPENJDK_SRC
|
2013-03-15 19:28:01 +00:00
|
|
|
interceptFileOperations(t, true);
|
2014-07-11 15:50:18 +00:00
|
|
|
#else // not AVIAN_OPENJDK_SRC
|
2011-04-10 17:26:44 +00:00
|
|
|
expect(t, loadLibrary(t, libraryPath, "verify", true, true));
|
|
|
|
expect(t, loadLibrary(t, libraryPath, "java", true, true));
|
2014-07-11 15:50:18 +00:00
|
|
|
#endif // not AVIAN_OPENJDK_SRC
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
|
|
|
GcField* assertionLock = resolveField(t,
|
|
|
|
type(t, GcClassLoader::Type),
|
|
|
|
"assertionLock",
|
|
|
|
"Ljava/lang/Object;");
|
|
|
|
|
|
|
|
setField(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
assertionLock->offset(),
|
|
|
|
roots(t)->bootLoader());
|
2012-06-11 23:30:22 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
|
|
|
GcClass* class_ = resolveClass(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"java/util/Properties",
|
|
|
|
true,
|
|
|
|
GcNoClassDefFoundError::Type);
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2012-02-21 00:38:41 +00:00
|
|
|
PROTECT(t, class_);
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2012-02-21 00:38:41 +00:00
|
|
|
object instance = makeNew(t, class_);
|
|
|
|
|
|
|
|
PROTECT(t, instance);
|
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
GcMethod* constructor = resolveMethod(t, class_, "<init>", "()V");
|
2012-02-21 00:38:41 +00:00
|
|
|
|
|
|
|
t->m->processor->invoke(t, constructor, instance);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
t->m->processor->invoke(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"java/lang/System",
|
|
|
|
"setProperties",
|
|
|
|
"(Ljava/util/Properties;)V",
|
|
|
|
0,
|
|
|
|
instance);
|
2012-02-21 00:38:41 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
|
|
|
GcMethod* constructor = resolveMethod(t,
|
|
|
|
type(t, GcClassLoader::Type),
|
|
|
|
"<init>",
|
|
|
|
"(Ljava/lang/ClassLoader;)V");
|
2012-02-21 00:38:41 +00:00
|
|
|
|
|
|
|
PROTECT(t, constructor);
|
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
t->m->processor->invoke(t, constructor, roots(t)->bootLoader(), 0);
|
2012-02-21 00:38:41 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
t->m->processor->invoke(
|
|
|
|
t, constructor, roots(t)->appLoader(), roots(t)->bootLoader());
|
2012-02-21 00:38:41 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
|
|
|
GcField* scl = resolveField(
|
|
|
|
t, type(t, GcClassLoader::Type), "scl", "Ljava/lang/ClassLoader;");
|
2012-02-21 00:38:41 +00:00
|
|
|
|
|
|
|
PROTECT(t, scl);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcField* sclSet
|
|
|
|
= resolveField(t, type(t, GcClassLoader::Type), "sclSet", "Z");
|
2012-02-21 00:38:41 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
setField(t,
|
|
|
|
type(t, GcClassLoader::Type)->staticTable(),
|
|
|
|
scl->offset(),
|
|
|
|
roots(t)->appLoader());
|
2012-02-21 00:38:41 +00:00
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
fieldAtOffset<uint8_t>(type(t, GcClassLoader::Type)->staticTable(),
|
2014-07-11 15:47:57 +00:00
|
|
|
sclSet->offset()) = true;
|
2012-02-21 00:38:41 +00:00
|
|
|
}
|
2010-11-04 17:43:50 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
t->m->processor->invoke(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"java/lang/System",
|
|
|
|
"initializeSystemClass",
|
|
|
|
"()V",
|
|
|
|
0);
|
2012-08-30 00:27:37 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
t->m->processor->invoke(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"sun/misc/Launcher",
|
|
|
|
"getLauncher",
|
|
|
|
"()Lsun/misc/Launcher;",
|
|
|
|
0);
|
2012-08-30 00:27:37 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
t->javaThread->setContextClassLoader(t, roots(t)->appLoader());
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual const char* bootClasspath()
|
2010-09-20 23:31:23 +00:00
|
|
|
{
|
|
|
|
return classpath;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual object makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
|
2013-02-22 21:41:24 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* c
|
|
|
|
= resolveClass(t, roots(t)->bootLoader(), "java/nio/DirectByteBuffer");
|
2013-02-22 21:41:24 +00:00
|
|
|
PROTECT(t, c);
|
|
|
|
|
|
|
|
object instance = makeNew(t, c);
|
|
|
|
PROTECT(t, instance);
|
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
GcMethod* constructor = resolveMethod(t, c, "<init>", "(JI)V");
|
2013-02-22 21:41:24 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->processor->invoke(t,
|
|
|
|
constructor,
|
|
|
|
instance,
|
|
|
|
reinterpret_cast<int64_t>(p),
|
|
|
|
static_cast<int32_t>(capacity));
|
2013-02-22 21:41:24 +00:00
|
|
|
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void* getDirectBufferAddress(Thread* t, object b)
|
2013-02-22 21:41:24 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, b);
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcField* field = resolveField(t, objectClass(t, b), "address", "J");
|
2013-02-22 21:41:24 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<void*>(fieldAtOffset<int64_t>(b, field->offset()));
|
2013-02-22 21:41:24 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual int64_t getDirectBufferCapacity(Thread* t, object b)
|
2013-02-22 21:41:24 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, b);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcField* field = resolveField(t, objectClass(t, b), "capacity", "I");
|
2013-02-22 21:41:24 +00:00
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
return fieldAtOffset<int32_t>(b, field->offset());
|
2013-02-22 21:41:24 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
virtual bool canTailCall(Thread* t UNUSED,
|
|
|
|
GcMethod*,
|
|
|
|
GcByteArray* calleeClassName,
|
|
|
|
GcByteArray* calleeMethodName,
|
|
|
|
GcByteArray*)
|
2013-03-05 22:43:49 +00:00
|
|
|
{
|
|
|
|
// we can't tail call System.loadLibrary or Runtime.loadLibrary
|
|
|
|
// due to their use of System.getCallerClass, which gets confused
|
|
|
|
// if we elide stack frames.
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return (strcmp("loadLibrary",
|
|
|
|
reinterpret_cast<char*>(calleeMethodName->body().begin()))
|
|
|
|
or (strcmp("java/lang/System",
|
|
|
|
reinterpret_cast<char*>(calleeClassName->body().begin()))
|
|
|
|
and strcmp("java/lang/Runtime",
|
|
|
|
reinterpret_cast<char*>(
|
|
|
|
calleeClassName->body().begin()))))
|
|
|
|
|
|
|
|
// and we can't tail call Reflection.getCallerClass because the
|
|
|
|
// number of stack frames will be wrong
|
|
|
|
and (strcmp(
|
|
|
|
"getCallerClass",
|
|
|
|
reinterpret_cast<char*>(calleeMethodName->body().begin()))
|
|
|
|
or strcmp("sun/reflect/Reflection",
|
|
|
|
reinterpret_cast<char*>(
|
|
|
|
calleeClassName->body().begin())));
|
2013-03-05 22:43:49 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 04:16:33 +00:00
|
|
|
virtual GcClassLoader* libraryClassLoader(Thread* t, GcMethod* caller)
|
2014-07-01 16:18:45 +00:00
|
|
|
{
|
|
|
|
#ifdef AVIAN_OPENJDK_SRC
|
2014-07-15 14:07:57 +00:00
|
|
|
return (caller->class_() == type(t, GcClassLoader::Type)
|
2014-07-11 15:47:57 +00:00
|
|
|
and t->libraryLoadStack)
|
2014-07-01 16:18:45 +00:00
|
|
|
? t->libraryLoadStack->classLoader
|
|
|
|
#else
|
2014-06-21 04:16:33 +00:00
|
|
|
return strcmp("java/lang/ClassLoader$NativeLibrary",
|
2014-07-11 15:47:57 +00:00
|
|
|
reinterpret_cast<char*>(
|
|
|
|
caller->class_()->name()->body().begin())) == 0
|
2014-06-21 04:16:33 +00:00
|
|
|
? cast<GcClass>(
|
2014-07-01 16:18:45 +00:00
|
|
|
t,
|
2014-06-21 04:16:33 +00:00
|
|
|
cast<GcJclass>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
resolveMethod(t,
|
|
|
|
caller->class_(),
|
|
|
|
"getFromClass",
|
|
|
|
"()Ljava/lang/Class;"),
|
|
|
|
0))->vmClass())->loader()
|
2014-07-01 16:18:45 +00:00
|
|
|
#endif
|
2014-06-21 04:16:33 +00:00
|
|
|
: caller->class_()->loader();
|
2014-07-01 16:18:45 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void shutDown(Thread* t)
|
2013-04-19 19:00:47 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* c
|
|
|
|
= resolveClass(t, roots(t)->bootLoader(), "java/lang/Shutdown", false);
|
2013-04-19 19:00:47 +00:00
|
|
|
|
|
|
|
if (c) {
|
2014-05-29 04:17:25 +00:00
|
|
|
GcMethod* m = findMethodOrNull(t, c, "shutdown", "()V");
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2013-04-19 19:00:47 +00:00
|
|
|
if (m) {
|
|
|
|
t->m->processor->invoke(t, m, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual void dispose()
|
|
|
|
{
|
2012-10-03 15:43:51 +00:00
|
|
|
allocator->free(buffer, bufferSize);
|
2010-09-10 21:05:29 +00:00
|
|
|
allocator->free(this, sizeof(*this));
|
|
|
|
}
|
|
|
|
|
|
|
|
Allocator* allocator;
|
2010-09-20 23:31:23 +00:00
|
|
|
const char* javaHome;
|
|
|
|
const char* classpath;
|
|
|
|
const char* libraryPath;
|
2010-11-07 19:24:40 +00:00
|
|
|
const char* tzMappings;
|
2010-11-05 19:18:28 +00:00
|
|
|
const char* embedPrefix;
|
2012-10-03 15:43:51 +00:00
|
|
|
char* buffer;
|
|
|
|
unsigned bufferSize;
|
2010-11-07 19:24:40 +00:00
|
|
|
unsigned tzMappingsLength;
|
2010-11-05 19:18:28 +00:00
|
|
|
unsigned embedPrefixLength;
|
2010-11-07 17:08:04 +00:00
|
|
|
unsigned filePathField;
|
|
|
|
unsigned fileDescriptorFdField;
|
|
|
|
unsigned fileInputStreamFdField;
|
2011-03-04 23:55:31 +00:00
|
|
|
unsigned zipFileJzfileField;
|
|
|
|
unsigned zipEntryNameField;
|
|
|
|
unsigned zipEntryTimeField;
|
|
|
|
unsigned zipEntryCrcField;
|
|
|
|
unsigned zipEntrySizeField;
|
|
|
|
unsigned zipEntryCsizeField;
|
|
|
|
unsigned zipEntryMethodField;
|
2010-12-09 04:38:16 +00:00
|
|
|
bool ranNetOnLoad;
|
2011-08-06 00:06:29 +00:00
|
|
|
bool ranManagementOnLoad;
|
2011-04-10 03:17:15 +00:00
|
|
|
JmmInterface jmmInterface;
|
2010-09-10 21:05:29 +00:00
|
|
|
};
|
|
|
|
|
2010-11-05 19:18:28 +00:00
|
|
|
struct JVM_ExceptionTableEntryType {
|
|
|
|
jint start_pc;
|
|
|
|
jint end_pc;
|
|
|
|
jint handler_pc;
|
|
|
|
jint catchType;
|
2010-09-10 21:05:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct jvm_version_info {
|
2010-11-05 19:18:28 +00:00
|
|
|
unsigned jvm_version;
|
2014-07-11 15:50:18 +00:00
|
|
|
unsigned update_version : 8;
|
|
|
|
unsigned special_update_version : 8;
|
|
|
|
unsigned reserved1 : 16;
|
2010-11-05 19:18:28 +00:00
|
|
|
unsigned reserved2;
|
2014-07-11 15:50:18 +00:00
|
|
|
unsigned is_attach_supported : 1;
|
|
|
|
unsigned is_kernel_jvm : 1;
|
|
|
|
unsigned : 30;
|
|
|
|
unsigned : 32;
|
|
|
|
unsigned : 32;
|
2010-09-10 21:05:29 +00:00
|
|
|
};
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
bool pathEqual(const char* a, const char* b, unsigned length)
|
2010-11-07 04:21:19 +00:00
|
|
|
{
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
return strncasecmp(a, b, length) == 0;
|
|
|
|
#else
|
|
|
|
return strncmp(a, b, length) == 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-11-05 19:18:28 +00:00
|
|
|
class EmbeddedFile {
|
|
|
|
public:
|
2014-07-11 15:50:18 +00:00
|
|
|
EmbeddedFile(MyClasspath* cp, const char* path, unsigned pathLength)
|
|
|
|
{
|
2010-11-07 04:21:19 +00:00
|
|
|
if (pathEqual(cp->embedPrefix, path, cp->embedPrefixLength)) {
|
2010-11-05 19:18:28 +00:00
|
|
|
const char* p = path + cp->embedPrefixLength;
|
2014-07-11 15:50:18 +00:00
|
|
|
while (*p == '/')
|
|
|
|
++p;
|
2010-11-05 19:18:28 +00:00
|
|
|
|
|
|
|
this->jar = p;
|
|
|
|
|
|
|
|
if (*p == 0) {
|
|
|
|
this->jarLength = 0;
|
|
|
|
this->path = 0;
|
|
|
|
this->pathLength = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
while (*p and *p != '/')
|
|
|
|
++p;
|
|
|
|
|
2010-11-05 19:18:28 +00:00
|
|
|
this->jarLength = p - this->jar;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
while (*p == '/')
|
|
|
|
++p;
|
2010-11-05 19:18:28 +00:00
|
|
|
|
|
|
|
this->path = p;
|
|
|
|
this->pathLength = pathLength - (p - path);
|
|
|
|
} else {
|
|
|
|
this->jar = 0;
|
2014-07-11 15:50:18 +00:00
|
|
|
this->jarLength = 0;
|
2010-11-05 19:18:28 +00:00
|
|
|
this->path = 0;
|
|
|
|
this->pathLength = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* jar;
|
|
|
|
const char* path;
|
|
|
|
unsigned jarLength;
|
|
|
|
unsigned pathLength;
|
|
|
|
};
|
|
|
|
|
2013-07-03 20:33:46 +00:00
|
|
|
#ifdef AVIAN_OPENJDK_SRC
|
2010-11-05 19:18:28 +00:00
|
|
|
int64_t JNICALL
|
2014-07-15 14:07:57 +00:00
|
|
|
getFileAttributes(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-05 19:18:28 +00:00
|
|
|
{
|
|
|
|
const unsigned Exists = 1;
|
|
|
|
const unsigned Regular = 2;
|
|
|
|
const unsigned Directory = 4;
|
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
|
|
|
object file = reinterpret_cast<object>(arguments[1]);
|
2014-07-15 14:07:57 +00:00
|
|
|
GcString* path
|
|
|
|
= cast<GcString>(t, fieldAtOffset<object>(file, cp->filePathField));
|
2010-11-05 19:18:28 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, p, path->length(t) + 1);
|
2010-11-05 19:18:28 +00:00
|
|
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
2010-11-07 04:21:19 +00:00
|
|
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
2010-11-05 19:18:28 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), path->length(t));
|
2010-12-09 04:38:16 +00:00
|
|
|
if (ef.jar) {
|
|
|
|
if (ef.jarLength == 0) {
|
|
|
|
return Exists | Directory;
|
|
|
|
}
|
|
|
|
|
|
|
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
|
|
|
if (finder) {
|
|
|
|
if (ef.pathLength == 0) {
|
2010-11-05 19:18:28 +00:00
|
|
|
return Exists | Directory;
|
|
|
|
}
|
|
|
|
|
2010-12-09 04:38:16 +00:00
|
|
|
unsigned length;
|
|
|
|
System::FileType type = finder->stat(ef.path, &length, true);
|
|
|
|
switch (type) {
|
2014-07-11 15:50:18 +00:00
|
|
|
case System::TypeUnknown:
|
|
|
|
return Exists;
|
|
|
|
case System::TypeDoesNotExist:
|
|
|
|
return 0;
|
|
|
|
case System::TypeFile:
|
|
|
|
return Exists | Regular;
|
|
|
|
case System::TypeDirectory:
|
|
|
|
return Exists | Directory;
|
|
|
|
default:
|
|
|
|
abort(t);
|
2010-11-05 19:18:28 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-12-09 04:38:16 +00:00
|
|
|
return 0;
|
2010-11-05 19:18:28 +00:00
|
|
|
}
|
2010-12-09 04:38:16 +00:00
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcInt>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
reinterpret_cast<object>(arguments[0]),
|
|
|
|
file))->value();
|
2010-11-05 19:18:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL
|
|
|
|
checkFileAccess(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-12-01 20:40:43 +00:00
|
|
|
{
|
|
|
|
const unsigned Read = 4;
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2010-12-01 20:40:43 +00:00
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
|
|
|
object file = reinterpret_cast<object>(arguments[1]);
|
|
|
|
unsigned mask = arguments[2];
|
2014-07-15 14:07:57 +00:00
|
|
|
GcString* path
|
|
|
|
= cast<GcString>(t, fieldAtOffset<object>(file, cp->filePathField));
|
2010-12-01 20:40:43 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, p, path->length(t) + 1);
|
2010-12-01 20:40:43 +00:00
|
|
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
|
|
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), path->length(t));
|
2010-12-09 04:38:16 +00:00
|
|
|
if (ef.jar) {
|
|
|
|
if (ef.jarLength == 0) {
|
|
|
|
return mask == Read;
|
|
|
|
}
|
|
|
|
|
|
|
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
|
|
|
if (finder) {
|
|
|
|
if (ef.pathLength == 0) {
|
2010-12-01 20:40:43 +00:00
|
|
|
return mask == Read;
|
|
|
|
}
|
|
|
|
|
2010-12-09 04:38:16 +00:00
|
|
|
unsigned length;
|
|
|
|
System::FileType type = finder->stat(ef.path, &length, true);
|
|
|
|
switch (type) {
|
2014-07-11 15:50:18 +00:00
|
|
|
case System::TypeDoesNotExist:
|
|
|
|
return false;
|
2010-12-09 04:38:16 +00:00
|
|
|
case System::TypeUnknown:
|
|
|
|
case System::TypeFile:
|
2014-07-11 15:50:18 +00:00
|
|
|
case System::TypeDirectory:
|
|
|
|
return mask == Read;
|
|
|
|
default:
|
|
|
|
abort(t);
|
2010-12-01 20:40:43 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-12-09 04:38:16 +00:00
|
|
|
return 0;
|
2010-12-01 20:40:43 +00:00
|
|
|
}
|
2010-12-09 04:38:16 +00:00
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcInt>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
reinterpret_cast<object>(arguments[0]),
|
|
|
|
file,
|
|
|
|
mask))->value() != 0;
|
2010-12-01 20:40:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL getFileLength(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-05 19:18:28 +00:00
|
|
|
{
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
|
|
|
object file = reinterpret_cast<object>(arguments[1]);
|
2014-07-15 14:07:57 +00:00
|
|
|
GcString* path
|
|
|
|
= cast<GcString>(t, fieldAtOffset<object>(file, cp->filePathField));
|
2010-11-05 19:18:28 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, p, path->length(t) + 1);
|
2010-11-05 19:18:28 +00:00
|
|
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
2010-11-07 04:21:19 +00:00
|
|
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
2010-11-05 19:18:28 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), path->length(t));
|
2010-11-05 19:18:28 +00:00
|
|
|
if (ef.jar) {
|
|
|
|
if (ef.jarLength == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
|
|
|
if (finder) {
|
|
|
|
if (ef.pathLength == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned fileLength;
|
|
|
|
finder->stat(ef.path, &fileLength);
|
|
|
|
return fileLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcLong>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t,
|
|
|
|
getMethodRuntimeData(t, method)
|
|
|
|
->native())->original()),
|
|
|
|
reinterpret_cast<object>(arguments[0]),
|
|
|
|
file))->value();
|
2010-11-05 19:18:28 +00:00
|
|
|
}
|
2010-11-04 17:02:09 +00:00
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
void JNICALL openFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
2014-07-15 14:07:57 +00:00
|
|
|
GcString* path = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, p, path->length(t) + 1);
|
2010-11-07 17:08:04 +00:00
|
|
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
|
|
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), path->length(t));
|
2010-11-07 17:08:04 +00:00
|
|
|
if (ef.jar) {
|
|
|
|
if (ef.jarLength == 0 or ef.pathLength == 0) {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcFileNotFoundException::Type);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
|
2010-11-07 19:24:40 +00:00
|
|
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
2010-11-07 17:08:04 +00:00
|
|
|
if (finder == 0) {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcFileNotFoundException::Type);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
System::Region* r = finder->find(ef.path);
|
|
|
|
if (r == 0) {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcFileNotFoundException::Type);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PROTECT(t, this_);
|
|
|
|
|
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
|
|
|
|
|
|
|
int index = -1;
|
2014-07-15 14:07:57 +00:00
|
|
|
unsigned oldLength
|
|
|
|
= roots(t)->virtualFiles() ? roots(t)->virtualFiles()->length() : 0;
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
for (unsigned i = 0; i < oldLength; ++i) {
|
2014-07-15 14:07:57 +00:00
|
|
|
if (roots(t)->virtualFiles()->body()[i] == 0) {
|
2010-11-07 17:08:04 +00:00
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index == -1) {
|
2014-07-15 14:07:57 +00:00
|
|
|
GcArray* newArray = growArray(t, roots(t)->virtualFiles());
|
|
|
|
roots(t)->setVirtualFiles(t, newArray);
|
2010-11-07 17:08:04 +00:00
|
|
|
index = oldLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
object region = makeRegion(t, r, 0);
|
2014-07-15 14:07:57 +00:00
|
|
|
roots(t)->virtualFiles()->setBodyElement(t, index, region);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
fieldAtOffset<int32_t>(
|
|
|
|
fieldAtOffset<object>(this_, cp->fileInputStreamFdField),
|
|
|
|
cp->fileDescriptorFdField) = index + VirtualFileBase;
|
2010-11-07 17:08:04 +00:00
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2014-07-11 15:50:18 +00:00
|
|
|
this_,
|
|
|
|
path);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL
|
|
|
|
readByteFromFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int fd = fieldAtOffset<int32_t>(
|
|
|
|
fieldAtOffset<object>(this_, cp->fileInputStreamFdField),
|
|
|
|
cp->fileDescriptorFdField);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2010-11-07 19:24:40 +00:00
|
|
|
if (fd >= VirtualFileBase) {
|
2010-11-07 17:08:04 +00:00
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcRegion* region = cast<GcRegion>(
|
|
|
|
t, roots(t)->virtualFiles()->body()[fd - VirtualFileBase]);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
if (region) {
|
2014-07-15 14:07:57 +00:00
|
|
|
System::Region* r = static_cast<System::Region*>(region->region());
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
if (r->length() > region->position()) {
|
|
|
|
return r->start()[region->position()++];
|
2010-11-07 17:08:04 +00:00
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcIoException::Type);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcInt>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
this_))->value();
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t JNICALL
|
2014-07-15 14:07:57 +00:00
|
|
|
readBytesFromFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
2014-07-15 14:07:57 +00:00
|
|
|
GcByteArray* dst
|
|
|
|
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[1]));
|
2010-11-07 17:08:04 +00:00
|
|
|
int32_t offset = arguments[2];
|
|
|
|
int32_t length = arguments[3];
|
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int fd = fieldAtOffset<int32_t>(
|
|
|
|
fieldAtOffset<object>(this_, cp->fileInputStreamFdField),
|
|
|
|
cp->fileDescriptorFdField);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2010-11-07 19:24:40 +00:00
|
|
|
if (fd >= VirtualFileBase) {
|
2011-03-17 14:43:01 +00:00
|
|
|
PROTECT(t, dst);
|
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcRegion* region = cast<GcRegion>(
|
|
|
|
t, roots(t)->virtualFiles()->body()[fd - VirtualFileBase]);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
if (region) {
|
2014-07-15 14:07:57 +00:00
|
|
|
System::Region* r = static_cast<System::Region*>(region->region());
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int available = r->length() - region->position();
|
2010-11-07 17:08:04 +00:00
|
|
|
if (available == 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (length > available) {
|
|
|
|
length = available;
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
memcpy(&dst->body()[offset], r->start() + region->position(), length);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
region->position() += length;
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
return length;
|
|
|
|
} else {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcIoException::Type);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcInt>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
this_,
|
|
|
|
dst,
|
|
|
|
offset,
|
|
|
|
length))->value();
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL
|
|
|
|
skipBytesInFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t count;
|
|
|
|
memcpy(&count, arguments + 1, 8);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int fd = fieldAtOffset<int32_t>(
|
|
|
|
fieldAtOffset<object>(this_, cp->fileInputStreamFdField),
|
|
|
|
cp->fileDescriptorFdField);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2010-11-07 19:24:40 +00:00
|
|
|
if (fd >= VirtualFileBase) {
|
2010-11-07 17:08:04 +00:00
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcRegion* region = cast<GcRegion>(
|
|
|
|
t, roots(t)->virtualFiles()->body()[fd - VirtualFileBase]);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
if (region) {
|
2014-07-15 14:07:57 +00:00
|
|
|
System::Region* r = static_cast<System::Region*>(region->region());
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int available = r->length() - region->position();
|
2010-11-07 17:08:04 +00:00
|
|
|
if (count > available) {
|
|
|
|
count = available;
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
region->position() += count;
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
return count;
|
|
|
|
} else {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcIoException::Type);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcLong>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t,
|
|
|
|
getMethodRuntimeData(t, method)
|
|
|
|
->native())->original()),
|
|
|
|
this_,
|
|
|
|
count))->value();
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t JNICALL
|
2014-07-15 14:07:57 +00:00
|
|
|
availableBytesInFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int fd = fieldAtOffset<int32_t>(
|
|
|
|
fieldAtOffset<object>(this_, cp->fileInputStreamFdField),
|
|
|
|
cp->fileDescriptorFdField);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2010-11-07 19:24:40 +00:00
|
|
|
if (fd >= VirtualFileBase) {
|
2010-11-07 17:08:04 +00:00
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcRegion* region = cast<GcRegion>(
|
|
|
|
t, roots(t)->virtualFiles()->body()[fd - VirtualFileBase]);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
if (region) {
|
2014-07-15 14:07:57 +00:00
|
|
|
return static_cast<System::Region*>(region->region())->length()
|
|
|
|
- region->position();
|
2010-11-07 17:08:04 +00:00
|
|
|
} else {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcIoException::Type);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
object r = t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2014-07-11 15:50:18 +00:00
|
|
|
this_);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
return r ? cast<GcInt>(t, r)->value() : 0;
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
void JNICALL closeFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int fd = fieldAtOffset<int32_t>(
|
|
|
|
fieldAtOffset<object>(this_, cp->fileInputStreamFdField),
|
|
|
|
cp->fileDescriptorFdField);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2010-11-07 19:24:40 +00:00
|
|
|
if (fd >= VirtualFileBase) {
|
2010-11-07 17:08:04 +00:00
|
|
|
ACQUIRE(t, t->m->referenceLock);
|
|
|
|
|
|
|
|
int index = fd - VirtualFileBase;
|
2014-07-15 14:07:57 +00:00
|
|
|
GcRegion* region
|
|
|
|
= cast<GcRegion>(t, roots(t)->virtualFiles()->body()[index]);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
|
|
|
if (region) {
|
2014-07-15 14:07:57 +00:00
|
|
|
static_cast<System::Region*>(region->region())->dispose();
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
roots(t)->virtualFiles()->setBodyElement(t, index, 0);
|
2010-11-07 17:08:04 +00:00
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2014-07-11 15:50:18 +00:00
|
|
|
this_);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-04 23:55:31 +00:00
|
|
|
class ZipFile {
|
|
|
|
public:
|
|
|
|
class Entry {
|
|
|
|
public:
|
2014-07-11 15:50:18 +00:00
|
|
|
Entry(unsigned hash, const uint8_t* start, Entry* next)
|
|
|
|
: hash(hash), start(start), next(next), entry(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry(int64_t entry) : hash(0), start(0), next(0), entry(entry)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry() : hash(0), start(0), next(0), entry(0)
|
|
|
|
{
|
|
|
|
}
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
unsigned hash;
|
|
|
|
const uint8_t* start;
|
|
|
|
Entry* next;
|
|
|
|
int64_t entry;
|
|
|
|
};
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
ZipFile(Thread* t, System::Region* region, unsigned entryCount)
|
|
|
|
: region(region),
|
|
|
|
entryCount(entryCount),
|
|
|
|
indexSize(nextPowerOfTwo(entryCount)),
|
|
|
|
index(reinterpret_cast<ZipFile::Entry**>(
|
|
|
|
t->m->heap->allocate(sizeof(ZipFile::Entry*) * indexSize))),
|
|
|
|
file(0)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
|
|
|
memset(index, 0, sizeof(ZipFile::Entry*) * indexSize);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
ZipFile(int64_t file)
|
|
|
|
: region(0), entryCount(0), indexSize(0), index(0), file(file)
|
|
|
|
{
|
|
|
|
}
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
System::Region* region;
|
|
|
|
unsigned entryCount;
|
|
|
|
unsigned indexSize;
|
|
|
|
Entry** index;
|
|
|
|
int64_t file;
|
|
|
|
Entry entries[0];
|
|
|
|
};
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL openZipFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-15 14:07:57 +00:00
|
|
|
GcString* path = cast<GcString>(t, reinterpret_cast<object>(arguments[0]));
|
2011-03-04 23:55:31 +00:00
|
|
|
int mode = arguments[1];
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t lastModified;
|
|
|
|
memcpy(&lastModified, arguments + 2, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, p, path->length(t) + 1);
|
2011-03-04 23:55:31 +00:00
|
|
|
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
|
|
|
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
EmbeddedFile ef(cp, RUNTIME_ARRAY_BODY(p), path->length(t));
|
2011-03-04 23:55:31 +00:00
|
|
|
if (ef.jar) {
|
|
|
|
if (ef.jarLength == 0 or ef.pathLength == 0) {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcFileNotFoundException::Type);
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
|
|
|
if (finder == 0) {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcFileNotFoundException::Type);
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
System::Region* r = finder->find(ef.path);
|
|
|
|
if (r == 0) {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcFileNotFoundException::Type);
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const uint8_t* start = r->start();
|
|
|
|
const uint8_t* end = start + r->length();
|
|
|
|
unsigned entryCount = 0;
|
|
|
|
for (const uint8_t* p = end - CentralDirectorySearchStart; p > start;) {
|
|
|
|
if (get4(p) == CentralDirectorySignature) {
|
|
|
|
p = start + centralDirectoryOffset(p);
|
|
|
|
|
|
|
|
while (p < end) {
|
|
|
|
if (get4(p) == EntrySignature) {
|
2014-07-11 15:50:18 +00:00
|
|
|
++entryCount;
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
p = endOfEntry(p);
|
|
|
|
} else {
|
|
|
|
goto make;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
--p;
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
make:
|
2014-07-11 15:50:18 +00:00
|
|
|
ZipFile* file = new (t->m->heap->allocate(
|
|
|
|
sizeof(ZipFile) + (sizeof(ZipFile::Entry) * entryCount)))
|
|
|
|
ZipFile(t, r, entryCount);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
{
|
|
|
|
unsigned position = 0;
|
2011-03-04 23:55:31 +00:00
|
|
|
for (const uint8_t* p = end - CentralDirectorySearchStart; p > start;) {
|
|
|
|
if (get4(p) == CentralDirectorySignature) {
|
|
|
|
p = start + centralDirectoryOffset(p);
|
|
|
|
|
|
|
|
while (p < end) {
|
|
|
|
if (get4(p) == EntrySignature) {
|
2014-07-15 14:07:57 +00:00
|
|
|
unsigned h
|
|
|
|
= hash(Slice<const uint8_t>(fileName(p), fileNameLength(p)));
|
2011-03-04 23:55:31 +00:00
|
|
|
unsigned i = h & (file->indexSize - 1);
|
|
|
|
|
|
|
|
file->index[i] = new (file->entries + (position++))
|
2014-07-11 15:50:18 +00:00
|
|
|
ZipFile::Entry(h, p, file->index[i]);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
p = endOfEntry(p);
|
|
|
|
} else {
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
--p;
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return reinterpret_cast<int64_t>(file);
|
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<int64_t>(
|
2014-07-15 14:07:57 +00:00
|
|
|
new (t->m->heap->allocate(sizeof(ZipFile))) ZipFile(
|
|
|
|
cast<GcLong>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t,
|
|
|
|
getMethodRuntimeData(t, method)
|
|
|
|
->native())->original()),
|
|
|
|
0,
|
|
|
|
path,
|
|
|
|
mode,
|
|
|
|
lastModified))->value()));
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t JNICALL
|
2014-07-15 14:07:57 +00:00
|
|
|
getZipFileEntryCount(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
|
|
|
if (file->region) {
|
|
|
|
return file->entryCount;
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcInt>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
0,
|
|
|
|
file->file))->value();
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
ZipFile::Entry* find(ZipFile* file, const char* path, unsigned pathLength)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
|
|
|
unsigned i = hash(path) & (file->indexSize - 1);
|
|
|
|
for (ZipFile::Entry* e = file->index[i]; e; e = e->next) {
|
|
|
|
const uint8_t* p = e->start;
|
|
|
|
if (equal(path, pathLength, fileName(p), fileNameLength(p))) {
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL
|
|
|
|
getZipFileEntry(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2014-07-15 14:07:57 +00:00
|
|
|
GcByteArray* path
|
|
|
|
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[2]));
|
2011-03-04 23:55:31 +00:00
|
|
|
bool addSlash = arguments[3];
|
|
|
|
|
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
|
|
|
if (file->region) {
|
2014-07-15 14:07:57 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, p, path->length() + 2);
|
|
|
|
memcpy(RUNTIME_ARRAY_BODY(p), path->body().begin(), path->length());
|
|
|
|
RUNTIME_ARRAY_BODY(p)[path->length()] = 0;
|
2011-03-04 23:55:31 +00:00
|
|
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p));
|
|
|
|
if (addSlash) {
|
2014-07-15 14:07:57 +00:00
|
|
|
RUNTIME_ARRAY_BODY(p)[path->length()] = '/';
|
|
|
|
RUNTIME_ARRAY_BODY(p)[path->length() + 1] = 0;
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<int64_t>(
|
2014-07-15 14:07:57 +00:00
|
|
|
find(file, RUNTIME_ARRAY_BODY(p), path->length()));
|
2011-03-04 23:55:31 +00:00
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t entry
|
|
|
|
= cast<GcLong>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
0,
|
|
|
|
file->file,
|
|
|
|
path,
|
|
|
|
addSlash))->value();
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return entry ? reinterpret_cast<int64_t>(new (t->m->heap->allocate(
|
|
|
|
sizeof(ZipFile::Entry))) ZipFile::Entry(entry))
|
|
|
|
: 0;
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-18 22:17:10 +00:00
|
|
|
int64_t JNICALL
|
2014-07-15 14:07:57 +00:00
|
|
|
getZipFileEntryBytes(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2012-02-18 22:17:10 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2012-02-18 22:17:10 +00:00
|
|
|
int type = arguments[2];
|
|
|
|
|
|
|
|
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(peer);
|
|
|
|
if (entry->start) {
|
|
|
|
switch (type) {
|
2014-07-11 15:50:18 +00:00
|
|
|
case 0: { // name
|
2012-02-18 22:17:10 +00:00
|
|
|
unsigned nameLength = fileNameLength(entry->start);
|
2014-07-15 14:07:57 +00:00
|
|
|
GcByteArray* array = makeByteArray(t, nameLength + 1);
|
|
|
|
memcpy(array->body().begin(), fileName(entry->start), nameLength);
|
|
|
|
array->body()[nameLength] = 0;
|
2012-02-18 22:17:10 +00:00
|
|
|
return reinterpret_cast<int64_t>(array);
|
|
|
|
} break;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
case 1: { // extra
|
2012-02-18 22:17:10 +00:00
|
|
|
return 0;
|
|
|
|
} break;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
case 2: { // comment
|
2012-02-18 22:17:10 +00:00
|
|
|
return 0;
|
|
|
|
} break;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
default:
|
|
|
|
abort(t);
|
2012-02-18 22:17:10 +00:00
|
|
|
}
|
|
|
|
return compressedSize(entry->start);
|
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<int64_t>(t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2014-07-11 15:50:18 +00:00
|
|
|
0,
|
|
|
|
entry->entry,
|
|
|
|
type));
|
2012-02-18 22:17:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-04 23:55:31 +00:00
|
|
|
int64_t JNICALL
|
2014-07-15 14:07:57 +00:00
|
|
|
getNextZipFileEntry(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
int index = arguments[2];
|
|
|
|
|
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
|
|
|
if (file->region) {
|
|
|
|
return reinterpret_cast<int64_t>(file->entries + index);
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t entry
|
|
|
|
= cast<GcLong>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
0,
|
|
|
|
file->file,
|
|
|
|
index))->value();
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return entry ? reinterpret_cast<int64_t>(new (t->m->heap->allocate(
|
|
|
|
sizeof(ZipFile::Entry))) ZipFile::Entry(entry))
|
|
|
|
: 0;
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t JNICALL
|
2014-07-15 14:07:57 +00:00
|
|
|
getZipFileEntryMethod(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(peer);
|
|
|
|
if (entry->start) {
|
|
|
|
return compressionMethod(entry->start);
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcInt>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
0,
|
|
|
|
entry->entry))->value();
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t JNICALL getZipFileEntryCompressedSize(Thread* t,
|
2014-07-15 14:07:57 +00:00
|
|
|
GcMethod* method,
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(peer);
|
|
|
|
if (entry->start) {
|
|
|
|
return compressedSize(entry->start);
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcLong>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t,
|
|
|
|
getMethodRuntimeData(t, method)
|
|
|
|
->native())->original()),
|
|
|
|
0,
|
|
|
|
entry->entry))->value();
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t JNICALL getZipFileEntryUncompressedSize(Thread* t,
|
2014-07-15 14:07:57 +00:00
|
|
|
GcMethod* method,
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(peer);
|
|
|
|
if (entry->start) {
|
|
|
|
return uncompressedSize(entry->start);
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcLong>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t,
|
|
|
|
getMethodRuntimeData(t, method)
|
|
|
|
->native())->original()),
|
|
|
|
0,
|
|
|
|
entry->entry))->value();
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
void JNICALL freeZipFileEntry(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t filePeer;
|
|
|
|
memcpy(&filePeer, arguments, 8);
|
|
|
|
int64_t entryPeer;
|
|
|
|
memcpy(&entryPeer, arguments + 2, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(filePeer);
|
|
|
|
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(entryPeer);
|
|
|
|
if (file->region == 0) {
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2014-07-11 15:50:18 +00:00
|
|
|
0,
|
|
|
|
file->file,
|
|
|
|
entry->entry);
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
2012-03-17 18:58:41 +00:00
|
|
|
|
|
|
|
t->m->heap->free(entry, sizeof(ZipFile::Entry));
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL
|
|
|
|
readZipFileEntry(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t filePeer;
|
|
|
|
memcpy(&filePeer, arguments, 8);
|
|
|
|
int64_t entryPeer;
|
|
|
|
memcpy(&entryPeer, arguments + 2, 8);
|
|
|
|
int64_t position;
|
|
|
|
memcpy(&position, arguments + 4, 8);
|
2014-07-15 14:07:57 +00:00
|
|
|
GcByteArray* buffer
|
|
|
|
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[6]));
|
2011-03-04 23:55:31 +00:00
|
|
|
int offset = arguments[7];
|
|
|
|
int length = arguments[8];
|
|
|
|
|
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(filePeer);
|
|
|
|
ZipFile::Entry* entry = reinterpret_cast<ZipFile::Entry*>(entryPeer);
|
|
|
|
if (file->region) {
|
|
|
|
unsigned size = uncompressedSize(entry->start);
|
|
|
|
if (position >= size) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (position + length > size) {
|
|
|
|
length = size - position;
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
memcpy(&buffer->body()[offset],
|
2011-03-04 23:55:31 +00:00
|
|
|
fileData(file->region->start() + localHeaderOffset(entry->start))
|
|
|
|
+ position,
|
|
|
|
length);
|
|
|
|
|
|
|
|
return length;
|
|
|
|
} else {
|
2014-07-15 14:07:57 +00:00
|
|
|
return cast<GcInt>(t,
|
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())
|
|
|
|
->original()),
|
|
|
|
0,
|
|
|
|
file->file,
|
|
|
|
entry->entry,
|
|
|
|
position,
|
|
|
|
buffer,
|
|
|
|
offset,
|
|
|
|
length))->value();
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL getZipMessage(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
|
|
|
if (file->region) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<int64_t>(t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2014-07-11 15:50:18 +00:00
|
|
|
0,
|
|
|
|
file->file));
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
int64_t JNICALL getJarFileMetaInfEntryNames(Thread* t,
|
|
|
|
GcMethod* method,
|
|
|
|
uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
|
|
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
|
|
|
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
int64_t peer = fieldAtOffset<int64_t>(this_, cp->zipFileJzfileField);
|
2011-03-04 23:55:31 +00:00
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
|
|
|
if (file->region) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
PROTECT(t, method);
|
|
|
|
|
|
|
|
// OpenJDK's Java_java_util_jar_JarFile_getMetaInfEntryNames
|
|
|
|
// implementation expects to find a pointer to an instance of its
|
|
|
|
// jzfile structure in the ZipFile.jzfile field of the object we
|
|
|
|
// pass in. However, we can't pass this_ in, because its
|
|
|
|
// ZipFile.jzfile field points to a ZipFile instance, not a
|
|
|
|
// jzfile. So we pass in a temporary object instead which has the
|
|
|
|
// desired pointer at the same offset. We assume here that
|
|
|
|
// ZipFile.jzfile is the first field in that class and that
|
|
|
|
// Java_java_util_jar_JarFile_getMetaInfEntryNames will not look
|
|
|
|
// for any other fields in the object.
|
|
|
|
object pseudoThis = makeLong(t, file->file);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<int64_t>(t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2011-03-04 23:55:31 +00:00
|
|
|
pseudoThis));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
void JNICALL closeZipFile(Thread* t, GcMethod* method, uintptr_t* arguments)
|
2011-03-04 23:55:31 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t peer;
|
|
|
|
memcpy(&peer, arguments, 8);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
ZipFile* file = reinterpret_cast<ZipFile*>(peer);
|
|
|
|
if (file->region) {
|
|
|
|
file->region->dispose();
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->heap->free(
|
|
|
|
file, sizeof(ZipFile) + (sizeof(ZipFile::Entry) * file->entryCount));
|
2011-03-04 23:55:31 +00:00
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
t->m->processor->invoke(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcNativeIntercept>(
|
|
|
|
t, getMethodRuntimeData(t, method)->native())->original()),
|
2014-07-11 15:50:18 +00:00
|
|
|
0,
|
|
|
|
file->file);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
|
|
|
t->m->heap->free(file, sizeof(ZipFile));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t JNICALL getBootstrapResource(Thread* t, object, uintptr_t* arguments)
|
2010-12-06 00:40:50 +00:00
|
|
|
{
|
|
|
|
object name = reinterpret_cast<object>(arguments[0]);
|
|
|
|
PROTECT(t, name);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* m = findMethodOrNull(t,
|
|
|
|
type(t, GcSystemClassLoader::Type),
|
|
|
|
"findResource",
|
|
|
|
"(Ljava/lang/String;)Ljava/net/URL;");
|
|
|
|
|
2010-12-06 00:40:50 +00:00
|
|
|
if (m) {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<int64_t>(
|
|
|
|
t->m->processor->invoke(t, m, roots(t)->bootLoader(), name));
|
2010-12-06 00:40:50 +00:00
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t JNICALL getBootstrapResources(Thread* t, object, uintptr_t* arguments)
|
2010-12-06 00:40:50 +00:00
|
|
|
{
|
|
|
|
object name = reinterpret_cast<object>(arguments[0]);
|
|
|
|
PROTECT(t, name);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* m = findMethodOrNull(t,
|
|
|
|
type(t, GcSystemClassLoader::Type),
|
|
|
|
"findResources",
|
|
|
|
"(Ljava/lang/String;)Ljava/util/Enumeration;");
|
|
|
|
|
2010-12-06 00:40:50 +00:00
|
|
|
if (m) {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<int64_t>(
|
|
|
|
t->m->processor->invoke(t, m, roots(t)->bootLoader(), name));
|
2010-12-06 00:40:50 +00:00
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL net_JNI_OnLoad(JavaVM*, void*);
|
2010-12-09 04:38:16 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL management_JNI_OnLoad(JavaVM*, void*);
|
2011-08-06 00:06:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void JNICALL loadLibrary(Thread* t, object, uintptr_t* arguments)
|
2010-12-09 04:38:16 +00:00
|
|
|
{
|
2014-07-01 16:18:45 +00:00
|
|
|
Thread::LibraryLoadStack stack(
|
|
|
|
t,
|
2014-07-15 14:07:57 +00:00
|
|
|
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))
|
|
|
|
->vmClass()
|
|
|
|
->loader());
|
2014-06-23 23:17:13 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcString* name = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
|
|
|
|
THREAD_RUNTIME_ARRAY(t, char, n, name->length(t) + 1);
|
2010-12-09 04:38:16 +00:00
|
|
|
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
|
|
|
|
|
|
|
|
bool absolute = arguments[2];
|
|
|
|
|
|
|
|
if (not absolute) {
|
2013-02-25 17:38:06 +00:00
|
|
|
if (strcmp(RUNTIME_ARRAY_BODY(n), "net") == 0) {
|
2010-12-09 04:38:16 +00:00
|
|
|
bool ran;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
{
|
|
|
|
ACQUIRE(t, t->m->classLock);
|
2010-12-09 04:38:16 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::MyClasspath* c
|
|
|
|
= static_cast<local::MyClasspath*>(t->m->classpath);
|
2010-12-09 04:38:16 +00:00
|
|
|
|
|
|
|
ran = c->ranNetOnLoad;
|
|
|
|
c->ranNetOnLoad = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not ran) {
|
|
|
|
net_JNI_OnLoad(t->m, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
2014-07-11 15:50:18 +00:00
|
|
|
} else if (strcmp(RUNTIME_ARRAY_BODY(n), "management") == 0) {
|
2011-08-06 00:06:29 +00:00
|
|
|
bool ran;
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
{
|
|
|
|
ACQUIRE(t, t->m->classLock);
|
2011-08-06 00:06:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::MyClasspath* c
|
|
|
|
= static_cast<local::MyClasspath*>(t->m->classpath);
|
2011-08-06 00:06:29 +00:00
|
|
|
|
|
|
|
ran = c->ranManagementOnLoad;
|
|
|
|
c->ranManagementOnLoad = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not ran) {
|
|
|
|
management_JNI_OnLoad(t->m, 0);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return;
|
2013-02-25 17:38:06 +00:00
|
|
|
} else if (strcmp(RUNTIME_ARRAY_BODY(n), "zip") == 0
|
2014-07-11 15:50:18 +00:00
|
|
|
or strcmp(RUNTIME_ARRAY_BODY(n), "nio") == 0) {
|
2010-12-09 04:38:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
|
|
|
|
loadLibrary(t,
|
|
|
|
static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
|
|
|
|
RUNTIME_ARRAY_BODY(n),
|
|
|
|
not absolute,
|
|
|
|
true);
|
2010-12-09 04:38:16 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void interceptFileOperations(Thread* t, bool updateRuntimeData)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
2014-07-15 14:07:57 +00:00
|
|
|
GcClass* fileClass
|
2014-07-11 15:47:57 +00:00
|
|
|
= resolveClass(t, roots(t)->bootLoader(), "java/io/File", false);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (fileClass) {
|
2014-07-15 14:07:57 +00:00
|
|
|
GcField* filePathField
|
2014-07-11 15:50:18 +00:00
|
|
|
= findFieldInClass2(t, fileClass, "path", "Ljava/lang/String;");
|
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (filePathField) {
|
2014-07-15 14:07:57 +00:00
|
|
|
cp->filePathField = filePathField->offset();
|
2011-04-10 23:01:38 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
2014-07-15 14:07:57 +00:00
|
|
|
GcClass* fileDescriptorClass = resolveClass(
|
2014-07-11 15:47:57 +00:00
|
|
|
t, roots(t)->bootLoader(), "java/io/FileDescriptor", false);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (fileDescriptorClass) {
|
2014-07-15 14:07:57 +00:00
|
|
|
GcField* fileDescriptorFdField
|
2014-07-11 15:50:18 +00:00
|
|
|
= findFieldInClass2(t, fileDescriptorClass, "fd", "I");
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (fileDescriptorFdField) {
|
2014-07-15 14:07:57 +00:00
|
|
|
cp->fileDescriptorFdField = fileDescriptorFdField->offset();
|
2011-04-10 23:01:38 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
2014-07-15 14:07:57 +00:00
|
|
|
GcClass* fileInputStreamClass = resolveClass(
|
2014-07-11 15:47:57 +00:00
|
|
|
t, roots(t)->bootLoader(), "java/io/FileInputStream", false);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (fileInputStreamClass) {
|
|
|
|
PROTECT(t, fileInputStreamClass);
|
2010-12-10 05:17:57 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcField* fileInputStreamFdField = findFieldInClass2(
|
2014-07-11 15:50:18 +00:00
|
|
|
t, fileInputStreamClass, "fd", "Ljava/io/FileDescriptor;");
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (fileInputStreamFdField) {
|
2014-07-15 14:07:57 +00:00
|
|
|
cp->fileInputStreamFdField = fileInputStreamFdField->offset();
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
fileInputStreamClass,
|
|
|
|
"open",
|
|
|
|
"(Ljava/lang/String;)V",
|
|
|
|
voidPointer(openFile),
|
|
|
|
updateRuntimeData);
|
|
|
|
|
|
|
|
if (findMethodOrNull(t, fileInputStreamClass, "read0", "()I") != 0) {
|
|
|
|
intercept(t,
|
|
|
|
fileInputStreamClass,
|
|
|
|
"read0",
|
|
|
|
"()I",
|
|
|
|
voidPointer(readByteFromFile),
|
|
|
|
updateRuntimeData);
|
2013-12-07 23:22:08 +00:00
|
|
|
} else {
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
fileInputStreamClass,
|
|
|
|
"read",
|
|
|
|
"()I",
|
|
|
|
voidPointer(readByteFromFile),
|
|
|
|
updateRuntimeData);
|
2013-12-07 23:22:08 +00:00
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
|
|
|
|
intercept(t,
|
|
|
|
fileInputStreamClass,
|
|
|
|
"readBytes",
|
|
|
|
"([BII)I",
|
|
|
|
voidPointer(readBytesFromFile),
|
|
|
|
updateRuntimeData);
|
|
|
|
|
|
|
|
intercept(t,
|
|
|
|
fileInputStreamClass,
|
|
|
|
"skip",
|
|
|
|
"(J)J",
|
|
|
|
voidPointer(skipBytesInFile),
|
|
|
|
updateRuntimeData);
|
|
|
|
|
|
|
|
intercept(t,
|
|
|
|
fileInputStreamClass,
|
|
|
|
"available",
|
|
|
|
"()I",
|
|
|
|
voidPointer(availableBytesInFile),
|
|
|
|
updateRuntimeData);
|
|
|
|
|
|
|
|
intercept(t,
|
|
|
|
fileInputStreamClass,
|
|
|
|
"close0",
|
|
|
|
"()V",
|
|
|
|
voidPointer(closeFile),
|
|
|
|
updateRuntimeData);
|
2011-04-10 23:01:38 +00:00
|
|
|
}
|
|
|
|
}
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
2014-07-15 14:07:57 +00:00
|
|
|
GcClass* zipFileClass = resolveClass(
|
2014-07-11 15:47:57 +00:00
|
|
|
t, roots(t)->bootLoader(), "java/util/zip/ZipFile", false);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (zipFileClass) {
|
|
|
|
PROTECT(t, zipFileClass);
|
2011-03-17 14:43:01 +00:00
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcField* zipFileJzfileField
|
2014-07-11 15:50:18 +00:00
|
|
|
= findFieldInClass2(t, zipFileClass, "jzfile", "J");
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (zipFileJzfileField) {
|
2014-07-15 14:07:57 +00:00
|
|
|
cp->zipFileJzfileField = zipFileJzfileField->offset();
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"open",
|
|
|
|
"(Ljava/lang/String;IJZ)J",
|
|
|
|
voidPointer(openZipFile),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getTotal",
|
|
|
|
"(J)I",
|
|
|
|
voidPointer(getZipFileEntryCount),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getEntry",
|
|
|
|
"(J[BZ)J",
|
|
|
|
voidPointer(getZipFileEntry),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getEntryBytes",
|
|
|
|
"(JI)[B",
|
|
|
|
voidPointer(getZipFileEntryBytes),
|
|
|
|
updateRuntimeData);
|
2012-02-18 22:17:10 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getNextEntry",
|
|
|
|
"(JI)J",
|
|
|
|
voidPointer(getNextZipFileEntry),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getEntryMethod",
|
|
|
|
"(J)I",
|
|
|
|
voidPointer(getZipFileEntryMethod),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"freeEntry",
|
|
|
|
"(JJ)V",
|
|
|
|
voidPointer(freeZipFileEntry),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"read",
|
|
|
|
"(JJJ[BII)I",
|
|
|
|
voidPointer(readZipFileEntry),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getEntryCSize",
|
|
|
|
"(J)J",
|
2013-03-15 19:28:01 +00:00
|
|
|
voidPointer(getZipFileEntryCompressedSize),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getEntrySize",
|
|
|
|
"(J)J",
|
2013-03-15 19:28:01 +00:00
|
|
|
voidPointer(getZipFileEntryUncompressedSize),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"getZipMessage",
|
|
|
|
"(J)Ljava/lang/String;",
|
|
|
|
voidPointer(getZipMessage),
|
|
|
|
updateRuntimeData);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
zipFileClass,
|
|
|
|
"close",
|
|
|
|
"(J)V",
|
|
|
|
voidPointer(closeZipFile),
|
|
|
|
updateRuntimeData);
|
2011-04-10 23:01:38 +00:00
|
|
|
}
|
|
|
|
}
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
2014-07-15 14:07:57 +00:00
|
|
|
GcClass* jarFileClass = resolveClass(
|
2014-07-11 15:47:57 +00:00
|
|
|
t, roots(t)->bootLoader(), "java/util/jar/JarFile", false);
|
2011-03-04 23:55:31 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (jarFileClass) {
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
jarFileClass,
|
|
|
|
"getMetaInfEntryNames",
|
2011-04-10 23:01:38 +00:00
|
|
|
"()[Ljava/lang/String;",
|
2014-07-11 15:50:18 +00:00
|
|
|
voidPointer(getJarFileMetaInfEntryNames),
|
|
|
|
updateRuntimeData);
|
2011-04-10 23:01:38 +00:00
|
|
|
}
|
2011-03-04 23:55:31 +00:00
|
|
|
}
|
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
const char* const fsClassName = "java/io/WinNTFileSystem";
|
|
|
|
const char* const gbaMethodName = "getBooleanAttributes";
|
|
|
|
#else
|
|
|
|
const char* const fsClassName = "java/io/UnixFileSystem";
|
|
|
|
const char* const gbaMethodName = "getBooleanAttributes0";
|
|
|
|
#endif
|
|
|
|
|
2014-07-15 14:07:57 +00:00
|
|
|
GcClass* fsClass
|
2014-07-11 15:47:57 +00:00
|
|
|
= resolveClass(t, roots(t)->bootLoader(), fsClassName, false);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2011-04-10 23:01:38 +00:00
|
|
|
if (fsClass) {
|
|
|
|
PROTECT(t, fsClass);
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
intercept(t,
|
|
|
|
fsClass,
|
|
|
|
gbaMethodName,
|
|
|
|
"(Ljava/io/File;)I",
|
|
|
|
voidPointer(getFileAttributes),
|
|
|
|
updateRuntimeData);
|
|
|
|
|
|
|
|
intercept(t,
|
|
|
|
fsClass,
|
|
|
|
"checkAccess",
|
|
|
|
"(Ljava/io/File;I)Z",
|
|
|
|
voidPointer(checkFileAccess),
|
|
|
|
updateRuntimeData);
|
|
|
|
|
|
|
|
intercept(t,
|
|
|
|
fsClass,
|
|
|
|
"getLength",
|
|
|
|
"(Ljava/io/File;)J",
|
|
|
|
voidPointer(getFileLength),
|
|
|
|
updateRuntimeData);
|
2011-04-10 23:01:38 +00:00
|
|
|
}
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
2010-12-06 00:40:50 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
intercept(t,
|
|
|
|
type(t, GcClassLoader::Type),
|
|
|
|
"loadLibrary",
|
2010-12-09 04:38:16 +00:00
|
|
|
"(Ljava/lang/Class;Ljava/lang/String;Z)V",
|
2014-07-11 15:47:57 +00:00
|
|
|
voidPointer(loadLibrary),
|
|
|
|
updateRuntimeData);
|
2010-12-09 04:38:16 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
intercept(t,
|
|
|
|
type(t, GcClassLoader::Type),
|
|
|
|
"getBootstrapResource",
|
2010-12-06 00:40:50 +00:00
|
|
|
"(Ljava/lang/String;)Ljava/net/URL;",
|
2014-07-11 15:47:57 +00:00
|
|
|
voidPointer(getBootstrapResource),
|
|
|
|
updateRuntimeData);
|
2010-12-06 00:40:50 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
intercept(t,
|
|
|
|
type(t, GcClassLoader::Type),
|
|
|
|
"getBootstrapResources",
|
2010-12-06 00:40:50 +00:00
|
|
|
"(Ljava/lang/String;)Ljava/util/Enumeration;",
|
2014-07-11 15:47:57 +00:00
|
|
|
voidPointer(getBootstrapResources),
|
|
|
|
updateRuntimeData);
|
2010-11-07 17:08:04 +00:00
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
#endif // AVIAN_OPENJDK_SRC
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
unsigned classDeclaredMethodCount(Thread* t, GcClass* c)
|
2011-04-10 03:20:56 +00:00
|
|
|
{
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClassAddendum* addendum = c->addendum();
|
2011-04-10 03:20:56 +00:00
|
|
|
if (addendum) {
|
2014-06-29 02:44:36 +00:00
|
|
|
int count = addendum->declaredMethodCount();
|
fix Class.getDeclaredMethods
getDeclaredMethods was returning methods which were inherited from
interfaces but not (re)declared in the class itself, due to the VM's
internal use of VMClass.methodTable differing from its role in
reflection. For reflection, we must only include the declared
methods, not the inherited but un-redeclared ones.
Previously, we saved the original method table in
ClassAddendum.methodTable before creating a new one which contains
both declared and inherited methods. That wasted space, so this patch
replaces ClassAddendum.methodTable with
ClassAddendum.declaredMethodCount, which specifies how many of the
methods in VMClass.methodTable were declared in that class.
Alternatively, we could ensure that undeclared methods always have
their VMMethod.class_ field set to the declaring class instead of the
inheriting class. I tried this, but it led to subtle crashes in
interface method lookup. The rest of the VM relies not only on
VMClass.methodTable containing all inherited interface methods but
also that those methods point to the inheriting class, not the
declaring class. Changing those assumptions would be a much bigger
(and more dangerous in terms of regression potential) effort than I
care to take on right now. The solution I chose is a bit ugly, but
it's safe.
2014-03-03 16:56:26 +00:00
|
|
|
if (count >= 0) {
|
|
|
|
return count;
|
2011-04-10 03:20:56 +00:00
|
|
|
}
|
|
|
|
}
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, c->methodTable());
|
|
|
|
return table == 0 ? 0 : table->length();
|
2011-04-10 03:20:56 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
unsigned countMethods(Thread* t, GcClass* c, bool publicOnly)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, c->methodTable());
|
2010-09-10 21:05:29 +00:00
|
|
|
unsigned count = 0;
|
fix Class.getDeclaredMethods
getDeclaredMethods was returning methods which were inherited from
interfaces but not (re)declared in the class itself, due to the VM's
internal use of VMClass.methodTable differing from its role in
reflection. For reflection, we must only include the declared
methods, not the inherited but un-redeclared ones.
Previously, we saved the original method table in
ClassAddendum.methodTable before creating a new one which contains
both declared and inherited methods. That wasted space, so this patch
replaces ClassAddendum.methodTable with
ClassAddendum.declaredMethodCount, which specifies how many of the
methods in VMClass.methodTable were declared in that class.
Alternatively, we could ensure that undeclared methods always have
their VMMethod.class_ field set to the declaring class instead of the
inheriting class. I tried this, but it led to subtle crashes in
interface method lookup. The rest of the VM relies not only on
VMClass.methodTable containing all inherited interface methods but
also that those methods point to the inheriting class, not the
declaring class. Changing those assumptions would be a much bigger
(and more dangerous in terms of regression potential) effort than I
care to take on right now. The solution I chose is a bit ugly, but
it's safe.
2014-03-03 16:56:26 +00:00
|
|
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, c); i < j; ++i) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcMethod* vmMethod = cast<GcMethod>(t, table->body()[i]);
|
2014-06-28 21:11:31 +00:00
|
|
|
if (((not publicOnly) or (vmMethod->flags() & ACC_PUBLIC))
|
2014-07-11 15:47:57 +00:00
|
|
|
and vmMethod->name()->body()[0] != '<') {
|
2014-07-11 15:50:18 +00:00
|
|
|
++count;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
unsigned countFields(Thread* t, GcClass* c, bool publicOnly)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, c->fieldTable());
|
2010-09-10 21:05:29 +00:00
|
|
|
if (publicOnly) {
|
|
|
|
unsigned count = 0;
|
2014-06-27 00:17:46 +00:00
|
|
|
for (unsigned i = 0; i < table->length(); ++i) {
|
|
|
|
GcField* vmField = cast<GcField>(t, table->body()[i]);
|
2014-06-27 00:17:16 +00:00
|
|
|
if (vmField->flags() & ACC_PUBLIC) {
|
2014-07-11 15:50:18 +00:00
|
|
|
++count;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
2010-09-14 16:49:41 +00:00
|
|
|
} else {
|
2014-07-02 21:11:27 +00:00
|
|
|
return objectArrayLength(t, table);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
unsigned countConstructors(Thread* t, GcClass* c, bool publicOnly)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, c->methodTable());
|
2010-09-10 21:05:29 +00:00
|
|
|
unsigned count = 0;
|
fix Class.getDeclaredMethods
getDeclaredMethods was returning methods which were inherited from
interfaces but not (re)declared in the class itself, due to the VM's
internal use of VMClass.methodTable differing from its role in
reflection. For reflection, we must only include the declared
methods, not the inherited but un-redeclared ones.
Previously, we saved the original method table in
ClassAddendum.methodTable before creating a new one which contains
both declared and inherited methods. That wasted space, so this patch
replaces ClassAddendum.methodTable with
ClassAddendum.declaredMethodCount, which specifies how many of the
methods in VMClass.methodTable were declared in that class.
Alternatively, we could ensure that undeclared methods always have
their VMMethod.class_ field set to the declaring class instead of the
inheriting class. I tried this, but it led to subtle crashes in
interface method lookup. The rest of the VM relies not only on
VMClass.methodTable containing all inherited interface methods but
also that those methods point to the inheriting class, not the
declaring class. Changing those assumptions would be a much bigger
(and more dangerous in terms of regression potential) effort than I
care to take on right now. The solution I chose is a bit ugly, but
it's safe.
2014-03-03 16:56:26 +00:00
|
|
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, c); i < j; ++i) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcMethod* vmMethod = cast<GcMethod>(t, table->body()[i]);
|
2014-06-28 21:11:31 +00:00
|
|
|
if (((not publicOnly) or (vmMethod->flags() & ACC_PUBLIC))
|
2014-07-11 15:47:57 +00:00
|
|
|
and strcmp(reinterpret_cast<char*>(vmMethod->name()->body().begin()),
|
|
|
|
"<init>") == 0) {
|
2014-07-11 15:50:18 +00:00
|
|
|
++count;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2014-04-23 21:22:10 +00:00
|
|
|
#ifdef HAVE_JexecutableHasRealParameterData
|
2014-07-11 15:50:18 +00:00
|
|
|
object makeJmethod(Thread* t,
|
|
|
|
uint8_t override,
|
|
|
|
object securityCheckCache,
|
|
|
|
object clazz,
|
|
|
|
uint32_t slot,
|
|
|
|
object name,
|
|
|
|
object returnType,
|
|
|
|
object parameterTypes,
|
|
|
|
object exceptionTypes,
|
|
|
|
uint32_t modifiers,
|
|
|
|
object signature,
|
|
|
|
object genericInfo,
|
|
|
|
object annotations,
|
|
|
|
object parameterAnnotations,
|
|
|
|
object annotationDefault,
|
|
|
|
object methodAccessor,
|
|
|
|
object root,
|
|
|
|
object declaredAnnotations)
|
|
|
|
{
|
|
|
|
return makeJmethod(t,
|
|
|
|
override,
|
|
|
|
securityCheckCache,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
declaredAnnotations,
|
|
|
|
clazz,
|
|
|
|
slot,
|
|
|
|
name,
|
|
|
|
returnType,
|
|
|
|
parameterTypes,
|
|
|
|
exceptionTypes,
|
|
|
|
modifiers,
|
|
|
|
signature,
|
|
|
|
genericInfo,
|
|
|
|
annotations,
|
|
|
|
parameterAnnotations,
|
|
|
|
annotationDefault,
|
|
|
|
methodAccessor,
|
|
|
|
root);
|
|
|
|
}
|
|
|
|
|
|
|
|
object makeJconstructor(Thread* t,
|
|
|
|
uint8_t override,
|
|
|
|
object securityCheckCache,
|
|
|
|
object clazz,
|
|
|
|
uint32_t slot,
|
|
|
|
object parameterTypes,
|
|
|
|
object exceptionTypes,
|
|
|
|
uint32_t modifiers,
|
|
|
|
object signature,
|
|
|
|
object genericInfo,
|
|
|
|
object annotations,
|
|
|
|
object parameterAnnotations,
|
|
|
|
object constructorAccessor,
|
|
|
|
object root,
|
|
|
|
object declaredAnnotations)
|
|
|
|
{
|
|
|
|
return makeJconstructor(t,
|
|
|
|
override,
|
|
|
|
securityCheckCache,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
declaredAnnotations,
|
|
|
|
clazz,
|
|
|
|
slot,
|
|
|
|
parameterTypes,
|
|
|
|
exceptionTypes,
|
|
|
|
modifiers,
|
|
|
|
signature,
|
|
|
|
genericInfo,
|
|
|
|
annotations,
|
|
|
|
parameterAnnotations,
|
|
|
|
constructorAccessor,
|
|
|
|
root);
|
|
|
|
}
|
|
|
|
#endif // HAVE_JexecutableHasRealParameterData
|
2014-04-23 21:22:10 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object makeJmethod(Thread* t, GcMethod* vmMethod, int index)
|
2012-12-19 19:39:33 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, vmMethod);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object name
|
|
|
|
= intern(t,
|
|
|
|
t->m->classpath->makeString(
|
|
|
|
t, vmMethod->name(), 0, vmMethod->name()->length() - 1));
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, name);
|
|
|
|
|
|
|
|
unsigned parameterCount;
|
|
|
|
unsigned returnTypeSpec;
|
2014-07-11 15:47:57 +00:00
|
|
|
object parameterTypes = resolveParameterJTypes(t,
|
|
|
|
vmMethod->class_()->loader(),
|
|
|
|
vmMethod->spec(),
|
|
|
|
¶meterCount,
|
|
|
|
&returnTypeSpec);
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, parameterTypes);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcJclass* returnType = resolveJType(
|
|
|
|
t,
|
|
|
|
vmMethod->class_()->loader(),
|
|
|
|
reinterpret_cast<char*>(&vmMethod->spec()->body()[returnTypeSpec]),
|
|
|
|
vmMethod->spec()->length() - 1 - returnTypeSpec);
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, returnType);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object exceptionTypes = resolveExceptionJTypes(
|
|
|
|
t, vmMethod->class_()->loader(), vmMethod->addendum());
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, exceptionTypes);
|
|
|
|
|
|
|
|
object signature;
|
|
|
|
object annotationTable;
|
2013-05-01 04:55:59 +00:00
|
|
|
object parameterAnnotationTable;
|
2012-12-19 19:39:33 +00:00
|
|
|
object annotationDefault;
|
2014-06-27 00:17:46 +00:00
|
|
|
GcMethodAddendum* addendum = vmMethod->addendum();
|
2012-12-19 19:39:33 +00:00
|
|
|
if (addendum) {
|
2014-06-27 00:17:46 +00:00
|
|
|
signature = addendum->signature();
|
2012-12-19 19:39:33 +00:00
|
|
|
if (signature) {
|
2013-02-03 22:19:35 +00:00
|
|
|
PROTECT(t, addendum);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
signature = t->m->classpath->makeString(
|
|
|
|
t, signature, 0, cast<GcByteArray>(t, signature)->length() - 1);
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
annotationTable = addendum->annotationTable();
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
parameterAnnotationTable = addendum->parameterAnnotationTable();
|
2013-05-01 04:55:59 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
annotationDefault = addendum->annotationDefault();
|
2012-12-19 19:39:33 +00:00
|
|
|
} else {
|
|
|
|
signature = 0;
|
|
|
|
annotationTable = 0;
|
2013-05-01 04:55:59 +00:00
|
|
|
parameterAnnotationTable = 0;
|
2012-12-19 19:39:33 +00:00
|
|
|
annotationDefault = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
PROTECT(t, signature);
|
|
|
|
PROTECT(t, annotationTable);
|
2013-05-01 04:55:59 +00:00
|
|
|
PROTECT(t, parameterAnnotationTable);
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, annotationDefault);
|
|
|
|
|
2013-05-01 04:55:59 +00:00
|
|
|
if (annotationTable or parameterAnnotationTable or annotationDefault) {
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClassRuntimeData* runtimeData
|
|
|
|
= getClassRuntimeData(t, vmMethod->class_());
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
runtimeData->setPool(t, vmMethod->addendum()->pool());
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (index == -1) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, vmMethod->class_()->methodTable());
|
|
|
|
for (unsigned i = 0; i < table->length(); ++i) {
|
2014-07-02 21:11:27 +00:00
|
|
|
if (vmMethod == table->body()[i]) {
|
2012-12-19 19:39:33 +00:00
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(t, index != -1);
|
|
|
|
|
2014-06-28 21:11:31 +00:00
|
|
|
GcJclass* jclass = getJClass(t, vmMethod->class_());
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return makeJmethod(t,
|
|
|
|
true,
|
|
|
|
0,
|
|
|
|
jclass,
|
|
|
|
index,
|
|
|
|
cast<GcString>(t, name),
|
|
|
|
returnType,
|
|
|
|
parameterTypes,
|
|
|
|
exceptionTypes,
|
|
|
|
vmMethod->flags(),
|
|
|
|
cast<GcString>(t, signature),
|
|
|
|
0,
|
|
|
|
cast<GcByteArray>(t, annotationTable),
|
|
|
|
cast<GcByteArray>(t, parameterAnnotationTable),
|
|
|
|
cast<GcByteArray>(t, annotationDefault),
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
object makeJconstructor(Thread* t, GcMethod* vmMethod, int index)
|
2012-12-19 19:39:33 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, vmMethod);
|
|
|
|
|
|
|
|
unsigned parameterCount;
|
|
|
|
unsigned returnTypeSpec;
|
2014-07-11 15:47:57 +00:00
|
|
|
object parameterTypes = resolveParameterJTypes(t,
|
|
|
|
vmMethod->class_()->loader(),
|
|
|
|
vmMethod->spec(),
|
|
|
|
¶meterCount,
|
|
|
|
&returnTypeSpec);
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, parameterTypes);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object exceptionTypes = resolveExceptionJTypes(
|
|
|
|
t, vmMethod->class_()->loader(), vmMethod->addendum());
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, exceptionTypes);
|
|
|
|
|
|
|
|
object signature;
|
|
|
|
object annotationTable;
|
2013-05-01 04:55:59 +00:00
|
|
|
object parameterAnnotationTable;
|
2014-06-27 00:17:46 +00:00
|
|
|
GcMethodAddendum* addendum = vmMethod->addendum();
|
2012-12-19 19:39:33 +00:00
|
|
|
if (addendum) {
|
2014-06-27 00:17:46 +00:00
|
|
|
signature = addendum->signature();
|
2012-12-19 19:39:33 +00:00
|
|
|
if (signature) {
|
2013-02-03 22:19:35 +00:00
|
|
|
PROTECT(t, addendum);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
signature = t->m->classpath->makeString(
|
|
|
|
t, signature, 0, cast<GcByteArray>(t, signature)->length() - 1);
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
annotationTable = addendum->annotationTable();
|
|
|
|
parameterAnnotationTable = addendum->parameterAnnotationTable();
|
2012-12-19 19:39:33 +00:00
|
|
|
} else {
|
|
|
|
signature = 0;
|
|
|
|
annotationTable = 0;
|
2013-05-01 04:55:59 +00:00
|
|
|
parameterAnnotationTable = 0;
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PROTECT(t, signature);
|
|
|
|
PROTECT(t, annotationTable);
|
2013-05-01 04:55:59 +00:00
|
|
|
PROTECT(t, parameterAnnotationTable);
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2013-05-01 04:55:59 +00:00
|
|
|
if (annotationTable or parameterAnnotationTable) {
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClassRuntimeData* runtimeData
|
|
|
|
= getClassRuntimeData(t, vmMethod->class_());
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
runtimeData->setPool(t, vmMethod->addendum()->pool());
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (index == -1) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, vmMethod->class_()->methodTable());
|
|
|
|
for (unsigned i = 0; i < table->length(); ++i) {
|
2014-07-02 21:11:27 +00:00
|
|
|
if (vmMethod == table->body()[i]) {
|
2012-12-19 19:39:33 +00:00
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(t, index != -1);
|
|
|
|
|
2014-06-28 21:11:31 +00:00
|
|
|
GcJclass* jclass = getJClass(t, vmMethod->class_());
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return makeJconstructor(t,
|
|
|
|
true,
|
|
|
|
0,
|
|
|
|
jclass,
|
|
|
|
index,
|
|
|
|
parameterTypes,
|
|
|
|
exceptionTypes,
|
|
|
|
vmMethod->flags(),
|
|
|
|
cast<GcString>(t, signature),
|
|
|
|
0,
|
|
|
|
cast<GcByteArray>(t, annotationTable),
|
|
|
|
cast<GcByteArray>(t, parameterAnnotationTable),
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
object makeJfield(Thread* t, GcField* vmField, int index)
|
2012-12-19 19:39:33 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, vmField);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object name
|
|
|
|
= intern(t,
|
|
|
|
t->m->classpath->makeString(
|
|
|
|
t, vmField->name(), 0, vmField->name()->length() - 1));
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, name);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* type = resolveClassBySpec(
|
|
|
|
t,
|
|
|
|
vmField->class_()->loader(),
|
|
|
|
reinterpret_cast<char*>(vmField->spec()->body().begin()),
|
|
|
|
vmField->spec()->length() - 1);
|
2012-12-19 19:39:33 +00:00
|
|
|
PROTECT(t, type);
|
|
|
|
|
2014-06-21 04:16:33 +00:00
|
|
|
GcJclass* jtype = getJClass(t, type);
|
2012-12-19 19:39:33 +00:00
|
|
|
|
|
|
|
object signature;
|
|
|
|
object annotationTable;
|
2014-06-27 00:17:16 +00:00
|
|
|
GcFieldAddendum* addendum = vmField->addendum();
|
2012-12-19 19:39:33 +00:00
|
|
|
if (addendum) {
|
2014-06-27 00:17:16 +00:00
|
|
|
signature = addendum->signature();
|
2012-12-19 19:39:33 +00:00
|
|
|
if (signature) {
|
2013-02-03 22:19:35 +00:00
|
|
|
PROTECT(t, addendum);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
signature = t->m->classpath->makeString(
|
|
|
|
t, signature, 0, cast<GcByteArray>(t, signature)->length() - 1);
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
2014-06-27 00:17:16 +00:00
|
|
|
annotationTable = addendum->annotationTable();
|
2012-12-19 19:39:33 +00:00
|
|
|
} else {
|
|
|
|
signature = 0;
|
|
|
|
annotationTable = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
PROTECT(t, signature);
|
|
|
|
PROTECT(t, annotationTable);
|
|
|
|
|
|
|
|
if (annotationTable) {
|
2014-06-27 00:17:16 +00:00
|
|
|
GcClassRuntimeData* runtimeData = getClassRuntimeData(t, vmField->class_());
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
runtimeData->setPool(t, vmField->addendum()->pool());
|
2012-12-19 19:39:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (index == -1) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, vmField->class_()->fieldTable());
|
|
|
|
for (unsigned i = 0; i < table->length(); ++i) {
|
2014-07-02 21:11:27 +00:00
|
|
|
if (vmField == table->body()[i]) {
|
2012-12-19 19:39:33 +00:00
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(t, index != -1);
|
|
|
|
|
2014-06-27 00:17:16 +00:00
|
|
|
GcJclass* jclass = getJClass(t, vmField->class_());
|
2012-12-19 19:39:33 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return makeJfield(t,
|
|
|
|
true,
|
|
|
|
0,
|
|
|
|
jclass,
|
|
|
|
index,
|
|
|
|
cast<GcString>(t, name),
|
|
|
|
jtype,
|
|
|
|
vmField->flags(),
|
|
|
|
cast<GcString>(t, signature),
|
|
|
|
0,
|
|
|
|
cast<GcByteArray>(t, annotationTable),
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setProperty(Thread* t,
|
|
|
|
GcMethod* method,
|
|
|
|
object properties,
|
|
|
|
const char* name,
|
|
|
|
const void* value,
|
|
|
|
const char* format = "%s")
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
PROTECT(t, method);
|
|
|
|
PROTECT(t, properties);
|
2014-07-11 15:47:57 +00:00
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcString* n = makeString(t, "%s", name);
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, n);
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcString* v = makeString(t, format, value);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
t->m->processor->invoke(t, method, properties, n, v);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
bool pipeAvailable(int fd, int* available)
|
2010-11-07 04:21:19 +00:00
|
|
|
{
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
|
|
|
|
if (h == INVALID_HANDLE_VALUE) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD n;
|
2014-07-11 15:50:18 +00:00
|
|
|
if (PeekNamedPipe(h, 0, 0, 0, &n, 0)) {
|
2010-11-07 04:21:19 +00:00
|
|
|
*available = n;
|
|
|
|
} else {
|
|
|
|
if (GetLastError() != ERROR_BROKEN_PIPE) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
*available = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return ioctl(fd, FIONREAD, available) >= 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
} // namespace local
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
} // namespace
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
namespace vm {
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
Classpath* makeClasspath(System* s,
|
|
|
|
Allocator* allocator,
|
|
|
|
const char* javaHome,
|
|
|
|
const char* embedPrefix)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return new (allocator->allocate(sizeof(local::MyClasspath)))
|
2014-07-11 15:50:18 +00:00
|
|
|
local::MyClasspath(s, allocator, javaHome, embedPrefix);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
} // namespace vm
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_java_lang_Class_getSuperclass(Thread* t, object, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* class_
|
|
|
|
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass();
|
2014-06-29 02:44:36 +00:00
|
|
|
if (class_->flags() & ACC_INTERFACE) {
|
2012-09-28 21:03:14 +00:00
|
|
|
return 0;
|
|
|
|
} else {
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClass* super = class_->super();
|
|
|
|
return super ? reinterpret_cast<int64_t>(getJClass(t, super)) : 0;
|
2012-09-28 21:03:14 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void Avian_sun_misc_Unsafe_registerNatives(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t*)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void Avian_sun_misc_Perf_registerNatives(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t*)
|
2012-03-11 22:26:46 +00:00
|
|
|
{
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Perf_createLong(Thread* t, object, uintptr_t*)
|
2012-03-11 22:26:46 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<int64_t>(
|
|
|
|
t->m->processor->invoke(t,
|
|
|
|
resolveMethod(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"java/nio/ByteBuffer",
|
|
|
|
"allocate",
|
|
|
|
"(I)Ljava/nio/ByteBuffer;"),
|
|
|
|
0,
|
|
|
|
8));
|
2012-03-11 22:26:46 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_addressSize(Thread*, object, uintptr_t*)
|
2011-04-10 03:19:49 +00:00
|
|
|
{
|
|
|
|
return BytesPerWord;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(
|
|
|
|
Thread* t,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
// object name = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:47:57 +00:00
|
|
|
GcByteArray* data
|
|
|
|
= cast<GcByteArray>(t, reinterpret_cast<object>(arguments[2]));
|
2010-09-14 16:49:41 +00:00
|
|
|
int32_t offset = arguments[3];
|
|
|
|
int32_t length = arguments[4];
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClassLoader* loader
|
|
|
|
= cast<GcClassLoader>(t, reinterpret_cast<object>(arguments[5]));
|
2014-07-11 15:50:18 +00:00
|
|
|
// object domain = reinterpret_cast<object>(arguments[6]);
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
uint8_t* buffer = static_cast<uint8_t*>(t->m->heap->allocate(length));
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
THREAD_RESOURCE2(
|
|
|
|
t, uint8_t*, buffer, int, length, t->m->heap->free(buffer, length));
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
memcpy(buffer, &data->body()[offset], length);
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<int64_t>(
|
|
|
|
getJClass(t, cast<GcClass>(t, defineClass(t, loader, buffer, length))));
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_allocateInstance(Thread* t,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* c
|
|
|
|
= cast<GcJclass>(t, reinterpret_cast<object>(arguments[1]))->vmClass();
|
2010-09-14 16:49:41 +00:00
|
|
|
PROTECT(t, c);
|
|
|
|
|
|
|
|
initClass(t, c);
|
|
|
|
|
|
|
|
return reinterpret_cast<int64_t>(make(t, c));
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_staticFieldOffset(Thread* t,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
GcJfield* jfield = cast<GcJfield>(t, reinterpret_cast<object>(arguments[1]));
|
2014-07-11 15:47:57 +00:00
|
|
|
return cast<GcField>(
|
|
|
|
t,
|
|
|
|
cast<GcArray>(t, jfield->clazz()->vmClass()->fieldTable())
|
|
|
|
->body()[jfield->slot()])->offset();
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_staticFieldBase(Thread* t,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<int64_t>(
|
|
|
|
cast<GcJfield>(t, reinterpret_cast<object>(arguments[1]))
|
|
|
|
->clazz()
|
|
|
|
->vmClass()
|
|
|
|
->staticTable());
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_objectFieldOffset(Thread* t,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
GcJfield* jfield = cast<GcJfield>(t, reinterpret_cast<object>(arguments[1]));
|
2014-07-11 15:47:57 +00:00
|
|
|
return cast<GcField>(
|
|
|
|
t,
|
|
|
|
cast<GcArray>(t, jfield->clazz()->vmClass()->fieldTable())
|
|
|
|
->body()[jfield->slot()])->offset();
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getShort__Ljava_lang_Object_2J(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2011-03-27 20:12:41 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2011-03-27 20:12:41 +00:00
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
return fieldAtOffset<int16_t>(o, offset);
|
2011-03-27 20:12:41 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getChar__Ljava_lang_Object_2J(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2013-05-01 04:54:45 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2013-05-01 04:54:45 +00:00
|
|
|
|
|
|
|
return fieldAtOffset<uint16_t>(o, offset);
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getInt__Ljava_lang_Object_2J(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
return fieldAtOffset<int32_t>(o, offset);
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getFloat__Ljava_lang_Object_2J(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2011-03-18 03:42:15 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2011-03-18 03:42:15 +00:00
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
return fieldAtOffset<int32_t>(o, offset);
|
2011-03-18 03:42:15 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2011-03-02 15:35:45 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2011-03-02 15:35:45 +00:00
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
return fieldAtOffset<int64_t>(o, offset);
|
2011-03-02 15:35:45 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getDouble__Ljava_lang_Object_2J(Thread* t,
|
2014-07-15 14:07:57 +00:00
|
|
|
GcMethod* method,
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t* arguments)
|
2012-08-11 12:56:19 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
return Avian_sun_misc_Unsafe_getLong__Ljava_lang_Object_2J(
|
|
|
|
t, method, arguments);
|
2012-08-11 12:56:19 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_putByte__Ljava_lang_Object_2JB(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2011-03-28 14:55:20 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2011-03-28 14:55:20 +00:00
|
|
|
int8_t value = arguments[4];
|
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
fieldAtOffset<int8_t>(o, offset) = value;
|
2011-03-28 14:55:20 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_putShort__Ljava_lang_Object_2JS(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2011-04-10 03:20:21 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2011-04-10 03:20:21 +00:00
|
|
|
int16_t value = arguments[4];
|
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
fieldAtOffset<int16_t>(o, offset) = value;
|
2011-04-10 03:20:21 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_putChar__Ljava_lang_Object_2JC(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2013-05-01 04:54:45 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2013-05-01 04:54:45 +00:00
|
|
|
uint16_t value = arguments[4];
|
|
|
|
|
|
|
|
fieldAtOffset<uint16_t>(o, offset) = value;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_putInt__Ljava_lang_Object_2JI(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2010-09-14 16:49:41 +00:00
|
|
|
int32_t value = arguments[4];
|
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
fieldAtOffset<int32_t>(o, offset) = value;
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_putFloat__Ljava_lang_Object_2JF(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2011-03-18 03:42:15 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2011-03-18 03:42:15 +00:00
|
|
|
int32_t value = arguments[4];
|
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
fieldAtOffset<int32_t>(o, offset) = value;
|
2011-03-18 03:42:15 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
return fieldAtOffset<int8_t>(o, offset);
|
2012-03-14 18:35:22 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_getBoolean__Ljava_lang_Object_2J(Thread* t,
|
|
|
|
object method,
|
|
|
|
uintptr_t* arguments)
|
2012-03-14 18:35:22 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
return Avian_sun_misc_Unsafe_getByte__Ljava_lang_Object_2J(
|
|
|
|
t, method, arguments);
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_putBoolean__Ljava_lang_Object_2JZ(
|
|
|
|
Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
2010-09-14 16:49:41 +00:00
|
|
|
uint8_t value = arguments[4];
|
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
fieldAtOffset<uint8_t>(o, offset) = value;
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_putLong__Ljava_lang_Object_2JJ(Thread*,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
object o = reinterpret_cast<object>(arguments[1]);
|
2014-07-11 15:50:18 +00:00
|
|
|
int64_t offset;
|
|
|
|
memcpy(&offset, arguments + 2, 8);
|
|
|
|
int64_t value;
|
|
|
|
memcpy(&value, arguments + 4, 8);
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
fieldAtOffset<int64_t>(o, offset) = value;
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_pageSize(Thread*, object, uintptr_t*)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
return local::PageSize;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_ensureClassInitialized(Thread* t,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
initClass(
|
|
|
|
t, cast<GcJclass>(t, reinterpret_cast<object>(arguments[1]))->vmClass());
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_monitorEnter(Thread* t, object, uintptr_t* arguments)
|
2012-03-11 11:05:14 +00:00
|
|
|
{
|
|
|
|
acquire(t, reinterpret_cast<object>(arguments[1]));
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_sun_misc_Unsafe_monitorExit(Thread* t, object, uintptr_t* arguments)
|
2012-03-11 11:05:14 +00:00
|
|
|
{
|
|
|
|
release(t, reinterpret_cast<object>(arguments[1]));
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
namespace local {
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_GetInterfaceVersion)()
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return local::InterfaceVersion;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_IHashCode)(Thread* t, jobject o)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2011-02-25 15:17:15 +00:00
|
|
|
return o ? objectHash(t, *o) : 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmWait(Thread* t, uintptr_t* arguments)
|
2011-02-15 01:55:11 +00:00
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jobject>(arguments[0]);
|
2014-07-11 15:50:18 +00:00
|
|
|
jlong milliseconds;
|
|
|
|
memcpy(&milliseconds, arguments + 1, sizeof(jlong));
|
2011-02-15 01:55:11 +00:00
|
|
|
|
|
|
|
vm::wait(t, *o, milliseconds);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_MonitorWait)(Thread* t, jobject o, jlong milliseconds)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2011-02-15 01:55:11 +00:00
|
|
|
uintptr_t arguments[1 + (sizeof(jlong) / BytesPerWord)];
|
|
|
|
arguments[0] = reinterpret_cast<uintptr_t>(o);
|
|
|
|
memcpy(arguments + 1, &milliseconds, sizeof(jlong));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2011-02-15 01:55:11 +00:00
|
|
|
run(t, jvmWait, arguments);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmNotify(Thread* t, uintptr_t* arguments)
|
2011-02-15 01:55:11 +00:00
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
|
|
|
|
notify(t, *o);
|
|
|
|
|
|
|
|
return 1;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_MonitorNotify)(Thread* t, jobject o)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(o)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2011-02-15 01:55:11 +00:00
|
|
|
run(t, jvmNotify, arguments);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmNotifyAll(Thread* t, uintptr_t* arguments)
|
2011-02-15 01:55:11 +00:00
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
|
|
|
|
notifyAll(t, *o);
|
|
|
|
|
|
|
|
return 1;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_MonitorNotifyAll)(Thread* t, jobject o)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(o)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2011-02-15 01:55:11 +00:00
|
|
|
run(t, jvmNotifyAll, arguments);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmClone(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, clone(t, *o)));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL EXPORT(JVM_Clone)(Thread* t, jobject o)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(o)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jobject>(run(t, jvmClone, arguments));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmInternString(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject o = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, intern(t, *o)));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jstring JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_InternString)(Thread* t, jstring s)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(s)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
return reinterpret_cast<jstring>(run(t, jvmInternString, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_CurrentTimeMillis)(Thread* t, jclass)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return t->m->system->now();
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL EXPORT(JVM_NanoTime)(Thread* t, jclass)
|
2010-09-10 23:47:23 +00:00
|
|
|
{
|
|
|
|
return t->m->system->now() * 1000 * 1000;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmArrayCopy(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject src = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jint srcOffset = arguments[1];
|
|
|
|
jobject dst = reinterpret_cast<jobject>(arguments[2]);
|
|
|
|
jint dstOffset = arguments[3];
|
|
|
|
jint length = arguments[4];
|
|
|
|
|
|
|
|
arrayCopy(t, *src, srcOffset, *dst, dstOffset, length);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_ArrayCopy)(Thread* t,
|
|
|
|
jclass,
|
|
|
|
jobject src,
|
|
|
|
jint srcOffset,
|
|
|
|
jobject dst,
|
|
|
|
jint dstOffset,
|
|
|
|
jint length)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(src),
|
|
|
|
static_cast<uintptr_t>(srcOffset),
|
|
|
|
reinterpret_cast<uintptr_t>(dst),
|
|
|
|
static_cast<uintptr_t>(dstOffset),
|
|
|
|
static_cast<uintptr_t>(length)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
run(t, jvmArrayCopy, arguments);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmInitProperties(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jobject properties = reinterpret_cast<jobject>(arguments[0]);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* method = resolveMethod(
|
|
|
|
t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"java/util/Properties",
|
|
|
|
"setProperty",
|
|
|
|
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
PROTECT(t, method);
|
|
|
|
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
local::setProperty(t, method, *properties, "line.separator", "\r\n");
|
|
|
|
local::setProperty(t, method, *properties, "file.separator", "\\");
|
|
|
|
local::setProperty(t, method, *properties, "path.separator", ";");
|
|
|
|
local::setProperty(t, method, *properties, "os.name", "Windows");
|
|
|
|
|
|
|
|
TCHAR buffer[MAX_PATH];
|
|
|
|
GetTempPath(MAX_PATH, buffer);
|
|
|
|
|
|
|
|
local::setProperty(t, method, *properties, "java.io.tmpdir", buffer);
|
|
|
|
local::setProperty(t, method, *properties, "java.home", buffer);
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(
|
|
|
|
t, method, *properties, "user.home", _wgetenv(L"USERPROFILE"), "%ls");
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
GetCurrentDirectory(MAX_PATH, buffer);
|
|
|
|
|
|
|
|
local::setProperty(t, method, *properties, "user.dir", buffer);
|
2014-07-11 15:50:18 +00:00
|
|
|
#else // not PLATFORM_WINDOWS
|
2010-09-10 21:05:29 +00:00
|
|
|
local::setProperty(t, method, *properties, "line.separator", "\n");
|
|
|
|
local::setProperty(t, method, *properties, "file.separator", "/");
|
|
|
|
local::setProperty(t, method, *properties, "path.separator", ":");
|
2014-07-11 15:50:18 +00:00
|
|
|
#ifdef __APPLE__
|
2010-09-10 21:05:29 +00:00
|
|
|
local::setProperty(t, method, *properties, "os.name", "Mac OS X");
|
2014-07-11 15:50:18 +00:00
|
|
|
#elif defined __FreeBSD__
|
2012-08-02 16:36:16 +00:00
|
|
|
local::setProperty(t, method, *properties, "os.name", "FreeBSD");
|
2014-07-11 15:50:18 +00:00
|
|
|
#else // not __APPLE__
|
2010-09-10 21:05:29 +00:00
|
|
|
local::setProperty(t, method, *properties, "os.name", "Linux");
|
2014-07-11 15:50:18 +00:00
|
|
|
#endif // not __APPLE__
|
2010-09-10 21:05:29 +00:00
|
|
|
local::setProperty(t, method, *properties, "java.io.tmpdir", "/tmp");
|
|
|
|
local::setProperty(t, method, *properties, "user.home", getenv("HOME"));
|
2011-03-15 19:27:36 +00:00
|
|
|
|
|
|
|
char buffer[PATH_MAX];
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(
|
|
|
|
t, method, *properties, "user.dir", getcwd(buffer, PATH_MAX));
|
|
|
|
#endif // not PLATFORM_WINDOWS
|
2010-12-01 03:25:48 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(
|
|
|
|
t, method, *properties, "java.protocol.handler.pkgs", "avian");
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(
|
|
|
|
t, method, *properties, "java.vm.vendor", "Avian Contributors");
|
2011-03-27 05:24:05 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(t, method, *properties, "java.vm.name", "Avian");
|
2012-09-05 12:31:30 +00:00
|
|
|
#ifdef AVIAN_VERSION
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(t, method, *properties, "java.vm.version", AVIAN_VERSION);
|
2012-09-05 12:31:30 +00:00
|
|
|
#endif
|
|
|
|
#ifdef AVIAN_INFO
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(t, method, *properties, "java.vm.info", AVIAN_INFO);
|
2012-09-05 12:31:30 +00:00
|
|
|
#endif
|
2012-08-11 12:56:19 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(t,
|
|
|
|
method,
|
|
|
|
*properties,
|
|
|
|
"java.vm.specification.name",
|
|
|
|
"Java Virtual Machine Specification");
|
2014-06-05 13:29:58 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(
|
|
|
|
t,
|
|
|
|
method,
|
|
|
|
*properties,
|
|
|
|
"java.home",
|
|
|
|
static_cast<local::MyClasspath*>(t->m->classpath)->javaHome);
|
2010-09-20 23:31:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(
|
|
|
|
t,
|
|
|
|
method,
|
|
|
|
*properties,
|
|
|
|
"sun.boot.library.path",
|
|
|
|
static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath);
|
2010-09-20 23:31:23 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
local::setProperty(
|
|
|
|
t,
|
|
|
|
method,
|
|
|
|
*properties,
|
|
|
|
"sun.boot.class.path",
|
|
|
|
static_cast<Finder*>(
|
|
|
|
roots(t)->bootLoader()->as<GcSystemClassLoader>(t)->finder())
|
|
|
|
->path());
|
2012-02-29 18:46:50 +00:00
|
|
|
|
2013-04-17 01:25:19 +00:00
|
|
|
local::setProperty(t, method, *properties, "file.encoding", "UTF-8");
|
2014-07-22 23:06:55 +00:00
|
|
|
|
|
|
|
local::setProperty(t, method, *properties, "jdk.lang.Process.launchMechanism", "fork");
|
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
#ifdef ARCH_x86_32
|
|
|
|
local::setProperty(t, method, *properties, "os.arch", "x86");
|
|
|
|
#elif defined ARCH_x86_64
|
|
|
|
local::setProperty(t, method, *properties, "os.arch", "x86_64");
|
|
|
|
#elif defined ARCH_arm
|
|
|
|
local::setProperty(t, method, *properties, "os.arch", "arm");
|
|
|
|
#else
|
|
|
|
local::setProperty(t, method, *properties, "os.arch", "unknown");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < t->m->propertyCount; ++i) {
|
|
|
|
const char* start = t->m->properties[i];
|
|
|
|
const char* p = start;
|
2014-07-11 15:50:18 +00:00
|
|
|
while (*p and *p != '=')
|
|
|
|
++p;
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
if (*p == '=') {
|
2010-12-27 22:55:23 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, name, (p - start) + 1);
|
2013-02-22 21:20:09 +00:00
|
|
|
memcpy(RUNTIME_ARRAY_BODY(name), start, p - start);
|
|
|
|
RUNTIME_ARRAY_BODY(name)[p - start] = 0;
|
2014-07-11 15:50:18 +00:00
|
|
|
local::setProperty(
|
|
|
|
t, method, *properties, RUNTIME_ARRAY_BODY(name), p + 1);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
}
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>(properties);
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_InitProperties)(Thread* t, jobject properties)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(properties)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jobject>(run(t, jvmInitProperties, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_OnExit)(void (*)(void))
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_Exit)(jint code)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
exit(code);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_Halt)(jint code)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
exit(code);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGC(Thread* t, uintptr_t*)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
collect(t, Heap::MajorCollection);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_GC)()
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
Thread* t = static_cast<Thread*>(local::globalMachine->localThread->get());
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
run(t, jvmGC, 0);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL EXPORT(JVM_MaxObjectInspectionAge)(void)
|
2011-03-27 20:12:41 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_TraceInstructions)(jboolean)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_TraceMethodCalls)(jboolean)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL EXPORT(JVM_TotalMemory)()
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL EXPORT(JVM_FreeMemory)()
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL EXPORT(JVM_MaxMemory)()
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
2012-08-30 00:32:45 +00:00
|
|
|
return local::globalMachine->heap->limit();
|
2010-09-15 00:52:57 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_ActiveProcessorCount)()
|
2010-11-27 18:25:02 +00:00
|
|
|
{
|
2011-03-26 17:15:52 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
SYSTEM_INFO si;
|
|
|
|
GetSystemInfo(&si);
|
|
|
|
return si.dwNumberOfProcessors;
|
|
|
|
#else
|
|
|
|
return sysconf(_SC_NPROCESSORS_ONLN);
|
|
|
|
#endif
|
2010-11-27 18:25:02 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmLoadLibrary(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
const char* path = reinterpret_cast<const char*>(arguments[0]);
|
|
|
|
|
|
|
|
THREAD_RUNTIME_ARRAY(t, char, p, strlen(path) + 1);
|
|
|
|
replace('\\', '/', RUNTIME_ARRAY_BODY(p), path);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<uint64_t>(loadLibrary(
|
|
|
|
t,
|
|
|
|
static_cast<local::MyClasspath*>(t->m->classpath)->libraryPath,
|
|
|
|
RUNTIME_ARRAY_BODY(p),
|
|
|
|
false,
|
|
|
|
false));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void* JNICALL EXPORT(JVM_LoadLibrary)(const char* path)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
Thread* t = static_cast<Thread*>(local::globalMachine->localThread->get());
|
2010-11-04 17:02:09 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(path)};
|
|
|
|
|
|
|
|
return reinterpret_cast<void*>(run(t, jvmLoadLibrary, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_UnloadLibrary)(void*)
|
2013-05-13 19:08:40 +00:00
|
|
|
{
|
|
|
|
// todo: implement this correctly for POSIX and Windows
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_FindLibraryEntry)(void* library, const char* name)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
Thread* t = static_cast<Thread*>(local::globalMachine->localThread->get());
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2010-09-10 21:05:29 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2010-12-01 16:54:29 +00:00
|
|
|
if (library == RTLD_DEFAULT) {
|
2010-11-27 18:25:02 +00:00
|
|
|
library = t->m->libraries;
|
|
|
|
}
|
|
|
|
|
2014-04-23 21:22:10 +00:00
|
|
|
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
|
|
|
|
if (library == lib) {
|
|
|
|
return lib->resolve(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsSupportedJNIVersion)(jint version)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2011-03-26 17:15:52 +00:00
|
|
|
return version <= JNI_VERSION_1_6;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-09-21 23:31:45 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL EXPORT(JVM_IsNaN)(jdouble v)
|
2014-07-11 15:50:18 +00:00
|
|
|
{
|
2014-09-21 23:31:45 +00:00
|
|
|
return isnan(v);
|
2014-07-11 15:50:18 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmFillInStackTrace(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
GcThrowable* throwable
|
|
|
|
= cast<GcThrowable>(t, *reinterpret_cast<jobject>(arguments[0]));
|
2014-08-19 16:14:07 +00:00
|
|
|
PROTECT(t, throwable);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2012-02-18 22:17:10 +00:00
|
|
|
object trace = getTrace(t, 2);
|
2014-06-26 02:17:27 +00:00
|
|
|
throwable->setTrace(t, trace);
|
2011-03-17 14:43:01 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_FillInStackTrace)(Thread* t, jobject throwable)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(throwable)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
run(t, jvmFillInStackTrace, arguments);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_PrintStackTrace)(Thread*, jobject, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetStackTraceDepth)(Thread* t, jobject throwable)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
return objectArrayLength(t, cast<GcThrowable>(t, *throwable)->trace());
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetStackTraceElement(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject throwable = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jint index = arguments[1];
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeStackTraceElement(
|
|
|
|
t,
|
|
|
|
cast<GcTraceElement>(
|
|
|
|
t,
|
|
|
|
objectArrayBody(
|
|
|
|
t, cast<GcThrowable>(t, *throwable)->trace(), index)))));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetStackTraceElement)(Thread* t, jobject throwable, jint index)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= {reinterpret_cast<uintptr_t>(throwable), static_cast<uintptr_t>(index)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jobject>(run(t, jvmGetStackTraceElement, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_InitializeCompiler)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsSilentCompiler)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_CompileClass)(Thread*, jclass, jclass)
|
2011-03-26 00:50:31 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_CompileClasses)(Thread*, jclass, jstring)
|
2011-03-26 00:50:31 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_CompilerCommand)(Thread*, jclass, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_EnableCompiler)(Thread*, jclass)
|
2011-05-16 16:33:46 +00:00
|
|
|
{
|
|
|
|
// ignore
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_DisableCompiler)(Thread*, jclass)
|
2011-05-16 16:33:46 +00:00
|
|
|
{
|
|
|
|
// ignore
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmStartThread(Thread* t, uintptr_t* arguments)
|
2012-02-03 19:00:02 +00:00
|
|
|
{
|
|
|
|
jobject thread = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
|
2014-06-28 19:16:26 +00:00
|
|
|
return startThread(t, cast<GcThread>(t, *thread)) != 0;
|
2012-02-03 19:00:02 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_StartThread)(Thread* t, jobject thread)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(thread)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2012-02-03 19:00:02 +00:00
|
|
|
run(t, jvmStartThread, arguments);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_StopThread)(Thread*, jobject, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsThreadAlive)(Thread* t, jobject thread)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
Thread* p = reinterpret_cast<Thread*>(cast<GcThread>(t, *thread)->peer());
|
2014-08-20 15:49:00 +00:00
|
|
|
return p and (p->getFlags() & Thread::ActiveFlag) != 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_SuspendThread)(Thread*, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_ResumeThread)(Thread*, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SetThreadPriority)(Thread*, jobject, jint)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_Yield)(Thread* t, jclass)
|
2010-09-17 22:10:01 +00:00
|
|
|
{
|
2011-02-02 01:14:32 +00:00
|
|
|
t->m->system->yield();
|
2010-09-17 22:10:01 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmSleep(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
jlong milliseconds;
|
|
|
|
memcpy(&milliseconds, arguments, sizeof(jlong));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2012-08-12 17:17:59 +00:00
|
|
|
if (milliseconds <= 0) {
|
|
|
|
milliseconds = 1;
|
|
|
|
}
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
if (t->javaThread->sleepLock() == 0) {
|
|
|
|
GcJobject* lock = makeJobject(t);
|
2014-07-02 21:11:27 +00:00
|
|
|
t->javaThread->setSleepLock(t, lock);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
acquire(t, t->javaThread->sleepLock());
|
|
|
|
vm::wait(t, t->javaThread->sleepLock(), milliseconds);
|
|
|
|
release(t, t->javaThread->sleepLock());
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Sleep)(Thread* t, jclass, jlong milliseconds)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
uintptr_t arguments[sizeof(jlong) / BytesPerWord];
|
|
|
|
memcpy(arguments, &milliseconds, sizeof(jlong));
|
|
|
|
|
|
|
|
run(t, jvmSleep, arguments);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_CurrentThread)(Thread* t, jclass)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeLocalReference(t, t->javaThread);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_CountStackFrames)(Thread*, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmInterrupt(Thread* t, uintptr_t* arguments)
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
threadInterrupt(t,
|
|
|
|
cast<GcThread>(t, *reinterpret_cast<jobject>(arguments[0])));
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return 1;
|
2010-09-15 00:52:57 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Interrupt)(Thread* t, jobject thread)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(thread)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
run(t, jvmInterrupt, arguments);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmIsInterrupted(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject thread = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jboolean clear = arguments[1];
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
return threadIsInterrupted(t, cast<GcThread>(t, *thread), clear);
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsInterrupted)(Thread* t, jobject thread, jboolean clear)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(thread), clear};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return run(t, jvmIsInterrupted, arguments);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmHoldsLock(Thread* t, uintptr_t* arguments)
|
2012-03-11 11:06:08 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMonitor* m
|
|
|
|
= objectMonitor(t, *reinterpret_cast<jobject>(arguments[0]), false);
|
2012-03-11 11:06:08 +00:00
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
return m and m->owner() == t;
|
2012-03-11 11:06:08 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_HoldsLock)(Thread* t, jclass, jobject o)
|
2012-03-11 11:06:08 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(o)};
|
2012-03-11 11:06:08 +00:00
|
|
|
|
|
|
|
return run(t, jvmHoldsLock, arguments);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_DumpAllStacks)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetAllThreads)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmDumpThreads(Thread* t, uintptr_t* arguments)
|
2010-11-27 23:27:30 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jobjectArray threads = reinterpret_cast<jobjectArray>(arguments[0]);
|
2010-11-27 23:27:30 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
unsigned threadsLength
|
|
|
|
= objectArrayLength(t, reinterpret_cast<object>(*threads));
|
|
|
|
GcClass* arrayClass
|
|
|
|
= resolveObjectArrayClass(t,
|
|
|
|
type(t, GcStackTraceElement::Type)->loader(),
|
|
|
|
type(t, GcStackTraceElement::Type));
|
2010-11-27 23:27:30 +00:00
|
|
|
object result = makeObjectArray(t, arrayClass, threadsLength);
|
|
|
|
PROTECT(t, result);
|
|
|
|
|
|
|
|
for (unsigned threadsIndex = 0; threadsIndex < threadsLength;
|
2014-07-11 15:50:18 +00:00
|
|
|
++threadsIndex) {
|
2014-07-11 15:47:57 +00:00
|
|
|
Thread* peer = reinterpret_cast<Thread*>(
|
|
|
|
cast<GcThread>(t,
|
|
|
|
objectArrayBody(
|
|
|
|
t, reinterpret_cast<object>(*threads), threadsIndex))
|
|
|
|
->peer());
|
2010-11-27 23:27:30 +00:00
|
|
|
|
|
|
|
if (peer) {
|
|
|
|
object trace = t->m->processor->getStackTrace(t, peer);
|
|
|
|
PROTECT(t, trace);
|
|
|
|
|
|
|
|
unsigned traceLength = objectArrayLength(t, trace);
|
2014-07-11 15:47:57 +00:00
|
|
|
object array
|
|
|
|
= makeObjectArray(t, type(t, GcStackTraceElement::Type), traceLength);
|
2010-11-27 23:27:30 +00:00
|
|
|
PROTECT(t, array);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
for (unsigned traceIndex = 0; traceIndex < traceLength; ++traceIndex) {
|
2014-07-11 15:47:57 +00:00
|
|
|
object ste = makeStackTraceElement(
|
|
|
|
t, cast<GcTraceElement>(t, objectArrayBody(t, trace, traceIndex)));
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, array, ArrayBody + (traceIndex * BytesPerWord), ste);
|
2010-11-27 23:27:30 +00:00
|
|
|
}
|
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, result, ArrayBody + (threadsIndex * BytesPerWord), array);
|
2010-11-27 23:27:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, result));
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_DumpThreads)(Thread* t, jclass, jobjectArray threads)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(threads)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jobjectArray>(run(t, jvmDumpThreads, arguments));
|
2010-11-27 23:27:30 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL EXPORT(JVM_CurrentLoadedClass)(Thread*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL EXPORT(JVM_CurrentClassLoader)(Thread*)
|
2013-05-10 17:29:20 +00:00
|
|
|
{
|
|
|
|
// just return null, i.e. tell SecurityManager.currentClassLoader
|
|
|
|
// all permissions are granted, since Avian doesn't do any internal
|
|
|
|
// security checks:
|
|
|
|
return 0;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetClassContext(Thread* t, uintptr_t*)
|
2010-09-10 23:47:23 +00:00
|
|
|
{
|
|
|
|
object trace = getTrace(t, 1);
|
|
|
|
PROTECT(t, trace);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object context = makeObjectArray(
|
|
|
|
t, type(t, GcJclass::Type), objectArrayLength(t, trace));
|
2010-09-10 23:47:23 +00:00
|
|
|
PROTECT(t, context);
|
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
for (unsigned i = 0; i < objectArrayLength(t, trace); ++i) {
|
2014-07-02 21:11:27 +00:00
|
|
|
object c = getJClass(
|
2014-05-29 04:17:25 +00:00
|
|
|
t,
|
2014-07-11 15:47:57 +00:00
|
|
|
cast<GcMethod>(
|
|
|
|
t, cast<GcTraceElement>(t, objectArrayBody(t, trace, i))->method())
|
|
|
|
->class_());
|
2010-09-10 23:47:23 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, context, ArrayBody + (i * BytesPerWord), c);
|
2010-09-10 23:47:23 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, context));
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassContext)(Thread* t)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<jobjectArray>(run(t, jvmGetClassContext, 0));
|
2010-09-10 23:47:23 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_ClassDepth)(Thread*, jstring)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_ClassLoaderDepth)(Thread*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetSystemPackage(Thread* t, uintptr_t* arguments)
|
2012-09-24 23:43:34 +00:00
|
|
|
{
|
|
|
|
jstring s = reinterpret_cast<jstring>(arguments[0]);
|
|
|
|
|
|
|
|
ACQUIRE(t, t->m->classLock);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, chars, (*s)->length(t) + 1);
|
|
|
|
stringChars(t, *s, RUNTIME_ARRAY_BODY(chars));
|
2012-09-24 23:43:34 +00:00
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
object key = makeByteArray(t, RUNTIME_ARRAY_BODY(chars));
|
2012-09-24 23:43:34 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcByteArray* array = cast<GcByteArray>(
|
|
|
|
t,
|
|
|
|
hashMapFind(
|
|
|
|
t, roots(t)->packageMap(), key, byteArrayHash, byteArrayEqual));
|
2012-09-24 23:43:34 +00:00
|
|
|
|
|
|
|
if (array) {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
|
|
|
t, t->m->classpath->makeString(t, array, 0, array->length())));
|
2012-09-24 23:43:34 +00:00
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jstring JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetSystemPackage)(Thread* t, jstring s)
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(s)};
|
2012-09-24 23:43:34 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jstring>(run(t, jvmGetSystemPackage, arguments));
|
2010-09-15 00:52:57 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetSystemPackages(Thread* t, uintptr_t*)
|
2011-04-01 01:00:42 +00:00
|
|
|
{
|
2014-05-29 04:17:25 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeObjectArray(
|
2014-07-11 15:47:57 +00:00
|
|
|
t, resolveClass(t, roots(t)->bootLoader(), "java/lang/Package"), 0)));
|
2011-04-01 01:00:42 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetSystemPackages)(Thread* t)
|
2011-04-01 01:00:42 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<jobjectArray>(run(t, jvmGetSystemPackages, 0));
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_AllocateNewObject)(Thread*, jobject, jclass, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_AllocateNewArray)(Thread*, jobject, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_LatestUserDefinedLoader)(Thread* t)
|
2011-03-02 15:35:45 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
class Visitor : public Processor::StackVisitor {
|
2011-03-02 15:35:45 +00:00
|
|
|
public:
|
2014-07-11 15:50:18 +00:00
|
|
|
Visitor(Thread* t) : t(t), loader(0)
|
|
|
|
{
|
|
|
|
}
|
2011-03-02 15:35:45 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
virtual bool visit(Processor::StackWalker* walker)
|
|
|
|
{
|
2014-06-28 21:11:31 +00:00
|
|
|
GcClassLoader* loader = walker->method()->class_()->loader();
|
2014-07-11 15:47:57 +00:00
|
|
|
if (loader and loader != roots(t)->bootLoader()
|
|
|
|
and strcmp(objectClass(t, loader)->name()->body().begin(),
|
|
|
|
reinterpret_cast<const int8_t*>(
|
|
|
|
"sun/reflect/DelegatingClassLoader"))) {
|
2011-03-02 15:35:45 +00:00
|
|
|
this->loader = loader;
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Thread* t;
|
2014-06-28 21:11:31 +00:00
|
|
|
GcClassLoader* loader;
|
2011-03-02 15:35:45 +00:00
|
|
|
} v(t);
|
|
|
|
|
|
|
|
t->m->processor->walkStack(t, &v);
|
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeLocalReference(t, v.loader);
|
2011-03-02 15:35:45 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_LoadClass0)(Thread*, jobject, jclass, jstring)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetArrayLength)(Thread* t, jobject array)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2013-02-11 00:38:51 +00:00
|
|
|
return fieldAtOffset<uintptr_t>(*array, BytesPerWord);
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetArrayElement(Thread* t, uintptr_t* arguments)
|
2011-03-28 02:25:47 +00:00
|
|
|
{
|
|
|
|
jobject array = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jint index = arguments[1];
|
|
|
|
|
2014-06-21 04:16:33 +00:00
|
|
|
switch (objectClass(t, *array)->name()->body()[1]) {
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'Z':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t, makeBoolean(t, fieldAtOffset<int8_t>(*array, ArrayBody + index))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'B':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t, makeByte(t, fieldAtOffset<int8_t>(*array, ArrayBody + index))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'C':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeChar(t, fieldAtOffset<int16_t>(*array, ArrayBody + (index * 2)))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'S':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeShort(t, fieldAtOffset<int16_t>(*array, ArrayBody + (index * 2)))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'I':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeInt(t, fieldAtOffset<int32_t>(*array, ArrayBody + (index * 4)))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'F':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeFloat(t, fieldAtOffset<int32_t>(*array, ArrayBody + (index * 4)))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'J':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeLong(t, fieldAtOffset<int64_t>(*array, ArrayBody + (index * 8)))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'D':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeDouble(t,
|
|
|
|
fieldAtOffset<int64_t>(*array, ArrayBody + (index * 8)))));
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'L':
|
|
|
|
case '[':
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<intptr_t>(makeLocalReference(
|
|
|
|
t, fieldAtOffset<object>(*array, ArrayBody + (index * BytesPerWord))));
|
2011-03-28 02:25:47 +00:00
|
|
|
default:
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetArrayElement)(Thread* t, jobject array, jint index)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= {reinterpret_cast<uintptr_t>(array), static_cast<uintptr_t>(index)};
|
2010-09-14 16:49:41 +00:00
|
|
|
|
2011-03-28 02:25:47 +00:00
|
|
|
return reinterpret_cast<jobject>(run(t, jvmGetArrayElement, arguments));
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jvalue JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetPrimitiveArrayElement)(Thread*, jobject, jint, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_SetArrayElement)(Thread* t,
|
|
|
|
jobject array,
|
|
|
|
jint index,
|
|
|
|
jobject value)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-21 04:16:33 +00:00
|
|
|
switch (objectClass(t, *array)->name()->body()[1]) {
|
2011-03-28 02:25:47 +00:00
|
|
|
case 'Z':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int8_t>(*array, ArrayBody + index)
|
|
|
|
= cast<GcBoolean>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'B':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int8_t>(*array, ArrayBody + index)
|
|
|
|
= cast<GcByte>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'C':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int16_t>(*array, ArrayBody + (index * 2))
|
|
|
|
= cast<GcChar>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'S':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int16_t>(*array, ArrayBody + (index * 2))
|
|
|
|
= cast<GcShort>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'I':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int32_t>(*array, ArrayBody + (index * 4))
|
|
|
|
= cast<GcInt>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'F':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int32_t>(*array, ArrayBody + (index * 4))
|
|
|
|
= cast<GcFloat>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'J':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int64_t>(*array, ArrayBody + (index * 8))
|
|
|
|
= cast<GcLong>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'D':
|
2014-07-11 15:47:57 +00:00
|
|
|
fieldAtOffset<int64_t>(*array, ArrayBody + (index * 8))
|
|
|
|
= cast<GcDouble>(t, *value)->value();
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
case 'L':
|
|
|
|
case '[':
|
2014-07-11 15:47:57 +00:00
|
|
|
setField(
|
|
|
|
t, *array, ArrayBody + (index * BytesPerWord), (value ? *value : 0));
|
2011-03-28 02:25:47 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort(t);
|
|
|
|
}
|
2010-09-14 16:49:41 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(
|
|
|
|
JVM_SetPrimitiveArrayElement)(Thread*, jobject, jint, jvalue, unsigned char)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object makeNewArray(Thread* t, GcClass* c, unsigned length)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-27 00:17:46 +00:00
|
|
|
if (c->vmFlags() & PrimitiveFlag) {
|
2014-07-11 15:47:57 +00:00
|
|
|
const char* name
|
|
|
|
= reinterpret_cast<char*>(local::getClassName(t, c)->body().begin());
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
switch (*name) {
|
|
|
|
case 'b':
|
|
|
|
if (name[1] == 'o') {
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeBooleanArray(t, length);
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeByteArray(t, length);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
case 'c':
|
|
|
|
return makeCharArray(t, length);
|
|
|
|
case 'd':
|
|
|
|
return makeDoubleArray(t, length);
|
|
|
|
case 'f':
|
|
|
|
return makeFloatArray(t, length);
|
|
|
|
case 'i':
|
|
|
|
return makeIntArray(t, length);
|
|
|
|
case 'l':
|
|
|
|
return makeLongArray(t, length);
|
|
|
|
case 's':
|
|
|
|
return makeShortArray(t, length);
|
|
|
|
default:
|
|
|
|
abort(t);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
} else {
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeObjectArray(t, c, length);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmNewArray(Thread* t, uintptr_t* arguments)
|
2011-03-26 17:15:52 +00:00
|
|
|
{
|
|
|
|
jclass elementClass = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jint length = arguments[1];
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(
|
|
|
|
t, makeNewArray(t, (*elementClass)->vmClass(), length)));
|
2011-03-26 17:15:52 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_NewArray)(Thread* t, jclass elementClass, jint length)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(elementClass),
|
|
|
|
static_cast<uintptr_t>(length)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jobject>(run(t, jvmNewArray, arguments));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmNewMultiArray(Thread* t, uintptr_t* arguments)
|
2011-03-26 17:15:52 +00:00
|
|
|
{
|
|
|
|
jclass elementClass = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jintArray dimensions = reinterpret_cast<jintArray>(arguments[1]);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, int32_t, counts, (*dimensions)->length());
|
|
|
|
for (int i = (*dimensions)->length() - 1; i >= 0; --i) {
|
|
|
|
RUNTIME_ARRAY_BODY(counts)[i] = (*dimensions)->body()[i];
|
2011-03-26 17:15:52 +00:00
|
|
|
if (UNLIKELY(RUNTIME_ARRAY_BODY(counts)[i] < 0)) {
|
2014-07-11 15:47:57 +00:00
|
|
|
throwNew(t,
|
|
|
|
GcNegativeArraySizeException::Type,
|
|
|
|
"%d",
|
2011-03-26 17:15:52 +00:00
|
|
|
RUNTIME_ARRAY_BODY(counts)[i]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object array = makeNewArray(
|
|
|
|
t, (*elementClass)->vmClass(), RUNTIME_ARRAY_BODY(counts)[0]);
|
2011-03-26 17:15:52 +00:00
|
|
|
PROTECT(t, array);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
populateMultiArray(
|
|
|
|
t, array, RUNTIME_ARRAY_BODY(counts), 0, (*dimensions)->length());
|
2011-03-26 17:15:52 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_NewMultiArray)(Thread* t,
|
|
|
|
jclass elementClass,
|
|
|
|
jintArray dimensions)
|
2011-03-26 17:15:52 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(elementClass),
|
|
|
|
reinterpret_cast<uintptr_t>(dimensions)};
|
2011-03-26 17:15:52 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jobject>(run(t, jvmNewMultiArray, arguments));
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCallerClass)(Thread* t, int target)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
GcMethod* method = getCaller(t, target, true);
|
2011-03-26 00:54:09 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return method ? reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, method->class_())))
|
|
|
|
: 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_FindPrimitiveClass)(Thread* t, const char* name)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
switch (*name) {
|
|
|
|
case 'b':
|
|
|
|
if (name[1] == 'o') {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJboolean::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJbyte::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
case 'c':
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJchar::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
case 'd':
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJdouble::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
case 'f':
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJfloat::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
case 'i':
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJint::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
case 'l':
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJlong::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
case 's':
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJshort::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
case 'v':
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
makeLocalReference(t, getJClass(t, type(t, GcJvoid::Type))));
|
2010-09-10 21:05:29 +00:00
|
|
|
default:
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcIllegalArgumentException::Type);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmResolveClass(Thread* t, uintptr_t* arguments)
|
2011-03-27 05:24:48 +00:00
|
|
|
{
|
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* method = resolveMethod(
|
|
|
|
t, roots(t)->bootLoader(), "avian/Classes", "link", "(Lavian/VMClass;)V");
|
2011-03-27 05:24:48 +00:00
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
t->m->processor->invoke(t, method, 0, (*c)->vmClass());
|
2011-03-27 05:24:48 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ResolveClass)(Thread* t, jclass c)
|
2011-03-27 05:24:48 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2011-03-27 05:24:48 +00:00
|
|
|
|
|
|
|
run(t, jvmResolveClass, arguments);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmFindClassFromClassLoader(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
const char* name = reinterpret_cast<const char*>(arguments[0]);
|
|
|
|
jboolean init = arguments[1];
|
|
|
|
jobject loader = reinterpret_cast<jobject>(arguments[2]);
|
|
|
|
jboolean throwError = arguments[3];
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* c = resolveClass(
|
|
|
|
t,
|
|
|
|
loader ? cast<GcClassLoader>(t, *loader) : roots(t)->bootLoader(),
|
|
|
|
name,
|
|
|
|
true,
|
|
|
|
throwError ? static_cast<Gc::Type>(GcNoClassDefFoundError::Type)
|
|
|
|
: static_cast<Gc::Type>(GcClassNotFoundException::Type));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
if (init) {
|
|
|
|
PROTECT(t, c);
|
|
|
|
|
|
|
|
initClass(t, c);
|
|
|
|
}
|
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, getJClass(t, c)));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_FindClassFromClassLoader)(Thread* t,
|
|
|
|
const char* name,
|
|
|
|
jboolean init,
|
|
|
|
jobject loader,
|
|
|
|
jboolean throwError)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(name),
|
|
|
|
init,
|
|
|
|
reinterpret_cast<uintptr_t>(loader),
|
|
|
|
throwError};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<jclass>(
|
|
|
|
run(t, jvmFindClassFromClassLoader, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
JVM_FindClassFromBootLoader(Thread* t, const char* name)
|
2010-11-05 21:34:28 +00:00
|
|
|
{
|
2012-02-18 22:17:10 +00:00
|
|
|
return EXPORT(JVM_FindClassFromClassLoader)(t, name, false, 0, false);
|
2010-11-05 21:34:28 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_FindClassFromClass)(Thread*, const char*, jboolean, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmFindLoadedClass(Thread* t, uintptr_t* arguments)
|
2010-09-10 23:47:23 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jobject loader = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jstring name = reinterpret_cast<jstring>(arguments[1]);
|
2010-09-10 23:47:23 +00:00
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcByteArray* spec = makeByteArray(t, (*name)->length(t) + 1);
|
2010-09-22 19:58:46 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
{
|
|
|
|
char* s = reinterpret_cast<char*>(spec->body().begin());
|
2014-06-29 02:44:36 +00:00
|
|
|
stringChars(t, (*name), s);
|
2010-09-10 23:47:23 +00:00
|
|
|
replace('.', '/', s);
|
|
|
|
}
|
|
|
|
|
2014-06-28 21:11:31 +00:00
|
|
|
GcClass* c = findLoadedClass(t, cast<GcClassLoader>(t, *loader), spec);
|
2014-06-28 23:24:24 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<uint64_t>(c ? makeLocalReference(t, getJClass(t, c))
|
|
|
|
: 0);
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_FindLoadedClass)(Thread* t, jobject loader, jstring name)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(loader),
|
|
|
|
reinterpret_cast<uintptr_t>(name)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jclass>(run(t, jvmFindLoadedClass, arguments));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmDefineClass(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject loader = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
const uint8_t* data = reinterpret_cast<const uint8_t*>(arguments[1]);
|
|
|
|
jsize length = arguments[2];
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
getJClass(
|
|
|
|
t,
|
|
|
|
cast<GcClass>(
|
|
|
|
t,
|
|
|
|
defineClass(t, cast<GcClassLoader>(t, *loader), data, length)))));
|
2010-09-10 23:47:23 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_DefineClass)(Thread* t,
|
|
|
|
const char*,
|
|
|
|
jobject loader,
|
|
|
|
const uint8_t* data,
|
|
|
|
jsize length,
|
|
|
|
jobject)
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(loader),
|
|
|
|
reinterpret_cast<uintptr_t>(data),
|
|
|
|
static_cast<uintptr_t>(length)};
|
2010-09-15 00:52:57 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jclass>(run(t, jvmDefineClass, arguments));
|
2010-09-15 00:52:57 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_DefineClassWithSource)(Thread* t,
|
|
|
|
const char*,
|
|
|
|
jobject loader,
|
|
|
|
const uint8_t* data,
|
|
|
|
jsize length,
|
|
|
|
jobject,
|
|
|
|
const char*)
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
2010-11-07 17:08:04 +00:00
|
|
|
return EXPORT(JVM_DefineClass)(t, 0, loader, data, length, 0);
|
2010-09-15 00:52:57 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-04-23 21:22:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_DefineClassWithSourceCond)(Thread* t,
|
|
|
|
const char*,
|
|
|
|
jobject loader,
|
|
|
|
const uint8_t* data,
|
|
|
|
jsize length,
|
|
|
|
jobject,
|
|
|
|
const char*,
|
|
|
|
jboolean)
|
2014-04-23 21:22:10 +00:00
|
|
|
{
|
|
|
|
return EXPORT(JVM_DefineClass)(t, 0, loader, data, length, 0);
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jstring JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassName)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
return reinterpret_cast<jstring>(makeLocalReference(t, (*c)->name()));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetClassInterfaces(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClassAddendum* addendum = (*c)->vmClass()->addendum();
|
2011-03-28 02:29:31 +00:00
|
|
|
if (addendum) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, addendum->interfaceTable());
|
2011-03-28 02:29:31 +00:00
|
|
|
if (table) {
|
|
|
|
PROTECT(t, table);
|
2011-02-19 21:07:45 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object array
|
|
|
|
= makeObjectArray(t, type(t, GcJclass::Type), table->length());
|
2011-03-28 02:29:31 +00:00
|
|
|
PROTECT(t, array);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
for (unsigned i = 0; i < table->length(); ++i) {
|
2014-07-02 21:11:27 +00:00
|
|
|
object c = getJClass(t, cast<GcClass>(t, table->body()[i]));
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, array, ArrayBody + (i * BytesPerWord), c);
|
2011-03-28 02:29:31 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2011-03-28 02:29:31 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
2011-03-28 02:29:31 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(
|
|
|
|
makeLocalReference(t, makeObjectArray(t, type(t, GcJclass::Type), 0)));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassInterfaces)(Thread* t, jclass c)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jobjectArray>(
|
|
|
|
run(t, jvmGetClassInterfaces, arguments));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassLoader)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClassLoader* loader = (*c)->vmClass()->loader();
|
2010-11-04 17:43:50 +00:00
|
|
|
|
2014-06-30 01:44:41 +00:00
|
|
|
if (loader == roots(t)->bootLoader()) {
|
2010-11-04 17:43:50 +00:00
|
|
|
// sun.misc.Unsafe.getUnsafe expects a null result if the class
|
|
|
|
// loader is the boot classloader and will throw a
|
|
|
|
// SecurityException otherwise.
|
2014-05-29 04:17:25 +00:00
|
|
|
GcMethod* caller = getCaller(t, 2);
|
2014-07-11 15:47:57 +00:00
|
|
|
if (caller
|
|
|
|
and strcmp(reinterpret_cast<const char*>(
|
|
|
|
caller->class_()->name()->body().begin()),
|
|
|
|
"sun/misc/Unsafe") == 0) {
|
2010-11-04 17:43:50 +00:00
|
|
|
return 0;
|
|
|
|
} else {
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeLocalReference(t, roots(t)->bootLoader());
|
2010-11-04 17:43:50 +00:00
|
|
|
}
|
|
|
|
} else {
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeLocalReference(t, loader);
|
2010-11-04 17:43:50 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsInterface)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
return ((*c)->vmClass()->flags() & ACC_INTERFACE) != 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassSigners)(Thread* t, jclass c)
|
2010-11-27 18:25:02 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClassRuntimeData* runtimeData
|
|
|
|
= getClassRuntimeDataIfExists(t, (*c)->vmClass());
|
2010-11-27 18:25:02 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return runtimeData ? reinterpret_cast<jobjectArray>(
|
|
|
|
makeLocalReference(t, runtimeData->signers()))
|
|
|
|
: 0;
|
2010-11-27 18:25:02 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-04-23 21:22:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jbyteArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassTypeAnnotations)(Thread*, jclass)
|
2014-04-23 21:22:10 +00:00
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" AVIAN_EXPORT jbyteArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetFieldTypeAnnotations)(Thread*, jobject)
|
2014-04-23 21:22:10 +00:00
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" AVIAN_EXPORT jbyteArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodTypeAnnotations)(Thread*, jobject)
|
2014-04-23 21:22:10 +00:00
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SetClassSigners)(Thread* t, jclass c, jobjectArray signers)
|
2010-11-27 18:25:02 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClassRuntimeData* runtimeData = getClassRuntimeData(t, (*c)->vmClass());
|
2010-11-27 18:25:02 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
runtimeData->setSigners(t, reinterpret_cast<object>(*signers));
|
2010-11-27 18:25:02 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetProtectionDomain(Thread* t, uintptr_t* arguments)
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
2011-04-01 01:16:57 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
2010-09-15 00:52:57 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* method
|
|
|
|
= resolveMethod(t,
|
|
|
|
roots(t)->bootLoader(),
|
|
|
|
"avian/Classes",
|
|
|
|
"getProtectionDomain",
|
|
|
|
"(Lavian/VMClass;)Ljava/security/ProtectionDomain;");
|
2010-09-15 00:52:57 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(
|
|
|
|
t, t->m->processor->invoke(t, method, 0, (*c)->vmClass())));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetProtectionDomain)(Thread* t, jclass c)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2011-04-01 01:16:57 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jobject>(run(t, jvmGetProtectionDomain, arguments));
|
2010-09-15 00:52:57 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SetProtectionDomain)(Thread*, jclass, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsArrayClass)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
return (*c)->vmClass()->arrayDimensions() != 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsPrimitiveClass)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
return ((*c)->vmClass()->vmFlags() & PrimitiveFlag) != 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetComponentType(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-06-29 02:44:36 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
if ((*c)->vmClass()->arrayDimensions()) {
|
|
|
|
uint8_t n = (*c)->vmClass()->name()->body()[1];
|
2011-03-17 15:41:52 +00:00
|
|
|
if (n != 'L' and n != '[') {
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(
|
|
|
|
makeLocalReference(t, getJClass(t, primitiveClass(t, n))));
|
2011-03-17 15:41:52 +00:00
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
|
|
|
t, getJClass(t, (*c)->vmClass()->arrayElementClass())));
|
2011-03-17 15:41:52 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2011-03-17 15:41:52 +00:00
|
|
|
return 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetComponentType)(Thread* t, jclass c)
|
2011-03-17 14:43:01 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2011-03-17 14:43:01 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jclass>(run(t, jvmGetComponentType, arguments));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetClassModifiers(Thread* t, uintptr_t* arguments)
|
2014-03-06 22:01:44 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
return classModifiers(
|
|
|
|
t,
|
|
|
|
cast<GcJclass>(t, *reinterpret_cast<jobject>(arguments[0]))->vmClass());
|
2014-03-06 22:01:44 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassModifiers)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-03-06 22:01:44 +00:00
|
|
|
return run(t, jvmGetClassModifiers, arguments);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetDeclaredClasses(Thread* t, uintptr_t* arguments)
|
2011-04-01 01:47:26 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
getDeclaredClasses(
|
|
|
|
t,
|
|
|
|
cast<GcJclass>(t, *reinterpret_cast<jobject>(arguments[0]))
|
|
|
|
->vmClass(),
|
|
|
|
false)));
|
2011-04-01 01:47:26 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetDeclaredClasses)(Thread* t, jclass c)
|
2011-04-01 01:47:26 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2011-04-01 01:47:26 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<jobjectArray>(
|
|
|
|
run(t, jvmGetDeclaredClasses, arguments));
|
2011-04-01 01:47:26 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetDeclaringClass(Thread* t, uintptr_t* arguments)
|
2011-04-01 01:47:26 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
getDeclaringClass(
|
|
|
|
t,
|
|
|
|
cast<GcJclass>(t, *reinterpret_cast<jobject>(arguments[0]))
|
|
|
|
->vmClass())));
|
2011-04-01 01:47:26 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetDeclaringClass)(Thread* t, jclass c)
|
2011-02-25 15:17:15 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2011-04-01 01:47:26 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jclass>(run(t, jvmGetDeclaringClass, arguments));
|
2011-02-25 15:17:15 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetClassSignature(Thread* t, uintptr_t* arguments)
|
2011-02-25 15:17:15 +00:00
|
|
|
{
|
2014-06-29 02:44:36 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
2011-03-18 03:42:15 +00:00
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClassAddendum* addendum = (*c)->vmClass()->addendum();
|
2011-03-18 03:42:15 +00:00
|
|
|
if (addendum) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcByteArray* signature = cast<GcByteArray>(t, addendum->signature());
|
2011-03-18 03:42:15 +00:00
|
|
|
if (signature) {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(
|
|
|
|
makeLocalReference(t,
|
|
|
|
t->m->classpath->makeString(
|
|
|
|
t, signature, 0, signature->length() - 1)));
|
2011-03-18 03:42:15 +00:00
|
|
|
}
|
|
|
|
}
|
2011-02-25 15:17:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jstring JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassSignature)(Thread* t, jclass c)
|
2011-04-01 01:47:26 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2011-04-01 01:47:26 +00:00
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
return reinterpret_cast<jstring>(run(t, jvmGetClassSignature, arguments));
|
2011-04-01 01:47:26 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jbyteArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassAnnotations)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClassAddendum* addendum = (*c)->vmClass()->addendum();
|
2014-07-11 15:47:57 +00:00
|
|
|
return addendum ? reinterpret_cast<jbyteArray>(
|
|
|
|
makeLocalReference(t, addendum->annotationTable()))
|
|
|
|
: 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jboolean publicOnly = arguments[1];
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, (*c)->vmClass()->methodTable());
|
2010-09-10 21:05:29 +00:00
|
|
|
if (table) {
|
2010-09-14 16:49:41 +00:00
|
|
|
PROTECT(t, table);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object array
|
|
|
|
= makeObjectArray(t,
|
|
|
|
type(t, GcJmethod::Type),
|
|
|
|
local::countMethods(t, (*c)->vmClass(), publicOnly));
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, array);
|
|
|
|
|
|
|
|
unsigned ai = 0;
|
2014-06-29 02:44:36 +00:00
|
|
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, (*c)->vmClass());
|
2014-07-11 15:47:57 +00:00
|
|
|
i < j;
|
|
|
|
++i) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcMethod* vmMethod = cast<GcMethod>(t, table->body()[i]);
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, vmMethod);
|
|
|
|
|
2014-06-28 21:11:31 +00:00
|
|
|
if (((not publicOnly) or (vmMethod->flags() & ACC_PUBLIC))
|
2014-07-11 15:47:57 +00:00
|
|
|
and vmMethod->name()->body()[0] != '<') {
|
2012-12-19 19:39:33 +00:00
|
|
|
object method = makeJmethod(t, vmMethod, i);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-04 01:52:01 +00:00
|
|
|
assertT(t, ai < objectArrayLength(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, array, ArrayBody + ((ai++) * BytesPerWord), method);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(
|
|
|
|
makeLocalReference(t, makeObjectArray(t, type(t, GcJmethod::Type), 0)));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassDeclaredMethods)(Thread* t,
|
|
|
|
jclass c,
|
|
|
|
jboolean publicOnly)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c), publicOnly};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<jobjectArray>(
|
|
|
|
run(t, jvmGetClassDeclaredMethods, arguments));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetClassDeclaredFields(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jboolean publicOnly = arguments[1];
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, (*c)->vmClass()->fieldTable());
|
2010-09-10 21:05:29 +00:00
|
|
|
if (table) {
|
2010-09-14 16:49:41 +00:00
|
|
|
PROTECT(t, table);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object array
|
|
|
|
= makeObjectArray(t,
|
|
|
|
type(t, GcJfield::Type),
|
|
|
|
local::countFields(t, (*c)->vmClass(), publicOnly));
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, array);
|
|
|
|
|
|
|
|
unsigned ai = 0;
|
2014-06-27 00:17:46 +00:00
|
|
|
for (unsigned i = 0; i < table->length(); ++i) {
|
|
|
|
GcField* vmField = cast<GcField>(t, table->body()[i]);
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, vmField);
|
|
|
|
|
2014-06-27 00:17:16 +00:00
|
|
|
if ((not publicOnly) or (vmField->flags() & ACC_PUBLIC)) {
|
2012-12-19 19:39:33 +00:00
|
|
|
object field = makeJfield(t, vmField, i);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-04 01:52:01 +00:00
|
|
|
assertT(t, ai < objectArrayLength(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, array, ArrayBody + ((ai++) * BytesPerWord), field);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
2014-06-04 01:52:01 +00:00
|
|
|
assertT(t, ai == objectArrayLength(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(
|
|
|
|
makeLocalReference(t, makeObjectArray(t, type(t, GcJfield::Type), 0)));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassDeclaredFields)(Thread* t, jclass c, jboolean publicOnly)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c), publicOnly};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<jobjectArray>(
|
|
|
|
run(t, jvmGetClassDeclaredFields, arguments));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
|
|
|
jboolean publicOnly = arguments[1];
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
GcArray* table = cast<GcArray>(t, (*c)->vmClass()->methodTable());
|
2010-09-10 21:05:29 +00:00
|
|
|
if (table) {
|
2010-09-14 16:49:41 +00:00
|
|
|
PROTECT(t, table);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object array = makeObjectArray(
|
|
|
|
t,
|
|
|
|
type(t, GcJconstructor::Type),
|
|
|
|
local::countConstructors(t, (*c)->vmClass(), publicOnly));
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, array);
|
|
|
|
|
|
|
|
unsigned ai = 0;
|
2014-06-29 02:44:36 +00:00
|
|
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, (*c)->vmClass());
|
2014-07-11 15:47:57 +00:00
|
|
|
i < j;
|
|
|
|
++i) {
|
2014-06-27 00:17:46 +00:00
|
|
|
GcMethod* vmMethod = cast<GcMethod>(t, table->body()[i]);
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, vmMethod);
|
|
|
|
|
2014-06-28 21:11:31 +00:00
|
|
|
if (((not publicOnly) or (vmMethod->flags() & ACC_PUBLIC))
|
2014-07-11 15:47:57 +00:00
|
|
|
and strcmp(reinterpret_cast<char*>(vmMethod->name()->body().begin()),
|
|
|
|
"<init>") == 0) {
|
2012-12-19 19:39:33 +00:00
|
|
|
object method = makeJconstructor(t, vmMethod, i);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-04 01:52:01 +00:00
|
|
|
assertT(t, ai < objectArrayLength(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, array, ArrayBody + ((ai++) * BytesPerWord), method);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(
|
|
|
|
t, makeObjectArray(t, type(t, GcJconstructor::Type), 0)));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassDeclaredConstructors)(Thread* t,
|
|
|
|
jclass c,
|
|
|
|
jboolean publicOnly)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c), publicOnly};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<jobjectArray>(
|
|
|
|
run(t, jvmGetClassDeclaredConstructors, arguments));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassAccessFlags)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-03-06 22:01:44 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
return (*c)->vmClass()->flags();
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmInvokeMethod(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jobject method = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jobject instance = reinterpret_cast<jobject>(arguments[1]);
|
|
|
|
jobjectArray args = reinterpret_cast<jobjectArray>(arguments[2]);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* vmMethod = cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcArray>(
|
|
|
|
t, cast<GcJmethod>(t, *method)->clazz()->vmClass()->methodTable())
|
|
|
|
->body()[cast<GcJmethod>(t, *method)->slot()]);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
if (vmMethod->flags() & ACC_STATIC) {
|
2013-04-18 17:25:29 +00:00
|
|
|
instance = 0;
|
|
|
|
}
|
|
|
|
|
2014-06-21 04:16:33 +00:00
|
|
|
if (instance and not instanceOf(t, vmMethod->class_(), *instance)) {
|
2014-05-29 04:17:25 +00:00
|
|
|
throwNew(t, GcIllegalArgumentException::Type);
|
2013-04-09 23:43:25 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
return reinterpret_cast<uint64_t>(
|
|
|
|
makeLocalReference(t,
|
|
|
|
invoke(t,
|
|
|
|
vmMethod,
|
|
|
|
instance ? *instance : 0,
|
|
|
|
args ? reinterpret_cast<object>(*args) : 0)));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_InvokeMethod)(Thread* t,
|
|
|
|
jobject method,
|
|
|
|
jobject instance,
|
|
|
|
jobjectArray args)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(method),
|
|
|
|
reinterpret_cast<uintptr_t>(instance),
|
|
|
|
reinterpret_cast<uintptr_t>(args)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
return reinterpret_cast<jobject>(run(t, jvmInvokeMethod, arguments));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmNewInstanceFromConstructor(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject constructor = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jobjectArray args = reinterpret_cast<jobjectArray>(arguments[1]);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object instance
|
|
|
|
= make(t, cast<GcJconstructor>(t, *constructor)->clazz()->vmClass());
|
2010-09-10 21:05:29 +00:00
|
|
|
PROTECT(t, instance);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* method = cast<GcMethod>(
|
|
|
|
t,
|
|
|
|
cast<GcArray>(t,
|
|
|
|
cast<GcJconstructor>(t, *constructor)
|
|
|
|
->clazz()
|
|
|
|
->vmClass()
|
|
|
|
->methodTable())
|
|
|
|
->body()[cast<GcJconstructor>(t, *constructor)->slot()]);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
invoke(t, method, instance, args ? reinterpret_cast<object>(*args) : 0);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(t, instance));
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_NewInstanceFromConstructor)(Thread* t,
|
|
|
|
jobject constructor,
|
|
|
|
jobjectArray args)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(constructor),
|
|
|
|
reinterpret_cast<uintptr_t>(args)};
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<jobject>(
|
|
|
|
run(t, jvmNewInstanceFromConstructor, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassConstantPool)(Thread* t, jclass c)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClass* vmClass = (*c)->vmClass();
|
|
|
|
GcClassAddendum* addendum = vmClass->addendum();
|
2010-11-26 19:41:31 +00:00
|
|
|
object pool;
|
|
|
|
if (addendum) {
|
2014-07-02 21:11:27 +00:00
|
|
|
pool = addendum->pool();
|
2010-11-26 19:41:31 +00:00
|
|
|
} else {
|
|
|
|
pool = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pool == 0) {
|
2014-06-29 02:44:36 +00:00
|
|
|
pool = getClassRuntimeData(t, vmClass)->pool();
|
2010-11-26 19:41:31 +00:00
|
|
|
}
|
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
return makeLocalReference(t, makeConstantPool(t, pool));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetSize)(Thread* t, jobject, jobject pool)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
if (pool == 0)
|
|
|
|
return 0;
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
return singletonCount(t, cast<GcSingleton>(t, *pool));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetClassAt)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jclass JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetClassAtIfLoaded)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetMethodAt)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetMethodAtIfLoaded)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetFieldAt)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetFieldAtIfLoaded)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetMemberRefInfoAt)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(
|
|
|
|
JVM_ConstantPoolGetIntAt)(Thread* t, jobject, jobject pool, jint index)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
return singletonValue(t, cast<GcSingleton>(t, *pool), index - 1);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL EXPORT(
|
|
|
|
JVM_ConstantPoolGetLongAt)(Thread* t, jobject, jobject pool, jint index)
|
2013-04-09 23:44:21 +00:00
|
|
|
{
|
|
|
|
ENTER(t, Thread::ActiveState);
|
|
|
|
|
|
|
|
uint64_t v;
|
2014-05-29 04:17:25 +00:00
|
|
|
memcpy(&v, &singletonValue(t, cast<GcSingleton>(t, *pool), index - 1), 8);
|
2013-04-09 23:44:21 +00:00
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jfloat JNICALL EXPORT(
|
|
|
|
JVM_ConstantPoolGetFloatAt)(Thread* t, jobject, jobject pool, jint index)
|
2012-08-30 00:34:28 +00:00
|
|
|
{
|
2013-04-23 03:23:32 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
2012-08-30 00:34:28 +00:00
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
return bitsToFloat(singletonValue(t, cast<GcSingleton>(t, *pool), index - 1));
|
2012-08-30 00:34:28 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jdouble JNICALL EXPORT(
|
|
|
|
JVM_ConstantPoolGetDoubleAt)(Thread* t, jobject, jobject pool, jint index)
|
2012-08-30 00:34:28 +00:00
|
|
|
{
|
2013-04-23 03:23:32 +00:00
|
|
|
ENTER(t, Thread::ActiveState);
|
2012-08-30 00:34:28 +00:00
|
|
|
|
2013-04-23 03:23:32 +00:00
|
|
|
double v;
|
2014-05-29 04:17:25 +00:00
|
|
|
memcpy(&v, &singletonValue(t, cast<GcSingleton>(t, *pool), index - 1), 8);
|
2013-04-23 03:23:32 +00:00
|
|
|
|
|
|
|
return v;
|
2012-08-30 00:34:28 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jstring JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_ConstantPoolGetStringAt)(Thread*, jobject, jobject, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmConstantPoolGetUTF8At(Thread* t, uintptr_t* arguments)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
|
|
|
jobject pool = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jint index = arguments[1];
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
object array = parseUtf8(
|
|
|
|
t,
|
|
|
|
cast<GcByteArray>(
|
|
|
|
t, singletonObject(t, cast<GcSingleton>(t, *pool), index - 1)));
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<uint64_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
t->m->classpath->makeString(
|
|
|
|
t, array, 0, fieldAtOffset<uintptr_t>(array, BytesPerWord) - 1)));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jstring JNICALL EXPORT(
|
|
|
|
JVM_ConstantPoolGetUTF8At)(Thread* t, jobject, jobject pool, jint index)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[]
|
|
|
|
= {reinterpret_cast<uintptr_t>(pool), static_cast<uintptr_t>(index)};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<jstring>(run(t, jvmConstantPoolGetUTF8At, arguments));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
void maybeWrap(Thread* t, bool wrapException)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
if (t->exception and wrapException
|
|
|
|
and not(instanceOf(t, type(t, GcError::Type), t->exception)
|
|
|
|
or instanceOf(
|
|
|
|
t, type(t, GcRuntimeException::Type), t->exception))) {
|
2014-06-28 23:24:24 +00:00
|
|
|
GcThrowable* exception = t->exception;
|
2010-12-27 22:55:23 +00:00
|
|
|
t->exception = 0;
|
|
|
|
|
|
|
|
PROTECT(t, exception);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* paeClass = resolveClass(
|
|
|
|
t, roots(t)->bootLoader(), "java/security/PrivilegedActionException");
|
2010-12-27 22:55:23 +00:00
|
|
|
PROTECT(t, paeClass);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcMethod* paeConstructor
|
|
|
|
= resolveMethod(t, paeClass, "<init>", "(Ljava/lang/Exception;)V");
|
2010-12-27 22:55:23 +00:00
|
|
|
PROTECT(t, paeConstructor);
|
|
|
|
|
2014-06-28 23:24:24 +00:00
|
|
|
GcThrowable* result = cast<GcThrowable>(t, make(t, paeClass));
|
2010-12-27 22:55:23 +00:00
|
|
|
PROTECT(t, result);
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
t->m->processor->invoke(t, paeConstructor, result, exception);
|
2010-12-27 22:55:23 +00:00
|
|
|
|
|
|
|
t->exception = result;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t jvmDoPrivileged(Thread* t, uintptr_t* arguments)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-12-27 22:55:23 +00:00
|
|
|
jobject action = reinterpret_cast<jobject>(arguments[0]);
|
|
|
|
jboolean wrapException = arguments[1];
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-09-14 16:49:41 +00:00
|
|
|
// todo: cache these class and method lookups in the t->m->classpath
|
|
|
|
// object:
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* privilegedAction = resolveClass(
|
|
|
|
t, roots(t)->bootLoader(), "java/security/PrivilegedAction");
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
GcMethod* method;
|
2010-09-10 21:05:29 +00:00
|
|
|
if (instanceOf(t, privilegedAction, *action)) {
|
2014-07-11 15:50:18 +00:00
|
|
|
method = resolveMethod(t, privilegedAction, "run", "()Ljava/lang/Object;");
|
2010-09-10 21:05:29 +00:00
|
|
|
} else {
|
2014-07-11 15:47:57 +00:00
|
|
|
GcClass* privilegedExceptionAction = resolveClass(
|
|
|
|
t, roots(t)->bootLoader(), "java/security/PrivilegedExceptionAction");
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
method = resolveMethod(
|
|
|
|
t, privilegedExceptionAction, "run", "()Ljava/lang/Object;");
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
THREAD_RESOURCE(t, jboolean, wrapException, maybeWrap(t, wrapException));
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<uint64_t>(
|
|
|
|
makeLocalReference(t, t->m->processor->invoke(t, method, *action)));
|
2010-12-27 22:55:23 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_DoPrivileged)(Thread* t,
|
|
|
|
jclass,
|
|
|
|
jobject action,
|
|
|
|
jobject,
|
|
|
|
jboolean wrapException)
|
2010-12-27 22:55:23 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(action), wrapException};
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
return reinterpret_cast<jobject>(run(t, jvmDoPrivileged, arguments));
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetInheritedAccessControlContext)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetStackAccessControlContext)(Thread*, jclass)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void* JNICALL EXPORT(JVM_RegisterSignal)(jint, void*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL EXPORT(JVM_RaiseSignal)(jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_FindSignal)(const char*)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_DesiredAssertionStatus)(Thread*, jclass, jclass)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_AssertionStatusDirectives)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL EXPORT(JVM_SupportsCX8)()
|
2010-09-10 23:47:23 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassNameUTF)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassCPTypes)(Thread*, jclass, unsigned char*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassCPEntriesCount)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassFieldsCount)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetClassMethodsCount)(Thread*, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(
|
|
|
|
JVM_GetMethodIxExceptionIndexes)(Thread*, jclass, jint, unsigned short*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxExceptionsCount)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxByteCode)(Thread*, jclass, jint, unsigned char*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxByteCodeLength)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_GetMethodIxExceptionTableEntry)(
|
|
|
|
Thread*,
|
|
|
|
jclass,
|
|
|
|
jint,
|
|
|
|
jint,
|
|
|
|
local::JVM_ExceptionTableEntryType*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxExceptionTableLength)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetFieldIxModifiers)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxModifiers)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxLocalsCount)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxArgsSize)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxMaxStack)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsConstructorIx)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2014-04-23 21:22:10 +00:00
|
|
|
|
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsVMGeneratedMethodIx)(Thread*, jclass, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxNameUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetMethodIxSignatureUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPFieldNameUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPMethodNameUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPMethodSignatureUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPFieldSignatureUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPClassNameUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPFieldClassNameUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT const char* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPMethodClassNameUTF)(Thread*, jclass, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPFieldModifiers)(Thread*, jclass, int, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetCPMethodModifiers)(Thread*, jclass, int, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_ReleaseUTF)(const char*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_IsSameClassPackage)(Thread*, jclass, jclass)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetLastErrorString)(char* dst, int length)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
strncpy(dst, strerror(errno), length);
|
|
|
|
return strlen(dst);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT char* JNICALL EXPORT(JVM_NativePath)(char* path)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Open)(const char* path, jint flags, jint mode)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2013-05-13 19:11:12 +00:00
|
|
|
int r = OPEN(path, flags & 0xFFFF, mode);
|
2012-03-13 14:26:51 +00:00
|
|
|
if (r == -1) {
|
|
|
|
return errno == EEXIST ? JVM_EEXIST : -1;
|
|
|
|
} else {
|
|
|
|
return r;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_Close)(jint fd)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-11-07 17:08:04 +00:00
|
|
|
return CLOSE(fd);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Read)(jint fd, char* dst, jint length)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-11-07 17:08:04 +00:00
|
|
|
return READ(fd, dst, length);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Write)(jint fd, char* src, jint length)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return WRITE(fd, src, length);
|
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Available)(jint fd, jlong* result)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
struct STAT buffer;
|
|
|
|
int n;
|
|
|
|
if (FSTAT(fd, &buffer) >= 0
|
2014-07-11 15:50:18 +00:00
|
|
|
and (S_ISCHR(buffer.st_mode) or S_ISFIFO(buffer.st_mode)
|
|
|
|
or S_ISSOCK(buffer.st_mode)) and local::pipeAvailable(fd, &n)) {
|
2010-11-07 17:08:04 +00:00
|
|
|
*result = n;
|
|
|
|
return 1;
|
|
|
|
}
|
2010-09-23 14:49:36 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
int current = LSEEK(fd, 0, SEEK_CUR);
|
2014-07-11 15:50:18 +00:00
|
|
|
if (current == -1)
|
|
|
|
return 0;
|
2010-09-10 23:47:23 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
int end = LSEEK(fd, 0, SEEK_END);
|
2014-07-11 15:50:18 +00:00
|
|
|
if (end == -1)
|
|
|
|
return 0;
|
2010-09-10 23:47:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
if (LSEEK(fd, current, SEEK_SET) == -1)
|
|
|
|
return 0;
|
2010-09-10 23:47:23 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
*result = end - current;
|
|
|
|
return 1;
|
2010-09-10 23:47:23 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jlong JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Lseek)(jint fd, jlong offset, jint seek)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-11-07 17:08:04 +00:00
|
|
|
return LSEEK(fd, offset, seek);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SetLength)(jint fd, jlong length)
|
2011-03-26 17:15:52 +00:00
|
|
|
{
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
|
|
|
|
if (h == INVALID_HANDLE_VALUE) {
|
|
|
|
errno = EBADF;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-03-26 17:45:33 +00:00
|
|
|
long high = length >> 32;
|
|
|
|
DWORD r = SetFilePointer(h, static_cast<long>(length), &high, FILE_BEGIN);
|
|
|
|
if (r == 0xFFFFFFFF and GetLastError() != NO_ERROR) {
|
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SetEndOfFile(h)) {
|
2011-03-26 17:15:52 +00:00
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
return ftruncate(fd, length);
|
|
|
|
#endif
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_Sync)(jint fd)
|
2010-09-15 00:52:57 +00:00
|
|
|
{
|
2010-11-07 04:21:19 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
|
|
|
|
if (h == INVALID_HANDLE_VALUE) {
|
|
|
|
errno = EBADF;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FlushFileBuffers(h)) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
errno = EIO;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#else
|
2010-09-15 00:52:57 +00:00
|
|
|
return fsync(fd);
|
2010-11-07 04:21:19 +00:00
|
|
|
#endif
|
2010-09-15 00:52:57 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_InitializeSocketLibrary)()
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
static bool wsaInitialized = false;
|
|
|
|
if (not wsaInitialized) {
|
|
|
|
WSADATA data;
|
|
|
|
int r = WSAStartup(MAKEWORD(2, 2), &data);
|
|
|
|
if (r or LOBYTE(data.wVersion) != 2 or HIBYTE(data.wVersion) != 2) {
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
wsaInitialized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Socket)(jint domain, jint type, jint protocol)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
return socket(domain, type, protocol);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_SocketClose)(jint socket)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
return closesocket(socket);
|
|
|
|
#else
|
|
|
|
return close(socket);
|
|
|
|
#endif
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SocketShutdown)(jint socket, jint how)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
return shutdown(socket, how);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Recv)(jint socket, char* dst, jint count, jint flags)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
return recv(socket, dst, count, flags);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Send)(jint socket, char* src, jint count, jint flags)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
return send(socket, src, count, flags);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_Timeout)(int, long)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_Listen)(jint socket, jint count)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
return listen(socket, count);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Connect)(jint socket, sockaddr* address, jint addressLength)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
return connect(socket, address, addressLength);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Bind)(jint, struct sockaddr*, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_Accept)(jint socket,
|
|
|
|
struct sockaddr* address,
|
|
|
|
jint* addressLength)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
socklen_t length = *addressLength;
|
|
|
|
int r = accept(socket, address, &length);
|
|
|
|
*addressLength = length;
|
|
|
|
return r;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_RecvFrom)(jint, char*, int, int, struct sockaddr*, int*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SendTo)(jint, char*, int, int, struct sockaddr*, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SocketAvailable)(jint socket, jint* count)
|
2011-03-02 15:35:45 +00:00
|
|
|
{
|
2011-03-26 17:45:33 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
unsigned long c = *count;
|
|
|
|
int r = ioctlsocket(socket, FIONREAD, &c);
|
|
|
|
*count = c;
|
|
|
|
return r;
|
|
|
|
#else
|
2011-03-02 15:35:45 +00:00
|
|
|
return ioctl(socket, FIONREAD, count) < 0 ? 0 : 1;
|
2011-03-26 17:45:33 +00:00
|
|
|
#endif
|
2011-03-02 15:35:45 +00:00
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetSockName)(jint socket,
|
|
|
|
struct sockaddr* address,
|
|
|
|
int* addressLength)
|
2010-09-14 16:49:41 +00:00
|
|
|
{
|
|
|
|
socklen_t length = *addressLength;
|
|
|
|
int r = getsockname(socket, address, &length);
|
|
|
|
*addressLength = length;
|
|
|
|
return r;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_GetSockOpt)(jint socket,
|
|
|
|
int level,
|
|
|
|
int optionName,
|
|
|
|
char* optionValue,
|
|
|
|
int* optionLength)
|
2011-02-25 15:17:15 +00:00
|
|
|
{
|
2011-03-18 03:42:15 +00:00
|
|
|
socklen_t length = *optionLength;
|
2011-02-25 15:17:15 +00:00
|
|
|
int rv = getsockopt(socket, level, optionName, optionValue, &length);
|
|
|
|
*optionLength = length;
|
|
|
|
return rv;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SetSockOpt)(jint socket,
|
|
|
|
int level,
|
|
|
|
int optionName,
|
|
|
|
const char* optionValue,
|
|
|
|
int optionLength)
|
2011-02-23 01:37:42 +00:00
|
|
|
{
|
|
|
|
return setsockopt(socket, level, optionName, optionValue, optionLength);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT struct protoent* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetProtoByName)(char*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT struct hostent* JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetHostByAddr)(const char*, int, int)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT struct hostent* JNICALL EXPORT(JVM_GetHostByName)(char*)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetHostName)(char* name, int length)
|
2010-09-17 01:43:27 +00:00
|
|
|
{
|
|
|
|
return gethostname(name, length);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void* JNICALL EXPORT(JVM_RawMonitorCreate)(void)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
System* s = local::globalMachine->system;
|
|
|
|
System::Monitor* lock;
|
|
|
|
if (s->success(s->make(&lock))) {
|
|
|
|
return lock;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_RawMonitorDestroy)(void* lock)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
static_cast<System::Monitor*>(lock)->dispose();
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT jint JNICALL EXPORT(JVM_RawMonitorEnter)(void* lock)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
static_cast<System::Monitor*>(lock)
|
|
|
|
->acquire(static_cast<Thread*>(local::globalMachine->localThread->get())
|
|
|
|
->systemThread);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL EXPORT(JVM_RawMonitorExit)(void* lock)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
static_cast<System::Monitor*>(lock)
|
|
|
|
->release(static_cast<Thread*>(local::globalMachine->localThread->get())
|
|
|
|
->systemThread);
|
2010-09-10 21:05:29 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
int JNICALL GetVersion(Thread*)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
|
|
|
return JMM_VERSION_1_0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t getInputArgumentArray(Thread* t, uintptr_t*)
|
2011-08-06 00:06:29 +00:00
|
|
|
{
|
2014-07-11 15:47:57 +00:00
|
|
|
object array
|
|
|
|
= makeObjectArray(t, type(t, GcString::Type), t->m->argumentCount);
|
2011-08-06 00:06:29 +00:00
|
|
|
PROTECT(t, array);
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < t->m->argumentCount; ++i) {
|
2014-06-28 23:24:24 +00:00
|
|
|
GcString* argument = makeString(t, t->m->arguments[i]);
|
2014-07-02 21:11:27 +00:00
|
|
|
setField(t, array, ArrayBody + (i * BytesPerWord), argument);
|
2011-08-06 00:06:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(t, array));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray JNICALL GetInputArgumentArray(Thread* t)
|
2011-08-06 00:06:29 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<jobjectArray>(run(t, getInputArgumentArray, 0));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jint JNICALL GetOptionalSupport(Thread*, jmmOptionalSupport* support)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
|
|
|
memset(support, 0, sizeof(jmmOptionalSupport));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jlong JNICALL GetLongAttribute(Thread* t, jobject, jmmLongAttribute attribute)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
|
|
|
const unsigned JMM_JVM_INIT_DONE_TIME_MS = 7;
|
|
|
|
|
|
|
|
switch (attribute) {
|
|
|
|
case JMM_JVM_INIT_DONE_TIME_MS:
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
default:
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jboolean JNICALL GetBoolAttribute(Thread* t, jmmBoolAttribute attribute)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
|
|
|
const unsigned JMM_THREAD_CPU_TIME = 24;
|
2012-02-22 00:32:20 +00:00
|
|
|
const unsigned JMM_THREAD_ALLOCATED_MEMORY = 25;
|
2011-04-10 03:17:15 +00:00
|
|
|
|
|
|
|
switch (attribute) {
|
|
|
|
case JMM_THREAD_CPU_TIME:
|
2012-02-22 00:32:20 +00:00
|
|
|
case JMM_THREAD_ALLOCATED_MEMORY:
|
2011-04-10 03:17:15 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
default:
|
|
|
|
abort(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t getMemoryManagers(Thread* t, uintptr_t*)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
2014-05-29 04:17:25 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeObjectArray(t,
|
|
|
|
resolveClass(t,
|
2014-06-30 01:44:41 +00:00
|
|
|
roots(t)->bootLoader(),
|
2014-05-29 04:17:25 +00:00
|
|
|
"java/lang/management/MemoryManagerMXBean"),
|
|
|
|
0)));
|
2011-04-10 03:17:15 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray JNICALL GetMemoryManagers(Thread* t, jobject)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<jobjectArray>(run(t, getMemoryManagers, 0));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t getMemoryPools(Thread* t, uintptr_t*)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
2014-05-29 04:17:25 +00:00
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(
|
|
|
|
t,
|
|
|
|
makeObjectArray(t,
|
|
|
|
resolveClass(t,
|
2014-06-30 01:44:41 +00:00
|
|
|
roots(t)->bootLoader(),
|
2014-05-29 04:17:25 +00:00
|
|
|
"java/lang/management/MemoryPoolMXBean"),
|
|
|
|
0)));
|
2011-04-10 03:17:15 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
jobjectArray JNICALL GetMemoryPools(Thread* t, jobject)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<jobjectArray>(run(t, getMemoryPools, 0));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void* JNICALL EXPORT(JVM_GetManagement)(jint version)
|
2011-04-10 03:17:15 +00:00
|
|
|
{
|
|
|
|
if (version == JMM_VERSION_1_0) {
|
2014-07-11 15:50:18 +00:00
|
|
|
JmmInterface* interface = &(static_cast<MyClasspath*>(
|
|
|
|
local::globalMachine->classpath)
|
|
|
|
->jmmInterface);
|
2011-04-10 03:17:15 +00:00
|
|
|
|
|
|
|
memset(interface, 0, sizeof(JmmInterface));
|
|
|
|
|
|
|
|
interface->GetVersion = GetVersion;
|
|
|
|
interface->GetOptionalSupport = GetOptionalSupport;
|
|
|
|
interface->GetLongAttribute = GetLongAttribute;
|
|
|
|
interface->GetBoolAttribute = GetBoolAttribute;
|
|
|
|
interface->GetMemoryManagers = GetMemoryManagers;
|
|
|
|
interface->GetMemoryPools = GetMemoryPools;
|
2011-08-06 00:06:29 +00:00
|
|
|
interface->GetInputArgumentArray = GetInputArgumentArray;
|
2011-04-10 03:17:15 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return interface;
|
2011-04-10 03:17:15 +00:00
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobject JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_InitAgentProperties)(Thread*, jobject)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
uint64_t getEnclosingMethodInfo(Thread* t, uintptr_t* arguments)
|
2011-02-25 15:17:15 +00:00
|
|
|
{
|
2013-04-17 21:12:58 +00:00
|
|
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClass* class_ = (*c)->vmClass();
|
2013-04-17 21:12:58 +00:00
|
|
|
PROTECT(t, class_);
|
|
|
|
|
2014-06-29 02:44:36 +00:00
|
|
|
GcClassAddendum* addendum = class_->addendum();
|
2013-04-17 21:12:58 +00:00
|
|
|
if (addendum) {
|
2014-06-29 02:44:36 +00:00
|
|
|
object enclosingClass = addendum->enclosingClass();
|
2013-04-17 21:12:58 +00:00
|
|
|
if (enclosingClass) {
|
|
|
|
PROTECT(t, enclosingClass);
|
|
|
|
|
2014-05-29 04:17:25 +00:00
|
|
|
object array = makeObjectArray(t, type(t, GcJobject::Type), 3);
|
2013-04-17 21:12:58 +00:00
|
|
|
PROTECT(t, array);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
enclosingClass = getJClass(
|
|
|
|
t,
|
|
|
|
resolveClass(
|
|
|
|
t, class_->loader(), cast<GcByteArray>(t, enclosingClass)));
|
2014-05-29 04:17:25 +00:00
|
|
|
|
2014-06-26 02:17:27 +00:00
|
|
|
setField(t, array, ArrayBody, enclosingClass);
|
2013-04-17 21:12:58 +00:00
|
|
|
|
2014-06-27 00:17:46 +00:00
|
|
|
GcPair* enclosingMethod = cast<GcPair>(t, addendum->enclosingMethod());
|
2013-04-17 21:12:58 +00:00
|
|
|
|
|
|
|
if (enclosingMethod) {
|
|
|
|
PROTECT(t, enclosingMethod);
|
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcString* name = t->m->classpath->makeString(
|
|
|
|
t,
|
|
|
|
enclosingMethod->first(),
|
|
|
|
0,
|
|
|
|
cast<GcByteArray>(t, enclosingMethod->first())->length() - 1);
|
2013-04-17 21:12:58 +00:00
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
setField(t, array, ArrayBody + BytesPerWord, name);
|
2013-04-17 21:12:58 +00:00
|
|
|
|
2014-07-11 15:47:57 +00:00
|
|
|
GcString* spec = t->m->classpath->makeString(
|
|
|
|
t,
|
|
|
|
enclosingMethod->second(),
|
|
|
|
0,
|
|
|
|
cast<GcByteArray>(t, enclosingMethod->second())->length() - 1);
|
2013-04-17 21:12:58 +00:00
|
|
|
|
2014-07-02 21:11:27 +00:00
|
|
|
setField(t, array, ArrayBody + (2 * BytesPerWord), spec);
|
2013-04-17 21:12:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return reinterpret_cast<uintptr_t>(makeLocalReference(t, array));
|
|
|
|
}
|
|
|
|
}
|
2011-02-25 15:17:15 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetEnclosingMethodInfo)(Thread* t, jclass c)
|
2013-04-17 21:12:58 +00:00
|
|
|
{
|
2014-07-11 15:50:18 +00:00
|
|
|
uintptr_t arguments[] = {reinterpret_cast<uintptr_t>(c)};
|
2013-04-17 21:12:58 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
return reinterpret_cast<jobjectArray>(
|
|
|
|
run(t, getEnclosingMethodInfo, arguments));
|
2013-04-17 21:12:58 +00:00
|
|
|
}
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jintArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetThreadStateValues)(JNIEnv*, jint)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jobjectArray JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetThreadStateNames)(JNIEnv*, jint, jintArray)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_GetVersionInfo)(JNIEnv*,
|
|
|
|
local::jvm_version_info* info,
|
|
|
|
size_t size)
|
2012-02-18 22:17:10 +00:00
|
|
|
{
|
|
|
|
memset(info, 0, size);
|
|
|
|
info->jvm_version = 0x01070000;
|
|
|
|
}
|
2010-11-07 17:08:04 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT jboolean JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_CX8Field)(JNIEnv*, jobject*, jfieldID*, jlong, jlong)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT void JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
EXPORT(JVM_SetNativeThreadName)(JNIEnv*, jobject, jstring)
|
|
|
|
{
|
|
|
|
abort();
|
|
|
|
}
|
2012-03-11 22:26:46 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
} // namespace local
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
} // namespace
|
2010-12-27 22:55:23 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT int jio_vsnprintf(char* dst,
|
|
|
|
size_t size,
|
|
|
|
const char* format,
|
|
|
|
va_list a)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
|
|
|
return vm::vsnprintf(dst, size, format, a);
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT int jio_vfprintf(FILE* stream,
|
|
|
|
const char* format,
|
|
|
|
va_list a)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
return vfprintf(stream, format, a);
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT void* JNICALL EXPORT(JVM_GetThreadInterruptEvent)()
|
2012-03-13 16:31:08 +00:00
|
|
|
{
|
|
|
|
// hack: We don't want to expose thread interruption implementation
|
|
|
|
// details, so we give the class library a fake event to play with.
|
|
|
|
// This means that threads won't be interruptable when blocked in
|
|
|
|
// Process.waitFor.
|
|
|
|
static HANDLE fake = 0;
|
|
|
|
if (fake == 0) {
|
|
|
|
fake = CreateEvent(0, true, false, 0);
|
|
|
|
}
|
|
|
|
return fake;
|
|
|
|
}
|
2010-11-07 19:24:40 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
namespace {
|
|
|
|
HMODULE jvmHandle = 0;
|
|
|
|
}
|
2010-11-07 19:24:40 +00:00
|
|
|
|
|
|
|
extern "C" int JDK_InitJvmHandle()
|
|
|
|
{
|
|
|
|
jvmHandle = GetModuleHandle(0);
|
|
|
|
return jvmHandle != 0;
|
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
|
2010-11-07 19:24:40 +00:00
|
|
|
extern "C" void* JDK_FindJvmEntry(const char* name)
|
|
|
|
{
|
|
|
|
return voidPointer(GetProcAddress(jvmHandle, name));
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
#ifdef AVIAN_OPENJDK_SRC
|
2010-11-07 19:24:40 +00:00
|
|
|
|
|
|
|
extern "C" char* findJavaTZ_md(const char*, const char*);
|
|
|
|
|
2013-11-08 15:35:10 +00:00
|
|
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
2014-07-11 15:50:18 +00:00
|
|
|
Avian_java_util_TimeZone_getSystemTimeZoneID(Thread* t,
|
|
|
|
object,
|
|
|
|
uintptr_t* arguments)
|
2010-11-07 19:24:40 +00:00
|
|
|
{
|
|
|
|
// On Windows, findJavaTZ_md loads tzmappings from the filesystem
|
|
|
|
// using fopen, so we have no opportunity to make it read straight
|
|
|
|
// from the embedded JAR file as with files read from Java code.
|
|
|
|
// Therefore, we must extract tzmappings to a temporary location
|
|
|
|
// before calling findJavaTZ_md. We could avoid this by
|
|
|
|
// implementing findJavaTZ_md ourselves from scratch, but that would
|
|
|
|
// be a lot of code to implement and maintain.
|
|
|
|
|
2014-08-19 17:49:18 +00:00
|
|
|
GcString* country = cast<GcString>(t, reinterpret_cast<object>(arguments[1]));
|
2010-11-07 19:24:40 +00:00
|
|
|
|
2014-08-19 17:49:18 +00:00
|
|
|
THREAD_RUNTIME_ARRAY(t, char, countryChars, country->length(t) + 1);
|
2010-11-07 19:24:40 +00:00
|
|
|
stringChars(t, country, RUNTIME_ARRAY_BODY(countryChars));
|
|
|
|
|
|
|
|
local::MyClasspath* cp = static_cast<local::MyClasspath*>(t->m->classpath);
|
|
|
|
|
|
|
|
local::EmbeddedFile ef(cp, cp->tzMappings, cp->tzMappingsLength);
|
|
|
|
if (ef.jar == 0 or ef.jarLength == 0 or ef.pathLength == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-03-26 15:53:47 +00:00
|
|
|
Finder* finder = getFinder(t, ef.jar, ef.jarLength);
|
2010-11-07 19:24:40 +00:00
|
|
|
if (finder == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
System::Region* r = finder->find(ef.path);
|
|
|
|
if (r == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-12-27 22:55:23 +00:00
|
|
|
THREAD_RESOURCE(t, System::Region*, r, r->dispose());
|
2010-11-07 19:24:40 +00:00
|
|
|
|
|
|
|
char tmpPath[MAX_PATH + 1];
|
|
|
|
GetTempPathA(MAX_PATH, tmpPath);
|
|
|
|
|
|
|
|
char tmpDir[MAX_PATH + 1];
|
|
|
|
vm::snprintf(tmpDir, MAX_PATH, "%s/avian-tmp", tmpPath);
|
|
|
|
if (_mkdir(tmpDir) != 0 and errno != EEXIST) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
THREAD_RESOURCE(t, char*, tmpDir, rmdir(tmpDir));
|
2010-11-07 19:24:40 +00:00
|
|
|
|
|
|
|
char libDir[MAX_PATH + 1];
|
|
|
|
vm::snprintf(libDir, MAX_PATH, "%s/lib", tmpDir);
|
|
|
|
if (mkdir(libDir) != 0 and errno != EEXIST) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
THREAD_RESOURCE(t, char*, libDir, rmdir(libDir));
|
2010-11-07 19:24:40 +00:00
|
|
|
|
|
|
|
char file[MAX_PATH + 1];
|
|
|
|
vm::snprintf(file, MAX_PATH, "%s/tzmappings", libDir);
|
|
|
|
FILE* out = vm::fopen(file, "wb");
|
|
|
|
if (out == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
|
|
|
|
THREAD_RESOURCE(t, char*, file, unlink(file));
|
2010-12-27 22:55:23 +00:00
|
|
|
THREAD_RESOURCE(t, FILE*, out, fclose(out));
|
2010-11-07 19:24:40 +00:00
|
|
|
|
|
|
|
if (fwrite(r->start(), 1, r->length(), out) != r->length()
|
2014-07-11 15:50:18 +00:00
|
|
|
or fflush(out) != 0) {
|
2010-11-07 19:24:40 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* javaTZ = findJavaTZ_md(tmpDir, RUNTIME_ARRAY_BODY(countryChars));
|
|
|
|
if (javaTZ) {
|
2010-12-27 22:55:23 +00:00
|
|
|
THREAD_RESOURCE(t, char*, javaTZ, free(javaTZ));
|
|
|
|
|
|
|
|
return reinterpret_cast<int64_t>(makeString(t, "%s", javaTZ));
|
2010-11-07 19:24:40 +00:00
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
#else // not AVIAN_OPENJDK_SRC
|
|
|
|
extern "C" AVIAN_EXPORT int jio_snprintf(char* dst,
|
|
|
|
size_t size,
|
|
|
|
const char* format,
|
|
|
|
...)
|
2010-11-07 17:08:04 +00:00
|
|
|
{
|
|
|
|
va_list a;
|
|
|
|
va_start(a, format);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
int r = jio_vsnprintf(dst, size, format, a);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
va_end(a);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2014-07-11 15:50:18 +00:00
|
|
|
extern "C" AVIAN_EXPORT int jio_fprintf(FILE* stream, const char* format, ...)
|
2010-09-10 21:05:29 +00:00
|
|
|
{
|
2010-11-07 17:08:04 +00:00
|
|
|
va_list a;
|
|
|
|
va_start(a, format);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
int r = jio_vfprintf(stream, format, a);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
va_end(a);
|
2010-09-10 21:05:29 +00:00
|
|
|
|
2010-11-07 17:08:04 +00:00
|
|
|
return r;
|
|
|
|
}
|
2014-07-11 15:50:18 +00:00
|
|
|
#endif // not AVIAN_OPENJDK_SRC
|
|
|
|
#endif // PLATFORM_WINDOWS
|