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:
* 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)
* JDK 1.5 or later
* JDK 1.6 or later
* MinGW 3.4 or later (only if compiling for Windows)
* 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
built using GCC.
The MSVC build has been tested with Visual Studio Express Edition
versions 8, 9, and 10. Other versions may also work.
*Note that the MSVC build isn't tested regularly, so is fairly likely to be broken.*
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
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 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 VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 9.0\VC"
$ export LIB="C:\Program Files\Microsoft Visual Studio 9.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 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 11.0\VC\LIB;"
$ export VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 11.0\VC"
$ 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 11.0\VC\INCLUDE;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include;"
Adjust these definitions as necessary according to your MSVC
installation.
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

View File

@ -25,6 +25,40 @@ class TraceHandler {
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 {
public:
class Client {
@ -83,12 +117,11 @@ class Compiler {
virtual unsigned topOfStack() = 0;
virtual ir::Value* peek(unsigned footprint, unsigned index) = 0;
virtual ir::Value* call(ir::Value* address,
unsigned flags,
TraceHandler* traceHandler,
ir::Type resultType,
unsigned argumentCount,
...) = 0;
virtual ir::Value* nativeCall(ir::Value* address,
unsigned flags,
TraceHandler* traceHandler,
ir::Type resultType,
util::Slice<ir::Value*> arguments) = 0;
virtual ir::Value* stackCall(ir::Value* address,
unsigned flags,
@ -110,7 +143,7 @@ class Compiler {
ir::Value* index,
intptr_t handler) = 0;
virtual ir::Value* truncateThenExtend(ir::SignExtendMode signExtend,
virtual ir::Value* truncateThenExtend(ir::ExtendMode extendMode,
ir::Type extendType,
ir::Type truncateType,
ir::Value* src) = 0;
@ -118,7 +151,7 @@ class Compiler {
virtual ir::Value* truncate(ir::Type type, ir::Value* src) = 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::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 {
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 "math.h"
#include "assert.h"
#include "cpp.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 T>
class Slice {
public:

View File

@ -378,7 +378,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
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) \
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
-DAVIAN_INFO="\"$(info)\"" \
@ -397,7 +397,7 @@ endif
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
"-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 \
-DAVIAN_TARGET_ARCH=AVIAN_ARCH_UNKNOWN \
-DAVIAN_TARGET_FORMAT=AVIAN_FORMAT_UNKNOWN \

View File

@ -2534,31 +2534,27 @@ class MyCompiler : public Compiler {
return s->value;
}
virtual ir::Value* call(ir::Value* address,
unsigned flags,
TraceHandler* traceHandler,
ir::Type resultType,
unsigned argumentCount,
...)
virtual ir::Value* nativeCall(ir::Value* address,
unsigned flags,
TraceHandler* traceHandler,
ir::Type resultType,
util::Slice<ir::Value*> arguments)
{
va_list a;
va_start(a, argumentCount);
bool bigEndian = c.arch->bigEndian();
unsigned footprint = 0;
unsigned size = TargetBytesPerWord;
RUNTIME_ARRAY(ir::Value*, arguments, argumentCount);
RUNTIME_ARRAY(ir::Value*, args, arguments.count);
int index = 0;
for (unsigned i = 0; i < argumentCount; ++i) {
Value* o = va_arg(a, Value*);
for (unsigned i = 0; i < arguments.count; ++i) {
Value* o = static_cast<Value*>(arguments[i]);
if (o) {
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) {
RUNTIME_ARRAY_BODY(arguments)[++index] = o->nextWord;
RUNTIME_ARRAY_BODY(args)[++index] = o->nextWord;
}
size = TargetBytesPerWord;
++index;
@ -2568,16 +2564,14 @@ class MyCompiler : public Compiler {
++footprint;
}
va_end(a);
Value* result = value(&c, resultType);
appendCall(&c,
static_cast<Value*>(address),
ir::NativeCallingConvention,
ir::CallingConvention::Native,
flags,
traceHandler,
result,
util::Slice<ir::Value*>(RUNTIME_ARRAY_BODY(arguments), index));
util::Slice<ir::Value*>(RUNTIME_ARRAY_BODY(args), index));
return result;
}
@ -2592,7 +2586,7 @@ class MyCompiler : public Compiler {
Stack* b UNUSED = c.stack;
appendCall(&c,
static_cast<Value*>(address),
ir::AvianCallingConvention,
ir::CallingConvention::Avian,
flags,
traceHandler,
result,
@ -2747,14 +2741,14 @@ class MyCompiler : public Compiler {
return dst;
}
virtual ir::Value* truncateThenExtend(ir::SignExtendMode signExtend,
virtual ir::Value* truncateThenExtend(ir::ExtendMode extendMode,
ir::Type extendType,
ir::Type truncateType,
ir::Value* src)
{
Value* dst = value(&c, extendType);
appendMove(&c,
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
extendMode == ir::ExtendMode::Signed ? lir::Move : lir::MoveZ,
TargetBytesPerWord,
truncateType.size(c.targetInfo),
static_cast<Value*>(src),
@ -2778,7 +2772,7 @@ class MyCompiler : public Compiler {
static_cast<Value*>(dst));
}
virtual ir::Value* load(ir::SignExtendMode signExtend,
virtual ir::Value* load(ir::ExtendMode extendMode,
ir::Value* src,
ir::Type dstType)
{
@ -2786,7 +2780,7 @@ class MyCompiler : public Compiler {
Value* dst = value(&c, dstType);
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),
static_cast<Value*>(src),

View File

@ -368,13 +368,13 @@ class CallEvent : public Event {
popIndex(0),
stackArgumentIndex(0),
flags(flags),
stackArgumentFootprint(callingConvention == ir::AvianCallingConvention
stackArgumentFootprint(callingConvention == ir::CallingConvention::Avian
? arguments.count
: 0)
{
uint32_t registerMask = c->regFile->generalRegisters.mask;
if (callingConvention == ir::NativeCallingConvention) {
if (callingConvention == ir::CallingConvention::Native) {
assertT(c, (flags & Compiler::TailJump) == 0);
assertT(c, stackArgumentFootprint == 0);
@ -450,7 +450,7 @@ class CallEvent : public Event {
Stack* stack = stackBefore;
if (callingConvention == ir::AvianCallingConvention) {
if (callingConvention == ir::CallingConvention::Avian) {
for (size_t i = 0; i < arguments.count; i++) {
stack = stack->next;
}
@ -1257,7 +1257,7 @@ void appendCombine(Context* c,
appendCall(c,
value(c, ir::Type::addr(), constantSite(c, handler)),
ir::NativeCallingConvention,
ir::CallingConvention::Native,
0,
0,
resultValue,
@ -1413,7 +1413,7 @@ void appendTranslate(Context* c,
op,
firstValue->type.size(c->targetInfo),
resultValue->type.size(c->targetInfo)))),
ir::NativeCallingConvention,
ir::CallingConvention::Native,
0,
0,
resultValue,
@ -1849,7 +1849,7 @@ void appendBranch(Context* c,
Value* result = value(c, ir::Type::addr());
appendCall(c,
value(c, ir::Type::addr(), constantSite(c, handler)),
ir::NativeCallingConvention,
ir::CallingConvention::Native,
0,
0,
result,

File diff suppressed because it is too large Load Diff

View File

@ -161,16 +161,12 @@ class Class {
}
ss << " {\n";
for (std::vector<Field*>::const_iterator it = fields.begin();
it != fields.end();
it++) {
ss << " " << (*it)->dump() << "\n";
for (const auto f : fields) {
ss << " " << f->dump() << "\n";
}
for (std::set<Method>::const_iterator it = methods.begin();
it != methods.end();
++it) {
ss << " " << it->dump() << "\n";
for (const auto m : methods) {
ss << " " << m.dump() << "\n";
}
ss << "}";
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());
}
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*") {
return "word";
} else if (type == "maybe_object") {
return "uintptr_t";
} else if (f.javaSpec.size() != 0
&& (f.javaSpec[0] == 'L' || f.javaSpec[0] == '[')) {
} else if (f->javaSpec.size() != 0
&& (f->javaSpec[0] == 'L' || f->javaSpec[0] == '[')) {
return "object";
}
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
assert(f.typeName.size() > 0);
const auto it = module.classes.find(f->typeName);
assert(f->typeName.size() > 0);
if (it != module.classes.end()) {
return "object";
} else {
return f.typeName;
return f->typeName;
}
}
@ -408,7 +404,7 @@ unsigned sizeOf(Module& module, const std::string& type)
} else if (namesPointer(type)) {
return BytesPerWord;
} else {
std::map<std::string, Class*>::iterator it = module.classes.find(type);
const auto it = module.classes.find(type);
if (it != module.classes.end()) {
return BytesPerWord;
} else {
@ -459,8 +455,7 @@ class ClassParser {
if (fields.find(f.field->name) != fields.end()) {
// printf("alias %s.%s -> %s.%s\n", cl->name.c_str(),
// f.field->name.c_str(), cl->name.c_str(), f.aliasName.c_str());
std::map<std::string, Field*>::iterator it
= fields.find(f.field->name);
const auto it = fields.find(f.field->name);
assert(it != fields.end());
Field* renamed = it->second;
fields.erase(it);
@ -474,11 +469,11 @@ class ClassParser {
renamed->javaSpec = f.field->javaSpec;
} else {
// 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 {
// 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());
}
} else {
@ -508,10 +503,8 @@ class ClassParser {
cl->super = super;
assert(!super->arrayField);
assert(fields.size() == 0);
for (std::vector<Field*>::iterator it = super->fields.begin();
it != super->fields.end();
it++) {
add(FieldSpec(false, *it));
for (const auto f : super->fields) {
add(FieldSpec(false, f));
}
}
};
@ -826,31 +819,27 @@ void layoutClass(Module& module, Class* cl)
alignment = BytesPerWord;
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it;
for (const auto f : cl->fields) {
f->elementSize = sizeOf(module, f->typeName);
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);
f.offset = offset;
f->offset = offset;
size = f.elementSize;
size = f->elementSize;
offset += size;
}
}
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);
f.offset = offset;
f->offset = offset;
}
// offset = (offset + BytesPerWord - 1) & ~(BytesPerWord - 1);
cl->fixedSize = offset;
@ -858,10 +847,8 @@ void layoutClass(Module& module, Class* cl)
void layoutClasses(Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
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[0] == 'L') {
std::string className = f.javaSpec.substr(1, f.javaSpec.size() - 2);
std::map<std::string, Class*>::iterator it
= module.javaClasses.find(className);
if (f->javaSpec.size() != 0) {
if (f->javaSpec[0] == 'L') {
std::string className = f->javaSpec.substr(1, f->javaSpec.size() - 2);
const auto it = module.javaClasses.find(className);
if (it != module.javaClasses.end()) {
return cppClassName(it->second);
}
} else if (f.javaSpec[0] == '[') {
std::map<std::string, Class*>::iterator it
= module.javaClasses.find(f.javaSpec);
} else if (f->javaSpec[0] == '[') {
const auto it = module.javaClasses.find(f->javaSpec);
if (it != module.javaClasses.end()) {
return cppClassName(it->second);
}
}
}
std::map<std::string, Class*>::iterator it = module.classes.find(f.typeName);
assert(f.typeName.size() > 0);
const auto it = module.classes.find(f->typeName);
assert(f->typeName.size() > 0);
if (it != module.classes.end()) {
return cppClassName(it->second);
} else if (f.typeName == "maybe_object") {
} else if (f->typeName == "maybe_object") {
return "uintptr_t";
} 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(capitalize(cl->name));
out->write(capitalize(field.name));
out->write(capitalize(f->name));
out->write(" = ");
writeOffset(out, field.offset);
writeOffset(out, f->offset);
out->write(";\n\n");
out->write("#define HAVE_");
out->write(capitalize(cl->name));
out->write(capitalize(field.name));
out->write(capitalize(f->name));
out->write(" 1\n\n");
}
void writeAccessors(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it;
if (!f.polyfill) {
for (const auto p : module.classes) {
Class* cl = p.second;
for (const auto f : cl->fields) {
if (!f->polyfill) {
writeAccessor(out, cl, f);
}
}
if (cl->arrayField) {
writeAccessor(out, cl, *cl->arrayField);
writeAccessor(out, cl, cl->arrayField);
}
}
}
void writeSizes(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
out->write("const unsigned FixedSizeOf");
out->write(capitalize(cl->name));
@ -992,43 +969,34 @@ std::string obfuscate(const std::string& s)
void writeConstructorParameters(Output* out, Module& module, Class* cl)
{
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it;
if (!f.polyfill) {
for (const auto f : cl->fields) {
if (!f->polyfill) {
out->write(", ");
out->write(cppFieldType(module, f));
out->write(" ");
out->write(obfuscate(f.name));
out->write(obfuscate(f->name));
}
}
}
void writeConstructorArguments(Output* out, Class* cl)
{
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it;
if (!f.polyfill) {
for (const auto f : cl->fields) {
if (!f->polyfill) {
out->write(", ");
out->write(obfuscate(f.name));
out->write(obfuscate(f->name));
}
}
}
void writeConstructorInitializations(Output* out, Class* cl)
{
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it;
if (!f.polyfill) {
for (const auto f : cl->fields) {
if (!f->polyfill) {
out->write(" o->set");
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write("(t, ");
out->write(obfuscate(f.name));
out->write(obfuscate(f->name));
out->write(");\n");
}
}
@ -1036,10 +1004,8 @@ void writeConstructorInitializations(Output* out, Class* cl)
void writeClassDeclarations(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
it++) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
out->write("class Gc");
out->write(capitalize(cl->name));
@ -1048,41 +1014,37 @@ void writeClassDeclarations(Output* out, Module& module)
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")
&& !f.nogc;
return (f->typeName == "maybe_object" || enumName(module, f) == "object")
&& !f->nogc;
}
void writeClassAccessors(Output* out, Module& module, Class* cl)
{
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
++it) {
Field& f = **it;
if (!f.polyfill) {
for (const auto f : cl->fields) {
if (!f->polyfill) {
out->write(" void set");
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write("(Thread* t UNUSED, ");
out->write(cppFieldType(module, f));
out->write(" value) { ");
if (isFieldGcMarkable(module, f)) {
out->write("setField(t, this , ");
out->write(capitalize(cl->name));
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write(", reinterpret_cast<object>(value));");
} else {
out->write("field_at<");
out->write(cppFieldType(module, f));
out->write(">(");
out->write(capitalize(cl->name));
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write(") = value;");
}
out->write(" }\n");
@ -1090,47 +1052,47 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
out->write(" ");
out->write(cppFieldType(module, f));
out->write("* ");
out->write(obfuscate(f.name));
out->write(obfuscate(f->name));
out->write("Ptr() { return &field_at<");
out->write(cppFieldType(module, f));
out->write(">(");
out->write(capitalize(cl->name));
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write("); }\n");
}
out->write(" ");
out->write(cppFieldType(module, f));
if (!f.polyfill && !isFieldGcMarkable(module, f)) {
if (!f->polyfill && !isFieldGcMarkable(module, f)) {
out->write("&");
}
out->write(" ");
out->write(obfuscate(f.name));
if (f.threadParam || f.polyfill) {
out->write(obfuscate(f->name));
if (f->threadParam || f->polyfill) {
out->write("(Thread*");
} else {
out->write("(");
}
if (f.polyfill) {
if (f->polyfill) {
out->write("); // polyfill, assumed to be implemented elsewhere\n");
} else {
out->write(") { return field_at<");
out->write(cppFieldType(module, f));
out->write(">(");
out->write(capitalize(cl->name));
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write("); }\n");
}
}
if (cl->arrayField) {
Field& f = *cl->arrayField;
Field* f = cl->arrayField;
out->write(" avian::util::Slice<");
if (isFieldGcVisible(module, f)) {
out->write("const ");
}
out->write(cppFieldType(module, f));
out->write("> ");
out->write(obfuscate(f.name));
out->write(obfuscate(f->name));
out->write("() { return avian::util::Slice<");
if (isFieldGcVisible(module, f)) {
out->write("const ");
@ -1143,31 +1105,31 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
out->write(cppFieldType(module, f));
out->write(">(");
out->write(capitalize(cl->name));
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write("), field_at<uintptr_t>(");
out->write(capitalize(cl->name));
out->write("Length)); }\n");
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(cppFieldType(module, f));
out->write(" value) { ");
if (isFieldGcMarkable(module, f)) {
out->write("setField(t, this , ");
out->write(capitalize(cl->name));
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write(" + index * (");
out->write(sizeOf(module, f.typeName));
out->write(sizeOf(module, f->typeName));
out->write("), reinterpret_cast<object>(value));");
} else {
out->write("field_at<");
out->write(cppFieldType(module, f));
out->write(">(");
out->write(capitalize(cl->name));
out->write(capitalize(f.name));
out->write(capitalize(f->name));
out->write(" + index * (");
out->write(sizeOf(module, f.typeName));
out->write(sizeOf(module, f->typeName));
out->write(")) = value;");
}
out->write(" }\n");
@ -1176,10 +1138,8 @@ void writeClassAccessors(Output* out, Module& module, Class* cl)
void writeClasses(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
it++) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
out->write("class Gc");
out->write(capitalize(cl->name));
@ -1206,10 +1166,8 @@ void writeClasses(Output* out, Module& module)
void writeInitializerDeclarations(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
out->write("void init");
out->write(capitalize(cl->name));
out->write("(Thread* t, Gc");
@ -1224,10 +1182,8 @@ void writeInitializerDeclarations(Output* out, Module& module)
void writeConstructorDeclarations(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
out->write("Gc");
out->write(capitalize(cl->name));
out->write("* make");
@ -1242,10 +1198,8 @@ void writeConstructorDeclarations(Output* out, Module& module)
void writeInitializers(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
out->write("void init");
out->write(capitalize(cl->name));
out->write("(Thread* t, Gc");
@ -1271,10 +1225,8 @@ void writeInitializers(Output* out, Module& module)
void writeConstructors(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
bool hasObjectMask = cl->name == "singleton";
@ -1309,21 +1261,18 @@ void writeConstructors(Output* out, Module& module)
writeConstructorParameters(out, module, cl);
out->write(")\n{\n");
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it;
if (enumName(module, f) == "object" and not f.nogc) {
for (const auto f : cl->fields) {
if (enumName(module, f) == "object" and not f->nogc) {
out->write(" PROTECT(t, ");
out->write(obfuscate(f.name));
out->write(obfuscate(f->name));
out->write(");\n");
hasObjectMask = true;
}
}
if (cl->arrayField) {
Field& f = *cl->arrayField;
if (f.typeName == "object" and not f.nogc) {
Field* f = cl->arrayField;
if (f->typeName == "object" and not f->nogc) {
hasObjectMask = true;
}
}
@ -1351,10 +1300,8 @@ void writeConstructors(Output* out, Module& module)
void writeEnums(Output* out, Module& module)
{
bool wrote = false;
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
if (wrote) {
out->write(",\n");
} else {
@ -1385,19 +1332,16 @@ uint32_t typeObjectMask(Module& module, Class* cl)
uint32_t mask = 1;
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it;
unsigned offset = f.offset / BytesPerWord;
for (const auto f : cl->fields) {
unsigned offset = f->offset / BytesPerWord;
if (isFieldGcVisible(module, f)) {
set(&mask, offset);
}
}
if (cl->arrayField) {
Field& f = *cl->arrayField;
unsigned offset = f.offset / BytesPerWord;
Field* f = cl->arrayField;
unsigned offset = f->offset / BytesPerWord;
if (isFieldGcVisible(module, f)) {
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["class"]);
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
if (cl->name != "intArray" && cl->name != "class") {
writeInitialization(out, module, alreadyInited, cl);
}
@ -1493,10 +1435,8 @@ void writeJavaInitialization(Output* out, Class* cl)
void writeJavaInitializations(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
if (cl->javaName.size()) {
writeJavaInitialization(out, cl);
}
@ -1521,10 +1461,8 @@ void writeNameInitialization(Output* out, Class* cl)
void writeNameInitializations(Output* out, Module& module)
{
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
if (!cl->javaName.size()) {
writeNameInitialization(out, cl);
}
@ -1534,14 +1472,10 @@ void writeNameInitializations(Output* out, Module& module)
void writeMap(Output* out, Module& module, Class* cl)
{
std::ostringstream ss;
for (std::vector<Field*>::iterator it = cl->fields.begin();
it != cl->fields.end();
it++) {
Field& f = **it;
for (const auto f : cl->fields) {
ss << "Type_";
ss << enumName(module, f);
if (f.nogc) {
if (f->nogc) {
ss << "_nogc";
}
@ -1549,7 +1483,7 @@ void writeMap(Output* out, Module& module, Class* cl)
}
if (cl->arrayField) {
Field& f = *cl->arrayField;
Field* f = cl->arrayField;
ss << "Type_array, ";
ss << "Type_";
ss << enumName(module, f);
@ -1567,10 +1501,8 @@ void writeMaps(Output* out, Module& module)
out->write(module.classes.size());
out->write("] = {\n");
bool wrote = false;
for (std::map<std::string, Class*>::iterator it = module.classes.begin();
it != module.classes.end();
++it) {
Class* cl = it->second;
for (const auto p : module.classes) {
Class* cl = p.second;
if (wrote) {
out->write(",\n");
} else {