Merge pull request #291 from joshuawarner32/cpp11

Begin using c++11 features
This commit is contained in:
Joel Dice 2014-07-24 13:13:30 -06:00
commit b811ca60c1
10 changed files with 522 additions and 592 deletions

View File

@ -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

View File

@ -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;

View File

@ -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
View 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

View File

@ -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:

View File

@ -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 \

View File

@ -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),

View File

@ -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,

File diff suppressed because it is too large Load Diff

View File

@ -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 {