mirror of
https://github.com/corda/corda.git
synced 2025-01-30 16:14:39 +00:00
provide bounds checking for array indexing; store bootstrap types in Machine::types
This commit is contained in:
parent
6756ade3bd
commit
36152603f4
9
makefile
9
makefile
@ -32,14 +32,19 @@ stdcpp-objects = $(call cpp-objects,$(stdcpp-sources),$(src))
|
|||||||
stdcpp-cflags = $(fast) $(cflags)
|
stdcpp-cflags = $(fast) $(cflags)
|
||||||
|
|
||||||
generated-code = \
|
generated-code = \
|
||||||
|
$(bld)/type-enums.cpp \
|
||||||
$(bld)/type-declarations.cpp \
|
$(bld)/type-declarations.cpp \
|
||||||
$(bld)/type-members.cpp \
|
|
||||||
$(bld)/type-constructors.cpp \
|
$(bld)/type-constructors.cpp \
|
||||||
$(bld)/type-initializations.cpp
|
$(bld)/type-initializations.cpp
|
||||||
interpreter-depends = \
|
interpreter-depends = \
|
||||||
$(generated-code) \
|
$(generated-code) \
|
||||||
|
$(src)/common.h \
|
||||||
|
$(src)/system.h \
|
||||||
$(src)/heap.h \
|
$(src)/heap.h \
|
||||||
$(src)/system.h
|
$(src)/class_finder.h \
|
||||||
|
$(src)/stream.h \
|
||||||
|
$(src)/constants.h \
|
||||||
|
$(src)/vm.h
|
||||||
interpreter-sources = \
|
interpreter-sources = \
|
||||||
$(src)/vm.cpp
|
$(src)/vm.cpp
|
||||||
interpreter-objects = $(call cpp-objects,$(interpreter-sources),$(src))
|
interpreter-objects = $(call cpp-objects,$(interpreter-sources),$(src))
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
|
||||||
class ClassFinder {
|
class ClassFinder {
|
||||||
public:
|
public:
|
||||||
virtual ~ClassFinder() { }
|
virtual ~ClassFinder() { }
|
||||||
@ -10,4 +12,6 @@ class ClassFinder {
|
|||||||
virtual void free(const uint8_t* class_) = 0;
|
virtual void free(const uint8_t* class_) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace vm
|
||||||
|
|
||||||
#endif//CLASS_FINDER_H
|
#endif//CLASS_FINDER_H
|
||||||
|
@ -992,9 +992,9 @@ writeSubtypeAssertions(Output* out, Object* o)
|
|||||||
{
|
{
|
||||||
for (Object* p = typeSubtypes(o); p; p = cdr(p)) {
|
for (Object* p = typeSubtypes(o); p; p = cdr(p)) {
|
||||||
Object* st = car(p);
|
Object* st = car(p);
|
||||||
out->write(" or objectClass(o) == t->vm->");
|
out->write(" or objectClass(o) == arrayBody(t, t->vm->types, Machine::");
|
||||||
out->write(typeName(st));
|
out->write(capitalize(typeName(st)));
|
||||||
out->write("Class");
|
out->write("Type)");
|
||||||
writeSubtypeAssertions(out, st);
|
writeSubtypeAssertions(out, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1007,7 +1007,11 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
|||||||
|
|
||||||
out->write("inline ");
|
out->write("inline ");
|
||||||
out->write(typeName);
|
out->write(typeName);
|
||||||
out->write(member->type == Object::Scalar ? "&" : "*");
|
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||||
|
out->write("*");
|
||||||
|
} else {
|
||||||
|
out->write("&");
|
||||||
|
}
|
||||||
out->write("\n");
|
out->write("\n");
|
||||||
writeAccessorName(out, member, true, unsafe);
|
writeAccessorName(out, member, true, unsafe);
|
||||||
if (memberOwner(member)->type == Object::Pod) {
|
if (memberOwner(member)->type == Object::Pod) {
|
||||||
@ -1020,32 +1024,40 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
|||||||
out->write(" o");
|
out->write(" o");
|
||||||
if (member->type != Object::Scalar) {
|
if (member->type != Object::Scalar) {
|
||||||
out->write(", unsigned i");
|
out->write(", unsigned i");
|
||||||
if (memberTypeObject(member) == 0) {
|
|
||||||
out->write(" = 0");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out->write(") {\n");
|
out->write(") {\n");
|
||||||
|
|
||||||
if (not unsafe and memberOwner(member)->type == Object::Type) {
|
if (not unsafe and memberOwner(member)->type == Object::Type) {
|
||||||
out->write(" assert(t, objectClass(o) == 0 or objectClass(o) == t->vm->");
|
out->write(" assert(t, objectClass(o) == 0 or ");
|
||||||
out->write(::typeName(memberOwner(member)));
|
out->write("objectClass(o) == arrayBody(t, t->vm->types, Machine::");
|
||||||
out->write("Class");
|
out->write(capitalize(::typeName(memberOwner(member))));
|
||||||
|
out->write("Type)");
|
||||||
writeSubtypeAssertions(out, memberOwner(member));
|
writeSubtypeAssertions(out, memberOwner(member));
|
||||||
out->write(");\n");
|
out->write(");\n");
|
||||||
|
|
||||||
|
if (member->type != Object::Scalar) {
|
||||||
|
out->write(" assert(t, i < ");
|
||||||
|
out->write(::typeName(memberOwner(member)));
|
||||||
|
out->write("Length(t, o));\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out->write(" return reinterpret_cast<");
|
out->write(" return reinterpret_cast<");
|
||||||
out->write(typeName);
|
out->write(typeName);
|
||||||
out->write(member->type == Object::Scalar ? "&" : "*");
|
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||||
|
out->write("*");
|
||||||
|
} else {
|
||||||
|
out->write("&");
|
||||||
|
}
|
||||||
if (memberOwner(member)->type == Object::Pod) {
|
if (memberOwner(member)->type == Object::Pod) {
|
||||||
out->write(">(o->body");
|
out->write(">(o->body");
|
||||||
} else {
|
} else {
|
||||||
out->write(">(static_cast<uint8_t*>(o)");
|
out->write(">(static_cast<uint8_t*>(o)");
|
||||||
}
|
}
|
||||||
if (member->type == Object::Scalar) {
|
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||||
out->write("[");
|
|
||||||
} else {
|
|
||||||
out->write(" + ");
|
out->write(" + ");
|
||||||
|
} else {
|
||||||
|
out->write("[");
|
||||||
}
|
}
|
||||||
writeOffset(out, offset);
|
writeOffset(out, offset);
|
||||||
if (member->type != Object::Scalar) {
|
if (member->type != Object::Scalar) {
|
||||||
@ -1056,7 +1068,7 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
|||||||
out->write(elementSize);
|
out->write(elementSize);
|
||||||
out->write(")");
|
out->write(")");
|
||||||
}
|
}
|
||||||
if (member->type == Object::Scalar) {
|
if (member->type == Object::Scalar or memberTypeObject(member) == 0) {
|
||||||
out->write("]");
|
out->write("]");
|
||||||
}
|
}
|
||||||
out->write(");\n}\n\n");
|
out->write(");\n}\n\n");
|
||||||
@ -1283,9 +1295,9 @@ writeConstructors(Output* out, Object* declarations)
|
|||||||
writeOffset(out, typeOffset(o), true);
|
writeOffset(out, typeOffset(o), true);
|
||||||
out->write(");\n");
|
out->write(");\n");
|
||||||
|
|
||||||
out->write(" objectClass(o) = t->vm->");
|
out->write(" objectClass(o) = arrayBody(t, t->vm->types, Machine::");
|
||||||
out->write(typeName(o));
|
out->write(capitalize(typeName(o)));
|
||||||
out->write("Class;\n");
|
out->write("Type);\n");
|
||||||
|
|
||||||
writeConstructorInitializations(out, o);
|
writeConstructorInitializations(out, o);
|
||||||
|
|
||||||
@ -1298,22 +1310,31 @@ writeConstructors(Output* out, Object* declarations)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
writeMembers(Output* out, Object* declarations)
|
writeEnums(Output* out, Object* declarations)
|
||||||
{
|
{
|
||||||
|
bool wrote = false;
|
||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
Object* o = car(p);
|
Object* o = car(p);
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case Object::Type: {
|
case Object::Type: {
|
||||||
if (typeMemberCount(o)) {
|
if (typeMemberCount(o)) {
|
||||||
out->write("object ");
|
if (wrote) {
|
||||||
out->write(typeName(o));
|
out->write(",\n");
|
||||||
out->write("Class;\n");
|
} else {
|
||||||
|
wrote = true;
|
||||||
|
}
|
||||||
|
out->write(capitalize(typeName(o)));
|
||||||
|
out->write("Type");
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wrote) {
|
||||||
|
out->write("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
@ -1425,41 +1446,69 @@ writeInitialization(Output* out, Object* type)
|
|||||||
if (typeObjectMask(type)) {
|
if (typeObjectMask(type)) {
|
||||||
out->write(" object mask = makeIntArray(t, 1);\n");
|
out->write(" object mask = makeIntArray(t, 1);\n");
|
||||||
|
|
||||||
out->write(" intArrayBody(t, mask)[0] = ");
|
out->write(" intArrayBody(t, mask, 0) = ");
|
||||||
out->write(typeObjectMask(type));
|
out->write(typeObjectMask(type));
|
||||||
out->write(";\n");
|
out->write(";\n");
|
||||||
} else {
|
} else {
|
||||||
out->write(" object mask = 0;\n");
|
out->write(" object mask = 0;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
out->write(" t->vm->");
|
out->write(" object class_ = makeClass");
|
||||||
out->write(typeName(type));
|
|
||||||
out->write("Class = makeClass");
|
|
||||||
out->write("(t, 0, ");
|
out->write("(t, 0, ");
|
||||||
out->write(typeFixedSize(type));
|
out->write(typeFixedSize(type));
|
||||||
out->write(", ");
|
out->write(", ");
|
||||||
out->write(typeArrayElementSize(type));
|
out->write(typeArrayElementSize(type));
|
||||||
out->write(", mask, 0, 0, 0, 0, 0, 0, 0, 0);\n");
|
out->write(", mask, 0, 0, 0, 0, 0, 0, 0, 0);\n");
|
||||||
|
|
||||||
|
out->write(" set(t, arrayBody(t, t->vm->types, Machine::");
|
||||||
|
out->write(capitalize(typeName(type)));
|
||||||
|
out->write("Type), class_);\n");
|
||||||
|
|
||||||
out->write("}\n\n");
|
out->write("}\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
typeCount(Object* declarations)
|
||||||
|
{
|
||||||
|
unsigned count = 0;
|
||||||
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
|
Object* o = car(p);
|
||||||
|
switch (o->type) {
|
||||||
|
case Object::Type: {
|
||||||
|
if (typeMemberCount(o)) {
|
||||||
|
++ count;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
writeInitializations(Output* out, Object* declarations)
|
writeInitializations(Output* out, Object* declarations)
|
||||||
{
|
{
|
||||||
|
out->write(" t->vm->types = makeArray(t, ");
|
||||||
|
out->write(typeCount(declarations));
|
||||||
|
out->write(");\n\n");
|
||||||
|
|
||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
Object* o = car(p);
|
Object* o = car(p);
|
||||||
if (o->type == Object::Type) {
|
if (o->type == Object::Type) {
|
||||||
writeInitialization(out, o);
|
writeInitialization(out, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out->write(" set(t, objectClass(t->vm->types), ");
|
||||||
|
out->write("arrayBody(t, t->vm->types, Machine::ArrayType));\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
usageAndExit(const char* command)
|
usageAndExit(const char* command)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s {declarations,members,constructors,initializations}\n",
|
"usage: %s {enums,declarations,constructors,initializations}\n",
|
||||||
command);
|
command);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
@ -1471,8 +1520,8 @@ main(int ac, char** av)
|
|||||||
{
|
{
|
||||||
if ((ac != 1 and ac != 2)
|
if ((ac != 1 and ac != 2)
|
||||||
or (ac == 2
|
or (ac == 2
|
||||||
|
and not equal(av[1], "enums")
|
||||||
and not equal(av[1], "declarations")
|
and not equal(av[1], "declarations")
|
||||||
and not equal(av[1], "members")
|
|
||||||
and not equal(av[1], "constructors")
|
and not equal(av[1], "constructors")
|
||||||
and not equal(av[1], "initializations")))
|
and not equal(av[1], "initializations")))
|
||||||
{
|
{
|
||||||
@ -1485,16 +1534,16 @@ main(int ac, char** av)
|
|||||||
|
|
||||||
FileOutput out(0, stdout, false);
|
FileOutput out(0, stdout, false);
|
||||||
|
|
||||||
|
if (ac == 1 or equal(av[1], "enums")) {
|
||||||
|
writeEnums(&out, declarations);
|
||||||
|
}
|
||||||
|
|
||||||
if (ac == 1 or equal(av[1], "declarations")) {
|
if (ac == 1 or equal(av[1], "declarations")) {
|
||||||
writePods(&out, declarations);
|
writePods(&out, declarations);
|
||||||
writeAccessors(&out, declarations);
|
writeAccessors(&out, declarations);
|
||||||
writeConstructorDeclarations(&out, declarations);
|
writeConstructorDeclarations(&out, declarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ac == 1 or equal(av[1], "members")) {
|
|
||||||
writeMembers(&out, declarations);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ac == 1 or equal(av[1], "constructors")) {
|
if (ac == 1 or equal(av[1], "constructors")) {
|
||||||
writeConstructors(&out, declarations);
|
writeConstructors(&out, declarations);
|
||||||
}
|
}
|
||||||
|
539
src/vm.cpp
539
src/vm.cpp
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user