provide bounds checking for array indexing; store bootstrap types in Machine::types

This commit is contained in:
Joel Dice 2007-06-18 15:13:21 -06:00
parent 6756ade3bd
commit 36152603f4
4 changed files with 405 additions and 262 deletions

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff