Windows Phone 8 / Windows RT initial support

Conflicts:

	makefile
This commit is contained in:
Alexey Pelykh 2013-01-28 17:20:52 +02:00
parent cc237b94c4
commit 2f2cac556c
13 changed files with 912 additions and 126 deletions

View File

@ -83,6 +83,16 @@ typedef char char_t;
#endif // not PLATFORM_WINDOWS
#ifndef WINAPI_FAMILY
# ifndef WINAPI_PARTITION_DESKTOP
# define WINAPI_PARTITION_DESKTOP 1
# endif
# ifndef WINAPI_FAMILY_PARTITION
# define WINAPI_FAMILY_PARTITION(x) (x)
# endif
#endif // WINAPI_FAMILY
inline void* operator new(size_t, void* p) throw() { return p; }
typedef const char_t* string_t;
@ -214,6 +224,7 @@ extern "C" JNIEXPORT jstring JNICALL
Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
{
#ifdef PLATFORM_WINDOWS
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
string_t chars = getChars(e, path);
if (chars) {
const unsigned BufferSize = MAX_PATH;
@ -228,6 +239,11 @@ Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path)
}
return path;
# else
// WinRT has no concept of full paths
throwNewErrno(e, "java/io/IOException");
return path;
# endif
#else
jstring result = path;
string_t chars = getChars(e, path);
@ -256,11 +272,24 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
LARGE_INTEGER fileSize;
string_t chars = getChars(e, path);
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE file = CreateFileW
(chars, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
#else
HANDLE file = CreateFile2
(chars, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
#endif
releaseChars(e, path, chars);
if (file != INVALID_HANDLE_VALUE)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
GetFileSizeEx(file, &fileSize);
#else
FILE_STANDARD_INFO info;
if(GetFileInformationByHandleEx(file, FileStandardInfo, &info, sizeof(info)))
fileSize = info.EndOfFile;
#endif
}
else return 0;
CloseHandle(file);
return static_cast<jlong>(fileSize.QuadPart);
@ -496,7 +525,11 @@ Java_java_io_File_openDir(JNIEnv* e, jclass, jstring path)
releaseChars(e, path, chars);
Directory* d = new (malloc(sizeof(Directory))) Directory;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
d->handle = FindFirstFileW(RUNTIME_ARRAY_BODY(buffer), &(d->data));
#else
d->handle = FindFirstFileExW(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, NULL, 0);
#endif
if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose();
d = 0;
@ -725,7 +758,11 @@ Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
uint8_t* dst = reinterpret_cast<uint8_t*>
(e->GetPrimitiveArrayCritical(buffer, 0));
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
ssize_t bytesRead = ::read(fd, dst + offset, length);
#else
auto bytesRead = ::read(fd, dst + offset, length);
#endif
e->ReleasePrimitiveArrayCritical(buffer, dst, 0);
if(bytesRead == -1) {
@ -737,7 +774,7 @@ Java_java_io_RandomAccessFile_readBytes(JNIEnv* e, jclass, jlong peer,
}
extern "C" JNIEXPORT void JNICALL
Java_java_io_RandomAccessFile_close(JNIEnv*/* e*/, jclass, jlong peer)
Java_java_io_RandomAccessFile_close(JNIEnv* /* e*/, jclass, jlong peer)
{
int fd = (int)peer;
::close(fd);

View File

@ -62,6 +62,16 @@
#endif // not PLATFORM_WINDOWS
#ifndef WINAPI_FAMILY
# ifndef WINAPI_PARTITION_DESKTOP
# define WINAPI_PARTITION_DESKTOP 1
# endif
# ifndef WINAPI_FAMILY_PARTITION
# define WINAPI_FAMILY_PARTITION(x) (x)
# endif
#endif // WINAPI_FAMILY
namespace {
#ifdef PLATFORM_WINDOWS
char* getErrorStr(DWORD err){
@ -70,7 +80,8 @@ namespace {
snprintf(errStr, 9, "%d", (int) err);
return errStr;
// The better way to do this, if I could figure out how to convert LPTSTR to char*
//TODO:
// The better way to do this, if I could figure out how to convert LPTSTR to char*
//char* errStr;
//LPTSTR s;
//if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
@ -83,6 +94,7 @@ namespace {
//return errStr;
}
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
void makePipe(JNIEnv* e, HANDLE p[2])
{
SECURITY_ATTRIBUTES sa;
@ -95,6 +107,7 @@ namespace {
throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
}
}
#endif
int descriptor(JNIEnv* e, HANDLE h)
{
@ -196,7 +209,7 @@ extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
jobjectArray command, jlongArray process)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int size = 0;
for (int i = 0; i < e->GetArrayLength(command); ++i){
jstring element = (jstring) e->GetObjectArrayElement(command, i);
@ -267,11 +280,15 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
e->SetLongArrayRegion(process, 0, 1, &pid);
jlong tid = reinterpret_cast<jlong>(pi.hThread);
e->SetLongArrayRegion(process, 1, 1, &tid);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
DWORD exitCode;
WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
@ -283,14 +300,23 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
CloseHandle(reinterpret_cast<HANDLE>(tid));
return exitCode;
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
return -1;
#endif
}
extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_kill(JNIEnv*, jclass, jlong pid) {
Java_java_lang_Runtime_kill(JNIEnv* e UNUSED, jclass, jlong pid) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TerminateProcess(reinterpret_cast<HANDLE>(pid), 1);
#else
throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}
Locale getLocale() {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
const char* lang = "";
const char* reg = "";
unsigned langid = GetUserDefaultUILanguage();
@ -362,8 +388,11 @@ Locale getLocale() {
default: lang = "en";
}
Locale locale(lang, reg);
return locale;
return Locale(lang, reg);
#else
//TODO: CultureInfo.CurrentCulture
return Locale("en", "US");
#endif
}
#else
extern "C" JNIEXPORT void JNICALL
@ -531,8 +560,15 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
} else if (strcmp(chars, "file.separator") == 0) {
r = e->NewStringUTF("\\");
} else if (strcmp(chars, "os.name") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
r = e->NewStringUTF("Windows");
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE)
r = e->NewStringUTF("Windows Phone");
# else
r = e->NewStringUTF("Windows RT");
# endif
} else if (strcmp(chars, "os.version") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
unsigned size = 32;
RUNTIME_ARRAY(char, buffer, size);
OSVERSIONINFO OSversion;
@ -540,6 +576,10 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
::GetVersionEx(&OSversion);
snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%i.%i", (int)OSversion.dwMajorVersion, (int)OSversion.dwMinorVersion);
r = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer));
# else
// Currently there is no alternative on WinRT/WP8
r = e->NewStringUTF("8.0");
# endif
} else if (strcmp(chars, "os.arch") == 0) {
#ifdef ARCH_x86_32
r = e->NewStringUTF("x86");
@ -551,15 +591,28 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
r = e->NewStringUTF("arm");
#endif
} else if (strcmp(chars, "java.io.tmpdir") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TCHAR buffer[MAX_PATH];
GetTempPath(MAX_PATH, buffer);
r = e->NewStringUTF(buffer);
# else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.Storage.ApplicationData.Current.TemporaryFolder
r = 0;
# endif
} else if (strcmp(chars, "user.dir") == 0) {
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
TCHAR buffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buffer);
r = e->NewStringUTF(buffer);
# else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.ApplicationModel.Package.Current.InstalledLocation
r = 0;
# endif
} else if (strcmp(chars, "user.home") == 0) {
# ifdef _MSC_VER
# if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WCHAR buffer[MAX_PATH];
size_t needed;
if (_wgetenv_s(&needed, buffer, MAX_PATH, L"USERPROFILE") == 0) {
@ -567,6 +620,11 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
} else {
r = 0;
}
# else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.Storage.KnownFolders.DocumentsLibrary;
r = 0;
# endif
# else
LPWSTR home = _wgetenv(L"USERPROFILE");
r = e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
@ -654,6 +712,9 @@ namespace {
#elif defined __APPLE__
# include <crt_externs.h>
# define environ (*_NSGetEnviron())
#elif defined(WINAPI_FAMILY) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// WinRT/WP8 does not provide alternative for environment variables
char* environ[] = { 0 };
#else
extern char** environ;
#endif

401
makefile
View File

@ -51,7 +51,7 @@ ifeq ($(continuations),true)
endif
root := $(shell (cd .. && pwd))
build = build/$(platform)-$(arch)$(options)
build = $(build-prefix)build/$(platform)-$(arch)$(options)
classpath-build = $(build)/classpath
test-build = $(build)/test
src = src
@ -59,6 +59,8 @@ classpath-src = classpath
test = test
win32 ?= $(root)/win32
win64 ?= $(root)/win64
winrt ?= $(root)/winrt
wp8 ?= $(root)/wp8
classpath = avian
@ -183,6 +185,18 @@ strip-all = --strip-all
rdynamic = -rdynamic
cflags_debug = -O0 -g3
cflags_debug_fast = -O0 -g3
cflags_stress = -O0 -g3
cflags_stress_major = -O0 -g3
ifeq ($(use-clang),true)
cflags_fast = -O4 -g3
cflags_small = -Oz -g3
else
cflags_fast = -O3 -g3
cflags_small = -Os -g3
endif
# note that we suppress the non-virtual-dtor warning because we never
# use the delete operator, which means we don't need virtual
# destructors:
@ -198,7 +212,7 @@ common-cflags = $(warnings) -fno-rtti -fno-exceptions -I$(classpath-src) \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags)
asmflags = $(target-cflags)
asmflags = $(target-cflags) -I$(src)
ifneq (,$(filter i386 x86_64,$(arch)))
ifeq ($(use-frame-pointer),true)
@ -237,6 +251,18 @@ pointer-size = 8
so-prefix = lib
so-suffix = .so
static-prefix = lib
static-suffix = .a
output = -o $(1)
asm-output = -o $(1)
asm-input = -c $(1)
asm-format = S
as = $(cc)
ld = $(cxx)
build-ld = $(build-cc)
static = -static
shared = -shared
no-error = -Wno-error
@ -244,6 +270,8 @@ no-error = -Wno-error
openjdk-extra-cflags = -fvisibility=hidden
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
bootimage-symbols = _binary_bootimage_bin_start:_binary_bootimage_bin_end
codeimage-symbols = _binary_codeimage_bin_start:_binary_codeimage_bin_end
developer-dir := $(shell if test -d /Developer; then echo /Developer; \
else echo /Applications/Xcode.app/Contents/Developer; fi)
@ -354,41 +382,68 @@ ifeq ($(platform),freebsd)
cflags = $(build-cflags)
endif
ifeq ($(platform),android)
asm = arm
pointer-size = 4
no-psabi = -Wno-psabi
use-lto = false
ifeq ($(build-platform),cygwin)
ifeq ($(build-platform),cygwin)
ndk = "$$(cygpath -u "$(ANDROID_NDK)")"
else
ndk = $(ANDROID_NDK)
endif
ifeq ($(android-version),)
android-version = 5
endif
ifeq ($(android-toolchain),)
android-toolchain = 4.7
endif
ifeq ($(arch),arm)
android-toolchain-name = arm-linux-androideabi
android-toolchain-prefix = arm-linux-androideabi-
endif
ifeq ($(arch),i386)
android-toolchain-name = x86
android-toolchain-prefix = i686-linux-android-
endif
ifeq ($(android-arm-arch),)
android-arm-arch = armv5
endif
options := $(options)-api$(android-version)-$(android-toolchain)-$(android-arm-arch)
build-cflags = $(common-cflags) -I$(src)
#build-lflags = -lz -lpthread -ldl
build-lflags = -lz -lpthread
ifeq ($(subst cygwin,windows,$(subst mingw32,windows,$(build-platform))),windows)
toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))
build-system = windows
build-cxx = i686-w64-mingw32-g++
build-cc = i686-w64-mingw32-gcc
sysroot = "$$(cygpath -w "$(ndk)/platforms/android-5/arch-arm")"
sysroot = "$$(cygpath -w "$(ndk)/platforms/android-$(android-version)/arch-arm")"
build-cflags += "-I$(JAVA_HOME)/include/win32"
else
toolchain-host-platform = $(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))-*
sysroot = $(ndk)/platforms/android-5/arch-arm
sysroot = $(ndk)/platforms/android-$(android-version)/arch-arm
build-cflags += "-I$(JAVA_HOME)/include/linux"
build-lflags += -ldl
endif
toolchain = $(ndk)/toolchains/arm-linux-androideabi-4.7/prebuilt/$(toolchain-host-platform)
cflags = "-I$(sysroot)/usr/include" "-I$(JAVA_HOME)/include/linux" $(common-cflags) "-I$(src)" -std=c++11 -marm $(no-psabi)
lflags = "-L$(sysroot)/usr/lib" $(common-lflags) -ldl
toolchain = $(ndk)/toolchains/$(android-toolchain-name)-$(android-toolchain)/prebuilt/$(toolchain-host-platform)
cflags = "-I$(sysroot)/usr/include" "-I$(JAVA_HOME)/include/linux" $(common-cflags) "-I$(src)" -std=c++11 $(no-psabi)
lflags = "-L$(sysroot)/usr/lib" $(common-lflags) -llog
target-format = elf
use-lto = false
cxx = $(toolchain)/bin/arm-linux-androideabi-g++ --sysroot="$(sysroot)"
cc = $(toolchain)/bin/arm-linux-androideabi-gcc --sysroot="$(sysroot)"
as = $(toolchain)/bin/arm-linux-androideabi-as --sysroot="$(sysroot)"
ar = $(toolchain)/bin/arm-linux-androideabi-ar
ranlib = $(toolchain)/bin/arm-linux-androideabi-ranlib
strip = $(toolchain)/bin/arm-linux-androideabi-strip
ifeq ($(arch),arm)
cflags += -marm -march=$(android-arm-arch) -ftree-vectorize -ffast-math -mfloat-abi=softfp
endif
ifeq ($(arch),i386)
endif
cxx = $(toolchain)/bin/$(android-toolchain-prefix)g++ --sysroot="$(sysroot)"
cc = $(toolchain)/bin/$(android-toolchain-prefix)gcc --sysroot="$(sysroot)"
as = $(cxx)
ar = $(toolchain)/bin/$(android-toolchain-prefix)ar
ranlib = $(toolchain)/bin/$(android-toolchain-prefix)ranlib
strip = $(toolchain)/bin/$(android-toolchain-prefix)strip
endif
ifeq ($(platform),darwin)
@ -475,7 +530,9 @@ ifeq ($(platform),darwin)
endif
ifeq ($(platform),windows)
target-format = pe
ifeq ($(target-format),)
target-format = pe
endif
inc = "$(win32)/include"
lib = "$(win32)/lib"
@ -488,7 +545,8 @@ ifeq ($(platform),windows)
so-suffix = .dll
exe-suffix = .exe
lflags = -L$(lib) $(common-lflags) -lws2_32 -liphlpapi -mwindows -mconsole
lflags = -L$(lib) $(common-lflags) -lws2_32 -liphlpapi -mconsole
bootimage-generator-lflags = -static-libstdc++ -static-libgcc
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
@ -539,39 +597,197 @@ ifeq ($(platform),windows)
embed-loader-o = $(build-embed)/embed-loader.o
endif
ifeq ($(platform),wp8)
ifeq ($(shell uname -s | grep -i -c WOW64),1)
programFiles = Program Files (x86)
else
programFiles = Program Files
endif
ifeq ($(MSVS_ROOT),)
# Environment variable MSVS_ROOT not found. It should be something like
# "C:\$(programFiles)\Microsoft Visual Studio 11.0"
MSVS_ROOT = C:\$(programFiles)\Microsoft Visual Studio 11.0
endif
ifeq ($(MSVC_ROOT),)
# Environment variable MSVC_ROOT not found. It should be something like
# "C:\$(programFiles)\Microsoft Visual Studio 11.0\VC"
MSVC_ROOT = $(MSVS_ROOT)\VC
endif
ifeq ($(WP80_SDK),)
# Environment variable WP8_SDK not found. It should be something like
# "C:\Program Files[ (x86)]\Microsoft Visual Studio 11.0\VC\WPSDK\WP80"
# TODO: Lookup in SOFTWARE\Microsoft\Microsoft SDKs\WindowsPhone\v8.0
WP80_SDK = C:\$(programFiles)\Microsoft Visual Studio 11.0\VC\WPSDK\WP80
endif
ifeq ($(WP80_KIT),)
# Environment variable WP8_KIT not found. It should be something like
# "c:\Program Files[ (x86)]\Windows Phone Kits\8.0"
# TODO: Lookup in SOFTWARE\Microsoft\Microsoft SDKs\WindowsPhone\v8.0
WP80_KIT = C:\$(programFiles)\Windows Phone Kits\8.0
endif
ifeq ($(WIN8_KIT),)
# Environment variable WIN8_KIT not found. It should be something like
# "c:\Program Files[ (x86)]\Windows Kits\8.0"
WIN8_KIT = C:\$(programFiles)\Windows Kits\8.0
endif
ifeq ($(build-platform),cygwin)
windows-path = cygpath -w
else
windows-path = $(native-path)
endif
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
target-format = pe
ms_cl_compiler = wp8
use-lto = false
supports_avian_executable = false
process = interpret
ifneq ($(process),compile)
options := -$(process)
endif
bootimage = true
ifeq ($(bootimage),true)
options := $(options)-bootimage
endif
system = windows
build-system = windows
static-prefix =
static-suffix = .lib
so-prefix =
so-suffix = .dll
exe-suffix = .exe
ifeq ($(arch),arm)
wp8_arch = \x86_arm
vc_arch = \arm
w8kit_arch = arm
deps_arch = ARM
as = "$$(cygpath -u "$(WP80_SDK)\bin\x86_arm\armasm.exe")"
cxx = "$$(cygpath -u "$(WP80_SDK)\bin\x86_arm\cl.exe")"
ld = "$$(cygpath -u "$(WP80_SDK)\bin\x86_arm\link.exe")"
asmflags = -machine ARM -32
asm-output = -o $(1)
asm-input = $(1)
machine_type = ARM
bootimage-symbols = binary_bootimage_bin_start:binary_bootimage_bin_end
codeimage-symbols = binary_codeimage_bin_start:binary_codeimage_bin_end
endif
ifeq ($(arch),i386)
wp8_arch =
vc_arch =
w8kit_arch = x86
deps_arch = x86
as = "$$(cygpath -u "$(WP80_SDK)\bin\ml.exe")"
cxx = "$$(cygpath -u "$(WP80_SDK)\bin\cl.exe")"
ld = "$$(cygpath -u "$(WP80_SDK)\bin\link.exe")"
asmflags += -nologo
asm-output = $(output)
machine_type = X86
endif
PATH := $(shell cygpath -u "$(MSVS_ROOT)\Common7\IDE"):$(shell cygpath -u "$(WP80_SDK)\bin$(wp8_arch)"):$(shell cygpath -u "$(WP80_SDK)\bin"):${PATH}
build-cflags = $(common-cflags) -I$(src) -I$(inc) -mthreads
build-lflags = -lz -lpthread
cflags = -nologo \
-I"$(WP80_SDK)\include" -I"$(WP80_KIT)\Include" -I"$(WP80_KIT)\Include\minwin" -I"$(WP80_KIT)\Include\mincore" \
-DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP \
-DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
-I"$(shell $(windows-path) "$(wp8)/zlib/upstream")" \
-Fd$(build)/$(name).pdb -I"$(shell $(windows-path) "$(wp8)/include")" -I$(src) -I$(classpath-src) \
-I"$(build)" \
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
-DTARGET_BYTES_PER_WORD=$(pointer-size)
common-lflags = $(classpath-lflags)
arflags = -MACHINE:$(machine_type)
lflags = $(common-lflags) -nologo \
-MACHINE:$(machine_type) \
-LIBPATH:"$(WP80_KIT)\lib\$(w8kit_arch)" -LIBPATH:"$(WIN8_KIT)\Lib\win8\um\$(w8kit_arch)" -LIBPATH:"$(MSVC_ROOT)\lib$(vc_arch)" \
ws2_32.lib \
"$(shell $(windows-path) "$(wp8)\lib\$(deps_arch)\zlib.lib")" "$(shell $(windows-path) "$(wp8)\lib\$(deps_arch)\ThreadEmulation.lib")"
cc = $(cxx)
asm-format = masm
shared = -dll
ar = "$$(cygpath -u "$(WP80_SDK)\bin\lib.exe")"
arflags += -nologo
ifeq ($(build-platform),cygwin)
build-cxx = i686-w64-mingw32-g++
build-cc = i686-w64-mingw32-gcc
dlltool = i686-w64-mingw32-dlltool
ranlib =
strip =
endif
output = -Fo$(1)
cflags_debug = -Od -Zi -MDd
cflags_debug_fast = -Od -Zi -MDd
cflags_stress = -O0 -g3 -MD
cflags_stress_major = -O0 -g3 -MD
cflags_fast = -O2 -Zi -MD
cflags_small = -O1s -Zi -MD
# -GL [whole program optimization] in 'fast' and 'small' breaks compilation for some reason
ifeq ($(mode),debug)
cflags +=
lflags +=
endif
ifeq ($(mode),debug-fast)
cflags += -DNDEBUG
lflags +=
endif
ifeq ($(mode),stress_major)
cflags +=
lflags +=
endif
ifeq ($(mode),fast)
cflags +=
lflags +=
endif
# -LTCG is needed only if -GL is used
ifeq ($(mode),fast)
cflags += -DNDEBUG
lflags += -LTCG
arflags +=
endif
ifeq ($(mode),small)
cflags += -DNDEBUG
lflags += -LTCG
arflags +=
endif
strip = :
endif
ifeq ($(mode),debug)
optimization-cflags = -O0 -g3
converter-cflags += -O0 -g3
optimization-cflags = $(cflags_debug)
converter-cflags += $(cflags_debug)
strip = :
endif
ifeq ($(mode),debug-fast)
optimization-cflags = -O0 -g3 -DNDEBUG
optimization-cflags = $(cflags_debug_fast) -DNDEBUG
strip = :
endif
ifeq ($(mode),stress)
optimization-cflags = -O0 -g3 -DVM_STRESS
optimization-cflags = $(cflags_stress) -DVM_STRESS
strip = :
endif
ifeq ($(mode),stress-major)
optimization-cflags = -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
optimization-cflags = $(cflags_stress_major) -DVM_STRESS -DVM_STRESS_MAJOR
strip = :
endif
ifeq ($(mode),fast)
ifeq ($(use-clang),true)
optimization-cflags = -O4 -g3 -DNDEBUG
else
optimization-cflags = -O3 -g3 -DNDEBUG
endif
optimization-cflags = $(cflags_fast) -DNDEBUG
ifeq ($(use-lto),)
use-lto = true
endif
endif
ifeq ($(mode),small)
ifeq ($(use-clang),true)
optimization-cflags = -Oz -g3 -DNDEBUG
else
optimization-cflags = -Os -g3 -DNDEBUG
endif
optimization-cflags = $(cflags_small) -DNDEBUG
ifeq ($(use-lto),)
use-lto = true
endif
@ -596,6 +812,7 @@ endif
cflags += $(optimization-cflags)
ifndef ms_cl_compiler
ifneq ($(platform),darwin)
ifeq ($(arch),i386)
# this is necessary to support __sync_bool_compare_and_swap:
@ -603,16 +820,9 @@ ifeq ($(arch),i386)
lflags += -march=i586
endif
endif
output = -o $(1)
as := $(cc)
ld := $(cc)
build-ld := $(build-cc)
static = -static
endif
ifdef msvc
static =
no-error =
windows-path = $(native-path)
windows-java-home := $(shell $(windows-path) "$(JAVA_HOME)")
@ -621,6 +831,7 @@ ifdef msvc
cc = $(cxx)
ld = "$(msvc)/BIN/link.exe"
mt = "mt.exe"
manifest-flags = -MANIFEST -MANIFESTFILE:$(@).manifest
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
@ -629,7 +840,7 @@ ifdef msvc
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32" \
-DTARGET_BYTES_PER_WORD=$(pointer-size)
ifneq ($(lzma),)
ifneq ($(lzma),)
cflags += -I$(shell $(windows-path) "$(lzma)")
endif
@ -656,9 +867,11 @@ ifdef msvc
strip = :
endif
build-cflags += -DAVIAN_HOST_TARGET
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.$(asm-format),$(3)/%-asm.o,$(x)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
generated-code = \
@ -684,7 +897,7 @@ vm-sources = \
$(src)/jnienv.cpp \
$(src)/process.cpp
vm-asm-sources = $(src)/$(asm).S
vm-asm-sources = $(src)/$(asm).$(asm-format)
target-asm = $(asm)
@ -702,8 +915,9 @@ ifeq ($(process),compile)
$(src)/compiler.cpp \
$(src)/$(target-asm).cpp
vm-asm-sources += $(src)/compile-$(asm).S
vm-asm-sources += $(src)/compile-$(asm).$(asm-format)
endif
cflags += -DAVIAN_PROCESS_$(process)
vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(build))
vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(build))
@ -835,7 +1049,7 @@ converter-objects = $(call cpp-objects,$(converter-sources),$(src),$(build))
converter-tool-objects = $(call cpp-objects,$(converter-tool-sources),$(src),$(build))
converter = $(build)/binaryToObject/binaryToObject
static-library = $(build)/lib$(name).a
static-library = $(build)/$(static-prefix)$(name)${static-suffix}
executable = $(build)/$(name)${exe-suffix}
dynamic-library = $(build)/$(so-prefix)jvm$(so-suffix)
executable-dynamic = $(build)/$(name)-dynamic${exe-suffix}
@ -945,9 +1159,15 @@ test-flags = -Djava.library.path=$(build) -cp $(build)/test
test-args = $(test-flags) $(input)
.PHONY: build
ifneq ($(supports_avian_executable),false)
build: $(static-library) $(executable) $(dynamic-library) $(lzma-loader) \
$(lzma-encoder) $(executable-dynamic) $(classpath-dep) $(test-dep) \
$(test-extra-dep) $(embed)
else
build: $(static-library) $(dynamic-library) $(lzma-loader) \
$(lzma-encoder) $(classpath-dep) $(test-dep) \
$(test-extra-dep) $(embed)
endif
$(test-dep): $(classpath-dep)
@ -992,7 +1212,7 @@ clean:
@echo "removing build"
rm -rf build
$(build)/compile-x86-asm.o: $(src)/continuations-x86.S
$(build)/compile-x86-asm.o: $(src)/continuations-x86.$(asm-format)
gen-arg = $(shell echo $(1) | sed -e 's:$(build)/type-\(.*\)\.cpp:\1:')
$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
@ -1043,7 +1263,7 @@ endef
define compile-asm-object
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(as) -I$(src) $(asmflags) -c $(<) -o $(@)
$(as) $(asmflags) $(call asm-output,$(@)) $(call asm-input,$(<))
endef
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
@ -1054,10 +1274,12 @@ $(test-cpp-objects): $(test-build)/%.o: $(test)/%.cpp $(vm-depends)
$(test-library): $(test-cpp-objects)
@echo "linking $(@)"
ifdef msvc
ifdef ms_cl_compiler
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(test-build)/$(name).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
-IMPLIB:$(test-build)/$(name).lib $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
endif
else
$(ld) $(^) $(shared) $(lflags) -o $(@)
endif
@ -1065,10 +1287,12 @@ endif
ifdef embed
$(embed): $(embed-objects) $(embed-loader-o)
@echo "building $(embed)"
ifdef msvc
ifdef ms_cl_compiler
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
-IMPLIB:$(@).lib $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(cxx) $(^) $(lflags) $(static) $(call output,$(@))
endif
@ -1086,10 +1310,12 @@ $(embed-loader-o): $(embed-loader) $(converter)
$(embed-loader): $(embed-loader-objects) $(static-library)
@mkdir -p $(dir $(@))
cd $(dir $(@)) && $(ar) x ../../../$(static-library)
ifdef msvc
ifdef ms_cl_compiler
$(ld) $(lflags) $(dir $(@))/*.o -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
-IMPLIB:$(@).lib $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(dlltool) -z $(addsuffix .def,$(basename $(@))) $(dir $(@))/*.o
$(dlltool) -d $(addsuffix .def,$(basename $(@))) -e $(addsuffix .exp,$(basename $(@)))
@ -1109,7 +1335,7 @@ $(build)/%.o: $(lzma)/C/%.c
@mkdir -p $(dir $(@))
$(cxx) $(cflags) $(no-error) -c $$($(windows-path) $(<)) $(call output,$(@))
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.$(asm-format)
$(compile-asm-object)
$(bootimage-generator-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
@ -1196,14 +1422,18 @@ $(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
@echo "creating $(@)"
rm -rf $(@)
ifdef ms_cl_compiler
$(ar) $(arflags) $(^) -out:$(@)
else
$(ar) cru $(@) $(^)
$(ranlib) $(@)
endif
$(bootimage-object) $(codeimage-object): $(bootimage-generator) \
$(build)/classpath.jar
$(bootimage-object) $(codeimage-object): $(bootimage-generator)
@echo "generating bootimage and codeimage binaries using $(<)"
$(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \
-bootimage-symbols _binary_bootimage_bin_start:_binary_bootimage_bin_end \
-codeimage-symbols _binary_codeimage_bin_start:_binary_codeimage_bin_end
-bootimage-symbols $(bootimage-symbols) \
-codeimage-symbols $(codeimage-symbols)
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
@ -1212,10 +1442,12 @@ executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(executable): $(executable-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
ifdef ms_cl_compiler
$(ld) $(lflags) $(executable-objects) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
-IMPLIB:$(@).lib $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(dlltool) -z $(@).def $(executable-objects)
$(dlltool) -d $(@).def -e $(@).exp
@ -1229,6 +1461,7 @@ endif
$(bootimage-generator): $(bootimage-generator-objects)
echo arch=$(arch) platform=$(platform)
$(MAKE) mode=$(mode) \
build-prefix=$(build)/host/ \
arch=$(build-arch) \
target-arch=$(arch) \
platform=$(bootimage-platform) \
@ -1247,17 +1480,19 @@ $(build-bootimage-generator): \
$(lzma-decode-objects) $(lzma-encode-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib \
-MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
ifdef ms_cl_compiler
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(dlltool) -z $(@).def $(^)
$(dlltool) -d $(@).def -e $(@).exp
$(ld) $(@).exp $(^) $(lflags) -o $(@)
$(ld) $(@).exp $(^) $(bootimage-generator-lflags) $(lflags) -o $(@)
endif
else
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
$(ld) $(^) $(rdynamic) $(bootimage-generator-lflags) $(lflags) -o $(@)
endif
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
@ -1265,10 +1500,12 @@ $(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
$(classpath-libraries) $(javahome-object) $(boot-javahome-object) \
$(lzma-decode-objects)
@echo "linking $(@)"
ifdef msvc
ifdef ms_cl_compiler
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(build)/$(name).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
-IMPLIB:$(build)/$(name).lib $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);2"
endif
else
$(ld) $(^) $(version-script-flag) $(soname-flag) \
$(shared) $(lflags) $(bootimage-lflags) \
@ -1280,11 +1517,13 @@ endif
# Ubuntu 11.10 which may be fixable without disabling LTO.
$(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library)
@echo "linking $(@)"
ifdef msvc
ifdef ms_cl_compiler
$(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \
-PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) -out:$(@) \
-MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
-PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) \
-out:$(@) $(manifest-flags)
ifdef mt
$(mt) -nologo -manifest $(@).manifest -outputresource:"$(@);1"
endif
else
$(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) $(no-lto) -Wl,-rpath=\$$ORIGIN -z origin -o $(@)
endif

View File

@ -71,33 +71,53 @@ namespace vm {
inline void
trap()
{
#ifdef _MSC_VER
__debugbreak();
#else
asm("bkpt");
#endif
}
#ifndef _MSC_VER
inline void
memoryBarrier()
{
asm("nop");
}
#endif
inline void
storeStoreMemoryBarrier()
{
#ifdef _MSC_VER
_ReadWriteBarrier();
#else
memoryBarrier();
#endif
}
inline void
storeLoadMemoryBarrier()
{
#ifdef _MSC_VER
MemoryBarrier();
#else
memoryBarrier();
#endif
}
inline void
loadMemoryBarrier()
{
#ifdef _MSC_VER
_ReadWriteBarrier();
#else
memoryBarrier();
#endif
}
#if defined(AVIAN_PROCESS_compile)
#if defined(__ANDROID__)
// http://code.google.com/p/android/issues/detail?id=1803
extern "C" void __clear_cache (void *beg __attribute__((__unused__)), void *end __attribute__((__unused__)));
@ -116,6 +136,8 @@ syncInstructionCache(const void* start, unsigned size)
#endif
}
#endif // AVIAN_PROCESS_compile
#ifndef __APPLE__
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
@ -160,7 +182,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned vfpIndex = 0;
unsigned vfpBackfillIndex UNUSED = 0;
uintptr_t stack[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding
uintptr_t* stack = new uintptr_t[(argumentCount * 8) / BytesPerWord]; // is > argumentSize to account for padding
unsigned stackIndex = 0;
unsigned ai = 0;
@ -250,10 +272,12 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
}
unsigned stackSize = stackIndex*BytesPerWord + ((stackIndex & 1) << 2);
return vmNativeCall
auto retVal = vmNativeCall
(function, stackSize, stack, stackIndex * BytesPerWord,
(gprIndex ? gprTable : 0),
(vfpIndex ? vfpTable : 0), returnType);
delete[] stack;
return retVal;
}
} // namespace vm

77
src/arm.masm Normal file
View File

@ -0,0 +1,77 @@
AREA text, CODE, ARM
EXPORT vmNativeCall [FUNC]
vmNativeCall
; arguments:
; r0 -> r4 : function
; r1 -> r5 : stackTotal
; r2 : memoryTable
; r3 : memoryCount
; [sp, #0] -> r6 : gprTable
mov ip, sp ; save stack frame
stmfd sp!, {r4-r6, lr} ; save clobbered non-volatile regs
; mv args into non-volatile regs
mov r4, r0
mov r5, r1
ldr r6, [ip]
; setup stack arguments if necessary
sub sp, sp, r5 ; allocate stack
mov ip, sp
loop
tst r3, r3
ldrne r0, [r2], #4
strne r0, [ip], #4
subne r3, r3, #4
bne loop
; setup argument registers if necessary
tst r6, r6
ldmneia r6, {r0-r3}
blx r4 ; call function
add sp, sp, r5 ; deallocate stack
ldmfd sp!, {r4-r6, pc} ; restore non-volatile regs and return
EXPORT vmJump [FUNC]
vmJump
mov lr, r0
ldr r0, [sp]
ldr r1, [sp, #4]
mov sp, r2
mov r8, r3
bx lr
CHECKPOINT_THREAD EQU 4
CHECKPOINT_STACK EQU 24
EXPORT vmRun [FUNC]
vmRun
; r0: function
; r1: arguments
; r2: checkpoint
stmfd sp!, {r4-r11, lr}
; align stack
sub sp, sp, #12
str sp, [r2, #CHECKPOINT_STACK]
mov r12, r0
ldr r0, [r2, #CHECKPOINT_THREAD]
blx r12
EXPORT vmRun_returnAddress [FUNC]
vmRun_returnAddress
add sp, sp, #12
ldmfd sp!, {r4-r11, lr}
bx lr
EXPORT vmTrap [FUNC]
vmTrap
bkpt 3
END

View File

@ -17,13 +17,17 @@
namespace {
#define IMAGE_SIZEOF_SHORT_NAME 8
// --- winnt.h ----
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_FILE_RELOCS_STRIPPED 1
#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_32BIT_MACHINE 256
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
#define IMAGE_SCN_ALIGN_1BYTES 0x100000
#define IMAGE_SCN_ALIGN_2BYTES 0x200000
@ -73,6 +77,7 @@ struct IMAGE_SYMBOL {
uint8_t StorageClass;
uint8_t NumberOfAuxSymbols;
} __attribute__((packed));
// --- winnt.h ----
inline unsigned
pad(unsigned n)
@ -82,7 +87,7 @@ pad(unsigned n)
using namespace avian::tools;
template<unsigned BytesPerWord>
template<unsigned BytesPerWord, PlatformInfo::Architecture Architecture>
class WindowsPlatform : public Platform {
public:
@ -202,12 +207,15 @@ public:
int machine;
int machineMask;
if (BytesPerWord == 8) {
if (Architecture == PlatformInfo::x86_64) {
machine = IMAGE_FILE_MACHINE_AMD64;
machineMask = 0;
} else { // if (BytesPerWord == 8)
} else if (Architecture == PlatformInfo::x86) {
machine = IMAGE_FILE_MACHINE_I386;
machineMask = IMAGE_FILE_32BIT_MACHINE;
} else if (Architecture == PlatformInfo::Arm) {
machine = IMAGE_FILE_MACHINE_ARMNT;
machineMask = IMAGE_FILE_32BIT_MACHINE;
}
int sectionMask;
@ -269,10 +277,11 @@ public:
}
WindowsPlatform():
Platform(PlatformInfo(PlatformInfo::Pe, BytesPerWord == 4 ? PlatformInfo::x86 : PlatformInfo::x86_64)) {}
Platform(PlatformInfo(PlatformInfo::Pe, Architecture)) {}
};
WindowsPlatform<4> windows32Platform;
WindowsPlatform<8> windows64Platform;
WindowsPlatform<4, PlatformInfo::x86> windows32Platform;
WindowsPlatform<8, PlatformInfo::x86_64> windows64Platform;
WindowsPlatform<4, PlatformInfo::Arm> windowsRtPlatform; // Windows Phone 8 and Windows RT
} // namespace

View File

@ -342,7 +342,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
unsigned count = s.read2() - 1;
if (count) {
Type types[count + 2];
Type* types = new Type[count + 2];
types[0] = Type_object;
types[1] = Type_intptr_t;
@ -410,6 +410,9 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
(t, typeMaps, hashMapFind
(t, root(t, Machine::PoolMap), c, objectHash, objectEqual), array,
objectHash);
delete[] types;
types = 0;
}
}
@ -420,7 +423,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
object fields = allFields(t, typeMaps, c, &count, &array);
PROTECT(t, fields);
Field memberFields[count + 1];
Field* memberFields = new Field[count + 1];
unsigned memberIndex;
unsigned buildMemberOffset;
@ -454,7 +457,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
const unsigned StaticHeader = 3;
Field staticFields[count + StaticHeader];
Field* staticFields = new Field[count + StaticHeader];
init(new (staticFields) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
@ -586,6 +589,12 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
hashMapInsert
(t, typeMaps, classStaticTable(t, c), array, objectHash);
}
delete[] memberFields;
memberFields = 0;
delete[] staticFields;
staticFields = 0;
}
}
}
@ -1334,7 +1343,7 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
}
++ count;
Field fields[count];
Field* fields = new Field[count];
init(new (fields) Field, Type_object, 0, BytesPerWord, 0,
TargetBytesPerWord);
@ -1462,6 +1471,9 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
hashMapInsert
(t, typeMaps, vm::type(t, static_cast<Machine::Type>(i)), array,
objectHash);
delete[] fields;
fields = 0;
}
constants = makeCodeImage
@ -1646,10 +1658,10 @@ writeBootImage2(Thread* t, OutputStream* bootimageOutput, OutputStream* codeOutp
Platform* platform = Platform::getPlatform(PlatformInfo((PlatformInfo::Format)AVIAN_TARGET_FORMAT, (PlatformInfo::Architecture)AVIAN_TARGET_ARCH));
// if(!platform) {
// fprintf(stderr, "unsupported platform: %s/%s\n", os, architecture);
// return false;
// }
if(!platform) {
fprintf(stderr, "unsupported platform: target-format = %d / target-arch = %d\n", AVIAN_TARGET_FORMAT, AVIAN_TARGET_ARCH);
abort();
}
SymbolInfo bootimageSymbols[] = {
SymbolInfo(0, bootimageStart),
@ -1768,7 +1780,7 @@ bool ArgParser::parse(int ac, const char** av) {
}
bool found = false;
for(Arg* arg = first; arg; arg = arg->next) {
if(strcmp(arg->name, &av[i][1]) == 0) {
if(::strcmp(arg->name, &av[i][1]) == 0) {
found = true;
if (arg->desc == 0) {
arg->value = "true";
@ -1905,20 +1917,26 @@ public:
exit(1);
}
# if AVIAN_TARGET_FORMAT != AVIAN_FORMAT_PE
# define SYMBOL_PREFIX "_"
# else
# define SYMBOL_PREFIX
# endif
if(!bootimageStart) {
bootimageStart = strdup("_binary_bootimage_bin_start");
bootimageStart = strdup(SYMBOL_PREFIX"binary_bootimage_bin_start");
}
if(!bootimageEnd) {
bootimageEnd = strdup("_binary_bootimage_bin_end");
bootimageEnd = strdup(SYMBOL_PREFIX"binary_bootimage_bin_end");
}
if(!codeimageStart) {
codeimageStart = strdup("_binary_codeimage_bin_start");
codeimageStart = strdup(SYMBOL_PREFIX"binary_codeimage_bin_start");
}
if(!codeimageEnd) {
codeimageEnd = strdup("_binary_codeimage_bin_end");
codeimageEnd = strdup(SYMBOL_PREFIX"binary_codeimage_bin_end");
}
}

View File

@ -94,7 +94,13 @@ typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
# define UINT64_C(x) x##L
# define ARCH_x86_64
@ define BYTES_PER_WORD 8
# define BYTES_PER_WORD 8
# elif defined _M_ARM_FP
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
# define UINT64_C(x) x##LL
# define ARCH_arm
# define BYTES_PER_WORD 4
# else
# error "unsupported architecture"
# endif

View File

@ -18,7 +18,7 @@
using namespace vm;
namespace {
namespace local {
const unsigned FrameBaseOffset = 0;
const unsigned FrameNextOffset = 1;
@ -2321,7 +2321,7 @@ interpret3(Thread* t, const int base)
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
PROTECT(t, class_);
int32_t counts[dimensions];
int32_t* counts = new int32_t[dimensions];
for (int i = dimensions - 1; i >= 0; --i) {
counts[i] = popInt(t);
if (UNLIKELY(counts[i] < 0)) {
@ -2338,6 +2338,9 @@ interpret3(Thread* t, const int base)
populateMultiArray(t, array, counts, 0, dimensions);
pushObject(t, array);
delete[] counts;
counts = 0;
} goto loop;
case new_: {
@ -3100,7 +3103,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments);
return ::invoke(t, method);
return local::invoke(t, method);
}
virtual object
@ -3124,7 +3127,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments);
return ::invoke(t, method);
return local::invoke(t, method);
}
virtual object
@ -3148,7 +3151,7 @@ class MyProcessor: public Processor {
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, indirectObjects, arguments);
return ::invoke(t, method);
return local::invoke(t, method);
}
virtual object
@ -3174,7 +3177,7 @@ class MyProcessor: public Processor {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
return ::invoke(t, method);
return local::invoke(t, method);
}
virtual object getStackTrace(vm::Thread* t, vm::Thread*) {
@ -3254,8 +3257,8 @@ namespace vm {
Processor*
makeProcessor(System* system, Allocator* allocator, bool)
{
return new (allocator->allocate(sizeof(MyProcessor)))
MyProcessor(system, allocator);
return new (allocator->allocate(sizeof(local::MyProcessor)))
local::MyProcessor(system, allocator);
}
} // namespace vm

View File

@ -1325,6 +1325,9 @@ checkDaemon(Thread* t);
object&
root(Thread* t, Machine::Root root);
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
# define vmRun vmRun_
#endif
extern "C" uint64_t
vmRun(uint64_t (*function)(Thread*, uintptr_t*), uintptr_t* arguments,
void* checkpoint);

View File

@ -97,11 +97,13 @@ class System {
virtual void disposeAll() = 0;
};
#if defined(AVIAN_PROCESS_compile)
class SignalHandler {
public:
virtual bool handleSignal(void** ip, void** frame, void** stack,
void** thread) = 0;
};
#endif
class MonitorResource {
public:
@ -121,17 +123,21 @@ class System {
virtual bool success(Status) = 0;
virtual void* tryAllocate(unsigned sizeInBytes) = 0;
virtual void free(const void* p) = 0;
#if defined(AVIAN_PROCESS_compile)
virtual void* tryAllocateExecutable(unsigned sizeInBytes) = 0;
virtual void freeExecutable(const void* p, unsigned sizeInBytes) = 0;
#endif
virtual Status attach(Runnable*) = 0;
virtual Status start(Runnable*) = 0;
virtual Status make(Mutex**) = 0;
virtual Status make(Monitor**) = 0;
virtual Status make(Local**) = 0;
#if defined(AVIAN_PROCESS_compile)
virtual Status handleSegFault(SignalHandler* handler) = 0;
virtual Status handleDivideByZero(SignalHandler* handler) = 0;
virtual Status visit(Thread* thread, Thread* target,
ThreadVisitor* visitor) = 0;
#endif
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
unsigned count, unsigned size,
unsigned returnType) = 0;

View File

@ -26,6 +26,71 @@
#include "arch.h"
#include "system.h"
#if defined(WINAPI_FAMILY)
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#define WaitForSingleObject(hHandle, dwMilliseconds) \
WaitForSingleObjectEx((hHandle), (dwMilliseconds), FALSE)
#define CreateEvent(lpEventAttributes, bManualReset, bInitialState, lpName) \
CreateEventEx((lpEventAttributes), (lpName), ((bManualReset)?CREATE_EVENT_MANUAL_RESET:0)|((bInitialState)?CREATE_EVENT_INITIAL_SET:0), EVENT_MODIFY_STATE)
#define CreateMutex(lpEventAttributes, bInitialOwner, lpName) \
CreateMutexEx((lpEventAttributes), (lpName), (bInitialOwner)?CREATE_MUTEX_INITIAL_OWNER:0, MUTEX_MODIFY_STATE)
#include "thread-emulation.h"
#endif
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE)
// Headers in Windows Phone 8 DevKit contain severe error, so let's define needed functions on our own
extern "C"
{
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateFileMappingFromApp(
_In_ HANDLE hFile,
_In_opt_ PSECURITY_ATTRIBUTES SecurityAttributes,
_In_ ULONG PageProtection,
_In_ ULONG64 MaximumSize,
_In_opt_ PCWSTR Name
);
WINBASEAPI
_Ret_maybenull_ __out_data_source(FILE)
PVOID
WINAPI
MapViewOfFileFromApp(
_In_ HANDLE hFileMappingObject,
_In_ ULONG DesiredAccess,
_In_ ULONG64 FileOffset,
_In_ SIZE_T NumberOfBytesToMap
);
WINBASEAPI
BOOL
WINAPI
UnmapViewOfFile(
_In_ LPCVOID lpBaseAddress
);
}
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE)
#else
#ifndef WINAPI_PARTITION_DESKTOP
#define WINAPI_PARTITION_DESKTOP 1
#endif
#ifndef WINAPI_FAMILY_PARTITION
#define WINAPI_FAMILY_PARTITION(x) (x)
#endif
#endif
#define ACQUIRE(s, x) MutexResource MAKE_NAME(mutexResource_) (s, x)
using namespace vm;
@ -49,16 +114,20 @@ class MutexResource {
HANDLE m;
};
#if defined(AVIAN_PROCESS_compile)
const unsigned SegFaultIndex = 0;
const unsigned DivideByZeroIndex = 1;
const unsigned HandlerCount = 2;
#endif
class MySystem;
MySystem* system;
#if defined(AVIAN_PROCESS_compile)
LONG CALLBACK
handleException(LPEXCEPTION_POINTERS e);
#endif
DWORD WINAPI
run(void* r)
@ -559,18 +628,22 @@ class MySystem: public System {
};
MySystem(const char* crashDumpDirectory):
#if defined(AVIAN_PROCESS_compile)
oldHandler(0),
#endif
crashDumpDirectory(crashDumpDirectory)
{
expect(this, system == 0);
system = this;
#if defined(AVIAN_PROCESS_compile)
memset(handlers, 0, sizeof(handlers));
#endif
mutex = CreateMutex(0, false, 0);
assert(this, mutex);
}
#if defined(AVIAN_PROCESS_compile)
bool findHandler() {
for (unsigned i = 0; i < HandlerCount; ++i) {
if (handlers[i]) return true;
@ -578,6 +651,7 @@ class MySystem: public System {
return false;
}
//TODO: http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.application.unhandledexception(v=vs.105).aspx
int registerHandler(System::SignalHandler* handler, int index) {
if (handler) {
handlers[index] = handler;
@ -609,7 +683,7 @@ class MySystem: public System {
return 1;
}
}
#endif
virtual void* tryAllocate(unsigned sizeInBytes) {
return malloc(sizeInBytes);
}
@ -618,6 +692,7 @@ class MySystem: public System {
if (p) ::free(const_cast<void*>(p));
}
#if defined(AVIAN_PROCESS_compile)
virtual void* tryAllocateExecutable(unsigned sizeInBytes) {
return VirtualAlloc
(0, sizeInBytes, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
@ -627,6 +702,7 @@ class MySystem: public System {
int r UNUSED = VirtualFree(const_cast<void*>(p), 0, MEM_RELEASE);
assert(this, r);
}
#endif
virtual bool success(Status s) {
return s == 0;
@ -666,6 +742,7 @@ class MySystem: public System {
return 0;
}
#if defined(AVIAN_PROCESS_compile)
virtual Status handleSegFault(SignalHandler* handler) {
return registerHandler(handler, SegFaultIndex);
}
@ -710,6 +787,7 @@ class MySystem: public System {
return (success ? 0 : 1);
}
#endif
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
unsigned count, unsigned size, unsigned returnType)
@ -719,15 +797,39 @@ class MySystem: public System {
virtual Status map(System::Region** region, const char* name) {
Status status = 1;
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE file = CreateFile(name, FILE_READ_DATA, FILE_SHARE_READ, 0,
OPEN_EXISTING, 0, 0);
#else
size_t nameLen = strlen(name);
wchar_t* wideName = new wchar_t[nameLen + 1];
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, wideName, nameLen + 1, name, nameLen);
HANDLE file = CreateFile2(wideName, GENERIC_READ, FILE_SHARE_READ,
OPEN_EXISTING, 0);
delete[] wideName;
#endif
if (file != INVALID_HANDLE_VALUE) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
unsigned size = GetFileSize(file, 0);
#else
FILE_STANDARD_INFO info;
unsigned size = INVALID_FILE_SIZE;
if(GetFileInformationByHandleEx(file, FileStandardInfo, &info, sizeof(info)))
size = info.EndOfFile.QuadPart;
#endif
if (size != INVALID_FILE_SIZE) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, size, 0);
#else
HANDLE mapping = CreateFileMappingFromApp(file, 0, PAGE_READONLY, size, 0);
#endif
if (mapping) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
void* data = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
#else
void* data = MapViewOfFileFromApp(mapping, FILE_MAP_READ, 0, 0);
#endif
if (data) {
*region = new (allocate(this, sizeof(Region)))
Region(this, static_cast<uint8_t*>(data), size, file, mapping);
@ -757,7 +859,12 @@ class MySystem: public System {
memcpy(RUNTIME_ARRAY_BODY(buffer) + length, "\\*", 3);
Directory* d = new (allocate(this, sizeof(Directory))) Directory(this);
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
d->handle = FindFirstFile(RUNTIME_ARRAY_BODY(buffer), &(d->data));
#else
d->handle = FindFirstFileEx(RUNTIME_ARRAY_BODY(buffer), FindExInfoStandard, &(d->data), FindExSearchNameMatch, 0, 0);
#endif
if (d->handle == INVALID_HANDLE_VALUE) {
d->dispose();
} else {
@ -797,6 +904,7 @@ class MySystem: public System {
}
virtual const char* toAbsolutePath(Allocator* allocator, const char* name) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
if (strncmp(name, "//", 2) == 0
or strncmp(name, "\\\\", 2) == 0
or strncmp(name + 1, ":/", 2) == 0
@ -808,6 +916,11 @@ class MySystem: public System {
GetCurrentDirectory(MAX_PATH, buffer);
return append(allocator, buffer, "\\", name);
}
#else
//TODO:http://lunarfrog.com/blog/2012/05/21/winrt-folders-access/
//Windows.ApplicationModel.Package.Current.InstalledLocation
return name;
#endif
}
virtual Status load(System::Library** lib,
@ -816,9 +929,23 @@ class MySystem: public System {
HMODULE handle;
unsigned nameLength = (name ? strlen(name) : 0);
if (name) {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
handle = LoadLibrary(name);
#else
size_t nameLen = strlen(name);
wchar_t* wideName = new wchar_t[nameLen + 1];
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, wideName, nameLen + 1, name, nameLen);
handle = LoadPackagedLibrary(wideName, 0);
delete[] wideName;
#endif
} else {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
handle = GetModuleHandle(0);
#else
// Most of WinRT/WP8 applications can not host native object files inside main executable
assert(this, false);
#endif
}
if (handle) {
@ -866,7 +993,11 @@ class MySystem: public System {
}
virtual void yield() {
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
SwitchToThread();
#else
YieldProcessor();
#endif
}
virtual void exit(int code) {
@ -886,11 +1017,15 @@ class MySystem: public System {
}
HANDLE mutex;
#if defined(AVIAN_PROCESS_compile)
SignalHandler* handlers[HandlerCount];
LPTOP_LEVEL_EXCEPTION_FILTER oldHandler;
#endif
const char* crashDumpDirectory;
};
#if defined(AVIAN_PROCESS_compile)
#pragma pack(push,4)
struct MINIDUMP_EXCEPTION_INFORMATION {
DWORD thread;
@ -1005,6 +1140,8 @@ handleException(LPEXCEPTION_POINTERS e)
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
} // namespace
namespace vm {

166
src/x86.masm Normal file
View File

@ -0,0 +1,166 @@
comment #
Copyright (c) 2008-2011, Avian Contributors
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.
#
.586
.MODEL FLAT, C
VOID_TYPE equ 0
INT8_TYPE equ 1
INT16_TYPE equ 2
INT32_TYPE equ 3
INT64_TYPE equ 4
FLOAT_TYPE equ 5
DOUBLE_TYPE equ 6
POINTER_TYPE equ 7
CHECKPOINT_THREAD equ 4
CHECKPOINT_STACK equ 24
CHECKPOINT_BASE equ 28
_TEXT SEGMENT
public C detectFeature
detectFeature:
push ebp
mov ebp,esp
push edx
push ecx
push ebx
push esi
push edi
mov esi,ds:dword ptr[12+ebp]
mov edi,ds:dword ptr[8+ebp]
mov eax,1
cpuid
and edx,esi
and ecx,edi
or ecx,edx
test ecx,ecx
je LNOSSE
mov eax,1
jmp LSSEEND
LNOSSE:
mov eax,0
LSSEEND:
pop edi
pop esi
pop ebx
pop ecx
pop edx
mov esp,ebp
pop ebp
ret
public C vmNativeCall
vmNativeCall:
push ebp
mov ebp,esp
mov ecx,ds:dword ptr[16+ebp]
sub esp,ecx
mov ecx,0
jmp Ltest
Lloop:
mov eax,ecx
mov edx,ecx
add edx,esp
add eax,ds:dword ptr[12+ebp]
mov eax,ds:dword ptr[eax]
mov ds:dword ptr[edx],eax
add ecx,4
Ltest:
cmp ecx,ds:dword ptr[16+ebp]
jb Lloop
call dword ptr[8+ebp]
mov ecx,ds:dword ptr[20+ebp]
Lvoid:
cmp ecx,offset VOID_TYPE
jne Lint64
jmp Lexit
Lint64:
cmp ecx,offset INT64_TYPE
jne Lfloat
jmp Lexit
Lfloat:
cmp ecx,offset FLOAT_TYPE
jne Ldouble
fstp ds:dword ptr[8+ebp]
mov eax,ds:dword ptr[8+ebp]
jmp Lexit
Ldouble:
cmp ecx,offset DOUBLE_TYPE
jne Lexit
fstp ds:dword ptr[8+ebp]
mov eax,ds:dword ptr[8+ebp]
mov edx,ds:dword ptr[12+ebp]
Lexit:
mov esp,ebp
pop ebp
ret
public C vmJump
vmJump:
mov esi,ds:dword ptr[4+esp]
mov ebp,ds:dword ptr[8+esp]
mov ebx,ds:dword ptr[16+esp]
mov eax,ds:dword ptr[20+esp]
mov edx,ds:dword ptr[24+esp]
mov esp,ds:dword ptr[12+esp]
jmp esi
VMRUN_FRAME_SIZE equ 24
public C vmRun_
vmRun_:
; 8(%ebp): function
; 12(%ebp): arguments
; 16(%ebp): checkpoint
push ebp
mov ebp,esp
sub esp,offset VMRUN_FRAME_SIZE
mov ds:dword ptr[8+esp],ebx
mov ds:dword ptr[12+esp],esi
mov ds:dword ptr[16+esp],edi
mov eax,ds:dword ptr[12+ebp]
mov ds:dword ptr[4+esp],eax
mov ecx,ds:dword ptr[16+ebp]
mov eax,ds:dword ptr[CHECKPOINT_THREAD+ecx]
mov ds:dword ptr[0+esp],eax
mov ds:dword ptr[CHECKPOINT_STACK+ecx],esp
call dword ptr[8+ebp]
public C vmRun_returnAddress
vmRun_returnAddress:
mov ebx,ds:dword ptr[8+esp]
mov esi,ds:dword ptr[12+esp]
mov edi,ds:dword ptr[16+esp]
add esp,offset VMRUN_FRAME_SIZE
pop ebp
ret
_TEXT ENDS
END