begin enforcing more strong typing

This commit is contained in:
Joshua Warner 2014-05-02 09:01:57 -06:00
parent 43eb49cf53
commit cb7f570f20
3 changed files with 124 additions and 48 deletions

View File

@ -33,7 +33,11 @@ class Type {
// Represents the lack of a return value // Represents the lack of a return value
// TODO: remove when possible // TODO: remove when possible
Void Void,
// Represents some arbitrary type that should not be accessed
// TODO: remove when possible
Invalid
}; };
private: private:

View File

@ -1224,6 +1224,7 @@ unsigned typeFootprint(Context* c, ir::Type type)
case ir::Type::Object: case ir::Type::Object:
case ir::Type::Address: case ir::Type::Address:
case ir::Type::Half: case ir::Type::Half:
case ir::Type::Invalid:
return 1; return 1;
case ir::Type::Void: case ir::Type::Void:
return 0; return 0;
@ -1257,7 +1258,9 @@ Value* loadLocal(Context* c, ir::Type type, unsigned index)
|| c->locals[index].value->type.flavor() == ir::Type::Object || c->locals[index].value->type.flavor() == ir::Type::Object
// TODO: this is a very java-specific hole in the type system. Get // TODO: this is a very java-specific hole in the type system. Get
// rid of it: // rid of it:
|| c->locals[index].value->type.flavor() == ir::Type::Address); || c->locals[index].value->type.flavor() == ir::Type::Address
// TODO Temporary hack for Subroutine test!!!
|| c->locals[index].value->type.flavor() == ir::Type::Invalid);
return c->locals[index].value; return c->locals[index].value;
} }
@ -2279,7 +2282,7 @@ class MyCompiler: public Compiler {
for (unsigned li = 0; li < c.localFootprint; ++li) { for (unsigned li = 0; li < c.localFootprint; ++li) {
Local* local = c.locals + li; Local* local = c.locals + li;
if (local->value == 0) { if (local->value == 0) {
initLocal(1, li, ir::Type(ir::Type::Address, TargetBytesPerWord)); initLocal(1, li, ir::Type(ir::Type::Invalid, TargetBytesPerWord));
} }
} }
} }

View File

