mirror of
https://github.com/corda/corda.git
synced 2025-06-11 03:41:41 +00:00
Merge pull request #291 from joshuawarner32/cpp11
Begin using c++11 features
This commit is contained in:
commit
b811ca60c1
21
README.md
21
README.md
@ -72,9 +72,9 @@ Building
|
|||||||
Build requirements include:
|
Build requirements include:
|
||||||
|
|
||||||
* GNU make 3.80 or later
|
* GNU make 3.80 or later
|
||||||
* GCC 3.4 or later (4.5.1 or later for Windows/x86_64)
|
* GCC 4.6 or later
|
||||||
or LLVM Clang 3.1 or later (see use-clang option below)
|
or LLVM Clang 3.1 or later (see use-clang option below)
|
||||||
* JDK 1.5 or later
|
* JDK 1.6 or later
|
||||||
* MinGW 3.4 or later (only if compiling for Windows)
|
* MinGW 3.4 or later (only if compiling for Windows)
|
||||||
* zlib 1.2.3 or later
|
* zlib 1.2.3 or later
|
||||||
|
|
||||||
@ -226,24 +226,25 @@ still need to have GCC installed - MSVC is only used to compile the
|
|||||||
C++ portions of the VM, while the assembly code and helper tools are
|
C++ portions of the VM, while the assembly code and helper tools are
|
||||||
built using GCC.
|
built using GCC.
|
||||||
|
|
||||||
The MSVC build has been tested with Visual Studio Express Edition
|
*Note that the MSVC build isn't tested regularly, so is fairly likely to be broken.*
|
||||||
versions 8, 9, and 10. Other versions may also work.
|
|
||||||
|
Avian targets MSVC 11 and above (it uses c++ features not available in older versions).
|
||||||
|
|
||||||
To build with MSVC, install Cygwin as described above and set the
|
To build with MSVC, install Cygwin as described above and set the
|
||||||
following environment variables:
|
following environment variables:
|
||||||
|
|
||||||
$ export PATH="/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/Common7/IDE:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC/BIN:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/Common7/Tools:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v3.5:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC/VCPackages:/cygdrive/c/Program Files/Microsoft SDKs/Windows/v6.0A/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem"
|
$ export PATH="/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/Common7/IDE:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC/BIN:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/Common7/Tools:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v3.5:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC/VCPackages:/cygdrive/c/Program Files/Microsoft SDKs/Windows/v6.0A/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem"
|
||||||
$ export LIBPATH="C:\WINDOWS\Microsoft.NET\Framework\v3.5;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;"
|
$ export LIBPATH="C:\WINDOWS\Microsoft.NET\Framework\v3.5;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 11.0\VC\LIB;"
|
||||||
$ export VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 9.0\VC"
|
$ export VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 11.0\VC"
|
||||||
$ export LIB="C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib;"
|
$ export LIB="C:\Program Files\Microsoft Visual Studio 11.0\VC\LIB;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib;"
|
||||||
$ export INCLUDE="C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include;"
|
$ export INCLUDE="C:\Program Files\Microsoft Visual Studio 11.0\VC\INCLUDE;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include;"
|
||||||
|
|
||||||
Adjust these definitions as necessary according to your MSVC
|
Adjust these definitions as necessary according to your MSVC
|
||||||
installation.
|
installation.
|
||||||
|
|
||||||
Finally, build with the msvc flag set to the MSVC tool directory:
|
Finally, build with the msvc flag set to the MSVC tool directory:
|
||||||
|
|
||||||
$ make msvc="/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC"
|
$ make msvc="/cygdrive/c/Program Files/Microsoft Visual Studio 11.0/VC"
|
||||||
|
|
||||||
|
|
||||||
Building with the OpenJDK Class Library
|
Building with the OpenJDK Class Library
|
||||||
|
@ -25,6 +25,40 @@ class TraceHandler {
|
|||||||
virtual void handleTrace(Promise* address, unsigned argumentIndex) = 0;
|
virtual void handleTrace(Promise* address, unsigned argumentIndex) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
class Args {
|
||||||
|
public:
|
||||||
|
ir::Value* values[N];
|
||||||
|
|
||||||
|
template <class... Ts>
|
||||||
|
Args(Ts... ts)
|
||||||
|
: values{ts...}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
operator util::Slice<ir::Value*>()
|
||||||
|
{
|
||||||
|
return util::Slice<ir::Value*>(&values[0], N);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Args<0> args()
|
||||||
|
{
|
||||||
|
return Args<0>();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Args<1> args(ir::Value* first)
|
||||||
|
{
|
||||||
|
return Args<1>{first};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Ts>
|
||||||
|
inline Args<1 + util::ArgumentCount<Ts...>::Result> args(ir::Value* first,
|
||||||
|
Ts... rest)
|
||||||
|
{
|
||||||
|
return Args<1 + util::ArgumentCount<Ts...>::Result>{first, rest...};
|
||||||
|
}
|
||||||
|
|
||||||
class Compiler {
|
class Compiler {
|
||||||
public:
|
public:
|
||||||
class Client {
|
class Client {
|
||||||
@ -83,12 +117,11 @@ class Compiler {
|
|||||||
virtual unsigned topOfStack() = 0;
|
virtual unsigned topOfStack() = 0;
|
||||||
virtual ir::Value* peek(unsigned footprint, unsigned index) = 0;
|
virtual ir::Value* peek(unsigned footprint, unsigned index) = 0;
|
||||||
|
|
||||||
virtual ir::Value* call(ir::Value* address,
|
virtual ir::Value* nativeCall(ir::Value* address,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
TraceHandler* traceHandler,
|
TraceHandler* traceHandler,
|
||||||
ir::Type resultType,
|
ir::Type resultType,
|
||||||
unsigned argumentCount,
|
util::Slice<ir::Value*> arguments) = 0;
|
||||||
...) = 0;
|
|
||||||
|
|
||||||
virtual ir::Value* stackCall(ir::Value* address,
|
virtual ir::Value* stackCall(ir::Value* address,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
@ -110,7 +143,7 @@ class Compiler {
|
|||||||
ir::Value* index,
|
ir::Value* index,
|
||||||
intptr_t handler) = 0;
|
intptr_t handler) = 0;
|
||||||
|
|
||||||
virtual ir::Value* truncateThenExtend(ir::SignExtendMode signExtend,
|
virtual ir::Value* truncateThenExtend(ir::ExtendMode extendMode,
|
||||||
ir::Type extendType,
|
ir::Type extendType,
|
||||||
ir::Type truncateType,
|
ir::Type truncateType,
|
||||||
ir::Value* src) = 0;
|
ir::Value* src) = 0;
|
||||||
@ -118,7 +151,7 @@ class Compiler {
|
|||||||
virtual ir::Value* truncate(ir::Type type, ir::Value* src) = 0;
|
virtual ir::Value* truncate(ir::Type type, ir::Value* src) = 0;
|
||||||
|
|
||||||
virtual void store(ir::Value* src, ir::Value* dst) = 0;
|
virtual void store(ir::Value* src, ir::Value* dst) = 0;
|
||||||
virtual ir::Value* load(ir::SignExtendMode signExtend,
|
virtual ir::Value* load(ir::ExtendMode extendMode,
|
||||||
ir::Value* src,
|
ir::Value* src,
|
||||||
ir::Type dstType) = 0;
|
ir::Type dstType) = 0;
|
||||||
|
|
||||||
|
@ -132,9 +132,9 @@ class Type {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SignExtendMode { SignExtend, ZeroExtend };
|
enum class ExtendMode { Signed, Unsigned };
|
||||||
|
|
||||||
enum CallingConvention { NativeCallingConvention, AvianCallingConvention };
|
enum class CallingConvention { Native, Avian };
|
||||||
|
|
||||||
class Value {
|
class Value {
|
||||||
public:
|
public:
|
||||||
|
50
include/avian/util/cpp.h
Normal file
50
include/avian/util/cpp.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* Copyright (c) 2008-2014, 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. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_UTIL_CPP_H
|
||||||
|
#define AVIAN_UTIL_CPP_H
|
||||||
|
|
||||||
|
#include "allocator.h"
|
||||||
|
#include "math.h"
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace util {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct NonConst;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct NonConst<const T> {
|
||||||
|
typedef T Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct NonConst {
|
||||||
|
typedef T Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class... Ts>
|
||||||
|
struct ArgumentCount;
|
||||||
|
|
||||||
|
template <class T, class... Ts>
|
||||||
|
struct ArgumentCount<T, Ts...> {
|
||||||
|
enum { Result = 1 + ArgumentCount<Ts...>::Result };
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct ArgumentCount<> {
|
||||||
|
enum { Result = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace util
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_UTIL_CPP_H
|
@ -14,23 +14,11 @@
|
|||||||
#include "allocator.h"
|
#include "allocator.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
#include "cpp.h"
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct NonConst;
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct NonConst<const T> {
|
|
||||||
typedef T Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct NonConst {
|
|
||||||
typedef T Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class Slice {
|
class Slice {
|
||||||
public:
|
public:
|
||||||
|
4
makefile
4
makefile
@ -378,7 +378,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
|||||||
|
|
||||||
target-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
target-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||||
|
|
||||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions -I$(classpath-src) \
|
common-cflags = $(warnings) -std=c++0x -fno-rtti -fno-exceptions -I$(classpath-src) \
|
||||||
"-I$(JAVA_HOME)/include" -I$(src) -I$(build) -Iinclude $(classpath-cflags) \
|
"-I$(JAVA_HOME)/include" -I$(src) -I$(build) -Iinclude $(classpath-cflags) \
|
||||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||||
-DAVIAN_INFO="\"$(info)\"" \
|
-DAVIAN_INFO="\"$(info)\"" \
|
||||||
@ -397,7 +397,7 @@ endif
|
|||||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||||
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
||||||
|
|
||||||
converter-cflags = -D__STDC_CONSTANT_MACROS -Iinclude/ -Isrc/ \
|
converter-cflags = -D__STDC_CONSTANT_MACROS -std=c++0x -Iinclude/ -Isrc/ \
|
||||||
-fno-rtti -fno-exceptions \
|
-fno-rtti -fno-exceptions \
|
||||||
-DAVIAN_TARGET_ARCH=AVIAN_ARCH_UNKNOWN \
|
-DAVIAN_TARGET_ARCH=AVIAN_ARCH_UNKNOWN \
|
||||||
-DAVIAN_TARGET_FORMAT=AVIAN_FORMAT_UNKNOWN \
|
-DAVIAN_TARGET_FORMAT=AVIAN_FORMAT_UNKNOWN \
|
||||||
|
@ -2534,31 +2534,27 @@ class MyCompiler : public Compiler {
|
|||||||
return s->value;
|
return s->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ir::Value* call(ir::Value* address,
|
virtual ir::Value* nativeCall(ir::Value* address,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
TraceHandler* traceHandler,
|
TraceHandler* traceHandler,
|
||||||
ir::Type resultType,
|
ir::Type resultType,
|
||||||
unsigned argumentCount,
|
util::Slice<ir::Value*> arguments)
|
||||||
...)
|
|
||||||
{
|
{
|
||||||
va_list a;
|
|
||||||
va_start(a, argumentCount);
|
|
||||||
|
|
||||||
bool bigEndian = c.arch->bigEndian();
|
bool bigEndian = c.arch->bigEndian();
|
||||||
|
|
||||||
unsigned footprint = 0;
|
unsigned footprint = 0;
|
||||||
unsigned size = TargetBytesPerWord;
|
unsigned size = TargetBytesPerWord;
|
||||||
RUNTIME_ARRAY(ir::Value*, arguments, argumentCount);
|
RUNTIME_ARRAY(ir::Value*, args, arguments.count);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
for (unsigned i = 0; i < arguments.count; ++i) {
|
||||||
Value* o = va_arg(a, Value*);
|
Value* o = static_cast<Value*>(arguments[i]);
|
||||||
if (o) {
|
if (o) {
|
||||||
if (bigEndian and size > TargetBytesPerWord) {
|
if (bigEndian and size > TargetBytesPerWord) {
|
||||||
RUNTIME_ARRAY_BODY(arguments)[index++] = o->nextWord;
|
RUNTIME_ARRAY_BODY(args)[index++] = o->nextWord;
|
||||||
}
|
}
|
||||||
RUNTIME_ARRAY_BODY(arguments)[index] = o;
|
RUNTIME_ARRAY_BODY(args)[index] = o;
|
||||||
if ((not bigEndian) and size > TargetBytesPerWord) {
|
if ((not bigEndian) and size > TargetBytesPerWord) {
|
||||||
RUNTIME_ARRAY_BODY(arguments)[++index] = o->nextWord;
|
RUNTIME_ARRAY_BODY(args)[++index] = o->nextWord;
|
||||||
}
|
}
|
||||||
size = TargetBytesPerWord;
|
size = TargetBytesPerWord;
|
||||||
++index;
|
++index;
|
||||||
@ -2568,16 +2564,14 @@ class MyCompiler : public Compiler {
|
|||||||
++footprint;
|
++footprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(a);
|
|
||||||
|
|
||||||
Value* result = value(&c, resultType);
|
Value* result = value(&c, resultType);
|
||||||
appendCall(&c,
|
appendCall(&c,
|
||||||
static_cast<Value*>(address),
|
static_cast<Value*>(address),
|
||||||
ir::NativeCallingConvention,
|
ir::CallingConvention::Native,
|
||||||
flags,
|
flags,
|
||||||
traceHandler,
|
traceHandler,
|
||||||
result,
|
result,
|
||||||
util::Slice<ir::Value*>(RUNTIME_ARRAY_BODY(arguments), index));
|
util::Slice<ir::Value*>(RUNTIME_ARRAY_BODY(args), index));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -2592,7 +2586,7 @@ class MyCompiler : public Compiler {
|
|||||||
Stack* b UNUSED = c.stack;
|
Stack* b UNUSED = c.stack;
|
||||||
appendCall(&c,
|
appendCall(&c,
|
||||||
static_cast<Value*>(address),
|
static_cast<Value*>(address),
|
||||||
ir::AvianCallingConvention,
|
ir::CallingConvention::Avian,
|
||||||
flags,
|
flags,
|
||||||
traceHandler,
|
traceHandler,
|
||||||
result,
|
result,
|
||||||
@ -2747,14 +2741,14 @@ class MyCompiler : public Compiler {
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ir::Value* truncateThenExtend(ir::SignExtendMode signExtend,
|
virtual ir::Value* truncateThenExtend(ir::ExtendMode extendMode,
|
||||||
ir::Type extendType,
|
ir::Type extendType,
|
||||||
ir::Type truncateType,
|
ir::Type truncateType,
|
||||||
ir::Value* src)
|
ir::Value* src)
|
||||||
{
|
{
|
||||||
Value* dst = value(&c, extendType);
|
Value* dst = value(&c, extendType);
|
||||||
appendMove(&c,
|
appendMove(&c,
|
||||||
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
|
extendMode == ir::ExtendMode::Signed ? lir::Move : lir::MoveZ,
|
||||||
TargetBytesPerWord,
|
TargetBytesPerWord,
|
||||||
truncateType.size(c.targetInfo),
|
truncateType.size(c.targetInfo),
|
||||||
static_cast<Value*>(src),
|
static_cast<Value*>(src),
|
||||||
@ -2778,7 +2772,7 @@ class MyCompiler : public Compiler {
|
|||||||
static_cast<Value*>(dst));
|
static_cast<Value*>(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ir::Value* load(ir::SignExtendMode signExtend,
|
virtual ir::Value* load(ir::ExtendMode extendMode,
|
||||||
ir::Value* src,
|
ir::Value* src,
|
||||||
ir::Type dstType)
|
ir::Type dstType)
|
||||||
{
|
{
|
||||||
@ -2786,7 +2780,7 @@ class MyCompiler : public Compiler {
|
|||||||
|
|
||||||
Value* dst = value(&c, dstType);
|
Value* dst = value(&c, dstType);
|
||||||
appendMove(&c,
|
appendMove(&c,
|
||||||
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
|
extendMode == ir::ExtendMode::Signed ? lir::Move : lir::MoveZ,
|
||||||
src->type.size(c.targetInfo),
|
src->type.size(c.targetInfo),
|
||||||
src->type.size(c.targetInfo),
|
src->type.size(c.targetInfo),
|
||||||
static_cast<Value*>(src),
|
static_cast<Value*>(src),
|
||||||
|
@ -368,13 +368,13 @@ class CallEvent : public Event {
|
|||||||
popIndex(0),
|
popIndex(0),
|
||||||
stackArgumentIndex(0),
|
stackArgumentIndex(0),
|
||||||
flags(flags),
|
flags(flags),
|
||||||
stackArgumentFootprint(callingConvention == ir::AvianCallingConvention
|
stackArgumentFootprint(callingConvention == ir::CallingConvention::Avian
|
||||||
? arguments.count
|
? arguments.count
|
||||||
: 0)
|
: 0)
|
||||||
{
|
{
|
||||||
uint32_t registerMask = c->regFile->generalRegisters.mask;
|
uint32_t registerMask = c->regFile->generalRegisters.mask;
|
||||||
|
|
||||||
if (callingConvention == ir::NativeCallingConvention) {
|
if (callingConvention == ir::CallingConvention::Native) {
|
||||||
assertT(c, (flags & Compiler::TailJump) == 0);
|
assertT(c, (flags & Compiler::TailJump) == 0);
|
||||||
assertT(c, stackArgumentFootprint == 0);
|
assertT(c, stackArgumentFootprint == 0);
|
||||||
|
|
||||||
@ -450,7 +450,7 @@ class CallEvent : public Event {
|
|||||||
|
|
||||||
Stack* stack = stackBefore;
|
Stack* stack = stackBefore;
|
||||||
|
|
||||||
if (callingConvention == ir::AvianCallingConvention) {
|
if (callingConvention == ir::CallingConvention::Avian) {
|
||||||
for (size_t i = 0; i < arguments.count; i++) {
|
for (size_t i = 0; i < arguments.count; i++) {
|
||||||
stack = stack->next;
|
stack = stack->next;
|
||||||
}
|
}
|
||||||
@ -1257,7 +1257,7 @@ void appendCombine(Context* c,
|
|||||||
|
|
||||||
appendCall(c,
|
appendCall(c,
|
||||||
value(c, ir::Type::addr(), constantSite(c, handler)),
|
value(c, ir::Type::addr(), constantSite(c, handler)),
|
||||||
ir::NativeCallingConvention,
|
ir::CallingConvention::Native,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
resultValue,
|
resultValue,
|
||||||
@ -1413,7 +1413,7 @@ void appendTranslate(Context* c,
|
|||||||
op,
|
op,
|
||||||
firstValue->type.size(c->targetInfo),
|
firstValue->type.size(c->targetInfo),
|
||||||
resultValue->type.size(c->targetInfo)))),
|
resultValue->type.size(c->targetInfo)))),
|
||||||
ir::NativeCallingConvention,
|
ir::CallingConvention::Native,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
resultValue,
|
resultValue,
|
||||||
@ -1849,7 +1849,7 @@ void appendBranch(Context* c,
|
|||||||
Value* result = value(c, ir::Type::addr());
|
Value* result = value(c, ir::Type::addr());
|
||||||
appendCall(c,
|
appendCall(c,
|
||||||
value(c, ir::Type::addr(), constantSite(c, handler)),
|
value(c, ir::Type::addr(), constantSite(c, handler)),
|
||||||
ir::NativeCallingConvention,
|
ir::CallingConvention::Native,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
result,
|
result,
|
||||||
|
366
src/compile.cpp
366
src/compile.cpp
@ -3084,12 +3084,12 @@ bool useLongJump(MyThread* t, uintptr_t target)
|
|||||||
|
|
||||||
void compileSafePoint(MyThread* t, Compiler* c, Frame* frame)
|
void compileSafePoint(MyThread* t, Compiler* c, Frame* frame)
|
||||||
{
|
{
|
||||||
c->call(c->constant(getThunk(t, idleIfNecessaryThunk), ir::Type::iptr()),
|
c->nativeCall(
|
||||||
|
c->constant(getThunk(t, idleIfNecessaryThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
1,
|
args(c->threadRegister()));
|
||||||
c->threadRegister());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void compileDirectInvoke(MyThread* t,
|
void compileDirectInvoke(MyThread* t,
|
||||||
@ -3229,13 +3229,11 @@ void compileDirectReferenceInvoke(MyThread* t,
|
|||||||
|
|
||||||
compileReferenceInvoke(
|
compileReferenceInvoke(
|
||||||
frame,
|
frame,
|
||||||
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::iptr(),
|
ir::Type::iptr(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(pair))),
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair)),
|
|
||||||
reference,
|
reference,
|
||||||
isStatic,
|
isStatic,
|
||||||
tailCall);
|
tailCall);
|
||||||
@ -3260,13 +3258,11 @@ void compileDirectAbstractInvoke(MyThread* t,
|
|||||||
|
|
||||||
compileAbstractInvoke(
|
compileAbstractInvoke(
|
||||||
frame,
|
frame,
|
||||||
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::iptr(),
|
ir::Type::iptr(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(target))),
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(target)),
|
|
||||||
target,
|
target,
|
||||||
tailCall);
|
tailCall);
|
||||||
}
|
}
|
||||||
@ -3287,13 +3283,11 @@ void handleMonitorEvent(MyThread* t, Frame* frame, intptr_t function)
|
|||||||
frame->context, 1, ir::Type::object(), savedTargetIndex(t, method));
|
frame->context, 1, ir::Type::object(), savedTargetIndex(t, method));
|
||||||
}
|
}
|
||||||
|
|
||||||
c->call(c->constant(function, ir::Type::iptr()),
|
c->nativeCall(c->constant(function, ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), lock));
|
||||||
c->threadRegister(),
|
|
||||||
lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3582,7 +3576,7 @@ ir::Value* popLongAddress(Frame* frame)
|
|||||||
{
|
{
|
||||||
return TargetBytesPerWord == 8
|
return TargetBytesPerWord == 8
|
||||||
? frame->popLarge(ir::Type::i8())
|
? frame->popLarge(ir::Type::i8())
|
||||||
: frame->c->load(ir::SignExtend,
|
: frame->c->load(ir::ExtendMode::Signed,
|
||||||
frame->popLarge(ir::Type::i8()),
|
frame->popLarge(ir::Type::i8()),
|
||||||
ir::Type::iptr());
|
ir::Type::iptr());
|
||||||
}
|
}
|
||||||
@ -3623,7 +3617,7 @@ bool intrinsic(MyThread* t UNUSED, Frame* frame, GcMethod* target)
|
|||||||
ir::Value* address = popLongAddress(frame);
|
ir::Value* address = popLongAddress(frame);
|
||||||
frame->pop(ir::Type::object());
|
frame->pop(ir::Type::object());
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(address, ir::Type::i1()),
|
c->memory(address, ir::Type::i1()),
|
||||||
ir::Type::i4()));
|
ir::Type::i4()));
|
||||||
return true;
|
return true;
|
||||||
@ -3641,7 +3635,7 @@ bool intrinsic(MyThread* t UNUSED, Frame* frame, GcMethod* target)
|
|||||||
ir::Value* address = popLongAddress(frame);
|
ir::Value* address = popLongAddress(frame);
|
||||||
frame->pop(ir::Type::object());
|
frame->pop(ir::Type::object());
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(address, ir::Type::i2()),
|
c->memory(address, ir::Type::i2()),
|
||||||
ir::Type::i4()));
|
ir::Type::i4()));
|
||||||
return true;
|
return true;
|
||||||
@ -3662,8 +3656,9 @@ bool intrinsic(MyThread* t UNUSED, Frame* frame, GcMethod* target)
|
|||||||
frame->pop(ir::Type::object());
|
frame->pop(ir::Type::object());
|
||||||
ir::Type type = MATCH(target->name(), "getInt") ? ir::Type::i4()
|
ir::Type type = MATCH(target->name(), "getInt") ? ir::Type::i4()
|
||||||
: ir::Type::f4();
|
: ir::Type::f4();
|
||||||
frame->push(type,
|
frame->push(
|
||||||
c->load(ir::SignExtend, c->memory(address, type), type));
|
type,
|
||||||
|
c->load(ir::ExtendMode::Signed, c->memory(address, type), type));
|
||||||
return true;
|
return true;
|
||||||
} else if ((MATCH(target->name(), "putInt")
|
} else if ((MATCH(target->name(), "putInt")
|
||||||
and MATCH(target->spec(), "(JI)V"))
|
and MATCH(target->spec(), "(JI)V"))
|
||||||
@ -3684,8 +3679,9 @@ bool intrinsic(MyThread* t UNUSED, Frame* frame, GcMethod* target)
|
|||||||
frame->pop(ir::Type::object());
|
frame->pop(ir::Type::object());
|
||||||
ir::Type type = MATCH(target->name(), "getLong") ? ir::Type::i8()
|
ir::Type type = MATCH(target->name(), "getLong") ? ir::Type::i8()
|
||||||
: ir::Type::f8();
|
: ir::Type::f8();
|
||||||
frame->pushLarge(type,
|
frame->pushLarge(
|
||||||
c->load(ir::SignExtend, c->memory(address, type), type));
|
type,
|
||||||
|
c->load(ir::ExtendMode::Signed, c->memory(address, type), type));
|
||||||
return true;
|
return true;
|
||||||
} else if ((MATCH(target->name(), "putLong")
|
} else if ((MATCH(target->name(), "putLong")
|
||||||
and MATCH(target->spec(), "(JJ)V"))
|
and MATCH(target->spec(), "(JJ)V"))
|
||||||
@ -3703,7 +3699,7 @@ bool intrinsic(MyThread* t UNUSED, Frame* frame, GcMethod* target)
|
|||||||
ir::Value* address = popLongAddress(frame);
|
ir::Value* address = popLongAddress(frame);
|
||||||
frame->pop(ir::Type::object());
|
frame->pop(ir::Type::object());
|
||||||
frame->pushLarge(ir::Type::i8(),
|
frame->pushLarge(ir::Type::i8(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(address, ir::Type::iptr()),
|
c->memory(address, ir::Type::iptr()),
|
||||||
ir::Type::i8()));
|
ir::Type::i8()));
|
||||||
return true;
|
return true;
|
||||||
@ -3923,12 +3919,12 @@ loop:
|
|||||||
|
|
||||||
frame->pushObject();
|
frame->pushObject();
|
||||||
|
|
||||||
c->call(c->constant(getThunk(t, gcIfNecessaryThunk), ir::Type::iptr()),
|
c->nativeCall(
|
||||||
|
c->constant(getThunk(t, gcIfNecessaryThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
1,
|
args(c->threadRegister()));
|
||||||
c->threadRegister());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DebugInstructions) {
|
if (DebugInstructions) {
|
||||||
@ -3984,7 +3980,7 @@ loop:
|
|||||||
frame->push(
|
frame->push(
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
c->load(
|
c->load(
|
||||||
ir::SignExtend,
|
ir::ExtendMode::Signed,
|
||||||
c->memory(array, ir::Type::object(), TargetArrayBody, index),
|
c->memory(array, ir::Type::object(), TargetArrayBody, index),
|
||||||
ir::Type::object()));
|
ir::Type::object()));
|
||||||
break;
|
break;
|
||||||
@ -3992,7 +3988,7 @@ loop:
|
|||||||
case faload:
|
case faload:
|
||||||
frame->push(
|
frame->push(
|
||||||
ir::Type::f4(),
|
ir::Type::f4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(array, ir::Type::f4(), TargetArrayBody, index),
|
c->memory(array, ir::Type::f4(), TargetArrayBody, index),
|
||||||
ir::Type::f4()));
|
ir::Type::f4()));
|
||||||
break;
|
break;
|
||||||
@ -4000,7 +3996,7 @@ loop:
|
|||||||
case iaload:
|
case iaload:
|
||||||
frame->push(
|
frame->push(
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(array, ir::Type::i4(), TargetArrayBody, index),
|
c->memory(array, ir::Type::i4(), TargetArrayBody, index),
|
||||||
ir::Type::i4()));
|
ir::Type::i4()));
|
||||||
break;
|
break;
|
||||||
@ -4008,7 +4004,7 @@ loop:
|
|||||||
case baload:
|
case baload:
|
||||||
frame->push(
|
frame->push(
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(array, ir::Type::i1(), TargetArrayBody, index),
|
c->memory(array, ir::Type::i1(), TargetArrayBody, index),
|
||||||
ir::Type::i4()));
|
ir::Type::i4()));
|
||||||
break;
|
break;
|
||||||
@ -4016,7 +4012,7 @@ loop:
|
|||||||
case caload:
|
case caload:
|
||||||
frame->push(
|
frame->push(
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
c->load(ir::ZeroExtend,
|
c->load(ir::ExtendMode::Unsigned,
|
||||||
c->memory(array, ir::Type::i2(), TargetArrayBody, index),
|
c->memory(array, ir::Type::i2(), TargetArrayBody, index),
|
||||||
ir::Type::i4()));
|
ir::Type::i4()));
|
||||||
break;
|
break;
|
||||||
@ -4024,7 +4020,7 @@ loop:
|
|||||||
case daload:
|
case daload:
|
||||||
frame->pushLarge(
|
frame->pushLarge(
|
||||||
ir::Type::f8(),
|
ir::Type::f8(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(array, ir::Type::f8(), TargetArrayBody, index),
|
c->memory(array, ir::Type::f8(), TargetArrayBody, index),
|
||||||
ir::Type::f8()));
|
ir::Type::f8()));
|
||||||
break;
|
break;
|
||||||
@ -4032,7 +4028,7 @@ loop:
|
|||||||
case laload:
|
case laload:
|
||||||
frame->pushLarge(
|
frame->pushLarge(
|
||||||
ir::Type::i8(),
|
ir::Type::i8(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(array, ir::Type::i8(), TargetArrayBody, index),
|
c->memory(array, ir::Type::i8(), TargetArrayBody, index),
|
||||||
ir::Type::i8()));
|
ir::Type::i8()));
|
||||||
break;
|
break;
|
||||||
@ -4040,7 +4036,7 @@ loop:
|
|||||||
case saload:
|
case saload:
|
||||||
frame->push(
|
frame->push(
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(array, ir::Type::i2(), TargetArrayBody, index),
|
c->memory(array, ir::Type::i2(), TargetArrayBody, index),
|
||||||
ir::Type::i4()));
|
ir::Type::i4()));
|
||||||
break;
|
break;
|
||||||
@ -4082,12 +4078,12 @@ loop:
|
|||||||
|
|
||||||
switch (instruction) {
|
switch (instruction) {
|
||||||
case aastore: {
|
case aastore: {
|
||||||
c->call(c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()),
|
c->nativeCall(
|
||||||
|
c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
4,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
array,
|
array,
|
||||||
c->binaryOp(lir::Add,
|
c->binaryOp(lir::Add,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
@ -4097,7 +4093,7 @@ loop:
|
|||||||
c->constant(log(TargetBytesPerWord),
|
c->constant(log(TargetBytesPerWord),
|
||||||
ir::Type::i4()),
|
ir::Type::i4()),
|
||||||
index)),
|
index)),
|
||||||
value);
|
value));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fastore:
|
case fastore:
|
||||||
@ -4180,15 +4176,14 @@ loop:
|
|||||||
thunk = makeBlankObjectArrayFromReferenceThunk;
|
thunk = makeBlankObjectArrayFromReferenceThunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->push(ir::Type::object(),
|
frame->push(
|
||||||
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
ir::Type::object(),
|
||||||
|
c->nativeCall(
|
||||||
|
c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
3,
|
args(c->threadRegister(), frame->append(argument), length)));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(argument),
|
|
||||||
length));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case areturn: {
|
case areturn: {
|
||||||
@ -4199,7 +4194,7 @@ loop:
|
|||||||
|
|
||||||
case arraylength: {
|
case arraylength: {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(frame->pop(ir::Type::object()),
|
c->memory(frame->pop(ir::Type::object()),
|
||||||
ir::Type::iptr(),
|
ir::Type::iptr(),
|
||||||
TargetArrayLength),
|
TargetArrayLength),
|
||||||
@ -4228,13 +4223,11 @@ loop:
|
|||||||
|
|
||||||
case athrow: {
|
case athrow: {
|
||||||
ir::Value* target = frame->pop(ir::Type::object());
|
ir::Value* target = frame->pop(ir::Type::object());
|
||||||
c->call(c->constant(getThunk(t, throw_Thunk), ir::Type::iptr()),
|
c->nativeCall(c->constant(getThunk(t, throw_Thunk), ir::Type::iptr()),
|
||||||
Compiler::NoReturn,
|
Compiler::NoReturn,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), target));
|
||||||
c->threadRegister(),
|
|
||||||
target);
|
|
||||||
|
|
||||||
c->nullaryOp(lir::Trap);
|
c->nullaryOp(lir::Trap);
|
||||||
}
|
}
|
||||||
@ -4269,14 +4262,12 @@ loop:
|
|||||||
|
|
||||||
ir::Value* instance = c->peek(1, 0);
|
ir::Value* instance = c->peek(1, 0);
|
||||||
|
|
||||||
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
c->nativeCall(
|
||||||
|
c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
3,
|
args(c->threadRegister(), frame->append(argument), instance));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(argument),
|
|
||||||
instance);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case d2f: {
|
case d2f: {
|
||||||
@ -4316,16 +4307,12 @@ loop:
|
|||||||
goto branch;
|
goto branch;
|
||||||
} else {
|
} else {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->call(c->constant(getThunk(t, compareDoublesGThunk),
|
c->nativeCall(c->constant(getThunk(t, compareDoublesGThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
4,
|
args(nullptr, a, nullptr, b)));
|
||||||
static_cast<ir::Value*>(0),
|
|
||||||
a,
|
|
||||||
static_cast<ir::Value*>(0),
|
|
||||||
b));
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4337,16 +4324,12 @@ loop:
|
|||||||
goto branch;
|
goto branch;
|
||||||
} else {
|
} else {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->call(c->constant(getThunk(t, compareDoublesLThunk),
|
c->nativeCall(c->constant(getThunk(t, compareDoublesLThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
4,
|
args(nullptr, a, nullptr, b)));
|
||||||
static_cast<ir::Value*>(0),
|
|
||||||
a,
|
|
||||||
static_cast<ir::Value*>(0),
|
|
||||||
b));
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4427,14 +4410,12 @@ loop:
|
|||||||
goto branch;
|
goto branch;
|
||||||
} else {
|
} else {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->call(c->constant(getThunk(t, compareFloatsGThunk),
|
c->nativeCall(c->constant(getThunk(t, compareFloatsGThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
2,
|
args(a, b)));
|
||||||
a,
|
|
||||||
b));
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4446,14 +4427,12 @@ loop:
|
|||||||
goto branch;
|
goto branch;
|
||||||
} else {
|
} else {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->call(c->constant(getThunk(t, compareFloatsLThunk),
|
c->nativeCall(c->constant(getThunk(t, compareFloatsLThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
2,
|
args(a, b)));
|
||||||
a,
|
|
||||||
b));
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -4493,14 +4472,12 @@ loop:
|
|||||||
and (field->code() == DoubleField or field->code() == LongField)) {
|
and (field->code() == DoubleField or field->code() == LongField)) {
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
c->call(c->constant(getThunk(t, acquireMonitorForObjectThunk),
|
c->nativeCall(c->constant(getThunk(t, acquireMonitorForObjectThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(field)));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(field));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ir::Value* table;
|
ir::Value* table;
|
||||||
@ -4511,14 +4488,12 @@ loop:
|
|||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
if (classNeedsInit(t, field->class_())) {
|
if (classNeedsInit(t, field->class_())) {
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()),
|
c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(field->class_())));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(field->class_()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table = frame->append(field->class_()->staticTable());
|
table = frame->append(field->class_()->staticTable());
|
||||||
@ -4537,7 +4512,7 @@ loop:
|
|||||||
case ByteField:
|
case ByteField:
|
||||||
case BooleanField:
|
case BooleanField:
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::i1(),
|
ir::Type::i1(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4546,7 +4521,7 @@ loop:
|
|||||||
|
|
||||||
case CharField:
|
case CharField:
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->load(ir::ZeroExtend,
|
c->load(ir::ExtendMode::Unsigned,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::i2(),
|
ir::Type::i2(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4555,7 +4530,7 @@ loop:
|
|||||||
|
|
||||||
case ShortField:
|
case ShortField:
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::i2(),
|
ir::Type::i2(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4564,7 +4539,7 @@ loop:
|
|||||||
|
|
||||||
case FloatField:
|
case FloatField:
|
||||||
frame->push(ir::Type::f4(),
|
frame->push(ir::Type::f4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::f4(),
|
ir::Type::f4(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4573,7 +4548,7 @@ loop:
|
|||||||
|
|
||||||
case IntField:
|
case IntField:
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4582,7 +4557,7 @@ loop:
|
|||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
frame->pushLarge(ir::Type::f8(),
|
frame->pushLarge(ir::Type::f8(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::f8(),
|
ir::Type::f8(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4591,7 +4566,7 @@ loop:
|
|||||||
|
|
||||||
case LongField:
|
case LongField:
|
||||||
frame->pushLarge(ir::Type::i8(),
|
frame->pushLarge(ir::Type::i8(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::i8(),
|
ir::Type::i8(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4600,7 +4575,7 @@ loop:
|
|||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
frame->push(ir::Type::object(),
|
frame->push(ir::Type::object(),
|
||||||
c->load(ir::SignExtend,
|
c->load(ir::ExtendMode::Signed,
|
||||||
c->memory(table,
|
c->memory(table,
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
targetFieldOffset(context, field)),
|
targetFieldOffset(context, field)),
|
||||||
@ -4614,14 +4589,12 @@ loop:
|
|||||||
if (field->flags() & ACC_VOLATILE) {
|
if (field->flags() & ACC_VOLATILE) {
|
||||||
if (TargetBytesPerWord == 4 and (field->code() == DoubleField
|
if (TargetBytesPerWord == 4 and (field->code() == DoubleField
|
||||||
or field->code() == LongField)) {
|
or field->code() == LongField)) {
|
||||||
c->call(c->constant(getThunk(t, releaseMonitorForObjectThunk),
|
c->nativeCall(c->constant(getThunk(t, releaseMonitorForObjectThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(field)));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(field));
|
|
||||||
} else {
|
} else {
|
||||||
c->nullaryOp(lir::LoadBarrier);
|
c->nullaryOp(lir::LoadBarrier);
|
||||||
}
|
}
|
||||||
@ -4637,28 +4610,23 @@ loop:
|
|||||||
|
|
||||||
ir::Value* result;
|
ir::Value* result;
|
||||||
if (instruction == getstatic) {
|
if (instruction == getstatic) {
|
||||||
result = c->call(
|
result = c->nativeCall(
|
||||||
c->constant(getThunk(t, getStaticFieldValueFromReferenceThunk),
|
c->constant(getThunk(t, getStaticFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
2,
|
args(c->threadRegister(), frame->append(pair)));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair));
|
|
||||||
} else {
|
} else {
|
||||||
ir::Value* instance = frame->pop(ir::Type::object());
|
ir::Value* instance = frame->pop(ir::Type::object());
|
||||||
|
|
||||||
result = c->call(
|
result = c->nativeCall(
|
||||||
c->constant(getThunk(t, getFieldValueFromReferenceThunk),
|
c->constant(getThunk(t, getFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
3,
|
args(c->threadRegister(), frame->append(pair), instance));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair),
|
|
||||||
instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->pushReturnValue(fieldCode, result);
|
frame->pushReturnValue(fieldCode, result);
|
||||||
@ -4693,7 +4661,7 @@ loop:
|
|||||||
|
|
||||||
case i2b: {
|
case i2b: {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->truncateThenExtend(ir::SignExtend,
|
c->truncateThenExtend(ir::ExtendMode::Signed,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
ir::Type::i1(),
|
ir::Type::i1(),
|
||||||
frame->pop(ir::Type::i4())));
|
frame->pop(ir::Type::i4())));
|
||||||
@ -4701,7 +4669,7 @@ loop:
|
|||||||
|
|
||||||
case i2c: {
|
case i2c: {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->truncateThenExtend(ir::ZeroExtend,
|
c->truncateThenExtend(ir::ExtendMode::Unsigned,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
ir::Type::i2(),
|
ir::Type::i2(),
|
||||||
frame->pop(ir::Type::i4())));
|
frame->pop(ir::Type::i4())));
|
||||||
@ -4719,7 +4687,7 @@ loop:
|
|||||||
|
|
||||||
case i2l:
|
case i2l:
|
||||||
frame->pushLarge(ir::Type::i8(),
|
frame->pushLarge(ir::Type::i8(),
|
||||||
c->truncateThenExtend(ir::SignExtend,
|
c->truncateThenExtend(ir::ExtendMode::Signed,
|
||||||
ir::Type::i8(),
|
ir::Type::i8(),
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
frame->pop(ir::Type::i4())));
|
frame->pop(ir::Type::i4())));
|
||||||
@ -4727,7 +4695,7 @@ loop:
|
|||||||
|
|
||||||
case i2s: {
|
case i2s: {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->truncateThenExtend(ir::SignExtend,
|
c->truncateThenExtend(ir::ExtendMode::Signed,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
ir::Type::i2(),
|
ir::Type::i2(),
|
||||||
frame->pop(ir::Type::i4())));
|
frame->pop(ir::Type::i4())));
|
||||||
@ -4949,15 +4917,14 @@ loop:
|
|||||||
thunk = instanceOfFromReferenceThunk;
|
thunk = instanceOfFromReferenceThunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(
|
||||||
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
ir::Type::i4(),
|
||||||
|
c->nativeCall(
|
||||||
|
c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
3,
|
args(c->threadRegister(), frame->append(argument), instance)));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(argument),
|
|
||||||
instance));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case invokeinterface: {
|
case invokeinterface: {
|
||||||
@ -4999,14 +4966,13 @@ loop:
|
|||||||
unsigned rSize = resultSize(t, returnCode);
|
unsigned rSize = resultSize(t, returnCode);
|
||||||
|
|
||||||
ir::Value* result = c->stackCall(
|
ir::Value* result = c->stackCall(
|
||||||
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::iptr(),
|
ir::Type::iptr(),
|
||||||
3,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(argument),
|
frame->append(argument),
|
||||||
c->peek(1, parameterFootprint - 1)),
|
c->peek(1, parameterFootprint - 1))),
|
||||||
tailCall ? Compiler::TailJump : 0,
|
tailCall ? Compiler::TailJump : 0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
operandTypeForFieldCode(t, returnCode),
|
operandTypeForFieldCode(t, returnCode),
|
||||||
@ -5146,17 +5112,17 @@ loop:
|
|||||||
|
|
||||||
compileReferenceInvoke(
|
compileReferenceInvoke(
|
||||||
frame,
|
frame,
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, findVirtualMethodFromReferenceThunk),
|
c->constant(getThunk(t, findVirtualMethodFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::iptr(),
|
ir::Type::iptr(),
|
||||||
3,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair),
|
frame->append(pair),
|
||||||
c->peek(1,
|
c->peek(1,
|
||||||
methodReferenceParameterFootprint(t, ref, false) - 1)),
|
methodReferenceParameterFootprint(t, ref, false)
|
||||||
|
- 1))),
|
||||||
ref,
|
ref,
|
||||||
false,
|
false,
|
||||||
isReferenceTailCall(t, code, ip, context->method, ref));
|
isReferenceTailCall(t, code, ip, context->method, ref));
|
||||||
@ -5283,16 +5249,12 @@ loop:
|
|||||||
goto branch;
|
goto branch;
|
||||||
} else {
|
} else {
|
||||||
frame->push(ir::Type::i4(),
|
frame->push(ir::Type::i4(),
|
||||||
c->call(c->constant(getThunk(t, compareLongsThunk),
|
c->nativeCall(c->constant(getThunk(t, compareLongsThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ir::Type::i4(),
|
ir::Type::i4(),
|
||||||
4,
|
args(nullptr, a, nullptr, b)));
|
||||||
static_cast<ir::Value*>(0),
|
|
||||||
a,
|
|
||||||
static_cast<ir::Value*>(0),
|
|
||||||
b));
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -5330,29 +5292,28 @@ loop:
|
|||||||
if (UNLIKELY(v == 0)) {
|
if (UNLIKELY(v == 0)) {
|
||||||
frame->push(
|
frame->push(
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, getJClassFromReferenceThunk),
|
c->constant(getThunk(t, getJClassFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
2,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
frame->append(
|
||||||
frame->append(makePair(t, context->method, reference))));
|
makePair(t, context->method, reference)))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v) {
|
if (v) {
|
||||||
if (objectClass(t, v) == type(t, GcClass::Type)) {
|
if (objectClass(t, v) == type(t, GcClass::Type)) {
|
||||||
frame->push(ir::Type::object(),
|
frame->push(
|
||||||
c->call(c->constant(getThunk(t, getJClass64Thunk),
|
ir::Type::object(),
|
||||||
|
c->nativeCall(c->constant(getThunk(t, getJClass64Thunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(v))));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(v)));
|
|
||||||
} else {
|
} else {
|
||||||
frame->push(ir::Type::object(), frame->append(v));
|
frame->push(ir::Type::object(), frame->append(v));
|
||||||
}
|
}
|
||||||
@ -5468,16 +5429,15 @@ loop:
|
|||||||
}
|
}
|
||||||
assertT(t, start);
|
assertT(t, start);
|
||||||
|
|
||||||
ir::Value* address = c->call(
|
ir::Value* address = c->nativeCall(
|
||||||
c->constant(getThunk(t, lookUpAddressThunk), ir::Type::iptr()),
|
c->constant(getThunk(t, lookUpAddressThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ir::Type::iptr(),
|
ir::Type::iptr(),
|
||||||
4,
|
args(key,
|
||||||
key,
|
|
||||||
frame->absoluteAddressOperand(start),
|
frame->absoluteAddressOperand(start),
|
||||||
c->constant(pairCount, ir::Type::i4()),
|
c->constant(pairCount, ir::Type::i4()),
|
||||||
default_);
|
default_));
|
||||||
|
|
||||||
c->jmp(context->bootContext
|
c->jmp(context->bootContext
|
||||||
? c->binaryOp(lir::Add,
|
? c->binaryOp(lir::Add,
|
||||||
@ -5572,26 +5532,22 @@ loop:
|
|||||||
|
|
||||||
case monitorenter: {
|
case monitorenter: {
|
||||||
ir::Value* target = frame->pop(ir::Type::object());
|
ir::Value* target = frame->pop(ir::Type::object());
|
||||||
c->call(c->constant(getThunk(t, acquireMonitorForObjectThunk),
|
c->nativeCall(c->constant(getThunk(t, acquireMonitorForObjectThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), target));
|
||||||
c->threadRegister(),
|
|
||||||
target);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case monitorexit: {
|
case monitorexit: {
|
||||||
ir::Value* target = frame->pop(ir::Type::object());
|
ir::Value* target = frame->pop(ir::Type::object());
|
||||||
c->call(c->constant(getThunk(t, releaseMonitorForObjectThunk),
|
c->nativeCall(c->constant(getThunk(t, releaseMonitorForObjectThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), target));
|
||||||
c->threadRegister(),
|
|
||||||
target);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case multianewarray: {
|
case multianewarray: {
|
||||||
@ -5622,15 +5578,14 @@ loop:
|
|||||||
context->method) + t->arch->frameReturnAddressSize();
|
context->method) + t->arch->frameReturnAddressSize();
|
||||||
|
|
||||||
ir::Value* result
|
ir::Value* result
|
||||||
= c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
= c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
4,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(argument),
|
frame->append(argument),
|
||||||
c->constant(dimensions, ir::Type::i4()),
|
c->constant(dimensions, ir::Type::i4()),
|
||||||
c->constant(offset, ir::Type::i4()));
|
c->constant(offset, ir::Type::i4())));
|
||||||
|
|
||||||
frame->popFootprint(dimensions);
|
frame->popFootprint(dimensions);
|
||||||
frame->push(ir::Type::object(), result);
|
frame->push(ir::Type::object(), result);
|
||||||
@ -5661,14 +5616,13 @@ loop:
|
|||||||
thunk = makeNewFromReferenceThunk;
|
thunk = makeNewFromReferenceThunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->push(ir::Type::object(),
|
frame->push(
|
||||||
c->call(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
ir::Type::object(),
|
||||||
|
c->nativeCall(c->constant(getThunk(t, thunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(argument))));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(argument)));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case newarray: {
|
case newarray: {
|
||||||
@ -5677,15 +5631,14 @@ loop:
|
|||||||
ir::Value* length = frame->pop(ir::Type::i4());
|
ir::Value* length = frame->pop(ir::Type::i4());
|
||||||
|
|
||||||
frame->push(ir::Type::object(),
|
frame->push(ir::Type::object(),
|
||||||
c->call(c->constant(getThunk(t, makeBlankArrayThunk),
|
c->nativeCall(c->constant(getThunk(t, makeBlankArrayThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::object(),
|
ir::Type::object(),
|
||||||
3,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
c->constant(type, ir::Type::i4()),
|
c->constant(type, ir::Type::i4()),
|
||||||
length));
|
length)));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case nop:
|
case nop:
|
||||||
@ -5721,14 +5674,12 @@ loop:
|
|||||||
if (classNeedsInit(t, field->class_())) {
|
if (classNeedsInit(t, field->class_())) {
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()),
|
c->constant(getThunk(t, tryInitClassThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(field->class_())));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(field->class_()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
staticTable = field->class_()->staticTable();
|
staticTable = field->class_()->staticTable();
|
||||||
@ -5746,14 +5697,12 @@ loop:
|
|||||||
and (fieldCode == DoubleField or fieldCode == LongField)) {
|
and (fieldCode == DoubleField or fieldCode == LongField)) {
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
|
|
||||||
c->call(c->constant(getThunk(t, acquireMonitorForObjectThunk),
|
c->nativeCall(c->constant(getThunk(t, acquireMonitorForObjectThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(field)));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(field));
|
|
||||||
} else {
|
} else {
|
||||||
c->nullaryOp(lir::StoreStoreBarrier);
|
c->nullaryOp(lir::StoreStoreBarrier);
|
||||||
}
|
}
|
||||||
@ -5818,27 +5767,27 @@ loop:
|
|||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
if (instruction == putfield) {
|
if (instruction == putfield) {
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()),
|
c->constant(getThunk(t, setMaybeNullThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
4,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
table,
|
table,
|
||||||
c->constant(targetFieldOffset(context, field), ir::Type::i4()),
|
c->constant(targetFieldOffset(context, field),
|
||||||
value);
|
ir::Type::i4()),
|
||||||
|
value));
|
||||||
} else {
|
} else {
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, setObjectThunk), ir::Type::iptr()),
|
c->constant(getThunk(t, setObjectThunk), ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
4,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
table,
|
table,
|
||||||
c->constant(targetFieldOffset(context, field), ir::Type::i4()),
|
c->constant(targetFieldOffset(context, field),
|
||||||
value);
|
ir::Type::i4()),
|
||||||
|
value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -5849,14 +5798,12 @@ loop:
|
|||||||
if (field->flags() & ACC_VOLATILE) {
|
if (field->flags() & ACC_VOLATILE) {
|
||||||
if (TargetBytesPerWord == 4
|
if (TargetBytesPerWord == 4
|
||||||
and (fieldCode == DoubleField or fieldCode == LongField)) {
|
and (fieldCode == DoubleField or fieldCode == LongField)) {
|
||||||
c->call(c->constant(getThunk(t, releaseMonitorForObjectThunk),
|
c->nativeCall(c->constant(getThunk(t, releaseMonitorForObjectThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
ir::Type::void_(),
|
ir::Type::void_(),
|
||||||
2,
|
args(c->threadRegister(), frame->append(field)));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(field));
|
|
||||||
} else {
|
} else {
|
||||||
c->nullaryOp(lir::StoreLoadBarrier);
|
c->nullaryOp(lir::StoreLoadBarrier);
|
||||||
}
|
}
|
||||||
@ -5879,91 +5826,76 @@ loop:
|
|||||||
case FloatField:
|
case FloatField:
|
||||||
case IntField: {
|
case IntField: {
|
||||||
if (instruction == putstatic) {
|
if (instruction == putstatic) {
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, setStaticFieldValueFromReferenceThunk),
|
c->constant(getThunk(t, setStaticFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
3,
|
args(c->threadRegister(), frame->append(pair), value));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair),
|
|
||||||
value);
|
|
||||||
} else {
|
} else {
|
||||||
ir::Value* instance = frame->pop(ir::Type::object());
|
ir::Value* instance = frame->pop(ir::Type::object());
|
||||||
|
|
||||||
c->call(c->constant(getThunk(t, setFieldValueFromReferenceThunk),
|
c->nativeCall(
|
||||||
|
c->constant(getThunk(t, setFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
4,
|
args(
|
||||||
c->threadRegister(),
|
c->threadRegister(), frame->append(pair), instance, value));
|
||||||
frame->append(pair),
|
|
||||||
instance,
|
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
case LongField: {
|
case LongField: {
|
||||||
if (instruction == putstatic) {
|
if (instruction == putstatic) {
|
||||||
c->call(c->constant(
|
c->nativeCall(
|
||||||
|
c->constant(
|
||||||
getThunk(t, setStaticLongFieldValueFromReferenceThunk),
|
getThunk(t, setStaticLongFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
4,
|
args(c->threadRegister(), frame->append(pair), nullptr, value));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair),
|
|
||||||
static_cast<ir::Value*>(0),
|
|
||||||
value);
|
|
||||||
} else {
|
} else {
|
||||||
ir::Value* instance = frame->pop(ir::Type::object());
|
ir::Value* instance = frame->pop(ir::Type::object());
|
||||||
|
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, setLongFieldValueFromReferenceThunk),
|
c->constant(getThunk(t, setLongFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
5,
|
args(c->threadRegister(),
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair),
|
frame->append(pair),
|
||||||
instance,
|
instance,
|
||||||
static_cast<ir::Value*>(0),
|
nullptr,
|
||||||
value);
|
value));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ObjectField: {
|
case ObjectField: {
|
||||||
if (instruction == putstatic) {
|
if (instruction == putstatic) {
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(
|
c->constant(
|
||||||
getThunk(t, setStaticObjectFieldValueFromReferenceThunk),
|
getThunk(t, setStaticObjectFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
3,
|
args(c->threadRegister(), frame->append(pair), value));
|
||||||
c->threadRegister(),
|
|
||||||
frame->append(pair),
|
|
||||||
value);
|
|
||||||
} else {
|
} else {
|
||||||
ir::Value* instance = frame->pop(ir::Type::object());
|
ir::Value* instance = frame->pop(ir::Type::object());
|
||||||
|
|
||||||
c->call(
|
c->nativeCall(
|
||||||
c->constant(getThunk(t, setObjectFieldValueFromReferenceThunk),
|
c->constant(getThunk(t, setObjectFieldValueFromReferenceThunk),
|
||||||
ir::Type::iptr()),
|
ir::Type::iptr()),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
rType,
|
rType,
|
||||||
4,
|
args(
|
||||||
c->threadRegister(),
|
c->threadRegister(), frame->append(pair), instance, value));
|
||||||
frame->append(pair),
|
|
||||||
instance,
|
|
||||||
value);
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -6167,7 +6099,7 @@ next:
|
|||||||
0,
|
0,
|
||||||
normalizedKey);
|
normalizedKey);
|
||||||
|
|
||||||
c->jmp(c->load(ir::SignExtend,
|
c->jmp(c->load(ir::ExtendMode::Signed,
|
||||||
context->bootContext
|
context->bootContext
|
||||||
? c->binaryOp(lir::Add,
|
? c->binaryOp(lir::Add,
|
||||||
ir::Type::iptr(),
|
ir::Type::iptr(),
|
||||||
|
@ -161,16 +161,12 @@ class Class {
|
|||||||
}
|
}
|
||||||
ss << " {\n";
|
ss << " {\n";
|
||||||
|
|
||||||
for (std::vector<Field*>::const_iterator it = fields.begin();
|
for (const auto f : fields) {
|
||||||
it != fields.end();
|
ss << " " << f->dump() << "\n";
|
||||||
it++) {
|
|
||||||
ss << " " << (*it)->dump() << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<Method>::const_iterator it = methods.begin();
|
for (const auto m : methods) {
|
||||||
it != methods.end();
|
ss << " " << m.dump() << "\n";
|
||||||
++it) {
|
|
||||||
ss << " " << it->dump() << "\n";
|
|
||||||
}
|
}
|
||||||
ss << "}";
|
ss << "}";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
@ -226,23 +222,23 @@ inline bool endsWith(const std::string& b, const std::string& a)
|
|||||||
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
|
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string enumName(Module& module, Field& f)
|
std::string enumName(Module& module, Field* f)
|
||||||
{
|
{
|
||||||
std::string& type = f.typeName;
|
std::string& type = f->typeName;
|
||||||
if (type == "void*") {
|
if (type == "void*") {
|
||||||
return "word";
|
return "word";
|
||||||
} else if (type == "maybe_object") {
|
} else if (type == "maybe_object") {
|
||||||
return "uintptr_t";
|
return "uintptr_t";
|
||||||
} else if (f.javaSpec.size() != 0
|
} else if (f->javaSpec.size() != 0
|
||||||
&& (f.javaSpec[0] == 'L' || f.javaSpec[0] == '[')) {
|
&& (f->javaSpec[0] == 'L' || f->javaSpec[0] == '[')) {
|
||||||
return "object";
|
return "object";
|
||||||
}
|
}
|
||||||
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
|
const auto it = module.classes.find(f->typeName);
|
||||||
assert(f.typeName.size() > 0);
|
assert(f->typeName.size() > 0);
|
||||||
if (it != module.classes.end()) {
|
if (it != module.classes.end()) {
|
||||||
return "object";
|
return "object";
|
||||||
} else {
|
} else {
|
||||||
return f.typeName;
|
return f->typeName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +404,7 @@ unsigned sizeOf(Module& module, const std::string& type)
|
|||||||
} else if (namesPointer(type)) {
|
} else if (namesPointer(type)) {
|
||||||
return BytesPerWord;
|
return BytesPerWord;
|
||||||
} else {
|
} else {
|
||||||
std::map<std::string, Class*>::iterator it = module.classes.find(type);
|
const auto it = module.classes.find(type);
|
||||||
if (it != module.classes.end()) {
|
if (it != module.classes.end()) {
|
||||||
return BytesPerWord;
|
return BytesPerWord;
|
||||||
} else {
|
} else {
|
||||||
@ -459,8 +455,7 @@ class ClassParser {
|
|||||||
if (fields.find(f.field->name) != fields.end()) {
|
if (fields.find(f.field->name) != fields.end()) {
|
||||||
// printf("alias %s.%s -> %s.%s\n", cl->name.c_str(),
|
// printf("alias %s.%s -> %s.%s\n", cl->name.c_str(),
|
||||||
// f.field->name.c_str(), cl->name.c_str(), f.aliasName.c_str());
|
// f.field->name.c_str(), cl->name.c_str(), f.aliasName.c_str());
|
||||||
std::map<std::string, Field*>::iterator it
|
const auto it = fields.find(f.field->name);
|
||||||
= fields.find(f.field->name);
|
|
||||||
assert(it != fields.end());
|
assert(it != fields.end());
|
||||||
Field* renamed = it->second;
|
Field* renamed = it->second;
|
||||||
fields.erase(it);
|
fields.erase(it);
|
||||||
@ -474,11 +469,11 @@ class ClassParser {
|
|||||||
renamed->javaSpec = f.field->javaSpec;
|
renamed->javaSpec = f.field->javaSpec;
|
||||||
} else {
|
} else {
|
||||||
// printf("ignoring absent alias %s.%s -> %s.%s\n", cl->name.c_str(),
|
// printf("ignoring absent alias %s.%s -> %s.%s\n", cl->name.c_str(),
|
||||||
// f.field->name.c_str(), cl->name.c_str(), f. aliasName.c_str());
|
// f.field->name.c_str(), cl->name.c_str(), f-> aliasName.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// printf("ignoring already defined alias %s.%s -> %s.%s\n",
|
// printf("ignoring already defined alias %s.%s -> %s.%s\n",
|
||||||
// cl->name.c_str(), f.field->name.c_str(), cl->name.c_str(), f.
|
// cl->name.c_str(), f.field->name.c_str(), cl->name.c_str(), f->
|
||||||
// aliasName.c_str());
|
// aliasName.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -508,10 +503,8 @@ class ClassParser {
|
|||||||
cl->super = super;
|
cl->super = super;
|
||||||
assert(!super->arrayField);
|
assert(!super->arrayField);
|
||||||
assert(fields.size() == 0);
|
assert(fields.size() == 0);
|
||||||
for (std::vector<Field*>::iterator it = super->fields.begin();
|
for (const auto f : super->fields) {
|
||||||
it != super->fields.end();
|
add(FieldSpec(false, f));
|
||||||
it++) {
|
|
||||||
add(FieldSpec(false, *it));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -826,31 +819,27 @@ void layoutClass(Module& module, Class* cl)
|
|||||||
|
|
||||||
alignment = BytesPerWord;
|
alignment = BytesPerWord;
|
||||||
|
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
f->elementSize = sizeOf(module, f->typeName);
|
||||||
it++) {
|
|
||||||
Field& f = **it;
|
|
||||||
|
|
||||||
f.elementSize = sizeOf(module, f.typeName);
|
if (!f->polyfill) { // polyfills contribute no size
|
||||||
|
alignment = f->elementSize;
|
||||||
if (!f.polyfill) { // polyfills contribute no size
|
|
||||||
alignment = f.elementSize;
|
|
||||||
offset = (offset + alignment - 1) & ~(alignment - 1);
|
offset = (offset + alignment - 1) & ~(alignment - 1);
|
||||||
f.offset = offset;
|
f->offset = offset;
|
||||||
|
|
||||||
size = f.elementSize;
|
size = f->elementSize;
|
||||||
|
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cl->arrayField) {
|
if (cl->arrayField) {
|
||||||
Field& f = *cl->arrayField;
|
Field* f = cl->arrayField;
|
||||||
|
|
||||||
f.elementSize = sizeOf(module, f.typeName);
|
f->elementSize = sizeOf(module, f->typeName);
|
||||||
|
|
||||||
alignment = f.elementSize;
|
alignment = f->elementSize;
|
||||||
offset = (offset + alignment - 1) & ~(alignment - 1);
|
offset = (offset + alignment - 1) & ~(alignment - 1);
|
||||||
f.offset = offset;
|
f->offset = offset;
|
||||||
}
|
}
|
||||||
// offset = (offset + BytesPerWord - 1) & ~(BytesPerWord - 1);
|
// offset = (offset + BytesPerWord - 1) & ~(BytesPerWord - 1);
|
||||||
cl->fixedSize = offset;
|
cl->fixedSize = offset;
|
||||||
@ -858,10 +847,8 @@ void layoutClass(Module& module, Class* cl)
|
|||||||
|
|
||||||
void layoutClasses(Module& module)
|
void layoutClasses(Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
layoutClass(module, cl);
|
layoutClass(module, cl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -890,79 +877,69 @@ std::string cppClassName(Class* cl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cppFieldType(Module& module, Field& f)
|
std::string cppFieldType(Module& module, Field* f)
|
||||||
{
|
{
|
||||||
if (f.javaSpec.size() != 0) {
|
if (f->javaSpec.size() != 0) {
|
||||||
if (f.javaSpec[0] == 'L') {
|
if (f->javaSpec[0] == 'L') {
|
||||||
std::string className = f.javaSpec.substr(1, f.javaSpec.size() - 2);
|
std::string className = f->javaSpec.substr(1, f->javaSpec.size() - 2);
|
||||||
std::map<std::string, Class*>::iterator it
|
const auto it = module.javaClasses.find(className);
|
||||||
= module.javaClasses.find(className);
|
|
||||||
if (it != module.javaClasses.end()) {
|
if (it != module.javaClasses.end()) {
|
||||||
return cppClassName(it->second);
|
return cppClassName(it->second);
|
||||||
}
|
}
|
||||||
} else if (f.javaSpec[0] == '[') {
|
} else if (f->javaSpec[0] == '[') {
|
||||||
std::map<std::string, Class*>::iterator it
|
const auto it = module.javaClasses.find(f->javaSpec);
|
||||||
= module.javaClasses.find(f.javaSpec);
|
|
||||||
if (it != module.javaClasses.end()) {
|
if (it != module.javaClasses.end()) {
|
||||||
return cppClassName(it->second);
|
return cppClassName(it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
|
const auto it = module.classes.find(f->typeName);
|
||||||
assert(f.typeName.size() > 0);
|
assert(f->typeName.size() > 0);
|
||||||
if (it != module.classes.end()) {
|
if (it != module.classes.end()) {
|
||||||
return cppClassName(it->second);
|
return cppClassName(it->second);
|
||||||
} else if (f.typeName == "maybe_object") {
|
} else if (f->typeName == "maybe_object") {
|
||||||
return "uintptr_t";
|
return "uintptr_t";
|
||||||
} else {
|
} else {
|
||||||
return f.typeName;
|
return f->typeName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeAccessor(Output* out, Class* cl, Field& field)
|
void writeAccessor(Output* out, Class* cl, Field* f)
|
||||||
{
|
{
|
||||||
std::string typeName = field.typeName;
|
std::string typeName = f->typeName;
|
||||||
|
|
||||||
out->write("const unsigned ");
|
out->write("const unsigned ");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(field.name));
|
out->write(capitalize(f->name));
|
||||||
out->write(" = ");
|
out->write(" = ");
|
||||||
writeOffset(out, field.offset);
|
writeOffset(out, f->offset);
|
||||||
out->write(";\n\n");
|
out->write(";\n\n");
|
||||||
|
|
||||||
out->write("#define HAVE_");
|
out->write("#define HAVE_");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(field.name));
|
out->write(capitalize(f->name));
|
||||||
out->write(" 1\n\n");
|
out->write(" 1\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeAccessors(Output* out, Module& module)
|
void writeAccessors(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
for (const auto f : cl->fields) {
|
||||||
Class* cl = it->second;
|
if (!f->polyfill) {
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
|
||||||
it != cl->fields.end();
|
|
||||||
++it) {
|
|
||||||
Field& f = **it;
|
|
||||||
|
|
||||||
if (!f.polyfill) {
|
|
||||||
writeAccessor(out, cl, f);
|
writeAccessor(out, cl, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cl->arrayField) {
|
if (cl->arrayField) {
|
||||||
writeAccessor(out, cl, *cl->arrayField);
|
writeAccessor(out, cl, cl->arrayField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeSizes(Output* out, Module& module)
|
void writeSizes(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
|
|
||||||
out->write("const unsigned FixedSizeOf");
|
out->write("const unsigned FixedSizeOf");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
@ -992,43 +969,34 @@ std::string obfuscate(const std::string& s)
|
|||||||
|
|
||||||
void writeConstructorParameters(Output* out, Module& module, Class* cl)
|
void writeConstructorParameters(Output* out, Module& module, Class* cl)
|
||||||
{
|
{
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
if (!f->polyfill) {
|
||||||
++it) {
|
|
||||||
Field& f = **it;
|
|
||||||
if (!f.polyfill) {
|
|
||||||
out->write(", ");
|
out->write(", ");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(" ");
|
out->write(" ");
|
||||||
out->write(obfuscate(f.name));
|
out->write(obfuscate(f->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeConstructorArguments(Output* out, Class* cl)
|
void writeConstructorArguments(Output* out, Class* cl)
|
||||||
{
|
{
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
if (!f->polyfill) {
|
||||||
++it) {
|
|
||||||
Field& f = **it;
|
|
||||||
if (!f.polyfill) {
|
|
||||||
out->write(", ");
|
out->write(", ");
|
||||||
out->write(obfuscate(f.name));
|
out->write(obfuscate(f->name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeConstructorInitializations(Output* out, Class* cl)
|
void writeConstructorInitializations(Output* out, Class* cl)
|
||||||
{
|
{
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
if (!f->polyfill) {
|
||||||
++it) {
|
|
||||||
Field& f = **it;
|
|
||||||
if (!f.polyfill) {
|
|
||||||
out->write(" o->set");
|
out->write(" o->set");
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write("(t, ");
|
out->write("(t, ");
|
||||||
out->write(obfuscate(f.name));
|
out->write(obfuscate(f->name));
|
||||||
out->write(");\n");
|
out->write(");\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1036,10 +1004,8 @@ void writeConstructorInitializations(Output* out, Class* cl)
|
|||||||
|
|
||||||
void writeClassDeclarations(Output* out, Module& module)
|
void writeClassDeclarations(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
it++) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
|
|
||||||
out->write("class Gc");
|
out->write("class Gc");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
@ -1048,41 +1014,37 @@ void writeClassDeclarations(Output* out, Module& module)
|
|||||||
out->write("\n");
|
out->write("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFieldGcVisible(Module& module, Field& f)
|
bool isFieldGcVisible(Module& module, Field* f)
|
||||||
{
|
{
|
||||||
return enumName(module, f) == "object" && !f.nogc;
|
return enumName(module, f) == "object" && !f->nogc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFieldGcMarkable(Module& module, Field& f)
|
bool isFieldGcMarkable(Module& module, Field* f)
|
||||||
{
|
{
|
||||||
return (f.typeName == "maybe_object" || enumName(module, f) == "object")
|
return (f->typeName == "maybe_object" || enumName(module, f) == "object")
|
||||||
&& !f.nogc;
|
&& !f->nogc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeClassAccessors(Output* out, Module& module, Class* cl)
|
void writeClassAccessors(Output* out, Module& module, Class* cl)
|
||||||
{
|
{
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
if (!f->polyfill) {
|
||||||
++it) {
|
|
||||||
Field& f = **it;
|
|
||||||
|
|
||||||
if (!f.polyfill) {
|
|
||||||
out->write(" void set");
|
out->write(" void set");
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write("(Thread* t UNUSED, ");
|
out->write("(Thread* t UNUSED, ");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(" value) { ");
|
out->write(" value) { ");
|
||||||
if (isFieldGcMarkable(module, f)) {
|
if (isFieldGcMarkable(module, f)) {
|
||||||
out->write("setField(t, this , ");
|
out->write("setField(t, this , ");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write(", reinterpret_cast<object>(value));");
|
out->write(", reinterpret_cast<object>(value));");
|
||||||
} else {
|
} else {
|
||||||
out->write("field_at<");
|
out->write("field_at<");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(">(");
|
out->write(">(");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write(") = value;");
|
out->write(") = value;");
|
||||||
}
|
}
|
||||||
out->write(" }\n");
|
out->write(" }\n");
|
||||||
@ -1090,47 +1052,47 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
|
|||||||
out->write(" ");
|
out->write(" ");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write("* ");
|
out->write("* ");
|
||||||
out->write(obfuscate(f.name));
|
out->write(obfuscate(f->name));
|
||||||
out->write("Ptr() { return &field_at<");
|
out->write("Ptr() { return &field_at<");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(">(");
|
out->write(">(");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write("); }\n");
|
out->write("); }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
out->write(" ");
|
out->write(" ");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
if (!f.polyfill && !isFieldGcMarkable(module, f)) {
|
if (!f->polyfill && !isFieldGcMarkable(module, f)) {
|
||||||
out->write("&");
|
out->write("&");
|
||||||
}
|
}
|
||||||
out->write(" ");
|
out->write(" ");
|
||||||
out->write(obfuscate(f.name));
|
out->write(obfuscate(f->name));
|
||||||
if (f.threadParam || f.polyfill) {
|
if (f->threadParam || f->polyfill) {
|
||||||
out->write("(Thread*");
|
out->write("(Thread*");
|
||||||
} else {
|
} else {
|
||||||
out->write("(");
|
out->write("(");
|
||||||
}
|
}
|
||||||
if (f.polyfill) {
|
if (f->polyfill) {
|
||||||
out->write("); // polyfill, assumed to be implemented elsewhere\n");
|
out->write("); // polyfill, assumed to be implemented elsewhere\n");
|
||||||
} else {
|
} else {
|
||||||
out->write(") { return field_at<");
|
out->write(") { return field_at<");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(">(");
|
out->write(">(");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write("); }\n");
|
out->write("); }\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cl->arrayField) {
|
if (cl->arrayField) {
|
||||||
Field& f = *cl->arrayField;
|
Field* f = cl->arrayField;
|
||||||
out->write(" avian::util::Slice<");
|
out->write(" avian::util::Slice<");
|
||||||
if (isFieldGcVisible(module, f)) {
|
if (isFieldGcVisible(module, f)) {
|
||||||
out->write("const ");
|
out->write("const ");
|
||||||
}
|
}
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write("> ");
|
out->write("> ");
|
||||||
out->write(obfuscate(f.name));
|
out->write(obfuscate(f->name));
|
||||||
out->write("() { return avian::util::Slice<");
|
out->write("() { return avian::util::Slice<");
|
||||||
if (isFieldGcVisible(module, f)) {
|
if (isFieldGcVisible(module, f)) {
|
||||||
out->write("const ");
|
out->write("const ");
|
||||||
@ -1143,31 +1105,31 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
|
|||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(">(");
|
out->write(">(");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write("), field_at<uintptr_t>(");
|
out->write("), field_at<uintptr_t>(");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write("Length)); }\n");
|
out->write("Length)); }\n");
|
||||||
|
|
||||||
out->write(" void set");
|
out->write(" void set");
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write("Element(Thread* t UNUSED, size_t index, ");
|
out->write("Element(Thread* t UNUSED, size_t index, ");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(" value) { ");
|
out->write(" value) { ");
|
||||||
if (isFieldGcMarkable(module, f)) {
|
if (isFieldGcMarkable(module, f)) {
|
||||||
out->write("setField(t, this , ");
|
out->write("setField(t, this , ");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write(" + index * (");
|
out->write(" + index * (");
|
||||||
out->write(sizeOf(module, f.typeName));
|
out->write(sizeOf(module, f->typeName));
|
||||||
out->write("), reinterpret_cast<object>(value));");
|
out->write("), reinterpret_cast<object>(value));");
|
||||||
} else {
|
} else {
|
||||||
out->write("field_at<");
|
out->write("field_at<");
|
||||||
out->write(cppFieldType(module, f));
|
out->write(cppFieldType(module, f));
|
||||||
out->write(">(");
|
out->write(">(");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write(capitalize(f.name));
|
out->write(capitalize(f->name));
|
||||||
out->write(" + index * (");
|
out->write(" + index * (");
|
||||||
out->write(sizeOf(module, f.typeName));
|
out->write(sizeOf(module, f->typeName));
|
||||||
out->write(")) = value;");
|
out->write(")) = value;");
|
||||||
}
|
}
|
||||||
out->write(" }\n");
|
out->write(" }\n");
|
||||||
@ -1176,10 +1138,8 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
|
|||||||
|
|
||||||
void writeClasses(Output* out, Module& module)
|
void writeClasses(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
it++) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
|
|
||||||
out->write("class Gc");
|
out->write("class Gc");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
@ -1206,10 +1166,8 @@ void writeClasses(Output* out, Module& module)
|
|||||||
|
|
||||||
void writeInitializerDeclarations(Output* out, Module& module)
|
void writeInitializerDeclarations(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
out->write("void init");
|
out->write("void init");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write("(Thread* t, Gc");
|
out->write("(Thread* t, Gc");
|
||||||
@ -1224,10 +1182,8 @@ void writeInitializerDeclarations(Output* out, Module& module)
|
|||||||
|
|
||||||
void writeConstructorDeclarations(Output* out, Module& module)
|
void writeConstructorDeclarations(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
out->write("Gc");
|
out->write("Gc");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write("* make");
|
out->write("* make");
|
||||||
@ -1242,10 +1198,8 @@ void writeConstructorDeclarations(Output* out, Module& module)
|
|||||||
|
|
||||||
void writeInitializers(Output* out, Module& module)
|
void writeInitializers(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
out->write("void init");
|
out->write("void init");
|
||||||
out->write(capitalize(cl->name));
|
out->write(capitalize(cl->name));
|
||||||
out->write("(Thread* t, Gc");
|
out->write("(Thread* t, Gc");
|
||||||
@ -1271,10 +1225,8 @@ void writeInitializers(Output* out, Module& module)
|
|||||||
|
|
||||||
void writeConstructors(Output* out, Module& module)
|
void writeConstructors(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
|
|
||||||
bool hasObjectMask = cl->name == "singleton";
|
bool hasObjectMask = cl->name == "singleton";
|
||||||
|
|
||||||
@ -1309,21 +1261,18 @@ void writeConstructors(Output* out, Module& module)
|
|||||||
writeConstructorParameters(out, module, cl);
|
writeConstructorParameters(out, module, cl);
|
||||||
|
|
||||||
out->write(")\n{\n");
|
out->write(")\n{\n");
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
if (enumName(module, f) == "object" and not f->nogc) {
|
||||||
it++) {
|
|
||||||
Field& f = **it;
|
|
||||||
if (enumName(module, f) == "object" and not f.nogc) {
|
|
||||||
out->write(" PROTECT(t, ");
|
out->write(" PROTECT(t, ");
|
||||||
out->write(obfuscate(f.name));
|
out->write(obfuscate(f->name));
|
||||||
out->write(");\n");
|
out->write(");\n");
|
||||||
|
|
||||||
hasObjectMask = true;
|
hasObjectMask = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cl->arrayField) {
|
if (cl->arrayField) {
|
||||||
Field& f = *cl->arrayField;
|
Field* f = cl->arrayField;
|
||||||
if (f.typeName == "object" and not f.nogc) {
|
if (f->typeName == "object" and not f->nogc) {
|
||||||
hasObjectMask = true;
|
hasObjectMask = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1351,10 +1300,8 @@ void writeConstructors(Output* out, Module& module)
|
|||||||
void writeEnums(Output* out, Module& module)
|
void writeEnums(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
bool wrote = false;
|
bool wrote = false;
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
if (wrote) {
|
if (wrote) {
|
||||||
out->write(",\n");
|
out->write(",\n");
|
||||||
} else {
|
} else {
|
||||||
@ -1385,19 +1332,16 @@ uint32_t typeObjectMask(Module& module, Class* cl)
|
|||||||
|
|
||||||
uint32_t mask = 1;
|
uint32_t mask = 1;
|
||||||
|
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
unsigned offset = f->offset / BytesPerWord;
|
||||||
it++) {
|
|
||||||
Field& f = **it;
|
|
||||||
unsigned offset = f.offset / BytesPerWord;
|
|
||||||
if (isFieldGcVisible(module, f)) {
|
if (isFieldGcVisible(module, f)) {
|
||||||
set(&mask, offset);
|
set(&mask, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl->arrayField) {
|
if (cl->arrayField) {
|
||||||
Field& f = *cl->arrayField;
|
Field* f = cl->arrayField;
|
||||||
unsigned offset = f.offset / BytesPerWord;
|
unsigned offset = f->offset / BytesPerWord;
|
||||||
if (isFieldGcVisible(module, f)) {
|
if (isFieldGcVisible(module, f)) {
|
||||||
set(&mask, offset);
|
set(&mask, offset);
|
||||||
}
|
}
|
||||||
@ -1455,10 +1399,8 @@ void writeInitializations(Output* out, Module& module)
|
|||||||
writeInitialization(out, module, alreadyInited, module.classes["intArray"]);
|
writeInitialization(out, module, alreadyInited, module.classes["intArray"]);
|
||||||
writeInitialization(out, module, alreadyInited, module.classes["class"]);
|
writeInitialization(out, module, alreadyInited, module.classes["class"]);
|
||||||
|
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
if (cl->name != "intArray" && cl->name != "class") {
|
if (cl->name != "intArray" && cl->name != "class") {
|
||||||
writeInitialization(out, module, alreadyInited, cl);
|
writeInitialization(out, module, alreadyInited, cl);
|
||||||
}
|
}
|
||||||
@ -1493,10 +1435,8 @@ void writeJavaInitialization(Output* out, Class* cl)
|
|||||||
|
|
||||||
void writeJavaInitializations(Output* out, Module& module)
|
void writeJavaInitializations(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
if (cl->javaName.size()) {
|
if (cl->javaName.size()) {
|
||||||
writeJavaInitialization(out, cl);
|
writeJavaInitialization(out, cl);
|
||||||
}
|
}
|
||||||
@ -1521,10 +1461,8 @@ void writeNameInitialization(Output* out, Class* cl)
|
|||||||
|
|
||||||
void writeNameInitializations(Output* out, Module& module)
|
void writeNameInitializations(Output* out, Module& module)
|
||||||
{
|
{
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
if (!cl->javaName.size()) {
|
if (!cl->javaName.size()) {
|
||||||
writeNameInitialization(out, cl);
|
writeNameInitialization(out, cl);
|
||||||
}
|
}
|
||||||
@ -1534,14 +1472,10 @@ void writeNameInitializations(Output* out, Module& module)
|
|||||||
void writeMap(Output* out, Module& module, Class* cl)
|
void writeMap(Output* out, Module& module, Class* cl)
|
||||||
{
|
{
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
for (std::vector<Field*>::iterator it = cl->fields.begin();
|
for (const auto f : cl->fields) {
|
||||||
it != cl->fields.end();
|
|
||||||
it++) {
|
|
||||||
Field& f = **it;
|
|
||||||
|
|
||||||
ss << "Type_";
|
ss << "Type_";
|
||||||
ss << enumName(module, f);
|
ss << enumName(module, f);
|
||||||
if (f.nogc) {
|
if (f->nogc) {
|
||||||
ss << "_nogc";
|
ss << "_nogc";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1549,7 +1483,7 @@ void writeMap(Output* out, Module& module, Class* cl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cl->arrayField) {
|
if (cl->arrayField) {
|
||||||
Field& f = *cl->arrayField;
|
Field* f = cl->arrayField;
|
||||||
ss << "Type_array, ";
|
ss << "Type_array, ";
|
||||||
ss << "Type_";
|
ss << "Type_";
|
||||||
ss << enumName(module, f);
|
ss << enumName(module, f);
|
||||||
@ -1567,10 +1501,8 @@ void writeMaps(Output* out, Module& module)
|
|||||||
out->write(module.classes.size());
|
out->write(module.classes.size());
|
||||||
out->write("] = {\n");
|
out->write("] = {\n");
|
||||||
bool wrote = false;
|
bool wrote = false;
|
||||||
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
|
for (const auto p : module.classes) {
|
||||||
it != module.classes.end();
|
Class* cl = p.second;
|
||||||
++it) {
|
|
||||||
Class* cl = it->second;
|
|
||||||
if (wrote) {
|
if (wrote) {
|
||||||
out->write(",\n");
|
out->write(",\n");
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user