@ -1774,12 +1774,27 @@ class Frame {
return popQuiet(types.i8); return popQuiet(types.i8);
} }
void pushInt(ir::Value* o) void pushSmall(ir::Value* o)
{ {
pushQuiet(types.i4, o); pushQuiet(types.i4, o);
pushedInt(); pushedInt();
} }
void pushInt(ir::Value* o)
{
assert(t,
o->type.flavor() == ir::Type::Integer
// TODO Temporary hack for Subroutine test!!!
|| o->type.flavor() == ir::Type::Invalid);
pushSmall(o);
}
void pushFloat(ir::Value* o)
{
assert(t, o->type.flavor() == ir::Type::Float);
pushSmall(o);
}
void pushAddress(ir::Value* o) void pushAddress(ir::Value* o)
{ {
pushQuiet(types.i4, o); pushQuiet(types.i4, o);
@ -1788,7 +1803,11 @@ class Frame {
void pushObject(ir::Value* o) void pushObject(ir::Value* o)
{ {
assert(t, o->type == types.object || o->type.flavor() == ir::Type::Address); assert(t,
o->type == types.object
|| o->type.flavor() == ir::Type::Address
// TODO Temporary hack for Subroutine test!!!
|| o->type.flavor() == ir::Type::Invalid);
pushQuiet(types.object, o); pushQuiet(types.object, o);
pushedObject(); pushedObject();
} }
@ -1799,12 +1818,27 @@ class Frame {
pushedObject(); pushedObject();
} }
void pushLong(ir::Value* o) void pushLarge(ir::Value* o)
{ {
pushLongQuiet(o); pushLongQuiet(o);
pushedLong(); pushedLong();
} }
void pushLong(ir::Value* o)
{
assert(t,
o->type.flavor() == ir::Type::Integer
// TODO Temporary hack for Subroutine test!!!
|| o->type.flavor() == ir::Type::Invalid);
pushLarge(o);
}
void pushDouble(ir::Value* o)
{
assert(t, o->type.flavor() == ir::Type::Float);
pushLarge(o);
}
void pop(unsigned count) { void pop(unsigned count) {
popped(count); popped(count);
c->popped(count); c->popped(count);
@ -1833,11 +1867,23 @@ class Frame {
pushInt(loadLocal(context, 1, types.i4, index)); pushInt(loadLocal(context, 1, types.i4, index));
} }
void loadFloat(unsigned index)
{
assert(t, index < localSize());
pushFloat(loadLocal(context, 1, types.f4, index));
}
void loadLong(unsigned index) { void loadLong(unsigned index) {
assert(t, index < static_cast<unsigned>(localSize() - 1)); assert(t, index < static_cast<unsigned>(localSize() - 1));
pushLong(loadLocal(context, 2, types.i8, index)); pushLong(loadLocal(context, 2, types.i8, index));
} }
void loadDouble(unsigned index)
{
assert(t, index < static_cast<unsigned>(localSize() - 1));
pushDouble(loadLocal(context, 2, types.f8, index));
}
void loadObject(unsigned index) { void loadObject(unsigned index) {
assert(t, index < localSize()); assert(t, index < localSize());
pushObject(loadLocal(context, 1, types.object, index)); pushObject(loadLocal(context, 1, types.object, index));
@ -2018,16 +2064,18 @@ class Frame {
case BooleanField: case BooleanField:
case CharField: case CharField:
case ShortField: case ShortField:
case FloatField:
case IntField: case IntField:
return pushInt(result); return pushInt(result);
case FloatField:
return pushFloat(result);
case ObjectField: case ObjectField:
return pushObject(result); return pushObject(result);
case LongField: case LongField:
case DoubleField:
return pushLong(result); return pushLong(result);
case DoubleField:
return pushDouble(result);
default: default:
abort(t); abort(t);
@ -3776,7 +3824,7 @@ intrinsic(MyThread* t, Frame* frame, object target)
if (MATCH(methodName(t, target), "sqrt") if (MATCH(methodName(t, target), "sqrt")
and MATCH(methodSpec(t, target), "(D)D")) and MATCH(methodSpec(t, target), "(D)D"))
{ {
frame->pushLong( frame->pushDouble(
c->unaryOp(lir::FloatSquareRoot, types.f8, frame->popLong())); c->unaryOp(lir::FloatSquareRoot, types.f8, frame->popLong()));
return true; return true;
} else if (MATCH(methodName(t, target), "abs")) { } else if (MATCH(methodName(t, target), "abs")) {
@ -3787,7 +3835,7 @@ intrinsic(MyThread* t, Frame* frame, object target)
frame->pushLong(c->unaryOp(lir::Absolute, types.i8, frame->popLong())); frame->pushLong(c->unaryOp(lir::Absolute, types.i8, frame->popLong()));
return true; return true;
} else if (MATCH(methodSpec(t, target), "(F)F")) { } else if (MATCH(methodSpec(t, target), "(F)F")) {
frame->pushInt( frame->pushFloat(
c->unaryOp(lir::FloatAbsolute, types.f4, frame->popInt())); c->unaryOp(lir::FloatAbsolute, types.f4, frame->popInt()));
return true; return true;
} }
@ -3841,7 +3889,7 @@ intrinsic(MyThread* t, Frame* frame, object target)
{ {
ir::Value* address = popLongAddress(frame); ir::Value* address = popLongAddress(frame);
frame->popObject(); frame->popObject();
frame->pushInt( frame->pushSmall(
c->load(ir::SignExtend, c->load(ir::SignExtend,
types.i4, types.i4,
c->memory(address, c->memory(address,
@ -3868,7 +3916,7 @@ intrinsic(MyThread* t, Frame* frame, object target)
{ {
ir::Value* address = popLongAddress(frame); ir::Value* address = popLongAddress(frame);
frame->popObject(); frame->popObject();
frame->pushLong( frame->pushLarge(
c->load(ir::SignExtend, c->load(ir::SignExtend,
types.i8, types.i8,
c->memory(address, c->memory(address,
@ -4149,13 +4197,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
case aaload: case aaload:
frame->pushObject( frame->pushObject(
c->load(ir::SignExtend, c->load(ir::SignExtend,
types.address, types.object,
c->memory(array, types.object, TargetArrayBody, index), c->memory(array, types.object, TargetArrayBody, index),
types.address)); types.object));
break; break;
case faload: case faload:
frame->pushInt( frame->pushFloat(
c->load(ir::SignExtend, c->load(ir::SignExtend,
types.f4, types.f4,
c->memory(array, types.f4, TargetArrayBody, index), c->memory(array, types.f4, TargetArrayBody, index),
@ -4187,7 +4235,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
break; break;
case daload: case daload:
frame->pushLong( frame->pushDouble(
c->load(ir::SignExtend, c->load(ir::SignExtend,
types.f8, types.f8,
c->memory(array, types.f8, TargetArrayBody, index), c->memory(array, types.f8, TargetArrayBody, index),
@ -4440,7 +4488,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break; } break;
case d2f: { case d2f: {
frame->pushInt(c->f2f(types.f8, types.f4, frame->popLong())); frame->pushFloat(c->f2f(types.f8, types.f4, frame->popLong()));
} break; } break;
case d2i: { case d2i: {
@ -4459,7 +4507,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
ir::Value* a = frame->popLong(); ir::Value* a = frame->popLong();
ir::Value* b = frame->popLong(); ir::Value* b = frame->popLong();
frame->pushLong( frame->pushDouble(
c->binaryOp(toCompilerBinaryOp(t, instruction), types.f8, a, b)); c->binaryOp(toCompilerBinaryOp(t, instruction), types.f8, a, b));
} break; } break;
@ -4504,15 +4552,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break; } break;
case dconst_0: case dconst_0:
frame->pushLong(c->constant(doubleToBits(0.0), types.f4)); frame->pushDouble(c->constant(doubleToBits(0.0), types.f4));
break; break;
case dconst_1: case dconst_1:
frame->pushLong(c->constant(doubleToBits(1.0), types.f4)); frame->pushDouble(c->constant(doubleToBits(1.0), types.f4));
break; break;
case dneg: { case dneg: {
frame->pushLong(c->unaryOp(lir::FloatNegate, types.f8, frame->popLong())); frame->pushDouble(
c->unaryOp(lir::FloatNegate, types.f8, frame->popLong()));
} break; } break;
case dup: case dup:
@ -4540,7 +4589,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
break; break;
case f2d: { case f2d: {
frame->pushLong(c->f2f(types.f4, types.f8, frame->popInt())); frame->pushDouble(c->f2f(types.f4, types.f8, frame->popInt()));
} break; } break;
case f2i: { case f2i: {
@ -4559,7 +4608,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
ir::Value* a = frame->popInt(); ir::Value* a = frame->popInt();
ir::Value* b = frame->popInt(); ir::Value* b = frame->popInt();
frame->pushInt( frame->pushFloat(
c->binaryOp(toCompilerBinaryOp(t, instruction), types.f4, a, b)); c->binaryOp(toCompilerBinaryOp(t, instruction), types.f4, a, b));
} break; } break;
@ -4600,19 +4649,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break; } break;
case fconst_0: case fconst_0:
frame->pushInt(c->constant(floatToBits(0.0), types.f4)); frame->pushFloat(c->constant(floatToBits(0.0), types.f4));
break; break;
case fconst_1: case fconst_1:
frame->pushInt(c->constant(floatToBits(1.0), types.f4)); frame->pushFloat(c->constant(floatToBits(1.0), types.f4));
break; break;
case fconst_2: case fconst_2:
frame->pushInt(c->constant(floatToBits(2.0), types.f4)); frame->pushFloat(c->constant(floatToBits(2.0), types.f4));
break; break;
case fneg: { case fneg: {
frame->pushInt(c->unaryOp(lir::FloatNegate, types.f4, frame->popInt())); frame->pushFloat(c->unaryOp(lir::FloatNegate, types.f4, frame->popInt()));
} break; } break;
case getfield: case getfield:
@ -4700,7 +4749,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
break; break;
case FloatField: case FloatField:
frame->pushInt(c->load( frame->pushFloat(c->load(
ir::SignExtend, ir::SignExtend,
types.f4, types.f4,
c->memory(table, types.f4, targetFieldOffset(context, field)), c->memory(table, types.f4, targetFieldOffset(context, field)),
@ -4716,7 +4765,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
break; break;
case DoubleField: case DoubleField:
frame->pushLong(c->load( frame->pushDouble(c->load(
ir::SignExtend, ir::SignExtend,
types.f8, types.f8,
c->memory(table, types.f8, targetFieldOffset(context, field)), c->memory(table, types.f8, targetFieldOffset(context, field)),
@ -4734,9 +4783,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
case ObjectField: case ObjectField:
frame->pushObject(c->load( frame->pushObject(c->load(
ir::SignExtend, ir::SignExtend,
types.address, types.object,
c->memory(table, types.object, targetFieldOffset(context, field)), c->memory(table, types.object, targetFieldOffset(context, field)),
types.address)); types.object));
break; break;
default: default:
@ -4835,11 +4884,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break; } break;
case i2d: { case i2d: {
frame->pushLong(c->i2f(types.i4, types.f8, frame->popInt())); frame->pushDouble(c->i2f(types.i4, types.f8, frame->popInt()));
} break; } break;
case i2f: { case i2f: {
frame->pushInt(c->i2f(types.i4, types.f4, frame->popInt())); frame->pushFloat(c->i2f(types.i4, types.f4, frame->popInt()));
} break; } break;
case i2l: case i2l:
@ -4998,29 +5047,39 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break; } break;
case iload: case iload:
case fload:
frame->loadInt(codeBody(t, code, ip++)); frame->loadInt(codeBody(t, code, ip++));
break; break;
case fload:
frame->loadFloat(codeBody(t, code, ip++));
break;
case iload_0: case iload_0:
case fload_0:
frame->loadInt(0); frame->loadInt(0);
break; break;
case fload_0:
frame->loadFloat(0);
break;
case iload_1: case iload_1:
case fload_1:
frame->loadInt(1); frame->loadInt(1);
break; break;
case fload_1:
frame->loadFloat(1);
break;
case iload_2: case iload_2:
case fload_2:
frame->loadInt(2); frame->loadInt(2);
break; break;
case fload_2:
frame->loadFloat(2);
break;
case iload_3: case iload_3:
case fload_3:
frame->loadInt(3); frame->loadInt(3);
break; break;
case fload_3:
frame->loadFloat(3);
break;
case ineg: { case ineg: {
frame->pushInt(c->unaryOp(lir::Negate, types.i4, frame->popInt())); frame->pushInt(c->unaryOp(lir::Negate, types.i4, frame->popInt()));
@ -5322,11 +5381,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} goto start; } goto start;
case l2d: { case l2d: {
frame->pushLong(c->i2f(types.i8, types.f8, frame->popLong())); frame->pushDouble(c->i2f(types.i8, types.f8, frame->popLong()));
} break; } break;
case l2f: { case l2f: {
frame->pushInt(c->i2f(types.i8, types.f4, frame->popLong())); frame->pushFloat(c->i2f(types.i8, types.f4, frame->popLong()));
} break; } break;
case l2i: case l2i:
@ -5424,7 +5483,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} }
} }
} else { } else {
frame->pushInt(c->constant( frame->pushSmall(c->constant(
singletonValue(t, pool, index - 1), singletonValue(t, pool, index - 1),
singletonBit(t, pool, poolSize(t, pool), index - 1) ? types.f4 singletonBit(t, pool, poolSize(t, pool), index - 1) ? types.f4
: types.i4)); : types.i4));
@ -5438,7 +5497,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
uint64_t v; uint64_t v;
memcpy(&v, &singletonValue(t, pool, index - 1), 8); memcpy(&v, &singletonValue(t, pool, index - 1), 8);
frame->pushLong(c->constant( frame->pushLarge(c->constant(
v, v,
singletonBit(t, pool, poolSize(t, pool), index - 1) ? types.f8 singletonBit(t, pool, poolSize(t, pool), index - 1) ? types.f8
: types.i8)); : types.i8));
@ -5457,29 +5516,39 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
} break; } break;
case lload: case lload:
case dload:
frame->loadLong(codeBody(t, code, ip++)); frame->loadLong(codeBody(t, code, ip++));
break; break;
case dload:
frame->loadDouble(codeBody(t, code, ip++));
break;
case lload_0: case lload_0:
case dload_0:
frame->loadLong(0); frame->loadLong(0);
break; break;
case dload_0:
frame->loadDouble(0);
break;
case lload_1: case lload_1:
case dload_1:
frame->loadLong(1); frame->loadLong(1);
break; break;
case dload_1:
frame->loadDouble(1);
break;
case lload_2: case lload_2:
case dload_2:
frame->loadLong(2); frame->loadLong(2);
break; break;
case dload_2:
frame->loadDouble(2);
break;
case lload_3: case lload_3:
case dload_3:
frame->loadLong(3); frame->loadLong(3);
break; break;
case dload_3:
frame->loadDouble(3);
break;
case lneg: case lneg:
frame->pushLong(c->unaryOp(lir::Negate, types.i8, frame->popLong())); frame->pushLong(c->unaryOp(lir::Negate, types.i8, frame->popLong()));
@ -5821,7 +5890,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp,
value, value,
c->memory(table, types.i2, targetFieldOffset(context, field))); c->memory(table, types.i2, targetFieldOffset(context, field)));
break; break;
case FloatField: case FloatField:
c->store( c->store(
types.f4, types.f4,