From 82394c331d93a62510584de9a59fd0c24ba9d71d Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Thu, 1 Aug 2024 16:25:52 +0100 Subject: [PATCH 1/6] Apply clang-format --- src/Main.cpp | 41 +- src/compiler/BytecodeGenerator.cpp | 88 ++-- src/compiler/BytecodeGenerator.h | 30 +- src/compiler/ClassGenerationContext.cpp | 31 +- src/compiler/ClassGenerationContext.h | 20 +- src/compiler/Disassembler.cpp | 266 ++++++---- src/compiler/Disassembler.h | 8 +- src/compiler/Lexer.cpp | 106 ++-- src/compiler/Lexer.h | 32 +- src/compiler/LexicalScope.h | 16 +- src/compiler/MethodGenerationContext.cpp | 103 ++-- src/compiler/MethodGenerationContext.h | 45 +- src/compiler/Parser.cpp | 246 ++++----- src/compiler/Parser.h | 11 +- src/compiler/SourceCoordinate.h | 4 +- src/compiler/SourcecodeCompiler.cpp | 22 +- src/compiler/SourcecodeCompiler.h | 9 +- src/compiler/Variable.cpp | 6 +- src/compiler/Variable.h | 23 +- src/interpreter/Interpreter.cpp | 129 +++-- src/interpreter/Interpreter.h | 48 +- src/interpreter/InterpreterLoop.h | 309 ++++++----- src/interpreter/bytecodes.cpp | 173 +++---- src/interpreter/bytecodes.h | 21 +- src/memory/CopyingCollector.cpp | 16 +- src/memory/CopyingCollector.h | 3 +- src/memory/CopyingHeap.cpp | 31 +- src/memory/CopyingHeap.h | 1 + src/memory/DebugCopyingCollector.cpp | 10 +- src/memory/DebugCopyingCollector.h | 8 +- src/memory/DebugCopyingHeap.cpp | 18 +- src/memory/DebugCopyingHeap.h | 11 +- src/memory/GarbageCollector.h | 1 + src/memory/GenerationalCollector.cpp | 38 +- src/memory/GenerationalCollector.h | 2 +- src/memory/GenerationalHeap.cpp | 23 +- src/memory/GenerationalHeap.h | 25 +- src/memory/Heap.cpp | 24 +- src/memory/Heap.h | 23 +- src/memory/MarkSweepCollector.cpp | 20 +- src/memory/MarkSweepCollector.h | 5 +- src/memory/MarkSweepHeap.cpp | 18 +- src/memory/MarkSweepHeap.h | 4 +- src/misc/ParseInteger.cpp | 42 +- src/misc/StringUtil.h | 6 +- src/misc/Timer.h | 16 +- src/misc/VectorUtil.h | 4 +- src/misc/debug.cpp | 4 +- src/misc/debug.h | 20 +- src/misc/defs.h | 67 ++- src/misc/gettimeofday.h | 21 +- src/primitives/Array.cpp | 11 +- src/primitives/Array.h | 2 +- src/primitives/Block.cpp | 11 +- src/primitives/Block.h | 5 +- src/primitives/Class.cpp | 17 +- src/primitives/Class.h | 10 +- src/primitives/Double.cpp | 102 ++-- src/primitives/Double.h | 2 +- src/primitives/Integer.cpp | 152 +++--- src/primitives/Integer.h | 9 +- src/primitives/Method.cpp | 24 +- src/primitives/Method.h | 7 +- src/primitives/Object.cpp | 73 ++- src/primitives/Object.h | 4 +- src/primitives/Primitive.cpp | 24 +- src/primitives/Primitive.h | 7 +- src/primitives/String.cpp | 42 +- src/primitives/String.h | 2 +- src/primitives/Symbol.cpp | 7 +- src/primitives/Symbol.h | 2 +- src/primitives/System.cpp | 76 +-- src/primitives/System.h | 2 +- src/primitivesCore/PrimitiveContainer.cpp | 7 +- src/primitivesCore/PrimitiveContainer.h | 21 +- src/primitivesCore/PrimitiveLoader.cpp | 38 +- src/primitivesCore/PrimitiveLoader.h | 19 +- src/primitivesCore/Routine.h | 24 +- src/unitTests/BasicInterpreterTests.h | 355 ++++++------- src/unitTests/BytecodeGenerationTest.cpp | 603 +++++++++------------- src/unitTests/BytecodeGenerationTest.h | 53 +- src/unitTests/CloneObjectsTest.cpp | 205 +++++--- src/unitTests/CloneObjectsTest.h | 36 +- src/unitTests/WalkObjectsTest.cpp | 46 +- src/unitTests/WalkObjectsTest.h | 37 +- src/unitTests/WriteBarrierTest.cpp | 167 +++--- src/unitTests/WriteBarrierTest.h | 25 +- src/unitTests/main.cpp | 19 +- src/vm/Globals.cpp | 3 +- src/vm/IsValidObject.cpp | 105 ++-- src/vm/IsValidObject.h | 1 - src/vm/LogAllocation.cpp | 16 +- src/vm/LogAllocation.h | 15 +- src/vm/Print.cpp | 3 +- src/vm/Print.h | 1 - src/vm/Shell.cpp | 12 +- src/vm/Shell.h | 14 +- src/vm/Symbols.cpp | 25 +- src/vm/Universe.cpp | 401 +++++++------- src/vm/Universe.h | 25 +- src/vmobjects/AbstractObject.cpp | 6 +- src/vmobjects/AbstractObject.h | 32 +- src/vmobjects/IntegerBox.cpp | 1 + src/vmobjects/IntegerBox.h | 2 +- src/vmobjects/ObjectFormats.h | 98 ++-- src/vmobjects/PrimitiveRoutine.h | 2 +- src/vmobjects/Signature.cpp | 42 +- src/vmobjects/Signature.h | 2 +- src/vmobjects/VMArray.cpp | 20 +- src/vmobjects/VMArray.h | 11 +- src/vmobjects/VMBlock.cpp | 14 +- src/vmobjects/VMBlock.h | 16 +- src/vmobjects/VMClass.cpp | 94 ++-- src/vmobjects/VMClass.h | 58 ++- src/vmobjects/VMDouble.cpp | 3 +- src/vmobjects/VMDouble.h | 10 +- src/vmobjects/VMEvaluationPrimitive.cpp | 20 +- src/vmobjects/VMEvaluationPrimitive.h | 20 +- src/vmobjects/VMFrame.cpp | 80 +-- src/vmobjects/VMFrame.h | 14 +- src/vmobjects/VMInteger.cpp | 3 +- src/vmobjects/VMInteger.h | 14 +- src/vmobjects/VMInvokable.cpp | 3 +- src/vmobjects/VMInvokable.h | 20 +- src/vmobjects/VMMethod.cpp | 166 ++++-- src/vmobjects/VMMethod.h | 117 ++--- src/vmobjects/VMObject.cpp | 18 +- src/vmobjects/VMObject.h | 38 +- src/vmobjects/VMObjectBase.h | 14 +- src/vmobjects/VMPrimitive.cpp | 19 +- src/vmobjects/VMPrimitive.h | 35 +- src/vmobjects/VMString.cpp | 27 +- src/vmobjects/VMString.h | 21 +- src/vmobjects/VMSymbol.cpp | 131 ++--- src/vmobjects/VMSymbol.h | 7 +- 135 files changed, 3369 insertions(+), 2924 deletions(-) diff --git a/src/Main.cpp b/src/Main.cpp index 41b1c9dd..dc351161 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -22,55 +22,50 @@ THE SOFTWARE. */ -#include #include +#include #include "compiler/ClassGenerationContext.h" - #include "memory/Heap.h" - #include "misc/defs.h" - #include "vm/Universe.h" - -#include "vmobjects/VMObject.h" +#include "vmobjects/ObjectFormats.h" +#include "vmobjects/VMArray.h" #include "vmobjects/VMMethod.h" +#include "vmobjects/VMObject.h" #include "vmobjects/VMString.h" -#include "vmobjects/VMArray.h" -#include "vmobjects/ObjectFormats.h" int main(int argc, char** argv) { - cout << "This is SOM++" << endl; - if (GC_TYPE == GENERATIONAL) + if (GC_TYPE == GENERATIONAL) { cout << "\tgarbage collector: generational" << endl; - else if (GC_TYPE == COPYING) + } else if (GC_TYPE == COPYING) { cout << "\tgarbage collector: copying" << endl; - else if (GC_TYPE == MARK_SWEEP) + } else if (GC_TYPE == MARK_SWEEP) { cout << "\tgarbage collector: mark-sweep" << endl; - else if (GC_TYPE == DEBUG_COPYING) + } else if (GC_TYPE == DEBUG_COPYING) { cout << "\tgarbage collector: debug copying" << endl; - else + } else { cout << "\tgarbage collector: unknown" << endl; + } - if (USE_TAGGING) + if (USE_TAGGING) { cout << "\twith tagged integers" << endl; - else + } else { cout << "\tnot tagging integers" << endl; + } - if (CACHE_INTEGER) - cout << "\tcaching integers from " << INT_CACHE_MIN_VALUE - << " to " << INT_CACHE_MAX_VALUE << endl; - else + if (CACHE_INTEGER) { + cout << "\tcaching integers from " << INT_CACHE_MIN_VALUE << " to " + << INT_CACHE_MAX_VALUE << endl; + } else { cout << "\tnot caching integers" << endl; - + } cout << "--------------------------------------" << endl; - Universe::Start(argc, argv); Universe::Quit(ERR_SUCCESS); } - diff --git a/src/compiler/BytecodeGenerator.cpp b/src/compiler/BytecodeGenerator.cpp index 83ca5520..f4426658 100644 --- a/src/compiler/BytecodeGenerator.cpp +++ b/src/compiler/BytecodeGenerator.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "BytecodeGenerator.h" + #include #include #include @@ -36,18 +38,20 @@ #include "../vmobjects/Signature.h" #include "../vmobjects/VMMethod.h" #include "../vmobjects/VMSymbol.h" -#include "BytecodeGenerator.h" -void Emit1(MethodGenerationContext& mgenc, uint8_t bytecode, size_t stackEffect) { +void Emit1(MethodGenerationContext& mgenc, uint8_t bytecode, + size_t stackEffect) { mgenc.AddBytecode(bytecode, stackEffect); } -void Emit2(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, size_t stackEffect) { +void Emit2(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, + size_t stackEffect) { mgenc.AddBytecode(bytecode, stackEffect); mgenc.AddBytecodeArgument(idx); } -void Emit3(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, size_t ctx, size_t stackEffect) { +void Emit3(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, + size_t ctx, size_t stackEffect) { mgenc.AddBytecode(bytecode, stackEffect); mgenc.AddBytecodeArgument(idx); mgenc.AddBytecodeArgument(ctx); @@ -61,8 +65,7 @@ void EmitDUP(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_DUP, 1); } -void EmitPUSHLOCAL(MethodGenerationContext& mgenc, long idx, - int ctx) { +void EmitPUSHLOCAL(MethodGenerationContext& mgenc, long idx, int ctx) { assert(idx >= 0); assert(ctx >= 0); if (ctx == 0) { @@ -82,8 +85,7 @@ void EmitPUSHLOCAL(MethodGenerationContext& mgenc, long idx, Emit3(mgenc, BC_PUSH_LOCAL, idx, ctx, 1); } -void EmitPUSHARGUMENT(MethodGenerationContext& mgenc, - long idx, int ctx) { +void EmitPUSHARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx) { assert(idx >= 0); assert(ctx >= 0); @@ -162,13 +164,11 @@ void EmitPUSHCONSTANT(MethodGenerationContext& mgenc, vm_oop_t cst) { Emit2(mgenc, BC_PUSH_CONSTANT, idx, 1); } -void EmitPUSHCONSTANT(MethodGenerationContext& mgenc, - uint8_t literalIndex) { +void EmitPUSHCONSTANT(MethodGenerationContext& mgenc, uint8_t literalIndex) { Emit2(mgenc, BC_PUSH_CONSTANT, literalIndex, 1); } -void EmitPUSHCONSTANTString(MethodGenerationContext& mgenc, - VMString* str) { +void EmitPUSHCONSTANTString(MethodGenerationContext& mgenc, VMString* str) { Emit2(mgenc, BC_PUSH_CONSTANT, mgenc.FindLiteralIndex(str), 1); } @@ -189,8 +189,7 @@ void EmitPOP(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_POP, -1); } -void EmitPOPLOCAL(MethodGenerationContext& mgenc, long idx, - int ctx) { +void EmitPOPLOCAL(MethodGenerationContext& mgenc, long idx, int ctx) { assert(idx >= 0); assert(ctx >= 0); if (ctx == 0) { @@ -213,8 +212,7 @@ void EmitPOPLOCAL(MethodGenerationContext& mgenc, long idx, Emit3(mgenc, BC_POP_LOCAL, idx, ctx, -1); } -void EmitPOPARGUMENT(MethodGenerationContext& mgenc, - long idx, int ctx) { +void EmitPOPARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx) { Emit3(mgenc, BC_POP_ARGUMENT, idx, ctx, -1); } @@ -256,14 +254,15 @@ void EmitRETURNNONLOCAL(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_RETURN_NON_LOCAL, 0); } -size_t EmitJumpOnBoolWithDummyOffset(MethodGenerationContext& mgenc, bool isIfTrue, bool needsPop) { +size_t EmitJumpOnBoolWithDummyOffset(MethodGenerationContext& mgenc, + bool isIfTrue, bool needsPop) { // Remember: true and false seem flipped here. // This is because if the test passes, the block is inlined directly. // But if the test fails, we need to jump. // Thus, an `#ifTrue:` needs to generated a jump_on_false. uint8_t bc; size_t stackEffect; - + if (needsPop) { bc = isIfTrue ? BC_JUMP_ON_FALSE_POP : BC_JUMP_ON_TRUE_POP; stackEffect = -1; @@ -279,46 +278,51 @@ size_t EmitJumpOnBoolWithDummyOffset(MethodGenerationContext& mgenc, bool isIfTr return idx; } -void EmitJumpBackwardWithOffset(MethodGenerationContext& mgenc, size_t jumpOffset) { - uint8_t jumpBytecode = jumpOffset <= 0xFF ? BC_JUMP_BACKWARD : BC_JUMP2_BACKWARD; +void EmitJumpBackwardWithOffset(MethodGenerationContext& mgenc, + size_t jumpOffset) { + uint8_t jumpBytecode = + jumpOffset <= 0xFF ? BC_JUMP_BACKWARD : BC_JUMP2_BACKWARD; Emit3(mgenc, jumpBytecode, jumpOffset & 0xFF, jumpOffset >> 8, 0); } -size_t Emit3WithDummy(MethodGenerationContext& mgenc, uint8_t bytecode, size_t stackEffect) { +size_t Emit3WithDummy(MethodGenerationContext& mgenc, uint8_t bytecode, + size_t stackEffect) { mgenc.AddBytecode(bytecode, stackEffect); size_t index = mgenc.AddBytecodeArgumentAndGetIndex(0); mgenc.AddBytecodeArgument(0); return index; } -void EmitPushFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, uint8_t ctxLevel) { +void EmitPushFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, + uint8_t ctxLevel) { // if (ctxLevel == 0) { - if (fieldIdx == 0) { - Emit1(mgenc, BC_PUSH_FIELD_0, 1); - return; - } - - if (fieldIdx == 1) { - Emit1(mgenc, BC_PUSH_FIELD_1, 1); - return; - } + if (fieldIdx == 0) { + Emit1(mgenc, BC_PUSH_FIELD_0, 1); + return; + } + + if (fieldIdx == 1) { + Emit1(mgenc, BC_PUSH_FIELD_1, 1); + return; + } // } Emit2(mgenc, BC_PUSH_FIELD, fieldIdx, 1); } -void EmitPopFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, uint8_t ctxLevel) { +void EmitPopFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, + uint8_t ctxLevel) { // if (ctxLevel == 0) { - if (fieldIdx == 0) { - Emit1(mgenc, BC_POP_FIELD_0, 1); - return; - } - - if (fieldIdx == 1) { - Emit1(mgenc, BC_POP_FIELD_1, 1); - return; - } + if (fieldIdx == 0) { + Emit1(mgenc, BC_POP_FIELD_0, 1); + return; + } + + if (fieldIdx == 1) { + Emit1(mgenc, BC_POP_FIELD_1, 1); + return; + } // } - + Emit2(mgenc, BC_POP_FIELD, fieldIdx, 1); } diff --git a/src/compiler/BytecodeGenerator.h b/src/compiler/BytecodeGenerator.h index 19c86488..4b7ac283 100644 --- a/src/compiler/BytecodeGenerator.h +++ b/src/compiler/BytecodeGenerator.h @@ -32,14 +32,16 @@ #include "../vmobjects/ObjectFormats.h" #include "MethodGenerationContext.h" -void Emit1(MethodGenerationContext& mgenc, uint8_t bytecode, size_t stackEffect); -void Emit2(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, size_t stackEffect); -void Emit3(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, size_t ctx, size_t stackEffect); - +void Emit1(MethodGenerationContext& mgenc, uint8_t bytecode, + size_t stackEffect); +void Emit2(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, + size_t stackEffect); +void Emit3(MethodGenerationContext& mgenc, uint8_t bytecode, size_t idx, + size_t ctx, size_t stackEffect); void EmitHALT(MethodGenerationContext& mgenc); void EmitDUP(MethodGenerationContext& mgenc); -void EmitPUSHLOCAL(MethodGenerationContext& mgenc, long idx, int ctx); +void EmitPUSHLOCAL(MethodGenerationContext& mgenc, long idx, int ctx); void EmitPUSHARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx); void EmitPUSHFIELD(MethodGenerationContext& mgenc, VMSymbol* field); void EmitPUSHBLOCK(MethodGenerationContext& mgenc, VMMethod* block); @@ -48,7 +50,7 @@ void EmitPUSHCONSTANT(MethodGenerationContext& mgenc, uint8_t literalIndex); void EmitPUSHCONSTANTString(MethodGenerationContext& mgenc, VMString* str); void EmitPUSHGLOBAL(MethodGenerationContext& mgenc, VMSymbol* global); void EmitPOP(MethodGenerationContext& mgenc); -void EmitPOPLOCAL(MethodGenerationContext& mgenc, long idx, int ctx); +void EmitPOPLOCAL(MethodGenerationContext& mgenc, long idx, int ctx); void EmitPOPARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx); void EmitPOPFIELD(MethodGenerationContext& mgenc, VMSymbol* field); void EmitSEND(MethodGenerationContext& mgenc, VMSymbol* msg); @@ -56,10 +58,14 @@ void EmitSUPERSEND(MethodGenerationContext& mgenc, VMSymbol* msg); void EmitRETURNLOCAL(MethodGenerationContext& mgenc); void EmitRETURNNONLOCAL(MethodGenerationContext& mgenc); -size_t EmitJumpOnBoolWithDummyOffset(MethodGenerationContext& mgenc, bool isIfTrue, bool needsPop); -void EmitJumpBackwardWithOffset(MethodGenerationContext& mgenc, size_t jumpOffset); -size_t Emit3WithDummy(MethodGenerationContext& mgenc, uint8_t bytecode, size_t stackEffect); - -void EmitPushFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, uint8_t ctxLevel); -void EmitPopFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, uint8_t ctxLevel); +size_t EmitJumpOnBoolWithDummyOffset(MethodGenerationContext& mgenc, + bool isIfTrue, bool needsPop); +void EmitJumpBackwardWithOffset(MethodGenerationContext& mgenc, + size_t jumpOffset); +size_t Emit3WithDummy(MethodGenerationContext& mgenc, uint8_t bytecode, + size_t stackEffect); +void EmitPushFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, + uint8_t ctxLevel); +void EmitPopFieldWithIndex(MethodGenerationContext& mgenc, uint8_t fieldIdx, + uint8_t ctxLevel); diff --git a/src/compiler/ClassGenerationContext.cpp b/src/compiler/ClassGenerationContext.cpp index b3ba40c3..d9cd9e48 100644 --- a/src/compiler/ClassGenerationContext.cpp +++ b/src/compiler/ClassGenerationContext.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "ClassGenerationContext.h" + #include #include #include @@ -39,13 +41,10 @@ #include "../vmobjects/VMClass.h" #include "../vmobjects/VMInvokable.h" #include "../vmobjects/VMSymbol.h" -#include "ClassGenerationContext.h" - -ClassGenerationContext::ClassGenerationContext() : - name(nullptr), superName(nullptr), classSide(false), - instanceFields(), instanceMethods(), classFields(), - classMethods() { } +ClassGenerationContext::ClassGenerationContext() + : name(nullptr), superName(nullptr), classSide(false), instanceFields(), + instanceMethods(), classFields(), classMethods() {} void ClassGenerationContext::AddClassField(VMSymbol* field) { classFields.push_back(field); @@ -57,7 +56,7 @@ void ClassGenerationContext::AddInstanceField(VMSymbol* field) { void ClassGenerationContext::SetInstanceFieldsOfSuper(VMArray* fields) { size_t num = fields->GetNumberOfIndexableFields(); - for (size_t i = 0; i < num; i ++) { + for (size_t i = 0; i < num; i++) { VMSymbol* fieldName = (VMSymbol*)fields->GetIndexableField(i); assert(IsVMSymbol(fieldName)); instanceFields.push_back(fieldName); @@ -66,7 +65,7 @@ void ClassGenerationContext::SetInstanceFieldsOfSuper(VMArray* fields) { void ClassGenerationContext::SetClassFieldsOfSuper(VMArray* fields) { size_t num = fields->GetNumberOfIndexableFields(); - for (size_t i = 0; i < num; i ++) { + for (size_t i = 0; i < num; i++) { VMSymbol* fieldName = (VMSymbol*)fields->GetIndexableField(i); assert(IsVMSymbol(fieldName)); classFields.push_back(fieldName); @@ -107,7 +106,8 @@ VMClass* ClassGenerationContext::Assemble() { // Initialize the class of the resulting class resultClass->SetInstanceFields(GetUniverse()->NewArrayList(classFields)); - resultClass->SetInstanceInvokables(GetUniverse()->NewArrayList(classMethods)); + resultClass->SetInstanceInvokables( + GetUniverse()->NewArrayList(classMethods)); resultClass->SetName(SymbolFor(ccname)); VMClass* superMClass = superClass->GetClass(); @@ -126,11 +126,12 @@ VMClass* ClassGenerationContext::Assemble() { } void ClassGenerationContext::AssembleSystemClass(VMClass* systemClass) { - systemClass->SetInstanceInvokables(GetUniverse()->NewArrayList - (instanceMethods)); + systemClass->SetInstanceInvokables( + GetUniverse()->NewArrayList(instanceMethods)); systemClass->SetInstanceFields(GetUniverse()->NewArrayList(instanceFields)); // class-bound == class-instance-bound - VMClass* superMClass = systemClass->GetClass(); - superMClass->SetInstanceInvokables(GetUniverse()->NewArrayList(classMethods)); - superMClass->SetInstanceFields(GetUniverse()->NewArrayList(classFields)); - } + VMClass* superMClass = systemClass->GetClass(); + superMClass->SetInstanceInvokables( + GetUniverse()->NewArrayList(classMethods)); + superMClass->SetInstanceFields(GetUniverse()->NewArrayList(classFields)); +} diff --git a/src/compiler/ClassGenerationContext.h b/src/compiler/ClassGenerationContext.h index 5ee67428..a14b5cf0 100644 --- a/src/compiler/ClassGenerationContext.h +++ b/src/compiler/ClassGenerationContext.h @@ -28,12 +28,10 @@ #include -#include "../vmobjects/ObjectFormats.h" - #include "../misc/defs.h" +#include "../vmobjects/ObjectFormats.h" class ClassGenerationContext { - public: ClassGenerationContext(); ~ClassGenerationContext() = default; @@ -45,12 +43,12 @@ class ClassGenerationContext { void AddClassField(VMSymbol*); void AddInstanceMethod(VMInvokable*); void AddClassMethod(VMInvokable*); - void SetName(VMSymbol* n) {name = n;} - void SetSuperName(VMSymbol* sn) {superName = sn;} - void SetClassSide(bool cs) {classSide = cs;} - VMSymbol* GetName(void) {return name;}; - VMSymbol* GetSuperName(void) {return superName;}; - bool IsClassSide(void) {return classSide;}; + void SetName(VMSymbol* n) { name = n; } + void SetSuperName(VMSymbol* sn) { superName = sn; } + void SetClassSide(bool cs) { classSide = cs; } + VMSymbol* GetName(void) { return name; }; + VMSymbol* GetSuperName(void) { return superName; }; + bool IsClassSide(void) { return classSide; }; int16_t GetFieldIndex(VMSymbol* field); @@ -61,8 +59,8 @@ class ClassGenerationContext { VMSymbol* name; VMSymbol* superName; bool classSide; - std::vector instanceFields; + std::vector instanceFields; std::vector instanceMethods; - std::vector classFields; + std::vector classFields; std::vector classMethods; }; diff --git a/src/compiler/Disassembler.cpp b/src/compiler/Disassembler.cpp index 478c40cd..010a8006 100644 --- a/src/compiler/Disassembler.cpp +++ b/src/compiler/Disassembler.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Disassembler.h" + #include #include #include @@ -44,16 +46,13 @@ #include "../vmobjects/VMObject.h" #include "../vmobjects/VMString.h" #include "../vmobjects/VMSymbol.h" -#include "Disassembler.h" /** * Dispatch an object to its content and write out */ void Disassembler::dispatch(vm_oop_t o) { - //dispatch - // can't switch() objects, so: if (o == nullptr) { - return; // nullptr isn't interesting. + return; // nullptr isn't interesting. } else if (o == load_ptr(nilObject)) { DebugPrint("{Nil}"); } else if (o == load_ptr(trueObject)) { @@ -69,13 +68,15 @@ void Disassembler::dispatch(vm_oop_t o) { } else { VMClass* c = CLASS_OF(o); if (c == load_ptr(stringClass)) { - DebugPrint("\"%s\"", static_cast(o)->GetStdString().c_str()); - } else if(c == load_ptr(doubleClass)) { + DebugPrint("\"%s\"", + static_cast(o)->GetStdString().c_str()); + } else if (c == load_ptr(doubleClass)) { DebugPrint("%g", static_cast(o)->GetEmbeddedDouble()); - } else if(c == load_ptr(integerClass)) { + } else if (c == load_ptr(integerClass)) { DebugPrint("%lld", INT_VAL(o)); - } else if(c == load_ptr(symbolClass)) { - DebugPrint("#%s", static_cast(o)->GetStdString().c_str()); + } else if (c == load_ptr(symbolClass)) { + DebugPrint("#%s", + static_cast(o)->GetStdString().c_str()); } else { DebugPrint("address: %p", (void*)o); } @@ -88,11 +89,13 @@ void Disassembler::dispatch(vm_oop_t o) { void Disassembler::Dump(VMClass* cl) { long numInvokables = cl->GetNumberOfInstanceInvokables(); for (long i = 0; i < numInvokables; ++i) { - VMInvokable* inv = static_cast(cl->GetInstanceInvokable(i)); + VMInvokable* inv = + static_cast(cl->GetInstanceInvokable(i)); // output header and skip if the Invokable is a Primitive VMSymbol* sig = inv->GetSignature(); VMSymbol* cname = cl->GetName(); - DebugDump("%s>>%s = ", cname->GetStdString().c_str(), sig->GetStdString().c_str()); + DebugDump("%s>>%s = ", cname->GetStdString().c_str(), + sig->GetStdString().c_str()); if (inv->IsPrimitive()) { DebugPrint("\n"); continue; @@ -105,18 +108,23 @@ void Disassembler::Dump(VMClass* cl) { /** * Dump all Bytecode of a method. */ -void Disassembler::DumpMethod(VMMethod* method, const char* indent, bool printObjects) { - dumpMethod(method->GetBytecodes(), method->GetNumberOfBytecodes(), indent, method, printObjects); +void Disassembler::DumpMethod(VMMethod* method, const char* indent, + bool printObjects) { + dumpMethod(method->GetBytecodes(), method->GetNumberOfBytecodes(), indent, + method, printObjects); } -void Disassembler::DumpMethod(MethodGenerationContext* mgenc, const char* indent) { +void Disassembler::DumpMethod(MethodGenerationContext* mgenc, + const char* indent) { auto bytecodes = mgenc->GetBytecodes(); dumpMethod(bytecodes.data(), bytecodes.size(), indent, nullptr, true); } -void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, const char* indent, VMMethod* method, bool printObjects) { +void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, + const char* indent, VMMethod* method, + bool printObjects) { DebugPrint("(\n"); - if (method != nullptr) { // output stack information + if (method != nullptr) { // output stack information size_t locals = method->GetNumberOfLocals(); size_t max_stack = method->GetMaximumNumberOfStackElements(); DebugDump("%s<%d locals, %d stack, %d bc_count>\n", indent, locals, @@ -132,61 +140,74 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons } // output bytecodes - for (size_t bc_idx = 0; - bc_idx < numberOfBytecodes; + for (size_t bc_idx = 0; bc_idx < numberOfBytecodes; bc_idx += Bytecode::GetBytecodeLength(bytecodes[bc_idx])) { // the bytecode. uint8_t bytecode = bytecodes[bc_idx]; // indent, bytecode index, bytecode mnemonic - DebugDump("%s%4d:%s ", indent, bc_idx, Bytecode::GetBytecodeName(bytecode)); + DebugDump("%s%4d:%s ", indent, bc_idx, + Bytecode::GetBytecodeName(bytecode)); // parameters (if any) if (Bytecode::GetBytecodeLength(bytecode) == 1) { DebugPrint("\n"); continue; } - switch(bytecode) { + switch (bytecode) { case BC_PUSH_LOCAL_0: { - DebugPrint("local: 0, context: 0\n"); break; + DebugPrint("local: 0, context: 0\n"); + break; } case BC_PUSH_LOCAL_1: { - DebugPrint("local: 1, context: 0\n"); break; + DebugPrint("local: 1, context: 0\n"); + break; } case BC_PUSH_LOCAL_2: { - DebugPrint("local: 2, context: 0\n"); break; + DebugPrint("local: 2, context: 0\n"); + break; } case BC_PUSH_LOCAL: { - DebugPrint("local: %d, context: %d\n", bytecodes[bc_idx+1], bytecodes[bc_idx+2]); break; + DebugPrint("local: %d, context: %d\n", bytecodes[bc_idx + 1], + bytecodes[bc_idx + 2]); + break; } case BC_PUSH_ARGUMENT: { - DebugPrint("argument: %d, context %d\n", bytecodes[bc_idx+1], bytecodes[bc_idx+2]); break; + DebugPrint("argument: %d, context %d\n", bytecodes[bc_idx + 1], + bytecodes[bc_idx + 2]); + break; } case BC_PUSH_FIELD: { - long fieldIdx = bytecodes[bc_idx+1]; + long fieldIdx = bytecodes[bc_idx + 1]; if (method != nullptr && printObjects) { - VMClass* holder = dynamic_cast((VMObject*) method->GetHolder()); + VMClass* holder = + dynamic_cast((VMObject*)method->GetHolder()); if (holder) { VMSymbol* name = holder->GetInstanceFieldName(fieldIdx); if (name != nullptr) { - DebugPrint("(index: %d) field: %s\n", bytecodes[bc_idx+1], name->GetStdString().c_str()); + DebugPrint("(index: %d) field: %s\n", + bytecodes[bc_idx + 1], + name->GetStdString().c_str()); } else { - DebugPrint("(index: %d) field: !nullptr!: error!\n", bytecodes[bc_idx+1]); + DebugPrint("(index: %d) field: !nullptr!: error!\n", + bytecodes[bc_idx + 1]); } break; } } - DebugPrint("(index: %d)\n", bytecodes[bc_idx+1]); + DebugPrint("(index: %d)\n", bytecodes[bc_idx + 1]); break; } case BC_PUSH_BLOCK: { - size_t indent_size = strlen(indent)+1+1; + size_t indent_size = strlen(indent) + 1 + 1; char* nindent = new char[indent_size]; - DebugPrint("block: (index: %d) ", bytecodes[bc_idx+1]); + DebugPrint("block: (index: %d) ", bytecodes[bc_idx + 1]); if (method != nullptr && printObjects) { snprintf(nindent, indent_size, "%s\t", indent); - Disassembler::DumpMethod(static_cast(method->GetConstant(bc_idx)), nindent); + Disassembler::DumpMethod( + static_cast(method->GetConstant(bc_idx)), + nindent); } else { DebugPrint("\n"); } @@ -200,10 +221,11 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons VMSymbol* cname = cl->GetName(); DebugPrint("(index: %d) value: (%s) ", - bytecodes[bc_idx+1], cname->GetStdString().c_str()); + bytecodes[bc_idx + 1], + cname->GetStdString().c_str()); dispatch(constant); } else { - DebugPrint("(index: %d)", bytecodes[bc_idx+1]); + DebugPrint("(index: %d)", bytecodes[bc_idx + 1]); } DebugPrint("\n"); break; @@ -214,32 +236,41 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons if (cst != nullptr) { VMSymbol* name = static_cast(cst); if (name != nullptr) { - DebugPrint("(index: %d) value: %s\n", bytecodes[bc_idx+1], name->GetStdString().c_str()); + DebugPrint("(index: %d) value: %s\n", + bytecodes[bc_idx + 1], + name->GetStdString().c_str()); } else { - DebugPrint("(index: %d) value: !nullptr!: error!\n", bytecodes[bc_idx+1]); + DebugPrint("(index: %d) value: !nullptr!: error!\n", + bytecodes[bc_idx + 1]); } break; } } - DebugPrint("(index: %d)\n", bytecodes[bc_idx+1]); + DebugPrint("(index: %d)\n", bytecodes[bc_idx + 1]); break; } case BC_POP_LOCAL: - DebugPrint("local: %d, context: %d\n", bytecodes[bc_idx+1], bytecodes[bc_idx+2]); + DebugPrint("local: %d, context: %d\n", bytecodes[bc_idx + 1], + bytecodes[bc_idx + 2]); break; case BC_POP_ARGUMENT: - DebugPrint("argument: %d, context: %d\n", bytecodes[bc_idx+1], bytecodes[bc_idx+2]); + DebugPrint("argument: %d, context: %d\n", bytecodes[bc_idx + 1], + bytecodes[bc_idx + 2]); break; case BC_POP_FIELD: { - long fieldIdx = bytecodes[bc_idx+1]; + long fieldIdx = bytecodes[bc_idx + 1]; if (method != nullptr && printObjects) { - VMClass* holder = dynamic_cast((VMObject*) method->GetHolder()); + VMClass* holder = + dynamic_cast((VMObject*)method->GetHolder()); if (holder) { VMSymbol* name = holder->GetInstanceFieldName(fieldIdx); - DebugPrint("(index: %d) field: %s\n", fieldIdx, name->GetStdString().c_str()); + DebugPrint("(index: %d) field: %s\n", fieldIdx, + name->GetStdString().c_str()); } else { - DebugPrint("(index: %d) block holder is not a class!!\n", fieldIdx); + DebugPrint( + "(index: %d) block holder is not a class!!\n", + fieldIdx); } } else { DebugPrint("(index: %d)\n", fieldIdx); @@ -248,19 +279,25 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons } case BC_SEND: { if (method != nullptr && printObjects) { - VMSymbol* name = static_cast(method->GetConstant(bc_idx)); - DebugPrint("(index: %d) signature: %s\n", bytecodes[bc_idx+1], name->GetStdString().c_str()); + VMSymbol* name = + static_cast(method->GetConstant(bc_idx)); + DebugPrint("(index: %d) signature: %s\n", + bytecodes[bc_idx + 1], + name->GetStdString().c_str()); } else { - DebugPrint("(index: %d)\n", bytecodes[bc_idx+1]); + DebugPrint("(index: %d)\n", bytecodes[bc_idx + 1]); } break; } case BC_SUPER_SEND: { if (method != nullptr && printObjects) { - VMSymbol* name = static_cast(method->GetConstant(bc_idx)); - DebugPrint("(index: %d) signature: %s\n", bytecodes[bc_idx+1], name->GetStdString().c_str()); + VMSymbol* name = + static_cast(method->GetConstant(bc_idx)); + DebugPrint("(index: %d) signature: %s\n", + bytecodes[bc_idx + 1], + name->GetStdString().c_str()); } else { - DebugPrint("(index: %d)\n", bytecodes[bc_idx+1]); + DebugPrint("(index: %d)\n", bytecodes[bc_idx + 1]); } break; } @@ -276,15 +313,18 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons case BC_JUMP2_ON_FALSE_TOP_NIL: case BC_JUMP2_ON_TRUE_TOP_NIL: case BC_JUMP2_BACKWARD: { - uint16_t offset = ComputeOffset(bytecodes[bc_idx + 1], bytecodes[bc_idx + 2]); - + uint16_t offset = + ComputeOffset(bytecodes[bc_idx + 1], bytecodes[bc_idx + 2]); + int32_t target; - if (bytecode == BC_JUMP_BACKWARD || bytecode == BC_JUMP2_BACKWARD) { - target = ((int32_t) bc_idx) - offset; + if (bytecode == BC_JUMP_BACKWARD || + bytecode == BC_JUMP2_BACKWARD) { + target = ((int32_t)bc_idx) - offset; } else { - target = ((int32_t) bc_idx) + offset; + target = ((int32_t)bc_idx) + offset; } - DebugPrint("(jump offset: %d -> jump target: %d)\n", offset, target); + DebugPrint("(jump offset: %d -> jump target: %d)\n", offset, + target); break; } default: { @@ -299,9 +339,8 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons * Bytecode Index Accessor macros */ #define BC_0 method->GetBytecode(bc_idx) -#define BC_1 method->GetBytecode(bc_idx+1) -#define BC_2 method->GetBytecode(bc_idx+2) - +#define BC_1 method->GetBytecode(bc_idx + 1) +#define BC_2 method->GetBytecode(bc_idx + 2) /** * Dump bytecode from the frame running @@ -318,21 +357,20 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMSymbol* sig = method->GetSignature(); DebugTrace("%20s>>%-20s% 10lld %c %04d: %s\t", - cname->GetStdString().c_str(), sig->GetStdString().c_str(), - indentc, ikind, bc_idx, - Bytecode::GetBytecodeName(bc)); + cname->GetStdString().c_str(), sig->GetStdString().c_str(), + indentc, ikind, bc_idx, Bytecode::GetBytecodeName(bc)); } else { VMSymbol* sig = method->GetSignature(); - DebugTrace("%-42s% 10lld %c %04d: %s\t", - sig->GetStdString().c_str(), - indentc, ikind, bc_idx, - Bytecode::GetBytecodeName(bc)); + DebugTrace("%-42s% 10lld %c %04d: %s\t", sig->GetStdString().c_str(), + indentc, ikind, bc_idx, Bytecode::GetBytecodeName(bc)); } // reset send indicator - if(ikind != '@') ikind = '@'; + if (ikind != '@') { + ikind = '@'; + } - switch(bc) { + switch (bc) { case BC_HALT: { DebugPrint("\n\n\n"); break; @@ -344,10 +382,10 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMSymbol* cname = c->GetName(); DebugPrint("GetStdString().c_str()); - //dispatch dispatch(o); - } else + } else { DebugPrint("\n"); break; } @@ -357,9 +395,8 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMClass* c = CLASS_OF(o); VMSymbol* cname = c->GetName(); - DebugPrint("local: %d, context: %d <(%s) ", - BC_1, BC_2, cname->GetStdString().c_str()); - //dispatch + DebugPrint("local: %d, context: %d <(%s) ", BC_1, BC_2, + cname->GetStdString().c_str()); dispatch(o); DebugPrint(">\n"); break; @@ -370,9 +407,18 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { uint8_t bc1; uint8_t bc2; switch (bc) { - case BC_PUSH_LOCAL_0: bc1 = 0; bc2 = 0; break; - case BC_PUSH_LOCAL_1: bc1 = 1; bc2 = 0; break; - case BC_PUSH_LOCAL_2: bc1 = 2; bc2 = 0; break; + case BC_PUSH_LOCAL_0: + bc1 = 0; + bc2 = 0; + break; + case BC_PUSH_LOCAL_1: + bc1 = 1; + bc2 = 0; + break; + case BC_PUSH_LOCAL_2: + bc1 = 2; + bc2 = 0; + break; default: DebugPrint("Unexpected bytecode"); return; @@ -382,9 +428,8 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMClass* c = CLASS_OF(o); VMSymbol* cname = c->GetName(); - DebugPrint("local: %d, context: %d <(%s) ", - BC_1, BC_2, cname->GetStdString().c_str()); - //dispatch + DebugPrint("local: %d, context: %d <(%s) ", BC_1, BC_2, + cname->GetStdString().c_str()); dispatch(o); DebugPrint(">\n"); break; @@ -399,7 +444,6 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMSymbol* cname = c->GetName(); DebugPrint("<(%s) ", cname->GetStdString().c_str()); - //dispatch dispatch(o); DebugPrint(">"); } @@ -411,21 +455,23 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { vm_oop_t arg = ctxt->GetArgumentInCurrentContext(0); uint8_t field_index = BC_1; - vm_oop_t o = ((VMObject*) arg)->GetField(field_index); + vm_oop_t o = ((VMObject*)arg)->GetField(field_index); VMClass* c = CLASS_OF(o); VMSymbol* cname = c->GetName(); long fieldIdx = BC_1; - VMSymbol* name = method->GetHolder()->GetInstanceFieldName(fieldIdx); - DebugPrint("(index: %d) field: %s <(%s) ", BC_1, name->GetStdString().c_str(), + VMSymbol* name = + method->GetHolder()->GetInstanceFieldName(fieldIdx); + DebugPrint("(index: %d) field: %s <(%s) ", BC_1, + name->GetStdString().c_str(), cname->GetStdString().c_str()); - //dispatch dispatch(o); DebugPrint(">\n"); break; } case BC_PUSH_BLOCK: { DebugPrint("block: (index: %d) ", BC_1); - VMMethod* meth = dynamic_cast((AbstractVMObject*)method->GetConstant(bc_idx)); + VMMethod* meth = dynamic_cast( + (AbstractVMObject*)method->GetConstant(bc_idx)); DumpMethod(meth, "$"); break; } @@ -435,13 +481,14 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMSymbol* cname = c->GetName(); DebugPrint("(index: %d) value: (%s) ", BC_1, - cname->GetStdString().c_str()); + cname->GetStdString().c_str()); dispatch(constant); DebugPrint("\n"); break; } case BC_PUSH_GLOBAL: { - VMSymbol* name = static_cast(method->GetConstant(bc_idx)); + VMSymbol* name = + static_cast(method->GetConstant(bc_idx)); vm_oop_t o = GetUniverse()->GetGlobal(name); VMSymbol* cname; @@ -452,11 +499,12 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { cname = c->GetName(); c_cname_str = cname->GetStdString(); c_cname = c_cname_str.c_str(); - } else + } else { c_cname = "nullptr"; + } DebugPrint("(index: %d)value: %s <(%s) ", BC_1, - name->GetStdString().c_str(), c_cname); + name->GetStdString().c_str(), c_cname); dispatch(o); DebugPrint(">\n"); break; @@ -467,7 +515,6 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMSymbol* cname = c->GetName(); DebugPrint("popped <(%s) ", cname->GetStdString().c_str()); - //dispatch dispatch(o); DebugPrint(">\n"); break; @@ -478,8 +525,7 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMSymbol* cname = c->GetName(); DebugPrint("popped local: %d, context: %d <(%s) ", BC_1, BC_2, - cname->GetStdString().c_str()); - //dispatch + cname->GetStdString().c_str()); dispatch(o); DebugPrint(">\n"); break; @@ -489,8 +535,7 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMClass* c = CLASS_OF(o); VMSymbol* cname = c->GetName(); DebugPrint("argument: %d, context: %d <(%s) ", BC_1, BC_2, - cname->GetStdString().c_str()); - //dispatch + cname->GetStdString().c_str()); dispatch(o); DebugPrint(">\n"); break; @@ -499,9 +544,11 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { vm_oop_t o = frame->GetStackElement(0); VMClass* c = CLASS_OF(o); long fieldIdx = BC_1; - VMSymbol* name = method->GetHolder()->GetInstanceFieldName(fieldIdx); + VMSymbol* name = + method->GetHolder()->GetInstanceFieldName(fieldIdx); VMSymbol* cname = c->GetName(); - DebugPrint("(index: %d) field: %s <(%s) ", fieldIdx, name->GetStdString().c_str(), + DebugPrint("(index: %d) field: %s <(%s) ", fieldIdx, + name->GetStdString().c_str(), cname->GetStdString().c_str()); dispatch(o); DebugPrint(">\n"); @@ -512,24 +559,28 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMSymbol* sel = static_cast(method->GetConstant(bc_idx)); DebugPrint("(index: %d) signature: %s (", BC_1, - sel->GetStdString().c_str()); + sel->GetStdString().c_str()); // handle primitives, they don't increase call-depth - vm_oop_t elem = frame->GetStackElement(Signature::GetNumberOfArguments(sel)-1); + vm_oop_t elem = frame->GetStackElement( + Signature::GetNumberOfArguments(sel) - 1); VMClass* elemClass = CLASS_OF(elem); - VMInvokable* inv = dynamic_cast(elemClass->LookupInvokable(sel)); + VMInvokable* inv = + dynamic_cast(elemClass->LookupInvokable(sel)); - if(inv != nullptr && inv->IsPrimitive()) + if (inv != nullptr && inv->IsPrimitive()) { DebugPrint("*)\n"); - else { + } else { DebugPrint("\n"); - indentc++; ikind='>'; // visual + indentc++; + ikind = '>'; // visual } break; } case BC_RETURN_LOCAL: case BC_RETURN_NON_LOCAL: { DebugPrint(")\n"); - indentc--; ikind='<'; //visual + indentc--; + ikind = '<'; // visual break; } case BC_JUMP: @@ -544,13 +595,14 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { case BC_JUMP2_ON_FALSE_TOP_NIL: case BC_JUMP2_ON_TRUE_TOP_NIL: case BC_JUMP2_BACKWARD: { - uint16_t offset = ComputeOffset(method->GetBytecode(bc_idx + 1), method->GetBytecode(bc_idx + 2)); - + uint16_t offset = ComputeOffset(method->GetBytecode(bc_idx + 1), + method->GetBytecode(bc_idx + 2)); + int32_t target; if (bc == BC_JUMP_BACKWARD || bc == BC_JUMP2_BACKWARD) { - target = ((int32_t) bc_idx) - offset; + target = ((int32_t)bc_idx) - offset; } else { - target = ((int32_t) bc_idx) + offset; + target = ((int32_t)bc_idx) + offset; } DebugPrint("(jump offset: %d -> jump target: %d)", offset, target); break; diff --git a/src/compiler/Disassembler.h b/src/compiler/Disassembler.h index 49bd45b0..5b12b832 100644 --- a/src/compiler/Disassembler.h +++ b/src/compiler/Disassembler.h @@ -34,11 +34,15 @@ class Disassembler { public: static void Dump(VMClass* cl); - static void DumpMethod(VMMethod* method, const char* indent, bool printObjects = true); + static void DumpMethod(VMMethod* method, const char* indent, + bool printObjects = true); static void DumpMethod(MethodGenerationContext* mgenc, const char* indent); static void DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx); + private: static void dispatch(vm_oop_t o); - static void dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, const char* indent, VMMethod* method, bool printObjects); + static void dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, + const char* indent, VMMethod* method, + bool printObjects); }; diff --git a/src/compiler/Lexer.cpp b/src/compiler/Lexer.cpp index 7a3d4b0b..e1bebcf7 100644 --- a/src/compiler/Lexer.cpp +++ b/src/compiler/Lexer.cpp @@ -23,6 +23,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "Lexer.h" + #include #include #include @@ -32,15 +34,14 @@ #include "../misc/defs.h" #include "../vm/Universe.h" -#include "Lexer.h" -Lexer::Lexer(istream &file) : infile(file), peekDone(false) {} +Lexer::Lexer(istream& file) : infile(file), peekDone(false) {} #define _BC (buf[state.bufp]) #define EOB (state.bufp >= buf.length()) int64_t Lexer::fillBuffer() { - if (!infile.good()) { // file stream + if (!infile.good()) { // file stream return -1; } @@ -66,7 +67,6 @@ void Lexer::skipWhiteSpace() { } void Lexer::skipComment() { - if (_BC == '"') { do { state.incPtr(); @@ -80,13 +80,18 @@ void Lexer::skipComment() { } } -#define _ISOP(C) \ - ((C) == '~' || (C) == '&' || (C) == '|' || (C) == '*' || (C) == '/' || \ +#define _ISOP(C) \ + ((C) == '~' || (C) == '&' || (C) == '|' || (C) == '*' || (C) == '/' || \ (C) == '\\' || (C) == '+' || (C) == '=' || (C) == '>' || (C) == '<' || \ (C) == ',' || (C) == '@' || (C) == '%' || (C) == '-') -#define _MATCH(C, S) \ - if(_BC == (C)) { state.sym = (S); state.symc = _BC; state.text = _BC; state.incPtr();} -#define SEPARATOR StdString("----") //FIXME +#define _MATCH(C, S) \ + if (_BC == (C)) { \ + state.sym = (S); \ + state.symc = _BC; \ + state.text = _BC; \ + state.incPtr(); \ + } +#define SEPARATOR StdString("----") // FIXME #define PRIMITIVE StdString("primitive") void Lexer::lexNumber() { @@ -100,9 +105,7 @@ void Lexer::lexNumber() { state.text += _BC; state.incPtr(); - if (!sawDecimalMark and - '.' == _BC and - state.bufp + 1 < buf.length() and + if (!sawDecimalMark and '.' == _BC and state.bufp + 1 < buf.length() and isdigit(buf[state.bufp + 1]) != 0) { state.sym = Double; sawDecimalMark = true; @@ -113,19 +116,34 @@ void Lexer::lexNumber() { } while (isdigit(_BC) != 0); } - void Lexer::lexEscapeChar() { assert(!EOB); const char current = _BC; switch (current) { - case 't': state.text += '\t'; break; - case 'b': state.text += '\b'; break; - case 'n': state.text += '\n'; break; - case 'r': state.text += '\r'; break; - case 'f': state.text += '\f'; break; - case '0': state.text += '\0'; break; - case '\'': state.text += '\''; break; - case '\\': state.text += '\\'; break; + case 't': + state.text += '\t'; + break; + case 'b': + state.text += '\b'; + break; + case 'n': + state.text += '\n'; + break; + case 'r': + state.text += '\r'; + break; + case 'f': + state.text += '\f'; + break; + case '0': + state.text += '\0'; + break; + case '\'': + state.text += '\''; + break; + case '\\': + state.text += '\\'; + break; default: assert(false); break; @@ -172,12 +190,14 @@ void Lexer::lexOperator() { state.text += buf[state.bufp]; state.incPtr(); } - - } else _MATCH('~', Not) else _MATCH('&', And) else _MATCH('|', Or) - else _MATCH('*', Star) else _MATCH('/', Div) else _MATCH('\\', Mod) - else _MATCH('+', Plus) else _MATCH('=', Equal) else _MATCH('>', More) - else _MATCH('<', Less) else _MATCH(',', Comma) else _MATCH('@', At) - else _MATCH('%', Per) else _MATCH('-', Minus) + } + // clang-format off + else _MATCH('~', Not) else _MATCH('&', And) else _MATCH('|', Or) + else _MATCH('*', Star) else _MATCH('/', Div) else _MATCH('\\', Mod) + else _MATCH('+', Plus) else _MATCH('=', Equal) else _MATCH('>', More) + else _MATCH('<', Less) else _MATCH(',', Comma) else _MATCH('@', At) + else _MATCH('%', Per) else _MATCH('-', Minus) + // clang-format on } Symbol Lexer::GetSym() { @@ -202,8 +222,12 @@ Symbol Lexer::GetSym() { if (_BC == '\'') { lexString(); - } else _MATCH('[', NewBlock) else _MATCH(']', EndBlock) else if (_BC - == ':') { + } + // clang-format off + else _MATCH('[', NewBlock) + else _MATCH(']', EndBlock) + // clang-format on + else if (_BC == ':') { if (buf[state.bufp + 1] == '=') { state.incPtr(2); state.sym = Assign; @@ -215,8 +239,13 @@ Symbol Lexer::GetSym() { state.symc = ':'; state.text = ":"; } - } else _MATCH('(', NewTerm) else _MATCH(')', EndTerm) else _MATCH('#', Pound) else _MATCH('^', Exit) else _MATCH('.', Period) else if (_BC - == '-') { + } + // clang-format off + else _MATCH('(', NewTerm) else _MATCH(')', EndTerm) + else _MATCH('#', Pound) else _MATCH('^', Exit) + else _MATCH('.', Period) + // clang-format on + else if (_BC == '-') { if (!buf.substr(state.bufp, SEPARATOR.length()).compare(SEPARATOR)) { state.text.clear(); while (_BC == '-') { @@ -227,14 +256,17 @@ Symbol Lexer::GetSym() { } else { lexOperator(); } - } else if (_ISOP(_BC)) { + } + else if (_ISOP(_BC)) { lexOperator(); - } else if (nextWordInBufferIsPrimitive()) { + } + else if (nextWordInBufferIsPrimitive()) { state.incPtr(PRIMITIVE.length()); state.sym = Primitive; state.symc = 0; state.text = "primitive"; - } else if (isalpha(_BC) != 0) { + } + else if (isalpha(_BC) != 0) { state.text.clear(); state.symc = 0; while (isalpha(_BC) != 0 || isdigit(_BC) != 0 || _BC == '_') { @@ -254,9 +286,11 @@ Symbol Lexer::GetSym() { } } } - } else if (isdigit(_BC) != 0) { + } + else if (isdigit(_BC) != 0) { lexNumber(); - } else { + } + else { state.sym = NONE; state.symc = _BC; state.text = _BC; diff --git a/src/compiler/Lexer.h b/src/compiler/Lexer.h index 3d304916..4e3d236e 100644 --- a/src/compiler/Lexer.h +++ b/src/compiler/Lexer.h @@ -30,6 +30,7 @@ #include #include "../misc/defs.h" +#include "SourceCoordinate.h" using namespace std; @@ -68,19 +69,22 @@ typedef enum { KeywordSequence, OperatorSequence } Symbol; + +// clang-format off static const char* symnames[] = { "NONE", "Integer", "Not", "And", "Or", "Star", "Div", "Mod", "Plus", "Minus", "Equal", "More", "Less", "Comma", "At", "Per", "NewBlock", "EndBlock", "Colon", "Period", "Exit", "Assign", "NewTerm", "EndTerm", "Pound", "Primitive", "Separator", "STString", "Identifier", "Keyword", "KeywordSequence", "OperatorSequence" }; +// clang-format on class LexerState { public: - LexerState() : lineNumber(0), bufp(0), sym(Symbol::NONE), symc(0), text(""), startBufp(0) {} + LexerState() + : lineNumber(0), bufp(0), sym(Symbol::NONE), symc(0), text(""), + startBufp(0) {} - inline size_t incPtr() { - return incPtr(1); - } + inline size_t incPtr() { return incPtr(1); } inline size_t incPtr(size_t val) { const size_t cur = bufp; @@ -99,9 +103,7 @@ class LexerState { size_t startBufp; }; - class Lexer { - public: Lexer(istream& file); Lexer(const StdString& stream); @@ -109,16 +111,12 @@ class Lexer { Symbol GetSym(); Symbol Peek(); - StdString GetText() const { - return state.text; - } + StdString GetText() const { return state.text; } - StdString GetNextText() const { - return stateAfterPeek.text; - } + StdString GetNextText() const { return stateAfterPeek.text; } StdString GetRawBuffer() const { - //for debug + // for debug return StdString(buf); } @@ -128,13 +126,9 @@ class Lexer { return state.startBufp + 1 - state.text.length(); } - size_t GetCurrentLineNumber() const { - return state.lineNumber; - } + size_t GetCurrentLineNumber() const { return state.lineNumber; } - bool GetPeekDone() const { - return peekDone; - } + bool GetPeekDone() const { return peekDone; } SourceCoordinate GetCurrentSource() const { return SourceCoordinate(GetCurrentLineNumber(), GetCurrentColumn()); diff --git a/src/compiler/LexicalScope.h b/src/compiler/LexicalScope.h index 06ac1c1c..9e84df07 100644 --- a/src/compiler/LexicalScope.h +++ b/src/compiler/LexicalScope.h @@ -7,15 +7,13 @@ class LexicalScope { friend class MethodGenerationContext; public: - LexicalScope(LexicalScope* outer, vector arguments, vector locals) : outer(outer), arguments(arguments), locals(locals) {} + LexicalScope(LexicalScope* outer, vector arguments, + vector locals) + : outer(outer), arguments(arguments), locals(locals) {} - inline size_t GetNumberOfArguments() const { - return arguments.size(); - } + inline size_t GetNumberOfArguments() const { return arguments.size(); } - inline size_t GetNumberOfLocals() const { - return locals.size(); - } + inline size_t GetNumberOfLocals() const { return locals.size(); } void AddInlinedLocal(Variable& var) { assert(var.GetIndex() == locals.size()); @@ -28,7 +26,7 @@ class LexicalScope { } return &locals.at(index); } - + /** * This removes the inlined scope from the chain. * Removal is done exactly once, after all embedded blocks @@ -37,7 +35,7 @@ class LexicalScope { void DropInlinedScope() { assert(outer != nullptr); assert(outer->outer != nullptr); - + LexicalScope* newOuter = outer->outer; outer = newOuter; } diff --git a/src/compiler/MethodGenerationContext.cpp b/src/compiler/MethodGenerationContext.cpp index 5786e87e..77b68e4b 100644 --- a/src/compiler/MethodGenerationContext.cpp +++ b/src/compiler/MethodGenerationContext.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "MethodGenerationContext.h" + #include #include #include @@ -44,24 +46,26 @@ #include "BytecodeGenerator.h" #include "ClassGenerationContext.h" #include "LexicalScope.h" -#include "MethodGenerationContext.h" #include "SourceCoordinate.h" #include "Variable.h" -MethodGenerationContext::MethodGenerationContext(ClassGenerationContext& holder, MethodGenerationContext* outer) : - holderGenc(holder), outerGenc(outer), - blockMethod(outer != nullptr), signature(nullptr), primitive(false), finished(false), - currentStackDepth(0), maxStackDepth(0), maxContextLevel(outer == nullptr ? 0 : outer->GetMaxContextLevel() + 1) { - last4Bytecodes = {BC_INVALID, BC_INVALID, BC_INVALID, BC_INVALID}; - isCurrentlyInliningABlock = false; +MethodGenerationContext::MethodGenerationContext(ClassGenerationContext& holder, + MethodGenerationContext* outer) + : holderGenc(holder), outerGenc(outer), blockMethod(outer != nullptr), + signature(nullptr), primitive(false), finished(false), + currentStackDepth(0), maxStackDepth(0), + maxContextLevel(outer == nullptr ? 0 : outer->GetMaxContextLevel() + 1) { + last4Bytecodes = {BC_INVALID, BC_INVALID, BC_INVALID, BC_INVALID}; + isCurrentlyInliningABlock = false; } VMMethod* MethodGenerationContext::Assemble() { // create a method instance with the given number of bytecodes and literals size_t numLiterals = literals.size(); size_t numLocals = locals.size(); - VMMethod* meth = GetUniverse()->NewMethod(signature, bytecode.size(), - numLiterals, numLocals, maxStackDepth, lexicalScope, inlinedLoops); + VMMethod* meth = GetUniverse()->NewMethod( + signature, bytecode.size(), numLiterals, numLocals, maxStackDepth, + lexicalScope, inlinedLoops); // copy literals into the method for (size_t i = 0; i < numLiterals; i++) { @@ -83,8 +87,7 @@ VMPrimitive* MethodGenerationContext::AssemblePrimitive(bool classSide) { return VMPrimitive::GetEmptyPrimitive(signature, classSide); } -MethodGenerationContext::~MethodGenerationContext() { -} +MethodGenerationContext::~MethodGenerationContext() {} int8_t MethodGenerationContext::FindLiteralIndex(vm_oop_t lit) { return (int8_t)IndexOf(literals, lit); @@ -118,19 +121,19 @@ size_t IndexOf(std::vector& vec, std::string& name) { return -1; } - bool MethodGenerationContext::FindVar(std::string& var, int64_t* index, - int* context, bool* isArgument) { + int* context, bool* isArgument) { if ((*index = IndexOf(locals, var)) == -1) { if ((*index = IndexOf(arguments, var)) == -1) { - if (!outerGenc) + if (!outerGenc) { return false; - else { + } else { (*context)++; return outerGenc->FindVar(var, index, context, isArgument); } - } else + } else { *isArgument = true; + } } return true; @@ -152,12 +155,14 @@ void MethodGenerationContext::SetPrimitive(bool prim) { primitive = prim; } -void MethodGenerationContext::AddArgument(std::string& arg, const SourceCoordinate& coord) { +void MethodGenerationContext::AddArgument(std::string& arg, + const SourceCoordinate& coord) { size_t index = arguments.size(); arguments.push_back({arg, index, true, coord}); } -void MethodGenerationContext::AddLocal(std::string& local, const SourceCoordinate& coord) { +void MethodGenerationContext::AddLocal(std::string& local, + const SourceCoordinate& coord) { size_t index = locals.size(); locals.push_back({local, index, false, coord}); } @@ -173,18 +178,21 @@ uint8_t MethodGenerationContext::AddLiteral(vm_oop_t lit) { int8_t MethodGenerationContext::AddLiteralIfAbsent(vm_oop_t lit) { int8_t idx = IndexOf(literals, lit); if (idx != -1) { - assert(idx >= 0 && (size_t)idx < literals.size() && "Expect index to be inside the literals vector."); + assert(idx >= 0 && (size_t)idx < literals.size() && + "Expect index to be inside the literals vector."); return idx; } return AddLiteral(lit); } -void MethodGenerationContext::UpdateLiteral(vm_oop_t oldValue, uint8_t index, vm_oop_t newValue) { +void MethodGenerationContext::UpdateLiteral(vm_oop_t oldValue, uint8_t index, + vm_oop_t newValue) { assert(literals.at(index) == oldValue); literals[index] = newValue; } -bool MethodGenerationContext::AddArgumentIfAbsent(std::string& arg, const SourceCoordinate& coord) { +bool MethodGenerationContext::AddArgumentIfAbsent( + std::string& arg, const SourceCoordinate& coord) { if (Contains(locals, arg)) { return false; } @@ -192,7 +200,8 @@ bool MethodGenerationContext::AddArgumentIfAbsent(std::string& arg, const Source return true; } -bool MethodGenerationContext::AddLocalIfAbsent(std::string& local, const SourceCoordinate& coord) { +bool MethodGenerationContext::AddLocalIfAbsent(std::string& local, + const SourceCoordinate& coord) { if (Contains(locals, local)) { return false; } @@ -231,7 +240,8 @@ size_t MethodGenerationContext::AddBytecodeArgumentAndGetIndex(uint8_t bc) { return index; } -bool MethodGenerationContext::lastBytecodeIs(size_t indexFromEnd, uint8_t bytecode) { +bool MethodGenerationContext::lastBytecodeIs(size_t indexFromEnd, + uint8_t bytecode) { assert(indexFromEnd >= 0 && indexFromEnd < 4); uint8_t actual = last4Bytecodes[3 - indexFromEnd]; return actual == bytecode; @@ -242,7 +252,8 @@ void MethodGenerationContext::removeLastBytecodes(size_t numBytecodes) { size_t bytesToRemove = 0; for (size_t idxFromEnd = 0; idxFromEnd < numBytecodes; idxFromEnd += 1) { - bytesToRemove += Bytecode::GetBytecodeLength(last4Bytecodes[3 - idxFromEnd]); + bytesToRemove += + Bytecode::GetBytecodeLength(last4Bytecodes[3 - idxFromEnd]); } bytecode.erase(bytecode.end() - bytesToRemove, bytecode.end()); @@ -261,21 +272,23 @@ bool MethodGenerationContext::hasTwoLiteralBlockArguments() { * and inlining, where this is used, happens right after the block was added. * This also means, we need to remove blocks in reverse order. */ -vm_oop_t MethodGenerationContext::getLastBlockMethodAndFreeLiteral(uint8_t blockLiteralIdx) { +vm_oop_t MethodGenerationContext::getLastBlockMethodAndFreeLiteral( + uint8_t blockLiteralIdx) { assert(blockLiteralIdx == literals.size() - 1); vm_oop_t block = literals.back(); literals.pop_back(); return block; } -std::tuple MethodGenerationContext::extractBlockMethodsAndRemoveBytecodes() { +std::tuple +MethodGenerationContext::extractBlockMethodsAndRemoveBytecodes() { uint8_t block1LitIdx = bytecode.at(bytecode.size() - 3); uint8_t block2LitIdx = bytecode.at(bytecode.size() - 1); // grab the blocks' methods for inlining vm_oop_t toBeInlined2 = getLastBlockMethodAndFreeLiteral(block2LitIdx); vm_oop_t toBeInlined1 = getLastBlockMethodAndFreeLiteral(block1LitIdx); - + removeLastBytecodes(2); return {toBeInlined1, toBeInlined2}; @@ -288,7 +301,8 @@ bool MethodGenerationContext::InlineWhile(Parser& parser, bool isWhileTrue) { assert(Bytecode::GetBytecodeLength(BC_PUSH_BLOCK) == 2); - std::tuple methods = extractBlockMethodsAndRemoveBytecodes(); + std::tuple methods = + extractBlockMethodsAndRemoveBytecodes(); VMMethod* condMethod = static_cast(std::get<0>(methods)); VMMethod* bodyMethod = static_cast(std::get<1>(methods)); @@ -297,11 +311,13 @@ bool MethodGenerationContext::InlineWhile(Parser& parser, bool isWhileTrue) { isCurrentlyInliningABlock = true; condMethod->InlineInto(*this); - size_t jumpOffsetIdxToSkipLoopBody = EmitJumpOnBoolWithDummyOffset(*this, isWhileTrue, true); + size_t jumpOffsetIdxToSkipLoopBody = + EmitJumpOnBoolWithDummyOffset(*this, isWhileTrue, true); bodyMethod->InlineInto(*this); - completeJumpsAndEmitReturningNil(parser, loopBeginIdx, jumpOffsetIdxToSkipLoopBody); + completeJumpsAndEmitReturningNil(parser, loopBeginIdx, + jumpOffsetIdxToSkipLoopBody); isCurrentlyInliningABlock = false; @@ -309,8 +325,9 @@ bool MethodGenerationContext::InlineWhile(Parser& parser, bool isWhileTrue) { } void MethodGenerationContext::CompleteLexicalScope() { - lexicalScope = new LexicalScope(outerGenc == nullptr ? nullptr : outerGenc->lexicalScope, - arguments, locals); + lexicalScope = new LexicalScope( + outerGenc == nullptr ? nullptr : outerGenc->lexicalScope, arguments, + locals); } void MethodGenerationContext::MergeIntoScope(LexicalScope& scopeToBeInlined) { @@ -347,19 +364,27 @@ uint8_t MethodGenerationContext::GetInlinedLocalIdx(const Variable* var) const { char msg[200]; std::string qualifiedName = var->MakeQualifiedName(); - snprintf(msg, 200, "Unexpected issue trying to find an inlined variable. %s could not be found.", qualifiedName.data()); + snprintf( + msg, 200, + "Unexpected issue trying to find an inlined variable. %s could not " + "be found.", + qualifiedName.data()); Universe::ErrorExit(msg); } -void MethodGenerationContext::checkJumpOffset(size_t jumpOffset, uint8_t bytecode) { +void MethodGenerationContext::checkJumpOffset(size_t jumpOffset, + uint8_t bytecode) { if (jumpOffset < 0 || jumpOffset > 0xFFFF) { char msg[100]; - snprintf(msg, 100, "The jumpOffset for the %s bytecode is out of range: %zu\n", Bytecode::GetBytecodeName(bytecode), jumpOffset); + snprintf(msg, 100, + "The jumpOffset for the %s bytecode is out of range: %zu\n", + Bytecode::GetBytecodeName(bytecode), jumpOffset); Universe::ErrorExit(msg); } } -void MethodGenerationContext::EmitBackwardsJumpOffsetToTarget(size_t loopBeginIdx) { +void MethodGenerationContext::EmitBackwardsJumpOffsetToTarget( + size_t loopBeginIdx) { size_t addressOfJump = OffsetOfNextInstruction(); // we are going to jump backward and want a positive value @@ -374,7 +399,8 @@ void MethodGenerationContext::EmitBackwardsJumpOffsetToTarget(size_t loopBeginId inlinedLoops.push_back(BackJump(loopBeginIdx, backwardJumpIdx)); } -void MethodGenerationContext::completeJumpsAndEmitReturningNil(Parser& parser, size_t loopBeginIdx, size_t jumpOffsetIdxToSkipLoopBody) { +void MethodGenerationContext::completeJumpsAndEmitReturningNil( + Parser& parser, size_t loopBeginIdx, size_t jumpOffsetIdxToSkipLoopBody) { resetLastBytecodeBuffer(); EmitPOP(*this); @@ -385,7 +411,8 @@ void MethodGenerationContext::completeJumpsAndEmitReturningNil(Parser& parser, s resetLastBytecodeBuffer(); } -void MethodGenerationContext::PatchJumpOffsetToPointToNextInstruction(size_t indexOfOffset) { +void MethodGenerationContext::PatchJumpOffsetToPointToNextInstruction( + size_t indexOfOffset) { size_t instructionStart = indexOfOffset - 1; uint8_t bytecode = this->bytecode[instructionStart]; assert(IsJumpBytecode(bytecode)); diff --git a/src/compiler/MethodGenerationContext.h b/src/compiler/MethodGenerationContext.h index 95f525ab..54c23adc 100644 --- a/src/compiler/MethodGenerationContext.h +++ b/src/compiler/MethodGenerationContext.h @@ -31,6 +31,7 @@ #include "../misc/defs.h" #include "../vmobjects/ObjectFormats.h" +#include "../vmobjects/VMMethod.h" #include "ClassGenerationContext.h" #include "LexicalScope.h" #include "SourceCoordinate.h" @@ -39,15 +40,16 @@ class Parser; class MethodGenerationContext { public: - MethodGenerationContext(ClassGenerationContext& holder, MethodGenerationContext* outer = nullptr); + MethodGenerationContext(ClassGenerationContext& holder, + MethodGenerationContext* outer = nullptr); ~MethodGenerationContext(); VMMethod* Assemble(); VMPrimitive* AssemblePrimitive(bool classSide); int8_t FindLiteralIndex(vm_oop_t lit); - bool FindVar(std::string& var, int64_t* index, - int* context, bool* isArgument); + bool FindVar(std::string& var, int64_t* index, int* context, + bool* isArgument); bool HasField(VMSymbol* field); uint8_t GetFieldIndex(VMSymbol* field); @@ -67,33 +69,21 @@ class MethodGenerationContext { void SetFinished(bool finished = true); - ClassGenerationContext* GetHolder() const { - return &holderGenc; - } + ClassGenerationContext* GetHolder() const { return &holderGenc; } - MethodGenerationContext* GetOuter() const { - return outerGenc; - } + MethodGenerationContext* GetOuter() const { return outerGenc; } uint8_t GetMaxContextLevel() const { return maxContextLevel; } - VMSymbol* GetSignature() { - return signature; - } + VMSymbol* GetSignature() { return signature; } - bool IsPrimitive() const { - return primitive; - } + bool IsPrimitive() const { return primitive; } - bool IsBlockMethod() const { - return blockMethod; - } + bool IsBlockMethod() const { return blockMethod; } - bool IsFinished() const { - return finished; - } + bool IsFinished() const { return finished; } - void RemoveLastBytecode() {bytecode.pop_back();}; + void RemoveLastBytecode() { bytecode.pop_back(); }; size_t GetNumberOfArguments(); void AddBytecode(uint8_t bc, size_t stackEffect); void AddBytecodeArgument(uint8_t bc); @@ -101,15 +91,11 @@ class MethodGenerationContext { bool HasBytecodes(); - std::vector GetBytecodes() { - return bytecode; - } + std::vector GetBytecodes() { return bytecode; } bool InlineWhile(Parser& parser, bool isWhileTrue); - inline size_t OffsetOfNextInstruction() { - return bytecode.size(); - } + inline size_t OffsetOfNextInstruction() { return bytecode.size(); } void CompleteLexicalScope(); void MergeIntoScope(LexicalScope& scopeToBeInlined); @@ -126,7 +112,8 @@ class MethodGenerationContext { std::tuple extractBlockMethodsAndRemoveBytecodes(); vm_oop_t getLastBlockMethodAndFreeLiteral(uint8_t blockLiteralIdx); - void completeJumpsAndEmitReturningNil(Parser& parser, size_t loopBeginIdx, size_t jumpOffsetIdxToSkipLoopBody); + void completeJumpsAndEmitReturningNil(Parser& parser, size_t loopBeginIdx, + size_t jumpOffsetIdxToSkipLoopBody); void inlineLocals(LexicalScope& scopeToBeInlined); void checkJumpOffset(size_t jumpOffset, uint8_t bytecode); void resetLastBytecodeBuffer(); diff --git a/src/compiler/Parser.cpp b/src/compiler/Parser.cpp index f56f2fd6..35397469 100644 --- a/src/compiler/Parser.cpp +++ b/src/compiler/Parser.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Parser.h" + #include #include #include @@ -43,23 +45,22 @@ #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMClass.h" -#include "../vmobjects/VMDouble.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vmobjects/VMDouble.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "../vmobjects/VMMethod.h" #include "../vmobjects/VMPrimitive.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "../vmobjects/VMString.h" #include "../vmobjects/VMSymbol.h" #include "BytecodeGenerator.h" #include "Lexer.h" -#include "Parser.h" void Parser::GetSym() { - sym = lexer.GetSym(); + sym = lexer.GetSym(); text = lexer.GetText(); } void Parser::Peek() { nextSym = lexer.Peek(); - nextText = lexer.GetNextText(); + nextText = lexer.GetNextText(); } void Parser::PeekForNextSymbolFromLexerIfNecessary() { @@ -68,7 +69,8 @@ void Parser::PeekForNextSymbolFromLexerIfNecessary() { } } -Parser::Parser(istream& file, StdString& fname): lexer(file), fname(fname), sym(NONE), nextSym(NONE) { +Parser::Parser(istream& file, StdString& fname) + : lexer(file), fname(fname), sym(NONE), nextSym(NONE) { GetSym(); } @@ -77,9 +79,11 @@ Parser::Parser(istream& file, StdString& fname): lexer(file), fname(fname), sym( // bool Parser::symIn(Symbol* ss) { - while (*ss) - if (*ss++ == sym) + while (*ss) { + if (*ss++ == sym) { return true; + } + } return false; } @@ -110,20 +114,24 @@ bool Parser::expect(Symbol s) { return true; } - parseError("Unexpected symbol. Expected %(expected)s, but found %(found)s\n", s); + parseError( + "Unexpected symbol. Expected %(expected)s, but found %(found)s\n", s); return false; } bool Parser::expectOneOf(Symbol* ss) { - if (acceptOneOf(ss)) + if (acceptOneOf(ss)) { return true; - parseError("Unexpected symbol. Expected one of %(expected)s, but found %(found)s\n", ss); + } + parseError( + "Unexpected symbol. Expected one of %(expected)s, but found " + "%(found)s\n", + ss); return false; } -void Parser::genPushVariable(MethodGenerationContext& mgenc, - std::string& var) { +void Parser::genPushVariable(MethodGenerationContext& mgenc, std::string& var) { // The purpose of this function is to find out whether the variable to be // pushed on the stack is a local variable, argument, or object field. This // is done by examining all available lexical contexts, starting with the @@ -167,19 +175,19 @@ void Parser::genPopVariable(MethodGenerationContext& mgenc, std::string& var) { auto varSymbol = SymbolFor(var); EmitPOPFIELD(mgenc, varSymbol); } - } +} // // grammar // -Symbol singleOpSyms[] = { Not, And, Or, Star, Div, Mod, Plus, Equal, More, Less, - Comma, At, Per, Minus, NONE }; +Symbol singleOpSyms[] = {Not, And, Or, Star, Div, Mod, Plus, Equal, + More, Less, Comma, At, Per, Minus, NONE}; -Symbol binaryOpSyms[] = { Or, Comma, Minus, Equal, Not, And, Or, Star, Div, Mod, - Plus, Equal, More, Less, Comma, At, Per, NONE }; +Symbol binaryOpSyms[] = {Or, Comma, Minus, Equal, Not, And, Or, Star, Div, + Mod, Plus, Equal, More, Less, Comma, At, Per, NONE}; -Symbol keywordSelectorSyms[] = { Keyword, KeywordSequence }; +Symbol keywordSelectorSyms[] = {Keyword, KeywordSequence}; void Parser::Classdef(ClassGenerationContext& cgenc) { cgenc.SetName(SymbolFor(text)); @@ -193,14 +201,13 @@ void Parser::Classdef(ClassGenerationContext& cgenc) { instanceFields(cgenc); while (symIsIdentifier() || sym == Keyword || sym == OperatorSequence || symIn(binaryOpSyms)) { - MethodGenerationContext mgenc(cgenc); std::string self = strSelf; mgenc.AddArgument(self, lexer.GetCurrentSource()); method(mgenc); - if(mgenc.IsPrimitive()) { + if (mgenc.IsPrimitive()) { cgenc.AddInstanceMethod(mgenc.AssemblePrimitive(false)); } else { cgenc.AddInstanceMethod(mgenc.Assemble()); @@ -211,14 +218,14 @@ void Parser::Classdef(ClassGenerationContext& cgenc) { cgenc.SetClassSide(true); classFields(cgenc); while (symIsIdentifier() || sym == Keyword || sym == OperatorSequence || - symIn(binaryOpSyms)) { + symIn(binaryOpSyms)) { MethodGenerationContext mgenc(cgenc); std::string self = strSelf; mgenc.AddArgument(self, lexer.GetCurrentSource()); method(mgenc); - if(mgenc.IsPrimitive()) { + if (mgenc.IsPrimitive()) { cgenc.AddClassMethod(mgenc.AssemblePrimitive(true)); } else { cgenc.AddClassMethod(mgenc.Assemble()); @@ -242,16 +249,18 @@ void Parser::superclass(ClassGenerationContext& cgenc) { if (superName != SymbolFor("nil")) { VMClass* superClass = GetUniverse()->LoadClass(superName); cgenc.SetInstanceFieldsOfSuper(superClass->GetInstanceFields()); - cgenc.SetClassFieldsOfSuper(superClass->GetClass()->GetInstanceFields()); + cgenc.SetClassFieldsOfSuper( + superClass->GetClass()->GetInstanceFields()); } else { // we hardcode here the field names for Class // since Object class superclass = Class - // We avoid here any kind of dynamic solution to avoid further complexity. - // However, that makes it static, it is going to make it harder to - // change the definition of Class and Object - vector fieldNamesOfClass{ "class", "name", - "instanceFields", "instanceInvokables", "superClass" }; - VMArray* fieldNames = GetUniverse()->NewArrayOfSymbolsFromStrings(fieldNamesOfClass); + // We avoid here any kind of dynamic solution to avoid further + // complexity. However, that makes it static, it is going to make it + // harder to change the definition of Class and Object + vector fieldNamesOfClass{"class", "name", "instanceFields", + "instanceInvokables", "superClass"}; + VMArray* fieldNames = + GetUniverse()->NewArrayOfSymbolsFromStrings(fieldNamesOfClass); cgenc.SetClassFieldsOfSuper(fieldNames); } } @@ -294,16 +303,16 @@ void Parser::primitiveBlock() { void Parser::pattern(MethodGenerationContext& mgenc) { switch (sym) { - case Identifier: - case Primitive: - unaryPattern(mgenc); - break; - case Keyword: - keywordPattern(mgenc); - break; - default: - binaryPattern(mgenc); - break; + case Identifier: + case Primitive: + unaryPattern(mgenc); + break; + case Keyword: + keywordPattern(mgenc); + break; + default: + binaryPattern(mgenc); + break; } } @@ -355,9 +364,9 @@ VMSymbol* Parser::unarySelector() { VMSymbol* Parser::binarySelector() { StdString s(text); - if(acceptOneOf(singleOpSyms)) {} - else if(accept(OperatorSequence)) {} - else { + if (acceptOneOf(singleOpSyms)) { + } else if (accept(OperatorSequence)) { + } else { expect(NONE); } @@ -405,11 +414,11 @@ void Parser::locals(MethodGenerationContext& mgenc) { } } -void Parser::blockBody(MethodGenerationContext& mgenc, bool seen_period, bool is_inlined) { +void Parser::blockBody(MethodGenerationContext& mgenc, bool seen_period, + bool is_inlined) { if (accept(Exit)) { result(mgenc); - } - else if (sym == EndBlock) { + } else if (sym == EndBlock) { if (seen_period) { // a POP has been generated which must be elided (blocks always // return the value of the last expression, regardless of whether it @@ -498,8 +507,8 @@ std::string Parser::assignment() { void Parser::evaluation(MethodGenerationContext& mgenc) { bool super = primary(mgenc); - if (symIsIdentifier() || sym == Keyword || sym == OperatorSequence - || symIn(binaryOpSyms)) { + if (symIsIdentifier() || sym == Keyword || sym == OperatorSequence || + symIn(binaryOpSyms)) { messages(mgenc, super); } } @@ -507,33 +516,33 @@ void Parser::evaluation(MethodGenerationContext& mgenc) { bool Parser::primary(MethodGenerationContext& mgenc) { bool super = false; switch (sym) { - case Primitive: - case Identifier: { - auto v = variable(); - if (v == strSuper) { - super = true; - // sends to super push self as the receiver - v = strSelf; - } + case Primitive: + case Identifier: { + auto v = variable(); + if (v == strSuper) { + super = true; + // sends to super push self as the receiver + v = strSelf; + } - genPushVariable(mgenc, v); - break; - } - case NewTerm: - nestedTerm(mgenc); - break; - case NewBlock: { - MethodGenerationContext bgenc{*mgenc.GetHolder(), &mgenc}; + genPushVariable(mgenc, v); + break; + } + case NewTerm: + nestedTerm(mgenc); + break; + case NewBlock: { + MethodGenerationContext bgenc{*mgenc.GetHolder(), &mgenc}; - nestedBlock(bgenc); + nestedBlock(bgenc); - VMMethod* blockMethod = bgenc.Assemble(); - EmitPUSHBLOCK(mgenc, blockMethod); - break; - } - default: - literal(mgenc); - break; + VMMethod* blockMethod = bgenc.Assemble(); + EmitPUSHBLOCK(mgenc, blockMethod); + break; + } + default: + literal(mgenc); + break; } return super; @@ -606,7 +615,6 @@ bool Parser::binaryOperand(MethodGenerationContext& mgenc) { return super; } - void Parser::keywordMessage(MethodGenerationContext& mgenc, bool super) { StdString kw = keyword(); int numParts = 1; @@ -619,9 +627,9 @@ void Parser::keywordMessage(MethodGenerationContext& mgenc, bool super) { } if (!super) { - if (numParts == 1 && ( - (kw == "whileTrue:" && mgenc.InlineWhile(*this, true)) || - (kw == "whileFalse:" && mgenc.InlineWhile(*this, false)))) { + if (numParts == 1 && + ((kw == "whileTrue:" && mgenc.InlineWhile(*this, true)) || + (kw == "whileFalse:" && mgenc.InlineWhile(*this, false)))) { return; } } @@ -656,28 +664,29 @@ void Parser::nestedTerm(MethodGenerationContext& mgenc) { void Parser::literal(MethodGenerationContext& mgenc) { switch (sym) { - case Pound: - PeekForNextSymbolFromLexerIfNecessary(); - if (nextSym == NewTerm) { - literalArray(mgenc); - } else { - literalSymbol(mgenc); - } - break; - case STString: - literalString(mgenc); - break; - default: - literalNumber(mgenc); - break; + case Pound: + PeekForNextSymbolFromLexerIfNecessary(); + if (nextSym == NewTerm) { + literalArray(mgenc); + } else { + literalSymbol(mgenc); + } + break; + case STString: + literalString(mgenc); + break; + default: + literalNumber(mgenc); + break; } } vm_oop_t Parser::literalNumberOop() { - if (sym == Minus) + if (sym == Minus) { return negativeDecimal(); - else + } else { return literalDecimal(false); + } } void Parser::literalNumber(MethodGenerationContext& mgenc) { @@ -730,12 +739,13 @@ void Parser::literalArray(MethodGenerationContext& mgenc) { expect(Pound); expect(NewTerm); - VMSymbol* arrayClassName = SymbolFor("Array"); + VMSymbol* arrayClassName = SymbolFor("Array"); VMSymbol* arraySizePlaceholder = SymbolFor("ArraySizeLiteralPlaceholder"); - VMSymbol* newMessage = SymbolFor("new:"); - VMSymbol* atPutMessage = SymbolFor("at:put:"); + VMSymbol* newMessage = SymbolFor("new:"); + VMSymbol* atPutMessage = SymbolFor("at:put:"); - const uint8_t arraySizeLiteralIndex = mgenc.AddLiteral(arraySizePlaceholder); + const uint8_t arraySizeLiteralIndex = + mgenc.AddLiteral(arraySizePlaceholder); // create bytecode sequence for instantiating new array EmitPUSHGLOBAL(mgenc, arrayClassName); @@ -753,7 +763,8 @@ void Parser::literalArray(MethodGenerationContext& mgenc) { } // replace the placeholder with the actual array size - mgenc.UpdateLiteral(arraySizePlaceholder, arraySizeLiteralIndex, NEW_INT(i - 1)); + mgenc.UpdateLiteral(arraySizePlaceholder, arraySizeLiteralIndex, + NEW_INT(i - 1)); expect(EndTerm); } @@ -766,12 +777,13 @@ void Parser::literalString(MethodGenerationContext& mgenc) { } VMSymbol* Parser::selector() { - if(sym == OperatorSequence || symIn(singleOpSyms)) - return binarySelector(); - else if(sym == Keyword || sym == KeywordSequence) - return keywordSelector(); - else - return unarySelector(); + if (sym == OperatorSequence || symIn(singleOpSyms)) { + return binarySelector(); + } else if (sym == Keyword || sym == KeywordSequence) { + return keywordSelector(); + } else { + return unarySelector(); + } } VMSymbol* Parser::keywordSelector() { @@ -784,7 +796,7 @@ VMSymbol* Parser::keywordSelector() { StdString Parser::_string() { StdString s(text); expect(STString); - return s; // <-- Literal strings are At Most BUFSIZ chars long. + return s; // <-- Literal strings are At Most BUFSIZ chars long. } void Parser::nestedBlock(MethodGenerationContext& mgenc) { @@ -792,14 +804,17 @@ void Parser::nestedBlock(MethodGenerationContext& mgenc) { mgenc.AddArgumentIfAbsent(blockSelf, lexer.GetCurrentSource()); expect(NewBlock); - if (sym == Colon) + if (sym == Colon) { blockPattern(mgenc); + } // generate Block signature - StdString block_sig = "$blockMethod@" + to_string(lexer.GetCurrentLineNumber()); + StdString block_sig = + "$blockMethod@" + to_string(lexer.GetCurrentLineNumber()); size_t arg_size = mgenc.GetNumberOfArguments(); - for (size_t i = 1; i < arg_size; i++) + for (size_t i = 1; i < arg_size; i++) { block_sig += ":"; + } mgenc.SetSignature(SymbolFor(block_sig)); @@ -809,8 +824,8 @@ void Parser::nestedBlock(MethodGenerationContext& mgenc) { // in the block was not terminated by ., and can generate a return if (!mgenc.IsFinished()) { if (!mgenc.HasBytecodes()) { - // if the block is empty, we need to return nil - EmitPUSHCONSTANT(mgenc, load_ptr(nilObject)); + // if the block is empty, we need to return nil + EmitPUSHCONSTANT(mgenc, load_ptr(nilObject)); } EmitRETURNLOCAL(mgenc); mgenc.SetFinished(true); @@ -835,16 +850,16 @@ void Parser::blockArguments(MethodGenerationContext& mgenc) { } while (sym == Colon); } - - -__attribute__((noreturn)) void Parser::parseError(const char* msg, Symbol expected) { +__attribute__((noreturn)) void Parser::parseError(const char* msg, + Symbol expected) { StdString expectedStr(symnames[expected]); parseError(msg, expectedStr); } - -__attribute__((noreturn)) void Parser::parseError(const char* msg, StdString expected) { - StdString msgWithMeta = "%(file)s:%(line)d:%(column)d: error: " + StdString(msg); +__attribute__((noreturn)) void Parser::parseError(const char* msg, + StdString expected) { + StdString msgWithMeta = + "%(file)s:%(line)d:%(column)d: error: " + StdString(msg); StdString foundStr; if (_PRINTABLE_SYM) { @@ -867,7 +882,8 @@ __attribute__((noreturn)) void Parser::parseError(const char* msg, StdString exp GetUniverse()->Quit(ERR_FAIL); } -__attribute__((noreturn)) void Parser::parseError(const char* msg, Symbol* expected) { +__attribute__((noreturn)) void Parser::parseError(const char* msg, + Symbol* expected) { bool first = true; StdString expectedStr = ""; diff --git a/src/compiler/Parser.h b/src/compiler/Parser.h index 70dbe563..aa6f76a9 100644 --- a/src/compiler/Parser.h +++ b/src/compiler/Parser.h @@ -47,8 +47,10 @@ class Parser { private: __attribute__((noreturn)) void parseError(const char* msg, Symbol expected); - __attribute__((noreturn)) void parseError(const char* msg, Symbol* expected); - __attribute__((noreturn)) void parseError(const char* msg, StdString expected); + __attribute__((noreturn)) void parseError(const char* msg, + Symbol* expected); + __attribute__((noreturn)) void parseError(const char* msg, + StdString expected); void GetSym(); void Peek(); @@ -80,7 +82,8 @@ class Parser { std::string argument(); void blockContents(MethodGenerationContext& mgenc, bool is_inlined); void locals(MethodGenerationContext& mgenc); - void blockBody(MethodGenerationContext& mgenc, bool seen_period, bool is_inlined); + void blockBody(MethodGenerationContext& mgenc, bool seen_period, + bool is_inlined); void result(MethodGenerationContext& mgenc); void expression(MethodGenerationContext& mgenc); void assignation(MethodGenerationContext& mgenc); @@ -103,7 +106,7 @@ class Parser { vm_oop_t literalDecimal(bool negateValue); vm_oop_t negativeDecimal(void); vm_oop_t literalInteger(bool negateValue); - vm_oop_t literalDouble(bool negateValue); + vm_oop_t literalDouble(bool negateValue); void literalArray(MethodGenerationContext& mgenc); void literalSymbol(MethodGenerationContext& mgenc); void literalString(MethodGenerationContext& mgenc); diff --git a/src/compiler/SourceCoordinate.h b/src/compiler/SourceCoordinate.h index c7f0dab9..02f4f45b 100644 --- a/src/compiler/SourceCoordinate.h +++ b/src/compiler/SourceCoordinate.h @@ -4,7 +4,7 @@ class SourceCoordinate { public: SourceCoordinate(size_t line, size_t column) : line(line), column(column) {} SourceCoordinate() : line(0), column(0) {} - + inline size_t GetLine() const { return line; } inline size_t GetColumn() const { return column; } @@ -15,7 +15,7 @@ class SourceCoordinate { private: /* 1-based */ size_t line; - + /* 1-based */ size_t column; }; diff --git a/src/compiler/SourcecodeCompiler.cpp b/src/compiler/SourcecodeCompiler.cpp index 38eec45b..55679cce 100644 --- a/src/compiler/SourcecodeCompiler.cpp +++ b/src/compiler/SourcecodeCompiler.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "SourcecodeCompiler.h" + #include #include #include @@ -36,12 +38,10 @@ #include "../vmobjects/VMSymbol.h" #include "ClassGenerationContext.h" #include "Parser.h" -#include "SourcecodeCompiler.h" - -VMClass* SourcecodeCompiler::CompileClass( const std::string& path, - const std::string& file, - VMClass* systemClass ) { +VMClass* SourcecodeCompiler::CompileClass(const std::string& path, + const std::string& file, + VMClass* systemClass) { VMClass* result = systemClass; std::string fname = path + fileSeparator + file + ".som"; @@ -59,22 +59,21 @@ VMClass* SourcecodeCompiler::CompileClass( const std::string& path, StdString cnameC = cname->GetStdString(); if (file != cnameC) { - ostringstream Str; Str << "Filename: " << file << " does not match class name " << cnameC; showCompilationError(file, Str.str().c_str()); return nullptr; } - + #ifdef COMPILER_DEBUG ErrorPrint("Compilation finished\n"); #endif return result; } -VMClass* SourcecodeCompiler::CompileClassString( const StdString& stream, - VMClass* systemClass ) { +VMClass* SourcecodeCompiler::CompileClassString(const StdString& stream, + VMClass* systemClass) { istringstream ss(stream); StdString fileName = "repl"; @@ -85,9 +84,8 @@ VMClass* SourcecodeCompiler::CompileClassString( const StdString& stream, } void SourcecodeCompiler::showCompilationError(const StdString& filename, - const char* message) { - ErrorPrint("Error when compiling " + filename + ":\n" + - message + "\n"); + const char* message) { + ErrorPrint("Error when compiling " + filename + ":\n" + message + "\n"); } VMClass* SourcecodeCompiler::compile(Parser& parser, VMClass* systemClass) { diff --git a/src/compiler/SourcecodeCompiler.h b/src/compiler/SourcecodeCompiler.h index 44525497..5623a103 100644 --- a/src/compiler/SourcecodeCompiler.h +++ b/src/compiler/SourcecodeCompiler.h @@ -33,9 +33,12 @@ class SourcecodeCompiler { public: static VMClass* CompileClass(const StdString& path, const StdString& file, - VMClass* systemClass); - static VMClass* CompileClassString(const StdString& stream, VMClass* systemClass); + VMClass* systemClass); + static VMClass* CompileClassString(const StdString& stream, + VMClass* systemClass); + private: - static void showCompilationError(const StdString& filename, const char* message); + static void showCompilationError(const StdString& filename, + const char* message); static VMClass* compile(Parser& parser, VMClass* systemClass); }; diff --git a/src/compiler/Variable.cpp b/src/compiler/Variable.cpp index 0ae7a155..66cfc029 100644 --- a/src/compiler/Variable.cpp +++ b/src/compiler/Variable.cpp @@ -1,3 +1,5 @@ +#include "Variable.h" + #include #include #include @@ -5,14 +7,12 @@ #include "../vm/Symbols.h" #include "SourceCoordinate.h" -#include "Variable.h" std::string Variable::MakeQualifiedName() const { char qualified[100]; assert(name.size() < 80); - snprintf(qualified, 100, "%.*s:%zu:%zu", - (int)name.size(), name.data(), + snprintf(qualified, 100, "%.*s:%zu:%zu", (int)name.size(), name.data(), coord.GetLine(), coord.GetColumn()); return {qualified}; diff --git a/src/compiler/Variable.h b/src/compiler/Variable.h index 5379d3f5..ae64498a 100644 --- a/src/compiler/Variable.h +++ b/src/compiler/Variable.h @@ -8,33 +8,32 @@ class Variable { public: - Variable(std::string& name, size_t index, bool isArgument, SourceCoordinate coord) : name(name), index(index), isArgument(isArgument), coord(coord) { + Variable(std::string& name, size_t index, bool isArgument, + SourceCoordinate coord) + : name(name), index(index), isArgument(isArgument), coord(coord) { assert(index != 0xff); } Variable() : name(nullptr), index(0xff) {} - Variable(const Variable* old, size_t newIndex, bool isArgument) : name(old->name), index(newIndex), isArgument(isArgument), coord(old->coord) {} - - bool IsNamed(std::string& n) const { - return name == n; - } + Variable(const Variable* old, size_t newIndex, bool isArgument) + : name(old->name), index(newIndex), isArgument(isArgument), + coord(old->coord) {} - bool IsSame(const Variable& other) const { - return coord == other.coord; - } + bool IsNamed(std::string& n) const { return name == n; } + + bool IsSame(const Variable& other) const { return coord == other.coord; } bool IsValid() const { return index != 0xff; } inline uint8_t GetIndex() const { return index; } - + const std::string* GetName() const { return &name; } std::string MakeQualifiedName() const; - Variable CopyForInlining(size_t newIndex) const; - + protected: std::string name; uint8_t index; diff --git a/src/interpreter/Interpreter.cpp b/src/interpreter/Interpreter.cpp index 3aabe6c5..e2880f53 100644 --- a/src/interpreter/Interpreter.cpp +++ b/src/interpreter/Interpreter.cpp @@ -24,12 +24,14 @@ THE SOFTWARE. */ +#include "Interpreter.h" + #include #include #include #include "../compiler/Disassembler.h" -#include "../interpreter/bytecodes.h" // NOLINT(misc-include-cleaner) it's required for InterpreterLoop.h +#include "../interpreter/bytecodes.h" // NOLINT(misc-include-cleaner) it's required for InterpreterLoop.h #include "../memory/Heap.h" #include "../misc/defs.h" #include "../vm/IsValidObject.h" @@ -45,23 +47,22 @@ #include "../vmobjects/VMMethod.h" #include "../vmobjects/VMObject.h" #include "../vmobjects/VMSymbol.h" -#include "Interpreter.h" - - -const std::string Interpreter::unknownGlobal = "unknownGlobal:"; -const std::string Interpreter::doesNotUnderstand = "doesNotUnderstand:arguments:"; -const std::string Interpreter::escapedBlock = "escapedBlock:"; +const std::string Interpreter::unknownGlobal = "unknownGlobal:"; +const std::string Interpreter::doesNotUnderstand = + "doesNotUnderstand:arguments:"; +const std::string Interpreter::escapedBlock = "escapedBlock:"; Interpreter::Interpreter() : frame(nullptr) {} Interpreter::~Interpreter() {} vm_oop_t Interpreter::StartAndPrintBytecodes() { -#define PROLOGUE(bc_count) {\ -disassembleMethod(); \ -bytecodeIndexGlobal += bc_count;\ -} +#define PROLOGUE(bc_count) \ + { \ + disassembleMethod(); \ + bytecodeIndexGlobal += bc_count; \ + } #define HACK_INLINE_START #include "InterpreterLoop.h" #undef HACK_INLINE_START @@ -69,9 +70,8 @@ bytecodeIndexGlobal += bc_count;\ vm_oop_t Interpreter::Start() { #undef PROLOGUE -#define PROLOGUE(bc_count) {\ -bytecodeIndexGlobal += bc_count;\ -} +#define PROLOGUE(bc_count) \ + { bytecodeIndexGlobal += bc_count; } #define HACK_INLINE_START #include "InterpreterLoop.h" #undef HACK_INLINE_START @@ -83,15 +83,16 @@ VMFrame* Interpreter::PushNewFrame(VMMethod* method) { } void Interpreter::SetFrame(VMFrame* frame) { - if (this->frame != nullptr) + if (this->frame != nullptr) { this->frame->SetBytecodeIndex(bytecodeIndexGlobal); + } this->frame = frame; // update cached values - method = frame->GetMethod(); + method = frame->GetMethod(); bytecodeIndexGlobal = frame->GetBytecodeIndex(); - currentBytecodes = method->GetBytecodes(); + currentBytecodes = method->GetBytecodes(); } vm_oop_t Interpreter::GetSelf() const { @@ -106,7 +107,7 @@ VMFrame* Interpreter::popFrame() { result->ClearPreviousFrame(); #ifdef UNSAFE_FRAME_OPTIMIZATION - //remember this frame as free frame + // remember this frame as free frame result->GetMethod()->SetCachedFrame(result); #endif return result; @@ -118,7 +119,9 @@ void Interpreter::popFrameAndPushResult(vm_oop_t result) { VMMethod* method = prevFrame->GetMethod(); long numberOfArgs = method->GetNumberOfArguments(); - for (long i = 0; i < numberOfArgs; ++i) GetFrame()->Pop(); + for (long i = 0; i < numberOfArgs; ++i) { + GetFrame()->Pop(); + } GetFrame()->Push(result); } @@ -129,11 +132,14 @@ void Interpreter::send(VMSymbol* signature, VMClass* receiverClass) { if (invokable != nullptr) { #ifdef LOG_RECEIVER_TYPES std::string name = receiverClass->GetName()->GetStdString(); - if (GetUniverse()->callStats.find(name) == GetUniverse()->callStats.end()) - GetUniverse()->callStats[name] = {0,0}; + if (GetUniverse()->callStats.find(name) == + GetUniverse()->callStats.end()) { + GetUniverse()->callStats[name] = {0, 0}; + } GetUniverse()->callStats[name].noCalls++; - if (invokable->IsPrimitive()) - GetUniverse()->callStats[name].noPrimitiveCalls++; + if (invokable->IsPrimitive()) { + GetUniverse()->callStats[name].noPrimitiveCalls++; + } #endif // since an invokable is able to change/use the frame, we have to write // cached values before, and read cached values after calling @@ -150,7 +156,8 @@ void Interpreter::triggerDoesNotUnderstand(VMSymbol* signature) { vm_oop_t receiver = GetFrame()->GetStackElement(numberOfArgs - 1); - VMArray* argumentsArray = GetUniverse()->NewArray(numberOfArgs - 1); // without receiver + VMArray* argumentsArray = + GetUniverse()->NewArray(numberOfArgs - 1); // without receiver // the receiver should not go into the argumentsArray // so, numberOfArgs - 2 @@ -160,14 +167,15 @@ void Interpreter::triggerDoesNotUnderstand(VMSymbol* signature) { } vm_oop_t arguments[] = {signature, argumentsArray}; - GetFrame()->Pop(); // pop the receiver + GetFrame()->Pop(); // pop the receiver - //check if current frame is big enough for this unplanned Send - //doesNotUnderstand: needs 3 slots, one for this, one for method name, one for args + // check if current frame is big enough for this unplanned Send + // doesNotUnderstand: needs 3 slots, one for this, one for method name, one + // for args long additionalStackSlots = 3 - GetFrame()->RemainingStackSize(); if (additionalStackSlots > 0) { GetFrame()->SetBytecodeIndex(bytecodeIndexGlobal); - //copy current frame into a bigger one and replace the current frame + // copy current frame into a bigger one and replace the current frame SetFrame(VMFrame::EmergencyFrameFrom(GetFrame(), additionalStackSlots)); } @@ -188,7 +196,7 @@ void Interpreter::doPushLocal(long bytecodeIndex) { GetFrame()->Push(local); } -void Interpreter::doPushLocalWithIndex(uint8_t localIndex){ +void Interpreter::doPushLocalWithIndex(uint8_t localIndex) { vm_oop_t local = GetFrame()->GetLocalInCurrentContext(localIndex); GetFrame()->Push(local); } @@ -214,8 +222,7 @@ void Interpreter::doPushFieldWithIndex(uint8_t fieldIndex) { if (unlikely(IS_TAGGED(self))) { o = nullptr; Universe()->ErrorExit("Integers do not have fields!"); - } - else { + } else { o = ((VMObject*)self)->GetField(fieldIndex); } @@ -223,30 +230,35 @@ void Interpreter::doPushFieldWithIndex(uint8_t fieldIndex) { } void Interpreter::doPushBlock(long bytecodeIndex) { - VMMethod* blockMethod = static_cast(method->GetConstant(bytecodeIndex)); + VMMethod* blockMethod = + static_cast(method->GetConstant(bytecodeIndex)); long numOfArgs = blockMethod->GetNumberOfArguments(); - GetFrame()->Push(GetUniverse()->NewBlock(blockMethod, GetFrame(), numOfArgs)); + GetFrame()->Push( + GetUniverse()->NewBlock(blockMethod, GetFrame(), numOfArgs)); } void Interpreter::doPushGlobal(long bytecodeIndex) { - VMSymbol* globalName = static_cast(method->GetConstant(bytecodeIndex)); + VMSymbol* globalName = + static_cast(method->GetConstant(bytecodeIndex)); vm_oop_t global = GetUniverse()->GetGlobal(globalName); - if (global != nullptr) + if (global != nullptr) { GetFrame()->Push(global); - else { + } else { vm_oop_t arguments[] = {globalName}; vm_oop_t self = GetSelf(); - //check if there is enough space on the stack for this unplanned Send - //unknowGlobal: needs 2 slots, one for "this" and one for the argument + // check if there is enough space on the stack for this unplanned Send + // unknowGlobal: needs 2 slots, one for "this" and one for the argument long additionalStackSlots = 2 - GetFrame()->RemainingStackSize(); if (additionalStackSlots > 0) { GetFrame()->SetBytecodeIndex(bytecodeIndexGlobal); - //copy current frame into a bigger one and replace the current frame - SetFrame(VMFrame::EmergencyFrameFrom(GetFrame(), additionalStackSlots)); + // copy current frame into a bigger one and replace the current + // frame + SetFrame( + VMFrame::EmergencyFrameFrom(GetFrame(), additionalStackSlots)); } AS_OBJ(self)->Send(this, unknownGlobal, arguments, 1); @@ -290,18 +302,18 @@ void Interpreter::doPopFieldWithIndex(uint8_t fieldIndex) { if (unlikely(IS_TAGGED(self))) { GetUniverse()->ErrorExit("Integers do not have fields that can be set"); - } - else { - ((VMObject*) self)->SetField(fieldIndex, o); + } else { + ((VMObject*)self)->SetField(fieldIndex, o); } } void Interpreter::doSend(long bytecodeIndex) { - VMSymbol* signature = static_cast(method->GetConstant(bytecodeIndex)); + VMSymbol* signature = + static_cast(method->GetConstant(bytecodeIndex)); int numOfArgs = Signature::GetNumberOfArguments(signature); - vm_oop_t receiver = GetFrame()->GetStackElement(numOfArgs-1); + vm_oop_t receiver = GetFrame()->GetStackElement(numOfArgs - 1); assert(IsValidObject(receiver)); // make sure it is really a class @@ -319,18 +331,20 @@ void Interpreter::doSend(long bytecodeIndex) { } void Interpreter::doSuperSend(long bytecodeIndex) { - VMSymbol* signature = static_cast(method->GetConstant(bytecodeIndex)); + VMSymbol* signature = + static_cast(method->GetConstant(bytecodeIndex)); VMFrame* ctxt = GetFrame()->GetOuterContext(); VMMethod* realMethod = ctxt->GetMethod(); VMClass* holder = realMethod->GetHolder(); assert(holder->HasSuperClass()); - VMClass* super = (VMClass*) holder->GetSuperClass(); - VMInvokable* invokable = static_cast(super->LookupInvokable(signature)); + VMClass* super = (VMClass*)holder->GetSuperClass(); + VMInvokable* invokable = + static_cast(super->LookupInvokable(signature)); - if (invokable != nullptr) + if (invokable != nullptr) { invokable->Invoke(this, GetFrame()); - else { + } else { long numOfArgs = Signature::GetNumberOfArguments(signature); vm_oop_t receiver = GetFrame()->GetStackElement(numOfArgs - 1); VMArray* argumentsArray = GetUniverse()->NewArray(numOfArgs); @@ -356,7 +370,8 @@ void Interpreter::doReturnNonLocal() { VMFrame* context = GetFrame()->GetOuterContext(); if (!context->HasPreviousFrame()) { - VMBlock* block = static_cast(GetFrame()->GetArgumentInCurrentContext(0)); + VMBlock* block = + static_cast(GetFrame()->GetArgumentInCurrentContext(0)); VMFrame* prevFrame = GetFrame()->GetPreviousFrame(); VMFrame* outerContext = prevFrame->GetOuterContext(); vm_oop_t sender = outerContext->GetArgumentInCurrentContext(0); @@ -367,8 +382,9 @@ void Interpreter::doReturnNonLocal() { // Pop old arguments from stack VMMethod* method = GetFrame()->GetMethod(); long numberOfArgs = method->GetNumberOfArguments(); - for (long i = 0; i < numberOfArgs; ++i) + for (long i = 0; i < numberOfArgs; ++i) { GetFrame()->Pop(); + } // check if current frame is big enough for this unplanned send // #escapedBlock: needs 2 slots, one for self, and one for the block @@ -376,14 +392,17 @@ void Interpreter::doReturnNonLocal() { if (additionalStackSlots > 0) { GetFrame()->SetBytecodeIndex(bytecodeIndexGlobal); // copy current frame into a bigger one, and replace it - SetFrame(VMFrame::EmergencyFrameFrom(GetFrame(), additionalStackSlots)); + SetFrame( + VMFrame::EmergencyFrameFrom(GetFrame(), additionalStackSlots)); } AS_OBJ(sender)->Send(this, escapedBlock, arguments, 1); return; } - while (GetFrame() != context) popFrame(); + while (GetFrame() != context) { + popFrame(); + } popFrameAndPushResult(result); } @@ -394,7 +413,7 @@ void Interpreter::WalkGlobals(walk_heap_fn walk) { // Get the current frame and mark it. // Since marking is done recursively, this automatically // marks the whole stack - frame = load_ptr(static_cast(walk(tmp_ptr(frame)))); + frame = load_ptr(static_cast(walk(tmp_ptr(frame)))); } void Interpreter::startGC() { diff --git a/src/interpreter/Interpreter.h b/src/interpreter/Interpreter.h index 7315724c..2615c1dc 100644 --- a/src/interpreter/Interpreter.h +++ b/src/interpreter/Interpreter.h @@ -31,55 +31,55 @@ #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMMethod.h" -#define DISPATCH_NOGC() {\ - goto *loopTargets[currentBytecodes[bytecodeIndexGlobal]]; \ -} - -#define DISPATCH_GC() {\ - if (GetHeap()->isCollectionTriggered()) { startGC(); } \ - goto *loopTargets[currentBytecodes[bytecodeIndexGlobal]];\ -} +#define DISPATCH_NOGC() \ + { goto* loopTargets[currentBytecodes[bytecodeIndexGlobal]]; } +#define DISPATCH_GC() \ + { \ + if (GetHeap()->isCollectionTriggered()) { \ + startGC(); \ + } \ + goto* loopTargets[currentBytecodes[bytecodeIndexGlobal]]; \ + } class Interpreter { public: Interpreter(); ~Interpreter(); - + vm_oop_t StartAndPrintBytecodes(); vm_oop_t Start(); - - VMFrame* PushNewFrame(VMMethod* method); - void SetFrame(VMFrame* frame); + + VMFrame* PushNewFrame(VMMethod* method); + void SetFrame(VMFrame* frame); inline VMFrame* GetFrame() const; VMMethod* GetMethod() const; uint8_t* GetBytecodes() const; - void WalkGlobals(walk_heap_fn); - + void WalkGlobals(walk_heap_fn); + private: vm_oop_t GetSelf() const; - + VMFrame* frame; VMMethod* method; - + // The following three variables are used to cache main parts of the // current execution context - long bytecodeIndexGlobal; - uint8_t* currentBytecodes; + long bytecodeIndexGlobal; + uint8_t* currentBytecodes; - static const StdString unknownGlobal; static const StdString doesNotUnderstand; static const StdString escapedBlock; - + void startGC(); void disassembleMethod() const; VMFrame* popFrame(); void popFrameAndPushResult(vm_oop_t result); - + void send(VMSymbol* signature, VMClass* receiverClass); - + void triggerDoesNotUnderstand(VMSymbol* signature); void doDup(); @@ -89,12 +89,12 @@ class Interpreter { void doPushField(long bytecodeIndex); void doPushFieldWithIndex(uint8_t fieldIndex); void doPushBlock(long bytecodeIndex); - + inline void doPushConstant(long bytecodeIndex) { vm_oop_t constant = method->GetConstant(bytecodeIndex); GetFrame()->Push(constant); } - + void doPushGlobal(long bytecodeIndex); void doPop(void); void doPopLocal(long bytecodeIndex); diff --git a/src/interpreter/InterpreterLoop.h b/src/interpreter/InterpreterLoop.h index aae81384..45b4494d 100644 --- a/src/interpreter/InterpreterLoop.h +++ b/src/interpreter/InterpreterLoop.h @@ -5,63 +5,61 @@ vm_oop_t Start() { method = GetMethod(); currentBytecodes = GetBytecodes(); - void* loopTargets[] = { - &&LABEL_BC_HALT, - &&LABEL_BC_DUP, - &&LABEL_BC_PUSH_LOCAL, - &&LABEL_BC_PUSH_LOCAL_0, - &&LABEL_BC_PUSH_LOCAL_1, - &&LABEL_BC_PUSH_LOCAL_2, - &&LABEL_BC_PUSH_ARGUMENT, - &&LABEL_BC_PUSH_SELF, - &&LABEL_BC_PUSH_ARG_1, - &&LABEL_BC_PUSH_ARG_2, - &&LABEL_BC_PUSH_FIELD, - &&LABEL_BC_PUSH_FIELD_0, - &&LABEL_BC_PUSH_FIELD_1, - &&LABEL_BC_PUSH_BLOCK, - &&LABEL_BC_PUSH_CONSTANT, - &&LABEL_BC_PUSH_CONSTANT_0, - &&LABEL_BC_PUSH_CONSTANT_1, - &&LABEL_BC_PUSH_CONSTANT_2, - &&LABEL_BC_PUSH_0, - &&LABEL_BC_PUSH_1, - &&LABEL_BC_PUSH_NIL, - &&LABEL_BC_PUSH_GLOBAL, - &&LABEL_BC_POP, - &&LABEL_BC_POP_LOCAL, - &&LABEL_BC_POP_LOCAL_0, - &&LABEL_BC_POP_LOCAL_1, - &&LABEL_BC_POP_LOCAL_2, - &&LABEL_BC_POP_ARGUMENT, - &&LABEL_BC_POP_FIELD, - &&LABEL_BC_POP_FIELD_0, - &&LABEL_BC_POP_FIELD_1, - &&LABEL_BC_SEND, - &&LABEL_BC_SUPER_SEND, - &&LABEL_BC_RETURN_LOCAL, - &&LABEL_BC_RETURN_NON_LOCAL, - &&LABEL_BC_JUMP, - &&LABEL_BC_JUMP_ON_FALSE_POP, - &&LABEL_BC_JUMP_ON_TRUE_POP, - &&LABEL_BC_JUMP_ON_FALSE_TOP_NIL, - &&LABEL_BC_JUMP_ON_TRUE_TOP_NIL, - &&LABEL_BC_JUMP_BACKWARD, - &&LABEL_BC_JUMP2, - &&LABEL_BC_JUMP2_ON_FALSE_POP, - &&LABEL_BC_JUMP2_ON_TRUE_POP, - &&LABEL_BC_JUMP2_ON_FALSE_TOP_NIL, - &&LABEL_BC_JUMP2_ON_TRUE_TOP_NIL, - &&LABEL_BC_JUMP2_BACKWARD - }; - - goto *loopTargets[currentBytecodes[bytecodeIndexGlobal]]; + void* loopTargets[] = {&&LABEL_BC_HALT, + &&LABEL_BC_DUP, + &&LABEL_BC_PUSH_LOCAL, + &&LABEL_BC_PUSH_LOCAL_0, + &&LABEL_BC_PUSH_LOCAL_1, + &&LABEL_BC_PUSH_LOCAL_2, + &&LABEL_BC_PUSH_ARGUMENT, + &&LABEL_BC_PUSH_SELF, + &&LABEL_BC_PUSH_ARG_1, + &&LABEL_BC_PUSH_ARG_2, + &&LABEL_BC_PUSH_FIELD, + &&LABEL_BC_PUSH_FIELD_0, + &&LABEL_BC_PUSH_FIELD_1, + &&LABEL_BC_PUSH_BLOCK, + &&LABEL_BC_PUSH_CONSTANT, + &&LABEL_BC_PUSH_CONSTANT_0, + &&LABEL_BC_PUSH_CONSTANT_1, + &&LABEL_BC_PUSH_CONSTANT_2, + &&LABEL_BC_PUSH_0, + &&LABEL_BC_PUSH_1, + &&LABEL_BC_PUSH_NIL, + &&LABEL_BC_PUSH_GLOBAL, + &&LABEL_BC_POP, + &&LABEL_BC_POP_LOCAL, + &&LABEL_BC_POP_LOCAL_0, + &&LABEL_BC_POP_LOCAL_1, + &&LABEL_BC_POP_LOCAL_2, + &&LABEL_BC_POP_ARGUMENT, + &&LABEL_BC_POP_FIELD, + &&LABEL_BC_POP_FIELD_0, + &&LABEL_BC_POP_FIELD_1, + &&LABEL_BC_SEND, + &&LABEL_BC_SUPER_SEND, + &&LABEL_BC_RETURN_LOCAL, + &&LABEL_BC_RETURN_NON_LOCAL, + &&LABEL_BC_JUMP, + &&LABEL_BC_JUMP_ON_FALSE_POP, + &&LABEL_BC_JUMP_ON_TRUE_POP, + &&LABEL_BC_JUMP_ON_FALSE_TOP_NIL, + &&LABEL_BC_JUMP_ON_TRUE_TOP_NIL, + &&LABEL_BC_JUMP_BACKWARD, + &&LABEL_BC_JUMP2, + &&LABEL_BC_JUMP2_ON_FALSE_POP, + &&LABEL_BC_JUMP2_ON_TRUE_POP, + &&LABEL_BC_JUMP2_ON_FALSE_TOP_NIL, + &&LABEL_BC_JUMP2_ON_TRUE_TOP_NIL, + &&LABEL_BC_JUMP2_BACKWARD}; + + goto* loopTargets[currentBytecodes[bytecodeIndexGlobal]]; // // THIS IS THE former interpretation loop LABEL_BC_HALT: PROLOGUE(1); - return GetFrame()->GetStackElement(0); // handle the halt bytecode + return GetFrame()->GetStackElement(0); // handle the halt bytecode LABEL_BC_DUP: PROLOGUE(1); @@ -251,149 +249,140 @@ vm_oop_t Start() { doReturnNonLocal(); DISPATCH_NOGC(); -LABEL_BC_JUMP: - { +LABEL_BC_JUMP: { + uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; + bytecodeIndexGlobal += offset; +} + DISPATCH_NOGC(); + +LABEL_BC_JUMP_ON_FALSE_POP: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(falseObject)) { uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; bytecodeIndexGlobal += offset; + } else { + bytecodeIndexGlobal += 3; } + GetFrame()->PopVoid(); +} DISPATCH_NOGC(); -LABEL_BC_JUMP_ON_FALSE_POP: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(falseObject)) { - uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; - bytecodeIndexGlobal += offset; - } else { - bytecodeIndexGlobal += 3; - } - GetFrame()->PopVoid(); +LABEL_BC_JUMP_ON_TRUE_POP: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(trueObject)) { + uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; + bytecodeIndexGlobal += offset; + } else { + bytecodeIndexGlobal += 3; } + GetFrame()->PopVoid(); +} DISPATCH_NOGC(); -LABEL_BC_JUMP_ON_TRUE_POP: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(trueObject)) { - uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; - bytecodeIndexGlobal += offset; - } else { - bytecodeIndexGlobal += 3; - } +LABEL_BC_JUMP_ON_FALSE_TOP_NIL: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(falseObject)) { + uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; + bytecodeIndexGlobal += offset; + GetFrame()->SetTop(nilObject); + } else { GetFrame()->PopVoid(); + bytecodeIndexGlobal += 3; } +} DISPATCH_NOGC(); -LABEL_BC_JUMP_ON_FALSE_TOP_NIL: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(falseObject)) { - uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; - bytecodeIndexGlobal += offset; - GetFrame()->SetTop(nilObject); - } else { - GetFrame()->PopVoid(); - bytecodeIndexGlobal += 3; - } +LABEL_BC_JUMP_ON_TRUE_TOP_NIL: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(trueObject)) { + uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; + bytecodeIndexGlobal += offset; + GetFrame()->SetTop(nilObject); + } else { + GetFrame()->PopVoid(); + bytecodeIndexGlobal += 3; } +} DISPATCH_NOGC(); -LABEL_BC_JUMP_ON_TRUE_TOP_NIL: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(trueObject)) { - uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; - bytecodeIndexGlobal += offset; - GetFrame()->SetTop(nilObject); - } else { - GetFrame()->PopVoid(); - bytecodeIndexGlobal += 3; - } - } +LABEL_BC_JUMP_BACKWARD: { + uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; + bytecodeIndexGlobal -= offset; +} DISPATCH_NOGC(); -LABEL_BC_JUMP_BACKWARD: - { - uint8_t offset = currentBytecodes[bytecodeIndexGlobal + 1]; - bytecodeIndexGlobal -= offset; - } +LABEL_BC_JUMP2: { + uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], + currentBytecodes[bytecodeIndexGlobal + 2]); + bytecodeIndexGlobal += offset; +} DISPATCH_NOGC(); -LABEL_BC_JUMP2: - { - uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], - currentBytecodes[bytecodeIndexGlobal + 2]); +LABEL_BC_JUMP2_ON_FALSE_POP: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(falseObject)) { + uint16_t offset = + ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], + currentBytecodes[bytecodeIndexGlobal + 2]); bytecodeIndexGlobal += offset; + } else { + bytecodeIndexGlobal += 3; } + GetFrame()->PopVoid(); +} DISPATCH_NOGC(); -LABEL_BC_JUMP2_ON_FALSE_POP: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(falseObject)) { - uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], - currentBytecodes[bytecodeIndexGlobal + 2]); - bytecodeIndexGlobal += offset; - } else { - bytecodeIndexGlobal += 3; - } - GetFrame()->PopVoid(); +LABEL_BC_JUMP2_ON_TRUE_POP: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(trueObject)) { + uint16_t offset = + ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], + currentBytecodes[bytecodeIndexGlobal + 2]); + bytecodeIndexGlobal += offset; + } else { + bytecodeIndexGlobal += 3; } + GetFrame()->PopVoid(); +} DISPATCH_NOGC(); -LABEL_BC_JUMP2_ON_TRUE_POP: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(trueObject)) { - uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], - currentBytecodes[bytecodeIndexGlobal + 2]); - bytecodeIndexGlobal += offset; - } else { - bytecodeIndexGlobal += 3; - } +LABEL_BC_JUMP2_ON_FALSE_TOP_NIL: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(falseObject)) { + uint16_t offset = + ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], + currentBytecodes[bytecodeIndexGlobal + 2]); + bytecodeIndexGlobal += offset; + GetFrame()->SetTop(nilObject); + } else { GetFrame()->PopVoid(); + bytecodeIndexGlobal += 3; } +} DISPATCH_NOGC(); -LABEL_BC_JUMP2_ON_FALSE_TOP_NIL: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(falseObject)) { - uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], - currentBytecodes[bytecodeIndexGlobal + 2]); - bytecodeIndexGlobal += offset; - GetFrame()->SetTop(nilObject); - } else { - GetFrame()->PopVoid(); - bytecodeIndexGlobal += 3; - } - } - DISPATCH_NOGC(); - -LABEL_BC_JUMP2_ON_TRUE_TOP_NIL: - { - vm_oop_t val = GetFrame()->Top(); - if (val == load_ptr(trueObject)) { - uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], - currentBytecodes[bytecodeIndexGlobal + 2]); - bytecodeIndexGlobal += offset; - GetFrame()->SetTop(nilObject); - } else { - GetFrame()->PopVoid(); - bytecodeIndexGlobal += 3; - } +LABEL_BC_JUMP2_ON_TRUE_TOP_NIL: { + vm_oop_t val = GetFrame()->Top(); + if (val == load_ptr(trueObject)) { + uint16_t offset = + ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], + currentBytecodes[bytecodeIndexGlobal + 2]); + bytecodeIndexGlobal += offset; + GetFrame()->SetTop(nilObject); + } else { + GetFrame()->PopVoid(); + bytecodeIndexGlobal += 3; } +} DISPATCH_NOGC(); -LABEL_BC_JUMP2_BACKWARD: - { - uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], - currentBytecodes[bytecodeIndexGlobal + 2]); - bytecodeIndexGlobal -= offset; - } +LABEL_BC_JUMP2_BACKWARD: { + uint16_t offset = ComputeOffset(currentBytecodes[bytecodeIndexGlobal + 1], + currentBytecodes[bytecodeIndexGlobal + 2]); + bytecodeIndexGlobal -= offset; +} DISPATCH_NOGC(); - #ifndef HACK_INLINE_START } #endif diff --git a/src/interpreter/bytecodes.cpp b/src/interpreter/bytecodes.cpp index 81bf9df0..a3b927bc 100644 --- a/src/interpreter/bytecodes.cpp +++ b/src/interpreter/bytecodes.cpp @@ -30,106 +30,83 @@ #include const uint8_t Bytecode::bytecodeLengths[] = { - 1, // BC_HALT - 1, // BC_DUP - 3, // BC_PUSH_LOCAL - 1, // BC_PUSH_LOCAL_0 - 1, // BC_PUSH_LOCAL_1 - 1, // BC_PUSH_LOCAL_2 - 3, // BC_PUSH_ARGUMENT - 1, // BC_PUSH_SELF - 1, // BC_PUSH_ARG_1 - 1, // BC_PUSH_ARG_2 - 2, // BC_PUSH_FIELD - 1, // BC_PUSH_FIELD_0 - 1, // BC_PUSH_FIELD_1 - 2, // BC_PUSH_BLOCK - 2, // BC_PUSH_CONSTANT - 1, // BC_PUSH_CONSTANT_0 - 1, // BC_PUSH_CONSTANT_1 - 1, // BC_PUSH_CONSTANT_2 - 1, // BC_PUSH_0 - 1, // BC_PUSH_1 - 1, // BC_PUSH_NIL - 2, // BC_PUSH_GLOBAL - 1, // BC_POP - 3, // BC_POP_LOCAL - 1, // BC_POP_LOCAL_0 - 1, // BC_POP_LOCAL_1 - 1, // BC_POP_LOCAL_2 - 3, // BC_POP_ARGUMENT - 2, // BC_POP_FIELD - 1, // BC_POP_FIELD_0 - 2, // BC_POP_FIELD_1 - 2, // BC_SEND - 2, // BC_SUPER_SEND - 1, // BC_RETURN_LOCAL - 1, // BC_RETURN_NON_LOCAL + 1, // BC_HALT + 1, // BC_DUP + 3, // BC_PUSH_LOCAL + 1, // BC_PUSH_LOCAL_0 + 1, // BC_PUSH_LOCAL_1 + 1, // BC_PUSH_LOCAL_2 + 3, // BC_PUSH_ARGUMENT + 1, // BC_PUSH_SELF + 1, // BC_PUSH_ARG_1 + 1, // BC_PUSH_ARG_2 + 2, // BC_PUSH_FIELD + 1, // BC_PUSH_FIELD_0 + 1, // BC_PUSH_FIELD_1 + 2, // BC_PUSH_BLOCK + 2, // BC_PUSH_CONSTANT + 1, // BC_PUSH_CONSTANT_0 + 1, // BC_PUSH_CONSTANT_1 + 1, // BC_PUSH_CONSTANT_2 + 1, // BC_PUSH_0 + 1, // BC_PUSH_1 + 1, // BC_PUSH_NIL + 2, // BC_PUSH_GLOBAL + 1, // BC_POP + 3, // BC_POP_LOCAL + 1, // BC_POP_LOCAL_0 + 1, // BC_POP_LOCAL_1 + 1, // BC_POP_LOCAL_2 + 3, // BC_POP_ARGUMENT + 2, // BC_POP_FIELD + 1, // BC_POP_FIELD_0 + 2, // BC_POP_FIELD_1 + 2, // BC_SEND + 2, // BC_SUPER_SEND + 1, // BC_RETURN_LOCAL + 1, // BC_RETURN_NON_LOCAL - 3, // BC_JUMP - 3, // BC_JUMP_ON_TRUE_TOP_NIL - 3, // BC_JUMP_ON_FALSE_TOP_NIL - 3, // BC_JUMP_ON_TRUE_POP - 3, // BC_JUMP_ON_FALSE_POP - 3, // BC_JUMP_BACKWARDS + 3, // BC_JUMP + 3, // BC_JUMP_ON_TRUE_TOP_NIL + 3, // BC_JUMP_ON_FALSE_TOP_NIL + 3, // BC_JUMP_ON_TRUE_POP + 3, // BC_JUMP_ON_FALSE_POP + 3, // BC_JUMP_BACKWARDS - 3, // BC_JUMP2 - 3, // BC_JUMP2_ON_TRUE_TOP_NIL - 3, // BC_JUMP2_ON_FALSE_TOP_NIL - 3, // BC_JUMP2_ON_TRUE_POP - 3, // BC_JUMP2_ON_FALSE_POP - 3, // BC_JUMP2_BACKWARDS - }; + 3, // BC_JUMP2 + 3, // BC_JUMP2_ON_TRUE_TOP_NIL + 3, // BC_JUMP2_ON_FALSE_TOP_NIL + 3, // BC_JUMP2_ON_TRUE_POP + 3, // BC_JUMP2_ON_FALSE_POP + 3, // BC_JUMP2_BACKWARDS +}; const char* Bytecode::bytecodeNames[] = { - "HALT ", - "DUP ", - "PUSH_LOCAL ", - "PUSH_LOCAL_0 ", - "PUSH_LOCAL_1 ", - "PUSH_LOCAL_2 ", - "PUSH_ARGUMENT ", - "PUSH_SELF ", - "PUSH_ARG_1 ", - "PUSH_ARG_2 ", - "PUSH_FIELD ", - "PUSH_FIELD_0 ", - "PUSH_FIELD_1 ", - "PUSH_BLOCK ", - "PUSH_CONSTANT ", - "PUSH_CONSTANT_0 ", - "PUSH_CONSTANT_1 ", - "PUSH_CONSTANT_2 ", - "PUSH_0 ", - "PUSH_1 ", - "PUSH_NIL ", - "PUSH_GLOBAL ", - "POP ", - "POP_LOCAL ", - "POP_LOCAL_0 ", - "POP_LOCAL_1 ", - "POP_LOCAL_2 ", - "POP_ARGUMENT ", - "POP_FIELD ", - "POP_FIELD_0 ", - "POP_FIELD_1 ", - "SEND ", - "SUPER_SEND ", - "RETURN_LOCAL ", - "RETURN_NON_LOCAL", - "BC_JUMP ", - "BC_JUMP_ON_TRUE_TOP_NIL", - "BC_JUMP_ON_FALSE_TOP_NIL", - "BC_JUMP_ON_TRUE_POP", - "BC_JUMP_ON_FALSE_POP", + "HALT ", "DUP ", + "PUSH_LOCAL ", "PUSH_LOCAL_0 ", + "PUSH_LOCAL_1 ", "PUSH_LOCAL_2 ", + "PUSH_ARGUMENT ", "PUSH_SELF ", + "PUSH_ARG_1 ", "PUSH_ARG_2 ", + "PUSH_FIELD ", "PUSH_FIELD_0 ", + "PUSH_FIELD_1 ", "PUSH_BLOCK ", + "PUSH_CONSTANT ", "PUSH_CONSTANT_0 ", + "PUSH_CONSTANT_1 ", "PUSH_CONSTANT_2 ", + "PUSH_0 ", "PUSH_1 ", + "PUSH_NIL ", "PUSH_GLOBAL ", + "POP ", "POP_LOCAL ", + "POP_LOCAL_0 ", "POP_LOCAL_1 ", + "POP_LOCAL_2 ", "POP_ARGUMENT ", + "POP_FIELD ", "POP_FIELD_0 ", + "POP_FIELD_1 ", "SEND ", + "SUPER_SEND ", "RETURN_LOCAL ", + "RETURN_NON_LOCAL", "BC_JUMP ", + "BC_JUMP_ON_TRUE_TOP_NIL", "BC_JUMP_ON_FALSE_TOP_NIL", + "BC_JUMP_ON_TRUE_POP", "BC_JUMP_ON_FALSE_POP", "BC_JUMP_BACKWARDS", - "BC_JUMP2 ", - "BC_JUMP2_ON_TRUE_TOP_NIL", - "BC_JUMP2_ON_FALSE_TOP_NIL", - "BC_JUMP2_ON_TRUE_POP", - "BC_JUMP2_ON_FALSE_POP", - "BC_JUMP2_BACKWARDS", + "BC_JUMP2 ", "BC_JUMP2_ON_TRUE_TOP_NIL", + "BC_JUMP2_ON_FALSE_TOP_NIL", "BC_JUMP2_ON_TRUE_POP", + "BC_JUMP2_ON_FALSE_POP", "BC_JUMP2_BACKWARDS", }; bool IsJumpBytecode(uint8_t bc) { @@ -140,8 +117,12 @@ bool IsJumpBytecode(uint8_t bc) { } bool Bytecode::BytecodeDefinitionsAreConsistent() { - bool namesAndLengthMatch = (sizeof(Bytecode::bytecodeNames) / sizeof(char*)) == (sizeof(Bytecode::bytecodeLengths) / sizeof(uint8_t)); - bool lastBytecodeLinesUp = _LAST_BYTECODE == (sizeof(Bytecode::bytecodeLengths) - 1); // -1 because null terminated + bool namesAndLengthMatch = + (sizeof(Bytecode::bytecodeNames) / sizeof(char*)) == + (sizeof(Bytecode::bytecodeLengths) / sizeof(uint8_t)); + bool lastBytecodeLinesUp = + _LAST_BYTECODE == + (sizeof(Bytecode::bytecodeLengths) - 1); // -1 because null terminated return namesAndLengthMatch && lastBytecodeLinesUp; } diff --git a/src/interpreter/bytecodes.h b/src/interpreter/bytecodes.h index e272d13a..ad7d8c7d 100644 --- a/src/interpreter/bytecodes.h +++ b/src/interpreter/bytecodes.h @@ -32,6 +32,7 @@ // bytecode constants used by SOM++ +// clang-format off #define BC_HALT 0 #define BC_DUP 1 #define BC_PUSH_LOCAL 2 @@ -83,9 +84,12 @@ #define _LAST_BYTECODE BC_JUMP2_BACKWARD #define BC_INVALID 255 +// clang-format on // TODO: port support for these bytecodes -// they were already named in ported code, and it seemed nicer to just already include that code +// they were already named in ported code, and it seemed nicer to just +// already include that code +// clang-format off #define BC_INC_FIELD 254 #define BC_INC_FIELD_PUSH 253 #define BC_INC 252 @@ -98,36 +102,33 @@ #define BC_RETURN_FIELD_1 245 #define BC_RETURN_FIELD_2 244 #define BC_RETURN_SELF 243 - +// clang-format on // properties of the bytecodes -#define FIRST_DOUBLE_BYTE_JUMP_BYTECODE BC_JUMP2 -#define NUM_SINGLE_BYTE_JUMP_BYTECODES ((BC_JUMP_BACKWARD - BC_JUMP) + 1) +#define FIRST_DOUBLE_BYTE_JUMP_BYTECODE BC_JUMP2 +#define NUM_SINGLE_BYTE_JUMP_BYTECODES ((BC_JUMP_BACKWARD - BC_JUMP) + 1) class Bytecode { - public: static char* GetBytecodeName(uint8_t bc) { - return (char*) bytecodeNames[bc]; + return (char*)bytecodeNames[bc]; } inline static uint8_t GetBytecodeLength(uint8_t bc) { - return bytecodeLengths[bc]; // Return the length of the given bytecode + return bytecodeLengths[bc]; // Return the length of the given bytecode } static bool BytecodeDefinitionsAreConsistent(); private: - static const uint8_t bytecodeLengths[]; static const char* bytecodeNames[]; }; inline uint16_t ComputeOffset(uint8_t byte1, uint8_t byte2) { - return ((uint16_t) byte1) | (((uint16_t) byte2) << 8); + return ((uint16_t)byte1) | (((uint16_t)byte2) << 8); } bool IsJumpBytecode(uint8_t bc); - diff --git a/src/memory/CopyingCollector.cpp b/src/memory/CopyingCollector.cpp index 59e97cd5..06933a3c 100644 --- a/src/memory/CopyingCollector.cpp +++ b/src/memory/CopyingCollector.cpp @@ -1,3 +1,5 @@ +#include "CopyingCollector.h" + #include #include #include @@ -12,7 +14,6 @@ #include "../vmobjects/IntegerBox.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMFrame.h" -#include "CopyingCollector.h" #include "CopyingHeap.h" static gc_oop_t copy_if_necessary(gc_oop_t oop) { @@ -28,7 +29,7 @@ static gc_oop_t copy_if_necessary(gc_oop_t oop) { // GCField is used as forwarding pointer here // if someone has moved before, return the moved object if (gcField != 0) { - return (gc_oop_t) gcField; + return (gc_oop_t)gcField; } assert(GetHeap()->IsInOldBufferAndOldBufferIsValid(obj)); @@ -51,7 +52,7 @@ void CopyingCollector::Collect() { DebugLog("CopyGC Collect\n"); Timer::GCTimer->Resume(); - //reset collection trigger + // reset collection trigger heap->resetGCTrigger(); static bool increaseMemory; @@ -60,11 +61,13 @@ void CopyingCollector::Collect() { GetUniverse()->WalkGlobals(copy_if_necessary); - // now copy all objects that are referenced by the objects we have moved so far + // now copy all objects that are referenced by the objects we have moved so + // far AbstractVMObject* curObject = (AbstractVMObject*)(heap->currentBuffer); while (curObject < heap->nextFreePosition) { curObject->WalkObjects(copy_if_necessary); - curObject = (AbstractVMObject*)((size_t)curObject + curObject->GetObjectSize()); + curObject = + (AbstractVMObject*)((size_t)curObject + curObject->GetObjectSize()); } heap->invalidateOldBuffer(); @@ -72,8 +75,7 @@ void CopyingCollector::Collect() { // if semispace is still 50% full after collection, we have to realloc // bigger ones -> done in next collection if ((size_t)(heap->nextFreePosition) - (size_t)(heap->currentBuffer) >= - (size_t)(heap->currentBufferEnd) - - (size_t)(heap->nextFreePosition)) { + (size_t)(heap->currentBufferEnd) - (size_t)(heap->nextFreePosition)) { increaseMemory = true; } diff --git a/src/memory/CopyingCollector.h b/src/memory/CopyingCollector.h index 1f2703c8..090a7974 100644 --- a/src/memory/CopyingCollector.h +++ b/src/memory/CopyingCollector.h @@ -4,9 +4,10 @@ class CopyingHeap; -class CopyingCollector: public GarbageCollector { +class CopyingCollector : public GarbageCollector { public: explicit CopyingCollector(CopyingHeap* h) : GarbageCollector(h) {}; + private: void Collect() override; }; diff --git a/src/memory/CopyingHeap.cpp b/src/memory/CopyingHeap.cpp index f056bbee..e3eb1568 100644 --- a/src/memory/CopyingHeap.cpp +++ b/src/memory/CopyingHeap.cpp @@ -1,3 +1,5 @@ +#include "CopyingHeap.h" + #include #include #include @@ -8,10 +10,10 @@ #include "../vm/Universe.h" #include "../vmobjects/AbstractObject.h" #include "CopyingCollector.h" -#include "CopyingHeap.h" #include "Heap.h" -CopyingHeap::CopyingHeap(size_t objectSpaceSize) : Heap(new CopyingCollector(this)) { +CopyingHeap::CopyingHeap(size_t objectSpaceSize) + : Heap(new CopyingCollector(this)) { size_t bufSize = objectSpaceSize; currentBuffer = malloc(bufSize); @@ -21,7 +23,8 @@ CopyingHeap::CopyingHeap(size_t objectSpaceSize) : Heap(new Copying memset(oldBuffer, 0x0, bufSize); currentBufferEnd = (void*)((size_t)currentBuffer + bufSize); - collectionLimit = (void*)((size_t)currentBuffer + ((size_t)((double)bufSize * 0.9))); + collectionLimit = + (void*)((size_t)currentBuffer + ((size_t)((double)bufSize * 0.9))); nextFreePosition = currentBuffer; oldBufferEnd = (void*)((size_t)oldBuffer + bufSize); @@ -53,7 +56,8 @@ void CopyingHeap::switchBuffers(bool increaseMemory) { } currentBufferEnd = (void*)((size_t)currentBuffer + newSize); - collectionLimit = (void*)((size_t)currentBuffer + ((size_t)((double)newSize * 0.9))); + collectionLimit = + (void*)((size_t)currentBuffer + ((size_t)((double)newSize * 0.9))); nextFreePosition = currentBuffer; currentBufSize = newSize; } else { @@ -61,7 +65,9 @@ void CopyingHeap::switchBuffers(bool increaseMemory) { currentBufferEnd = oldBufferEndBeforeSwitch; currentBufSize = oldBufSizeBeforeSwitch; - collectionLimit = (void*)((size_t)oldBufferBeforeSwitch + (size_t)((double)oldBufSizeBeforeSwitch * 0.9)); + collectionLimit = + (void*)((size_t)oldBufferBeforeSwitch + + (size_t)((double)oldBufSizeBeforeSwitch * 0.9)); nextFreePosition = currentBuffer; } @@ -93,7 +99,7 @@ void CopyingHeap::invalidateOldBuffer() { } AbstractVMObject* CopyingHeap::AllocateObject(size_t size) { - AbstractVMObject* newObject = (AbstractVMObject*) nextFreePosition; + AbstractVMObject* newObject = (AbstractVMObject*)nextFreePosition; nextFreePosition = (void*)((size_t)nextFreePosition + size); if (nextFreePosition > currentBufferEnd) { ErrorPrint("\nFailed to allocate " + to_string(size) + " Bytes.\n"); @@ -113,8 +119,9 @@ bool CopyingHeap::IsInCurrentBuffer(AbstractVMObject* obj) { return true; } - size_t objAddress = (size_t) obj; - return (size_t) currentBuffer <= objAddress && objAddress < (size_t) currentBufferEnd; + size_t objAddress = (size_t)obj; + return (size_t)currentBuffer <= objAddress && + objAddress < (size_t)currentBufferEnd; } bool CopyingHeap::IsInOldBufferAndOldBufferIsValid(AbstractVMObject* obj) { @@ -127,9 +134,9 @@ bool CopyingHeap::IsInOldBufferAndOldBufferIsValid(AbstractVMObject* obj) { return false; } - size_t objAddress = (size_t) obj; - assert((size_t) oldBuffer <= objAddress); - assert(objAddress < (size_t) oldBufferEnd); + size_t objAddress = (size_t)obj; + assert((size_t)oldBuffer <= objAddress); + assert(objAddress < (size_t)oldBufferEnd); - return (size_t) oldBuffer <= objAddress && objAddress < (size_t) oldBufferEnd; + return (size_t)oldBuffer <= objAddress && objAddress < (size_t)oldBufferEnd; } diff --git a/src/memory/CopyingHeap.h b/src/memory/CopyingHeap.h index 01e22933..344cd212 100644 --- a/src/memory/CopyingHeap.h +++ b/src/memory/CopyingHeap.h @@ -6,6 +6,7 @@ class CopyingHeap : public Heap { friend class CopyingCollector; + public: explicit CopyingHeap(size_t objectSpaceSize); AbstractVMObject* AllocateObject(size_t size); diff --git a/src/memory/DebugCopyingCollector.cpp b/src/memory/DebugCopyingCollector.cpp index b8c5f605..2f457edf 100644 --- a/src/memory/DebugCopyingCollector.cpp +++ b/src/memory/DebugCopyingCollector.cpp @@ -1,4 +1,6 @@ +#include "DebugCopyingCollector.h" + #include #include @@ -9,7 +11,6 @@ #include "../vm/IsValidObject.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" -#include "DebugCopyingCollector.h" #include "DebugCopyingHeap.h" static gc_oop_t copy_if_necessary(gc_oop_t oop) { @@ -25,7 +26,7 @@ static gc_oop_t copy_if_necessary(gc_oop_t oop) { // GCField is used as forwarding pointer here // if someone has moved before, return the moved object if (gcField != 0) { - return (gc_oop_t) gcField; + return (gc_oop_t)gcField; } assert(GetHeap()->IsInOldBufferAndOldBufferIsValid(obj)); @@ -51,7 +52,7 @@ void DebugCopyingCollector::Collect() { assert(heap->oldHeap.empty()); Timer::GCTimer->Resume(); - //reset collection trigger + // reset collection trigger heap->resetGCTrigger(); static bool increaseMemory; @@ -60,7 +61,8 @@ void DebugCopyingCollector::Collect() { GetUniverse()->WalkGlobals(copy_if_necessary); - // now copy all objects that are referenced by the objects we have moved so far + // now copy all objects that are referenced by the objects we have moved so + // far for (size_t i = 0; i < heap->currentHeap.size(); i += 1) { heap->currentHeap.at(i)->WalkObjects(copy_if_necessary); } diff --git a/src/memory/DebugCopyingCollector.h b/src/memory/DebugCopyingCollector.h index 021b1603..a5685f4f 100644 --- a/src/memory/DebugCopyingCollector.h +++ b/src/memory/DebugCopyingCollector.h @@ -1,12 +1,14 @@ -# pragma once +#pragma once #include "GarbageCollector.h" class DebugCopyingHeap; -class DebugCopyingCollector: public GarbageCollector { +class DebugCopyingCollector : public GarbageCollector { public: - explicit DebugCopyingCollector(DebugCopyingHeap* h) : GarbageCollector(h) {}; + explicit DebugCopyingCollector(DebugCopyingHeap* h) + : GarbageCollector(h) {}; + private: void Collect() override; }; diff --git a/src/memory/DebugCopyingHeap.cpp b/src/memory/DebugCopyingHeap.cpp index c7779795..cc837fbe 100644 --- a/src/memory/DebugCopyingHeap.cpp +++ b/src/memory/DebugCopyingHeap.cpp @@ -1,3 +1,5 @@ +#include "DebugCopyingHeap.h" + #include #include #include @@ -7,10 +9,12 @@ #include "../vm/Print.h" #include "../vm/Universe.h" #include "../vmobjects/AbstractObject.h" -#include "DebugCopyingHeap.h" void DebugCopyingHeap::switchBuffers(bool increaseMemory) { - assert(oldHeap.empty() && "At this point, I'd assume the old heap is empty, because we want to use it to store into now"); + assert( + oldHeap.empty() && + "At this point, I'd assume the old heap is empty, because we want to " + "use it to store into now"); oldHeap.swap(currentHeap); oldHeapIsValid = true; @@ -18,11 +22,12 @@ void DebugCopyingHeap::switchBuffers(bool increaseMemory) { if (increaseMemory) { currentHeapSize += currentHeapSize; - collectionLimit = (double) currentHeapSize * 0.9; + collectionLimit = (double)currentHeapSize * 0.9; } currentHeapUsage = 0; - assert(currentHeap.empty() && "at the end, the current heap is expected to be empty"); + assert(currentHeap.empty() && + "at the end, the current heap is expected to be empty"); } void DebugCopyingHeap::invalidateOldBuffer() { @@ -45,7 +50,7 @@ void DebugCopyingHeap::invalidateOldBuffer() { } AbstractVMObject* DebugCopyingHeap::AllocateObject(size_t size) { - AbstractVMObject* newObject = (AbstractVMObject*) malloc(size); + AbstractVMObject* newObject = (AbstractVMObject*)malloc(size); currentHeap.push_back(newObject); currentHeapUsage += size; @@ -68,7 +73,8 @@ bool DebugCopyingHeap::IsInCurrentBuffer(AbstractVMObject* obj) { return true; } - return find(currentHeap.begin(), currentHeap.end(), obj) != currentHeap.end(); + return find(currentHeap.begin(), currentHeap.end(), obj) != + currentHeap.end(); } bool DebugCopyingHeap::IsInOldBufferAndOldBufferIsValid(AbstractVMObject* obj) { diff --git a/src/memory/DebugCopyingHeap.h b/src/memory/DebugCopyingHeap.h index 9d10a52f..63aaa966 100644 --- a/src/memory/DebugCopyingHeap.h +++ b/src/memory/DebugCopyingHeap.h @@ -1,4 +1,4 @@ -# pragma once +#pragma once #include @@ -7,11 +7,12 @@ class DebugCopyingHeap : public Heap { friend class DebugCopyingCollector; + public: - explicit DebugCopyingHeap(size_t objectSpaceSize) : - Heap(new DebugCopyingCollector(this)), - currentHeapSize(objectSpaceSize), - collectionLimit((double)objectSpaceSize * 0.9) {} + explicit DebugCopyingHeap(size_t objectSpaceSize) + : Heap(new DebugCopyingCollector(this)), + currentHeapSize(objectSpaceSize), + collectionLimit((double)objectSpaceSize * 0.9) {} AbstractVMObject* AllocateObject(size_t size); diff --git a/src/memory/GarbageCollector.h b/src/memory/GarbageCollector.h index d85594ec..8cb0ee34 100644 --- a/src/memory/GarbageCollector.h +++ b/src/memory/GarbageCollector.h @@ -37,6 +37,7 @@ class GarbageCollector { virtual void Collect() = 0; void PrintGCStat() const; void PrintCollectStat() const; + protected: HEAP_T* const heap; }; diff --git a/src/memory/GenerationalCollector.cpp b/src/memory/GenerationalCollector.cpp index 2eda5c9c..8744f12e 100644 --- a/src/memory/GenerationalCollector.cpp +++ b/src/memory/GenerationalCollector.cpp @@ -1,3 +1,5 @@ +#include "GenerationalCollector.h" + #include #include #include @@ -11,11 +13,11 @@ #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMObjectBase.h" #include "GarbageCollector.h" -#include "GenerationalCollector.h" -#define INITIAL_MAJOR_COLLECTION_THRESHOLD (5 * 1024 * 1024) //5 MB +#define INITIAL_MAJOR_COLLECTION_THRESHOLD (5 * 1024 * 1024) // 5 MB -GenerationalCollector::GenerationalCollector(GenerationalHeap* heap) : GarbageCollector(heap) { +GenerationalCollector::GenerationalCollector(GenerationalHeap* heap) + : GarbageCollector(heap) { majorCollectionThreshold = INITIAL_MAJOR_COLLECTION_THRESHOLD; matureObjectsSize = 0; } @@ -29,7 +31,6 @@ static gc_oop_t mark_object(gc_oop_t oop) { AbstractVMObject* obj = AS_OBJ(oop); assert(IsValidObject(obj)); - if ((obj->GetGCField() & MASK_OBJECT_IS_MARKED) != 0) { return oop; } @@ -49,7 +50,6 @@ static gc_oop_t copy_if_necessary(gc_oop_t oop) { AbstractVMObject* obj = AS_OBJ(oop); assert(IsValidObject(obj)); - size_t gcField = obj->GetGCField(); // if this is an old object already, we don't have to copy @@ -60,7 +60,7 @@ static gc_oop_t copy_if_necessary(gc_oop_t oop) { // GCField is abused as forwarding pointer here // if someone has moved before, return the moved object if (gcField != 0) { - return (gc_oop_t) gcField; + return (gc_oop_t)gcField; } // we have to clone ourselves @@ -70,10 +70,10 @@ static gc_oop_t copy_if_necessary(gc_oop_t oop) { obj->MarkObjectAsInvalid(); } - assert( (((size_t) newObj) & MASK_OBJECT_IS_MARKED) == 0 ); - assert( obj->GetObjectSize() == newObj->GetObjectSize()); + assert((((size_t)newObj) & MASK_OBJECT_IS_MARKED) == 0); + assert(obj->GetObjectSize() == newObj->GetObjectSize()); - obj->SetGCField((size_t) newObj); + obj->SetGCField((size_t)newObj); newObj->SetGCField(MASK_OBJECT_IS_OLD); // walk recursively @@ -90,7 +90,7 @@ void GenerationalCollector::MinorCollection() { // and also all objects that have been detected by the write barriers for (vector::iterator objIter = - heap->oldObjsWithRefToYoungObjs->begin(); + heap->oldObjsWithRefToYoungObjs->begin(); objIter != heap->oldObjsWithRefToYoungObjs->end(); objIter++) { // content of oldObjsWithRefToYoungObjs is not altered while iteration, @@ -110,20 +110,20 @@ void GenerationalCollector::MajorCollection() { // first we have to mark all objects (globals and current frame recursively) GetUniverse()->WalkGlobals(&mark_object); - //now that all objects are marked we can safely delete all allocated objects that are not marked + // now that all objects are marked we can safely delete all allocated + // objects that are not marked vector* survivors = new vector(); for (vector::iterator objIter = - heap->allocatedObjects->begin(); objIter != - heap->allocatedObjects->end(); objIter++) { - + heap->allocatedObjects->begin(); + objIter != heap->allocatedObjects->end(); + objIter++) { AbstractVMObject* obj = *objIter; assert(IsValidObject(obj)); if ((obj->GetGCField() & MASK_OBJECT_IS_MARKED) != 0) { survivors->push_back(obj); obj->SetGCField(MASK_OBJECT_IS_OLD); - } - else { + } else { heap->FreeObject(obj); } } @@ -133,15 +133,13 @@ void GenerationalCollector::MajorCollection() { void GenerationalCollector::Collect() { Timer::GCTimer->Resume(); - //reset collection trigger + // reset collection trigger heap->resetGCTrigger(); MinorCollection(); - if (heap->matureObjectsSize > majorCollectionThreshold) - { + if (heap->matureObjectsSize > majorCollectionThreshold) { MajorCollection(); majorCollectionThreshold = 2 * heap->matureObjectsSize; - } Timer::GCTimer->Halt(); } diff --git a/src/memory/GenerationalCollector.h b/src/memory/GenerationalCollector.h index b90c5ad2..eb678b7e 100644 --- a/src/memory/GenerationalCollector.h +++ b/src/memory/GenerationalCollector.h @@ -1,7 +1,6 @@ #pragma once #include "../misc/defs.h" - #include "GarbageCollector.h" class GenerationalHeap; @@ -9,6 +8,7 @@ class GenerationalCollector : public GarbageCollector { public: GenerationalCollector(GenerationalHeap* heap); void Collect() override; + private: uintptr_t majorCollectionThreshold; size_t matureObjectsSize; diff --git a/src/memory/GenerationalHeap.cpp b/src/memory/GenerationalHeap.cpp index 21a6bd92..450a66b2 100644 --- a/src/memory/GenerationalHeap.cpp +++ b/src/memory/GenerationalHeap.cpp @@ -1,3 +1,5 @@ +#include "GenerationalHeap.h" + #include #include #include @@ -9,14 +11,14 @@ #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMObjectBase.h" #include "GenerationalCollector.h" -#include "GenerationalHeap.h" #include "Heap.h" using namespace std; -GenerationalHeap::GenerationalHeap(size_t objectSpaceSize) : Heap(new GenerationalCollector(this)) { - //our initial collection limit is 90% of objectSpaceSize - //collectionLimit = objectSpaceSize * 0.9; +GenerationalHeap::GenerationalHeap(size_t objectSpaceSize) + : Heap(new GenerationalCollector(this)) { + // our initial collection limit is 90% of objectSpaceSize + // collectionLimit = objectSpaceSize * 0.9; nursery = malloc(objectSpaceSize); nurserySize = objectSpaceSize; @@ -24,21 +26,22 @@ GenerationalHeap::GenerationalHeap(size_t objectSpaceSize) : Heap(); oldObjsWithRefToYoungObjs = new vector(); } AbstractVMObject* GenerationalHeap::AllocateNurseryObject(size_t size) { - AbstractVMObject* newObject = (AbstractVMObject*) nextFreePosition; + AbstractVMObject* newObject = (AbstractVMObject*)nextFreePosition; nextFreePosition = (void*)((size_t)nextFreePosition + size); if ((size_t)nextFreePosition > nursery_end) { - ErrorPrint("\nFailed to allocate " + to_string(size) + " Bytes in nursery.\n"); + ErrorPrint("\nFailed to allocate " + to_string(size) + + " Bytes in nursery.\n"); GetUniverse()->Quit(-1); } - //let's see if we have to trigger the GC + // let's see if we have to trigger the GC if (nextFreePosition > collectionLimit) { requestGC(); } @@ -46,7 +49,7 @@ AbstractVMObject* GenerationalHeap::AllocateNurseryObject(size_t size) { } AbstractVMObject* GenerationalHeap::AllocateMatureObject(size_t size) { - AbstractVMObject* newObject = (AbstractVMObject*) malloc(size); + AbstractVMObject* newObject = (AbstractVMObject*)malloc(size); if (newObject == nullptr) { ErrorPrint("\nFailed to allocate " + to_string(size) + " Bytes.\n"); GetUniverse()->Quit(-1); diff --git a/src/memory/GenerationalHeap.h b/src/memory/GenerationalHeap.h index aa1dfae3..82e2e198 100644 --- a/src/memory/GenerationalHeap.h +++ b/src/memory/GenerationalHeap.h @@ -7,19 +7,19 @@ #include "../vmobjects/VMObjectBase.h" #include "Heap.h" - #ifdef UNITTESTS struct VMObjectCompare { - bool operator() (pair lhs, - pair rhs) const - { return (size_t) lhs.first < (size_t) rhs.first - && (size_t) lhs.second < (size_t) rhs.second; + bool operator()(pair lhs, pair rhs) + const { + return (size_t)lhs.first < (size_t)rhs.first && + (size_t)lhs.second < (size_t)rhs.second; } }; #endif class GenerationalHeap : public Heap { friend class GenerationalCollector; + public: explicit GenerationalHeap(size_t objectSpaceSize = 1048576); AbstractVMObject* AllocateNurseryObject(size_t size); @@ -28,7 +28,7 @@ class GenerationalHeap : public Heap { void writeBarrier(VMObjectBase* holder, vm_oop_t referencedObject); inline bool isObjectInNursery(vm_oop_t obj); #ifdef UNITTESTS - std::set< pair, VMObjectCompare > writeBarrierCalledOn; + std::set, VMObjectCompare> writeBarrierCalledOn; #endif private: void* nursery; @@ -37,7 +37,8 @@ class GenerationalHeap : public Heap { size_t maxNurseryObjSize; size_t matureObjectsSize; void* nextFreePosition; - void writeBarrier_OldHolder(VMObjectBase* holder, vm_oop_t referencedObject); + void writeBarrier_OldHolder(VMObjectBase* holder, + vm_oop_t referencedObject); void* collectionLimit; vector* oldObjsWithRefToYoungObjs; vector* allocatedObjects; @@ -46,14 +47,15 @@ class GenerationalHeap : public Heap { inline bool GenerationalHeap::isObjectInNursery(vm_oop_t obj) { assert(IsValidObject(obj)); - return (size_t) obj >= (size_t)nursery && (size_t) obj < nursery_end; + return (size_t)obj >= (size_t)nursery && (size_t)obj < nursery_end; } inline size_t GenerationalHeap::GetMaxNurseryObjectSize() { return maxNurseryObjSize; } -inline void GenerationalHeap::writeBarrier(VMObjectBase* holder, vm_oop_t referencedObject) { +inline void GenerationalHeap::writeBarrier(VMObjectBase* holder, + vm_oop_t referencedObject) { #ifdef UNITTESTS writeBarrierCalledOn.insert(make_pair(holder, referencedObject)); #endif @@ -61,8 +63,9 @@ inline void GenerationalHeap::writeBarrier(VMObjectBase* holder, vm_oop_t refere assert(IsValidObject(referencedObject)); assert(IsValidObject(holder)); - const size_t gcfield = *(((size_t*)holder)+1); - if ((gcfield & 6U /* MASK_OBJECT_IS_OLD + MASK_SEEN_BY_WRITE_BARRIER */) == 2U /* MASK_OBJECT_IS_OLD */) { + const size_t gcfield = *(((size_t*)holder) + 1); + if ((gcfield & 6U /* MASK_OBJECT_IS_OLD + MASK_SEEN_BY_WRITE_BARRIER */) == + 2U /* MASK_OBJECT_IS_OLD */) { writeBarrier_OldHolder(holder, referencedObject); } } diff --git a/src/memory/Heap.cpp b/src/memory/Heap.cpp index 780b1159..e2e8df92 100644 --- a/src/memory/Heap.cpp +++ b/src/memory/Heap.cpp @@ -24,39 +24,41 @@ THE SOFTWARE. */ +#include "Heap.h" + #include #include "../misc/defs.h" #include "../vm/Print.h" -#include "CopyingHeap.h" // NOLINT(misc-include-cleaner) -#include "DebugCopyingHeap.h" // NOLINT(misc-include-cleaner) -#include "GenerationalHeap.h" // NOLINT(misc-include-cleaner) -#include "Heap.h" -#include "MarkSweepHeap.h" // NOLINT(misc-include-cleaner) +#include "CopyingHeap.h" // NOLINT(misc-include-cleaner) +#include "DebugCopyingHeap.h" // NOLINT(misc-include-cleaner) +#include "GenerationalHeap.h" // NOLINT(misc-include-cleaner) +#include "MarkSweepHeap.h" // NOLINT(misc-include-cleaner) -template +template void Heap::InitializeHeap(long objectSpaceSize) { if (theHeap) { - ErrorPrint("Warning, reinitializing already initialized Heap, " - "all data will be lost!\n"); + ErrorPrint( + "Warning, reinitializing already initialized Heap, " + "all data will be lost!\n"); delete theHeap; } theHeap = new HEAP_CLS(objectSpaceSize); } -template +template void Heap::DestroyHeap() { if (theHeap) { delete theHeap; } } -template +template Heap::~Heap() { delete gc; } -template +template void Heap::FullGC() { gc->Collect(); } diff --git a/src/memory/Heap.h b/src/memory/Heap.h index bcdd7ef6..394e5dbd 100644 --- a/src/memory/Heap.h +++ b/src/memory/Heap.h @@ -37,13 +37,14 @@ /* * macro for padding - only word-aligned memory must be allocated */ -#define PADDED_SIZE(N) ((((size_t)(N))+(sizeof(void*)-1) & ~(sizeof(void*)-1))) +#define PADDED_SIZE(N) \ + ((((size_t)(N)) + (sizeof(void*) - 1) & ~(sizeof(void*) - 1))) #define IS_PADDED_SIZE(N) ((N) == PADDED_SIZE((N))) using namespace std; -template +template class Heap { friend class GarbageCollector; @@ -52,26 +53,30 @@ class Heap { static void DestroyHeap(); explicit Heap(GarbageCollector* const gc) : gc(gc) {} ~Heap(); - inline void requestGC() { gcWasRequested = true; } + inline void requestGC() { gcWasRequested = true; } inline void resetGCTrigger() { gcWasRequested = false; } - bool isCollectionTriggered() { return gcWasRequested; } + bool isCollectionTriggered() { return gcWasRequested; } void FullGC(); inline void FreeObject(AbstractVMObject* o) { free(o); } + protected: GarbageCollector* const gc; + private: - template friend HEAP_U* GetHeap(); + template + friend HEAP_U* GetHeap(); static HEAP_T* theHeap; // flag that shows if a Collection is triggered bool gcWasRequested{false}; }; -template HEAP_T* Heap::theHeap; +template +HEAP_T* Heap::theHeap; -template -inline HEAP_T* GetHeap() __attribute__ ((always_inline)); -template +template +inline HEAP_T* GetHeap() __attribute__((always_inline)); +template HEAP_T* GetHeap() { return Heap::theHeap; } diff --git a/src/memory/MarkSweepCollector.cpp b/src/memory/MarkSweepCollector.cpp index 96ca8dac..b80bdd20 100644 --- a/src/memory/MarkSweepCollector.cpp +++ b/src/memory/MarkSweepCollector.cpp @@ -1,3 +1,5 @@ +#include "MarkSweepCollector.h" + #include #include @@ -7,7 +9,6 @@ #include "../vmobjects/IntegerBox.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMFrame.h" -#include "MarkSweepCollector.h" #include "MarkSweepHeap.h" #define GC_MARKED 3456 @@ -15,26 +16,27 @@ void MarkSweepCollector::Collect() { MarkSweepHeap* heap = GetHeap(); Timer::GCTimer->Resume(); - //reset collection trigger + // reset collection trigger heap->resetGCTrigger(); - //now mark all reachables + // now mark all reachables markReachableObjects(); - //in this survivors stack we will remember all objects that survived + // in this survivors stack we will remember all objects that survived auto survivors = new vector(); size_t survivorsSize = 0; vector::iterator iter; - for (iter = heap->allocatedObjects->begin(); iter != - heap->allocatedObjects->end(); iter++) { + for (iter = heap->allocatedObjects->begin(); + iter != heap->allocatedObjects->end(); + iter++) { if ((*iter)->GetGCField() == GC_MARKED) { - //object ist marked -> let it survive + // object ist marked -> let it survive survivors->push_back(*iter); survivorsSize += (*iter)->GetObjectSize(); (*iter)->SetGCField(0); } else { - //not marked -> kill it + // not marked -> kill it heap->FreeObject(*iter); } } @@ -43,7 +45,7 @@ void MarkSweepCollector::Collect() { heap->allocatedObjects = survivors; heap->spcAlloc = survivorsSize; - //TODO: Maybe choose another constant to calculate new collectionLimit here + // TODO: Maybe choose another constant to calculate new collectionLimit here heap->collectionLimit = 2 * survivorsSize; Timer::GCTimer->Halt(); } diff --git a/src/memory/MarkSweepCollector.h b/src/memory/MarkSweepCollector.h index 17538c79..56a46f04 100644 --- a/src/memory/MarkSweepCollector.h +++ b/src/memory/MarkSweepCollector.h @@ -1,15 +1,14 @@ #pragma once #include "../misc/defs.h" - #include "GarbageCollector.h" class MarkSweepHeap; class MarkSweepCollector : public GarbageCollector { public: - MarkSweepCollector(MarkSweepHeap* heap) : GarbageCollector(heap) { - } + MarkSweepCollector(MarkSweepHeap* heap) : GarbageCollector(heap) {} void Collect() override; + private: void markReachableObjects(); }; diff --git a/src/memory/MarkSweepHeap.cpp b/src/memory/MarkSweepHeap.cpp index 0719d347..34c7bb89 100644 --- a/src/memory/MarkSweepHeap.cpp +++ b/src/memory/MarkSweepHeap.cpp @@ -1,3 +1,5 @@ +#include "MarkSweepHeap.h" + #include #include #include @@ -8,27 +10,27 @@ #include "../vm/Universe.h" #include "../vmobjects/AbstractObject.h" #include "MarkSweepCollector.h" -#include "MarkSweepHeap.h" - -MarkSweepHeap::MarkSweepHeap(size_t objectSpaceSize) : Heap(new MarkSweepCollector(this)) { - //our initial collection limit is 90% of objectSpaceSize +MarkSweepHeap::MarkSweepHeap(size_t objectSpaceSize) + : Heap(new MarkSweepCollector(this)) { + // our initial collection limit is 90% of objectSpaceSize collectionLimit = objectSpaceSize * 0.9; spcAlloc = 0; allocatedObjects = new vector(); } AbstractVMObject* MarkSweepHeap::AllocateObject(size_t size) { - AbstractVMObject* newObject = (AbstractVMObject*) malloc(size); + AbstractVMObject* newObject = (AbstractVMObject*)malloc(size); if (newObject == nullptr) { ErrorPrint("\nFailed to allocate " + to_string(size) + " Bytes.\n"); Universe::Quit(-1); } spcAlloc += size; - memset((void*) newObject, 0, size); - //AbstractObjects (Integer,...) have no Size field anymore -> set within VMObject's new operator + memset((void*)newObject, 0, size); + // AbstractObjects (Integer,...) have no Size field anymore -> set within + // VMObject's new operator allocatedObjects->push_back(newObject); - //let's see if we have to trigger the GC + // let's see if we have to trigger the GC if (spcAlloc >= collectionLimit) { requestGC(); } diff --git a/src/memory/MarkSweepHeap.h b/src/memory/MarkSweepHeap.h index 65b95211..749b96ee 100644 --- a/src/memory/MarkSweepHeap.h +++ b/src/memory/MarkSweepHeap.h @@ -1,17 +1,17 @@ #pragma once #include "../misc/defs.h" - #include "Heap.h" class MarkSweepHeap : public Heap { friend class MarkSweepCollector; + public: explicit MarkSweepHeap(size_t objectSpaceSize = 1048576); AbstractVMObject* AllocateObject(size_t size); + private: vector* allocatedObjects; size_t spcAlloc; size_t collectionLimit; - }; diff --git a/src/misc/ParseInteger.cpp b/src/misc/ParseInteger.cpp index f7e7d6eb..a1bfcffd 100644 --- a/src/misc/ParseInteger.cpp +++ b/src/misc/ParseInteger.cpp @@ -1,38 +1,38 @@ +#include "ParseInteger.h" + #include #include #include #include -#include "../misc/ParseInteger.h" -#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) +#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) #include "../vmobjects/ObjectFormats.h" - vm_oop_t ParseInteger(const char* str, int base, bool negateValue) { - errno = 0; + errno = 0; - char* pEnd {}; + char* pEnd{}; - const int64_t i = std::strtoll(str, &pEnd, base); + const int64_t i = std::strtoll(str, &pEnd, base); - if (str == pEnd) { - // did not parse anything - return NEW_INT(0); - } + if (str == pEnd) { + // did not parse anything + return NEW_INT(0); + } - const bool rangeError = errno == ERANGE; - if (rangeError) { - // TODO: try a big int library - return NEW_INT(0); - } + const bool rangeError = errno == ERANGE; + if (rangeError) { + // TODO: try a big int library + return NEW_INT(0); + } - // the normal case - if (negateValue) { - return NEW_INT(-i); - } - return NEW_INT(i); + // the normal case + if (negateValue) { + return NEW_INT(-i); + } + return NEW_INT(i); } vm_oop_t ParseInteger(std::string& str, int base, bool negateValue) { - return ParseInteger(str.c_str(), base, negateValue); + return ParseInteger(str.c_str(), base, negateValue); } diff --git a/src/misc/StringUtil.h b/src/misc/StringUtil.h index 3793ca9c..76fcfb3b 100644 --- a/src/misc/StringUtil.h +++ b/src/misc/StringUtil.h @@ -2,7 +2,8 @@ #include -inline bool ReplacePattern(std::string& str, const char* pattern, const char* replacement) { +inline bool ReplacePattern(std::string& str, const char* pattern, + const char* replacement) { size_t pos = str.find(pattern); if (pos == std::string::npos) { return false; @@ -12,7 +13,8 @@ inline bool ReplacePattern(std::string& str, const char* pattern, const char* re return true; } -inline bool ReplacePattern(std::string& str, const char* pattern, StdString& replacement) { +inline bool ReplacePattern(std::string& str, const char* pattern, + StdString& replacement) { size_t pos = str.find(pattern); if (pos == std::string::npos) { return false; diff --git a/src/misc/Timer.h b/src/misc/Timer.h index 8261a783..a003f6f3 100644 --- a/src/misc/Timer.h +++ b/src/misc/Timer.h @@ -10,15 +10,15 @@ static int64_t get_microseconds() { timespec now{}; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now); - return (now.tv_sec * 1000 * 1000) +// seconds - (now.tv_nsec / 1000);// nanoseconds + return (now.tv_sec * 1000 * 1000) + // seconds + (now.tv_nsec / 1000); // nanoseconds #else // this is for OSX, might work on other platforms struct timeval now; gettimeofday(&now, nullptr); return (now.tv_sec * 1000 * 1000) + // seconds - now.tv_usec; // microseconds + now.tv_usec; // microseconds #endif } @@ -26,19 +26,15 @@ class Timer { private: int64_t total; int64_t last_start; + public: static Timer* GCTimer; - inline void Resume() { - last_start = get_microseconds(); - } + inline void Resume() { last_start = get_microseconds(); } inline void Halt() { const int64_t end = get_microseconds(); total = end - last_start; } - double GetTotalTime() { - return (double)total / 1000.0; - } - + double GetTotalTime() { return (double)total / 1000.0; } }; diff --git a/src/misc/VectorUtil.h b/src/misc/VectorUtil.h index 50087086..d86a2f64 100644 --- a/src/misc/VectorUtil.h +++ b/src/misc/VectorUtil.h @@ -4,13 +4,13 @@ #include #include -template +template inline bool Contains(std::vector& vec, T elem) { auto it = std::find(vec.begin(), vec.end(), elem); return it != vec.end(); } -template +template inline size_t IndexOf(std::vector& vec, T elem) { auto it = std::find(vec.begin(), vec.end(), elem); if (it != vec.end()) { diff --git a/src/misc/debug.cpp b/src/misc/debug.cpp index ec9ddaf1..d87cef0d 100644 --- a/src/misc/debug.cpp +++ b/src/misc/debug.cpp @@ -1,11 +1,11 @@ +#include "debug.h" + #include #include "../compiler/Disassembler.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMClass.h" #include "../vmobjects/VMSymbol.h" -#include "debug.h" - std::string DebugGetClassName(vm_oop_t obj) { return CLASS_OF(obj)->GetName()->GetStdString(); diff --git a/src/misc/debug.h b/src/misc/debug.h index 1599646d..affe3d8c 100644 --- a/src/misc/debug.h +++ b/src/misc/debug.h @@ -31,9 +31,9 @@ #include "../vmobjects/ObjectFormats.h" -#define FprintfPass(f,x) \ - va_list ap; \ - va_start(ap, (x)); \ +#define FprintfPass(f, x) \ + va_list ap; \ + va_start(ap, (x)); \ (void)vfprintf((f), (x), ap); \ va_end(ap) @@ -45,9 +45,9 @@ static inline void DebugPrefix(const char* prefix) { DebugPrint("%-6s ", prefix); } -#define DebugPass(x) \ - va_list ap; \ - va_start(ap, (x)); \ +#define DebugPass(x) \ + va_list ap; \ + va_start(ap, (x)); \ (void)vfprintf(stderr, (x), ap); \ va_end(ap) @@ -56,7 +56,7 @@ static inline void DebugInfo(const char* fmt, ...) { DebugPrefix("INFO:"); DebugPass(fmt); #else - (void) fmt; + (void)fmt; #endif } @@ -65,7 +65,7 @@ static inline void DebugLog(const char* fmt, ...) { DebugPrefix("LOG:"); DebugPass(fmt); #else - (void) fmt; + (void)fmt; #endif } @@ -74,7 +74,7 @@ static inline void DebugWarn(const char* fmt, ...) { DebugPrefix("WARN:"); DebugPass(fmt); #else - (void) fmt; + (void)fmt; #endif } @@ -94,7 +94,7 @@ static inline void DebugTrace(const char* fmt, ...) { } #undef FprintfPass -#undef DebugPass +#undef DebugPass std::string DebugGetClassName(vm_oop_t); std::string DebugGetClassName(gc_oop_t); diff --git a/src/misc/defs.h b/src/misc/defs.h index ebbe82db..a305fbf4 100644 --- a/src/misc/defs.h +++ b/src/misc/defs.h @@ -33,26 +33,25 @@ // Macro Debugging #define VALUE_TO_STRING(x) #x #define VALUE(x) VALUE_TO_STRING(x) -#define VAR_NAME_VALUE(var) #var "=" VALUE(var) - +#define VAR_NAME_VALUE(var) #var "=" VALUE(var) // // error codes // -#define ERR_SUCCESS 0x0 -#define ERR_FAIL 0x1 -#define ERR_NOMEM 0x2 -#define ERR_PANIC 0xFFFF +#define ERR_SUCCESS 0x0 +#define ERR_FAIL 0x1 +#define ERR_NOMEM 0x2 +#define ERR_PANIC 0xFFFF // // Integer Ranges // #ifndef INT32_MAX -/*Maximum value of 32-bit integer is 0x7FFF FFFF (2 147 483 647) */ -#define INT32_MAX 0x7FFFFFFF /*2 147 483 647*/ + /*Maximum value of 32-bit integer is 0x7FFF FFFF (2 147 483 647) */ + #define INT32_MAX 0x7FFFFFFF /*2 147 483 647*/ #endif #ifndef INT32_MIN -#define INT32_MIN (-2147483647) + #define INT32_MIN (-2147483647) #endif @@ -66,34 +65,35 @@ // GC Types // #define GENERATIONAL 1 -#define COPYING 2 -#define MARK_SWEEP 3 +#define COPYING 2 +#define MARK_SWEEP 3 #define DEBUG_COPYING 4 -#if GC_TYPE == GENERATIONAL - class GenerationalHeap; - typedef GenerationalHeap HEAP_CLS; - #define write_barrier(obj, value_ptr) ((GetHeap())->writeBarrier(obj, value_ptr)) - #define ALLOC_MATURE , true +#if GC_TYPE == GENERATIONAL +class GenerationalHeap; +typedef GenerationalHeap HEAP_CLS; + #define write_barrier(obj, value_ptr) \ + ((GetHeap())->writeBarrier(obj, value_ptr)) + #define ALLOC_MATURE , true #define ALLOC_OUTSIDE_NURSERY(X) , (X) #define ALLOC_OUTSIDE_NURSERY_DECL , bool outsideNursery = false #elif GC_TYPE == COPYING - class CopyingHeap; - typedef CopyingHeap HEAP_CLS; +class CopyingHeap; +typedef CopyingHeap HEAP_CLS; #define write_barrier(obj, value_ptr) #define ALLOC_MATURE #define ALLOC_OUTSIDE_NURSERY(X) #define ALLOC_OUTSIDE_NURSERY_DECL #elif GC_TYPE == MARK_SWEEP - class MarkSweepHeap; - typedef MarkSweepHeap HEAP_CLS; +class MarkSweepHeap; +typedef MarkSweepHeap HEAP_CLS; #define write_barrier(obj, value_ptr) #define ALLOC_MATURE #define ALLOC_OUTSIDE_NURSERY(X) #define ALLOC_OUTSIDE_NURSERY_DECL #elif GC_TYPE == DEBUG_COPYING - class DebugCopyingHeap; - typedef DebugCopyingHeap HEAP_CLS; +class DebugCopyingHeap; +typedef DebugCopyingHeap HEAP_CLS; #define write_barrier(obj, value_ptr) #define ALLOC_MATURE #define ALLOC_OUTSIDE_NURSERY(X) @@ -110,7 +110,7 @@ #ifdef CACHE_INTEGER // Sanity check #if CACHE_INTEGER && USE_TAGGING - # error Caching of small integer instances is only useful without tagged integers + #error Caching of small integer instances is only useful without tagged integers #endif #endif @@ -126,13 +126,12 @@ #define INT_CACHE_MAX_VALUE (100) #endif - // // Debugging // #ifdef DEBUG // Sanity check - #if (!(DEBUG+0)) + #if (!(DEBUG + 0)) #pragma message(VAR_NAME_VALUE(DEBUG)) #error DEBUG needs to be set to a boolean #endif @@ -152,20 +151,19 @@ // Testing // #ifndef UNITTESTS - #define private_testable private - #define protected_testable protected + #define make_testable(label) #else - #define private_testable public - #define protected_testable public + #define make_testable(label) \ + label: #endif // // Log Levels // #define LOG_LEVEL_ERROR 0 -#define LOG_LEVEL_WARN 1 -#define LOG_LEVEL_LOG 2 -#define LOG_LEVEL_INFO 3 +#define LOG_LEVEL_WARN 1 +#define LOG_LEVEL_LOG 2 +#define LOG_LEVEL_INFO 3 #ifndef LOG_LEVEL #define LOG_LEVEL LOG_LEVEL_ERROR @@ -174,9 +172,8 @@ // // Performance Optimization // -#define likely(x) __builtin_expect((x),1) -#define unlikely(x) __builtin_expect((x),0) - +#define likely(x) __builtin_expect((x), 1) +#define unlikely(x) __builtin_expect((x), 0) typedef std::string StdString; diff --git a/src/misc/gettimeofday.h b/src/misc/gettimeofday.h index 13d46a2e..e2875929 100644 --- a/src/misc/gettimeofday.h +++ b/src/misc/gettimeofday.h @@ -26,26 +26,25 @@ THE SOFTWARE. */ -#include #include < time.h > +#include -//This file is only necessary for Visual Studio compatibility -//as sys/time.h is not available using MSVS +// This file is only necessary for Visual Studio compatibility +// as sys/time.h is not available using MSVS #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 #else -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL #endif struct timezone { int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ + int tz_dsttime; /* type of dst correction */ }; -int gettimeofday(struct timeval *tv, struct timezone *tz) { +int gettimeofday(struct timeval* tv, struct timezone* tz) { FILETIME ft; - unsigned __int64 - tmpres = 0; + unsigned __int64 tmpres = 0; static int tzflag; if (nullptr != tv) { @@ -58,8 +57,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) { /*converting file time to unix epoch*/ tmpres /= 10; /*convert into microseconds*/ tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long) (tmpres / 1000000UL); - tv->tv_usec = (long) (tmpres % 1000000UL); + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); } if (nullptr != tz) { diff --git a/src/primitives/Array.cpp b/src/primitives/Array.cpp index f4445ed1..42dfca0d 100644 --- a/src/primitives/Array.cpp +++ b/src/primitives/Array.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Array.h" + #include #include "../primitivesCore/PrimitiveContainer.h" @@ -32,13 +34,12 @@ #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMArray.h" #include "../vmobjects/VMFrame.h" -#include "Array.h" _Array::_Array() : PrimitiveContainer() { - SetPrimitive("new_", new Routine<_Array>(this, &_Array::New_, true)); - SetPrimitive("at_", new Routine<_Array>(this, &_Array::At_, false)); + SetPrimitive("new_", new Routine<_Array>(this, &_Array::New_, true)); + SetPrimitive("at_", new Routine<_Array>(this, &_Array::At_, false)); SetPrimitive("at_put_", new Routine<_Array>(this, &_Array::At_Put_, false)); - SetPrimitive("length", new Routine<_Array>(this, &_Array::Length, false)); + SetPrimitive("length", new Routine<_Array>(this, &_Array::Length, false)); } void _Array::At_(Interpreter*, VMFrame* frame) { @@ -58,7 +59,7 @@ void _Array::At_Put_(Interpreter*, VMFrame* frame) { void _Array::Length(Interpreter*, VMFrame* frame) { VMArray* self = static_cast(frame->Pop()); - vm_oop_t new_int = NEW_INT((int64_t) self->GetNumberOfIndexableFields()); + vm_oop_t new_int = NEW_INT((int64_t)self->GetNumberOfIndexableFields()); frame->Push(new_int); } diff --git a/src/primitives/Array.h b/src/primitives/Array.h index 7f8057a0..78500dee 100644 --- a/src/primitives/Array.h +++ b/src/primitives/Array.h @@ -29,7 +29,7 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Array: public PrimitiveContainer { +class _Array : public PrimitiveContainer { public: _Array(); void New_(Interpreter*, VMFrame*); diff --git a/src/primitives/Block.cpp b/src/primitives/Block.cpp index 1e6fac68..de2ab669 100644 --- a/src/primitives/Block.cpp +++ b/src/primitives/Block.cpp @@ -30,7 +30,6 @@ #include "../primitivesCore/Routine.h" #include "../vmobjects/VMFrame.h" - void _Block::Value(Interpreter*, VMFrame*) { // intentionally left blank } @@ -49,9 +48,9 @@ void _Block::Restart(Interpreter*, VMFrame* frame) { } _Block::_Block() : PrimitiveContainer() { - SetPrimitive("value", new Routine<_Block>(this, &_Block::Value, false)); - SetPrimitive("restart", new Routine<_Block>(this, &_Block::Restart, false)); - SetPrimitive("value_", new Routine<_Block>(this, &_Block::Value_, false)); - SetPrimitive("value_with_", new Routine<_Block>(this, &_Block::Value_with_, false)); + SetPrimitive("value", new Routine<_Block>(this, &_Block::Value, false)); + SetPrimitive("restart", new Routine<_Block>(this, &_Block::Restart, false)); + SetPrimitive("value_", new Routine<_Block>(this, &_Block::Value_, false)); + SetPrimitive("value_with_", + new Routine<_Block>(this, &_Block::Value_with_, false)); } - diff --git a/src/primitives/Block.h b/src/primitives/Block.h index 6597629c..bcf67b3d 100644 --- a/src/primitives/Block.h +++ b/src/primitives/Block.h @@ -29,15 +29,14 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Block: public PrimitiveContainer { +class _Block : public PrimitiveContainer { public: _Block(); void Value(Interpreter*, VMFrame*); void Restart(Interpreter*, VMFrame*); void Value_(Interpreter*, VMFrame*); void Value_with_(Interpreter*, VMFrame*); - + void Spawn(Interpreter*, VMFrame*); void Spawn_(Interpreter*, VMFrame*); - }; diff --git a/src/primitives/Class.cpp b/src/primitives/Class.cpp index f0141ffd..19c0977a 100644 --- a/src/primitives/Class.cpp +++ b/src/primitives/Class.cpp @@ -24,21 +24,22 @@ THE SOFTWARE. */ +#include "Class.h" + #include "../primitivesCore/PrimitiveContainer.h" #include "../primitivesCore/Routine.h" #include "../vm/Universe.h" #include "../vmobjects/VMClass.h" #include "../vmobjects/VMFrame.h" -#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete -#include "Class.h" - +#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete _Class::_Class() : PrimitiveContainer() { - SetPrimitive("new", new Routine<_Class>(this, &_Class::New, false)); - SetPrimitive("name", new Routine<_Class>(this, &_Class::Name, false)); - SetPrimitive("superclass", new Routine<_Class>(this, &_Class::Superclass, false)); - SetPrimitive("fields", new Routine<_Class>(this, &_Class::Fields, false)); - SetPrimitive("methods", new Routine<_Class>(this, &_Class::Methods, false)); + SetPrimitive("new", new Routine<_Class>(this, &_Class::New, false)); + SetPrimitive("name", new Routine<_Class>(this, &_Class::Name, false)); + SetPrimitive("superclass", + new Routine<_Class>(this, &_Class::Superclass, false)); + SetPrimitive("fields", new Routine<_Class>(this, &_Class::Fields, false)); + SetPrimitive("methods", new Routine<_Class>(this, &_Class::Methods, false)); } void _Class::New(Interpreter*, VMFrame* frame) { diff --git a/src/primitives/Class.h b/src/primitives/Class.h index 9028ce84..9714cc34 100644 --- a/src/primitives/Class.h +++ b/src/primitives/Class.h @@ -29,13 +29,13 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Class: public PrimitiveContainer { +class _Class : public PrimitiveContainer { public: _Class(); void New(Interpreter*, VMFrame*); - - void Name (Interpreter*, VMFrame*); + + void Name(Interpreter*, VMFrame*); void Superclass(Interpreter*, VMFrame*); - void Fields (Interpreter*, VMFrame*); - void Methods (Interpreter*, VMFrame*); + void Fields(Interpreter*, VMFrame*); + void Methods(Interpreter*, VMFrame*); }; diff --git a/src/primitives/Double.cpp b/src/primitives/Double.cpp index dfa5d6e0..f10fc2df 100644 --- a/src/primitives/Double.cpp +++ b/src/primitives/Double.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Double.h" + #include #include #include @@ -39,23 +41,25 @@ #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMInteger.h" #include "../vmobjects/VMString.h" -#include "Double.h" /* * This function coerces any right-hand parameter to a double, regardless of its * true nature. This is to make sure that all Double operations return Doubles. */ double _Double::coerceDouble(vm_oop_t x) { - if (IS_TAGGED(x)) - return (double) INT_VAL(x); + if (IS_TAGGED(x)) { + return (double)INT_VAL(x); + } VMClass* cl = ((AbstractVMObject*)x)->GetClass(); - if (cl == load_ptr(doubleClass)) + if (cl == load_ptr(doubleClass)) { return static_cast(x)->GetEmbeddedDouble(); - else if(cl == load_ptr(integerClass)) + } else if (cl == load_ptr(integerClass)) { return (double)static_cast(x)->GetEmbeddedInteger(); - else - GetUniverse()->ErrorExit("Attempt to apply Double operation to non-number."); + } else { + GetUniverse()->ErrorExit( + "Attempt to apply Double operation to non-number."); + } return 0.0f; } @@ -66,8 +70,8 @@ double _Double::coerceDouble(vm_oop_t x) { * extract the left-hand operand as an immediate Double. Afterwards, left and * right are prepared for the operation. */ -#define PREPARE_OPERANDS \ - double right = coerceDouble(frame->Pop()); \ +#define PREPARE_OPERANDS \ + double right = coerceDouble(frame->Pop()); \ VMDouble* leftObj = static_cast(frame->Pop()); \ double left = leftObj->GetEmbeddedDouble(); @@ -105,20 +109,20 @@ void _Double::Slashslash(Interpreter*, VMFrame* frame) { void _Double::Percent(Interpreter*, VMFrame* frame) { PREPARE_OPERANDS; - frame->Push(GetUniverse()->NewDouble((double)((int64_t)left % - (int64_t)right))); + frame->Push( + GetUniverse()->NewDouble((double)((int64_t)left % (int64_t)right))); } void _Double::And(Interpreter*, VMFrame* frame) { PREPARE_OPERANDS; - frame->Push(GetUniverse()->NewDouble((double)((int64_t)left & - (int64_t)right))); + frame->Push( + GetUniverse()->NewDouble((double)((int64_t)left & (int64_t)right))); } void _Double::BitwiseXor(Interpreter*, VMFrame* frame) { PREPARE_OPERANDS; - frame->Push(GetUniverse()->NewDouble((double)((int64_t)left ^ - (int64_t)right))); + frame->Push( + GetUniverse()->NewDouble((double)((int64_t)left ^ (int64_t)right))); } /* @@ -127,18 +131,20 @@ void _Double::BitwiseXor(Interpreter*, VMFrame* frame) { */ void _Double::Equal(Interpreter*, VMFrame* frame) { PREPARE_OPERANDS; - if(left == right) - frame->Push(load_ptr(trueObject)); - else - frame->Push(load_ptr(falseObject)); + if (left == right) { + frame->Push(load_ptr(trueObject)); + } else { + frame->Push(load_ptr(falseObject)); + } } void _Double::Lowerthan(Interpreter*, VMFrame* frame) { PREPARE_OPERANDS; - if(left < right) + if (left < right) { frame->Push(load_ptr(trueObject)); - else + } else { frame->Push(load_ptr(falseObject)); + } } void _Double::AsString(Interpreter*, VMFrame* frame) { @@ -148,12 +154,13 @@ void _Double::AsString(Interpreter*, VMFrame* frame) { ostringstream Str; Str.precision(17); Str << dbl; - frame->Push( GetUniverse()->NewString( Str.str().c_str() ) ); + frame->Push(GetUniverse()->NewString(Str.str().c_str())); } void _Double::Sqrt(Interpreter*, VMFrame* frame) { VMDouble* self = static_cast(frame->Pop()); - VMDouble* result = GetUniverse()->NewDouble( sqrt(self->GetEmbeddedDouble()) ); + VMDouble* result = + GetUniverse()->NewDouble(sqrt(self->GetEmbeddedDouble())); frame->Push(result); } @@ -166,7 +173,7 @@ void _Double::Round(Interpreter*, VMFrame* frame) { void _Double::AsInteger(Interpreter*, VMFrame* frame) { VMDouble* self = (VMDouble*)frame->Pop(); - int64_t rounded = (int64_t) self->GetEmbeddedDouble(); + int64_t rounded = (int64_t)self->GetEmbeddedDouble(); frame->Push(NEW_INT(rounded)); } @@ -177,29 +184,38 @@ void _Double::PositiveInfinity(Interpreter*, VMFrame* frame) { } void _Double::FromString(Interpreter*, VMFrame* frame) { - VMString* self = (VMString*) frame->Pop(); + VMString* self = (VMString*)frame->Pop(); frame->Pop(); - double value = stod(std::string(self->GetRawChars(), self->GetStringLength())); + double value = + stod(std::string(self->GetRawChars(), self->GetStringLength())); frame->Push(GetUniverse()->NewDouble(value)); } _Double::_Double() : PrimitiveContainer() { - SetPrimitive("plus", new Routine<_Double>(this, &_Double::Plus, false)); - SetPrimitive("minus", new Routine<_Double>(this, &_Double::Minus, false)); - SetPrimitive("star", new Routine<_Double>(this, &_Double::Star, false)); - SetPrimitive("cos", new Routine<_Double>(this, &_Double::Cos, false)); - SetPrimitive("sin", new Routine<_Double>(this, &_Double::Sin, false)); - SetPrimitive("slashslash", new Routine<_Double>(this, &_Double::Slashslash, false)); - SetPrimitive("percent", new Routine<_Double>(this, &_Double::Percent, false)); - SetPrimitive("and", new Routine<_Double>(this, &_Double::And, false)); - SetPrimitive("equal", new Routine<_Double>(this, &_Double::Equal, false)); - SetPrimitive("lowerthan", new Routine<_Double>(this, &_Double::Lowerthan, false)); - SetPrimitive("asString", new Routine<_Double>(this, &_Double::AsString, false)); - SetPrimitive("sqrt", new Routine<_Double>(this, &_Double::Sqrt, false)); - SetPrimitive("bitXor_", new Routine<_Double>(this, &_Double::BitwiseXor, false)); - SetPrimitive("round", new Routine<_Double>(this, &_Double::Round, false)); - SetPrimitive("asInteger", new Routine<_Double>(this, &_Double::AsInteger, false)); - SetPrimitive("PositiveInfinity", new Routine<_Double>(this, &_Double::PositiveInfinity, true)); - SetPrimitive("fromString_", new Routine<_Double>(this, &_Double::FromString, true)); + SetPrimitive("plus", new Routine<_Double>(this, &_Double::Plus, false)); + SetPrimitive("minus", new Routine<_Double>(this, &_Double::Minus, false)); + SetPrimitive("star", new Routine<_Double>(this, &_Double::Star, false)); + SetPrimitive("cos", new Routine<_Double>(this, &_Double::Cos, false)); + SetPrimitive("sin", new Routine<_Double>(this, &_Double::Sin, false)); + SetPrimitive("slashslash", + new Routine<_Double>(this, &_Double::Slashslash, false)); + SetPrimitive("percent", + new Routine<_Double>(this, &_Double::Percent, false)); + SetPrimitive("and", new Routine<_Double>(this, &_Double::And, false)); + SetPrimitive("equal", new Routine<_Double>(this, &_Double::Equal, false)); + SetPrimitive("lowerthan", + new Routine<_Double>(this, &_Double::Lowerthan, false)); + SetPrimitive("asString", + new Routine<_Double>(this, &_Double::AsString, false)); + SetPrimitive("sqrt", new Routine<_Double>(this, &_Double::Sqrt, false)); + SetPrimitive("bitXor_", + new Routine<_Double>(this, &_Double::BitwiseXor, false)); + SetPrimitive("round", new Routine<_Double>(this, &_Double::Round, false)); + SetPrimitive("asInteger", + new Routine<_Double>(this, &_Double::AsInteger, false)); + SetPrimitive("PositiveInfinity", + new Routine<_Double>(this, &_Double::PositiveInfinity, true)); + SetPrimitive("fromString_", + new Routine<_Double>(this, &_Double::FromString, true)); } diff --git a/src/primitives/Double.h b/src/primitives/Double.h index f2dbb28d..70a87959 100644 --- a/src/primitives/Double.h +++ b/src/primitives/Double.h @@ -29,7 +29,7 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Double: public PrimitiveContainer { +class _Double : public PrimitiveContainer { public: _Double(); void Plus(Interpreter*, VMFrame*); diff --git a/src/primitives/Integer.cpp b/src/primitives/Integer.cpp index 3c441d4b..9e04e4ea 100644 --- a/src/primitives/Integer.cpp +++ b/src/primitives/Integer.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Integer.h" + #include #include #include @@ -40,7 +42,6 @@ #include "../vmobjects/VMDouble.h" #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMString.h" -#include "Integer.h" /* * This macro performs a coercion check to Double. Depending on @@ -48,45 +49,64 @@ * Double operation (this type imposes itselves on the result * of an Integer operation). */ -#define CHECK_COERCION(obj,receiver,op) { \ - VMClass* cl = CLASS_OF(obj);\ - if(cl == load_ptr(doubleClass)) { \ - resendAsDouble(interp, (op), (receiver), static_cast(obj)); \ - return; \ - } \ -} +#define CHECK_COERCION(obj, receiver, op) \ + { \ + VMClass* cl = CLASS_OF(obj); \ + if (cl == load_ptr(doubleClass)) { \ + resendAsDouble(interp, (op), (receiver), \ + static_cast(obj)); \ + return; \ + } \ + } _Integer::_Integer() : PrimitiveContainer() { - srand((unsigned) time(nullptr)); - SetPrimitive("plus", new Routine<_Integer>(this, &_Integer::Plus, false)); - SetPrimitive("minus", new Routine<_Integer>(this, &_Integer::Minus, false)); - SetPrimitive("star", new Routine<_Integer>(this, &_Integer::Star, false)); - SetPrimitive("rem_", new Routine<_Integer>(this, &_Integer::Rem, false)); - SetPrimitive("bitAnd_", new Routine<_Integer>(this, &_Integer::BitwiseAnd, false)); - SetPrimitive("bitXor_", new Routine<_Integer>(this, &_Integer::BitwiseXor, false)); - SetPrimitive("lowerthanlowerthan", new Routine<_Integer>(this, &_Integer::LeftShift, false)); - SetPrimitive("greaterthangreaterthangreaterthan", new Routine<_Integer>(this, &_Integer::UnsignedRightShift, false)); - SetPrimitive("slash", new Routine<_Integer>(this, &_Integer::Slash, false)); - SetPrimitive("slashslash", new Routine<_Integer>(this, &_Integer::Slashslash, false)); - SetPrimitive("percent", new Routine<_Integer>(this, &_Integer::Percent, false)); - SetPrimitive("and", new Routine<_Integer>(this, &_Integer::And, false)); - SetPrimitive("equal", new Routine<_Integer>(this, &_Integer::Equal, false)); - SetPrimitive("equalequal", new Routine<_Integer>(this, &_Integer::EqualEqual, false)); - SetPrimitive("lowerthan", new Routine<_Integer>(this, &_Integer::Lowerthan, false)); - SetPrimitive("asString", new Routine<_Integer>(this, &_Integer::AsString, false)); - SetPrimitive("asDouble", new Routine<_Integer>(this, &_Integer::AsDouble, false)); - SetPrimitive("as32BitSignedValue", new Routine<_Integer>(this, &_Integer::As32BitSigned, false)); - SetPrimitive("as32BitUnsignedValue", new Routine<_Integer>(this, &_Integer::As32BitUnsigned, false)); - SetPrimitive("sqrt", new Routine<_Integer>(this, &_Integer::Sqrt, false)); - SetPrimitive("atRandom", new Routine<_Integer>(this, &_Integer::AtRandom, false)); - SetPrimitive("fromString_", new Routine<_Integer>(this, &_Integer::FromString, true)); + srand((unsigned)time(nullptr)); + SetPrimitive("plus", new Routine<_Integer>(this, &_Integer::Plus, false)); + SetPrimitive("minus", new Routine<_Integer>(this, &_Integer::Minus, false)); + SetPrimitive("star", new Routine<_Integer>(this, &_Integer::Star, false)); + SetPrimitive("rem_", new Routine<_Integer>(this, &_Integer::Rem, false)); + SetPrimitive("bitAnd_", + new Routine<_Integer>(this, &_Integer::BitwiseAnd, false)); + SetPrimitive("bitXor_", + new Routine<_Integer>(this, &_Integer::BitwiseXor, false)); + SetPrimitive("lowerthanlowerthan", + new Routine<_Integer>(this, &_Integer::LeftShift, false)); + SetPrimitive( + "greaterthangreaterthangreaterthan", + new Routine<_Integer>(this, &_Integer::UnsignedRightShift, false)); + SetPrimitive("slash", new Routine<_Integer>(this, &_Integer::Slash, false)); + SetPrimitive("slashslash", + new Routine<_Integer>(this, &_Integer::Slashslash, false)); + SetPrimitive("percent", + new Routine<_Integer>(this, &_Integer::Percent, false)); + SetPrimitive("and", new Routine<_Integer>(this, &_Integer::And, false)); + SetPrimitive("equal", new Routine<_Integer>(this, &_Integer::Equal, false)); + SetPrimitive("equalequal", + new Routine<_Integer>(this, &_Integer::EqualEqual, false)); + SetPrimitive("lowerthan", + new Routine<_Integer>(this, &_Integer::Lowerthan, false)); + SetPrimitive("asString", + new Routine<_Integer>(this, &_Integer::AsString, false)); + SetPrimitive("asDouble", + new Routine<_Integer>(this, &_Integer::AsDouble, false)); + SetPrimitive("as32BitSignedValue", + new Routine<_Integer>(this, &_Integer::As32BitSigned, false)); + SetPrimitive( + "as32BitUnsignedValue", + new Routine<_Integer>(this, &_Integer::As32BitUnsigned, false)); + SetPrimitive("sqrt", new Routine<_Integer>(this, &_Integer::Sqrt, false)); + SetPrimitive("atRandom", + new Routine<_Integer>(this, &_Integer::AtRandom, false)); + SetPrimitive("fromString_", + new Routine<_Integer>(this, &_Integer::FromString, true)); } // // private functions for Integer // -void _Integer::resendAsDouble(Interpreter* interp, const char* op, vm_oop_t left, VMDouble* right) { +void _Integer::resendAsDouble(Interpreter* interp, const char* op, + vm_oop_t left, VMDouble* right) { VMDouble* leftDouble = GetUniverse()->NewDouble((double)INT_VAL(left)); vm_oop_t operands[] = {right}; @@ -99,7 +119,7 @@ void _Integer::resendAsDouble(Interpreter* interp, const char* op, vm_oop_t left void _Integer::Plus(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "+"); @@ -109,7 +129,7 @@ void _Integer::Plus(Interpreter* interp, VMFrame* frame) { void _Integer::BitwiseAnd(Interpreter*, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); int64_t result = (int64_t)INT_VAL(leftObj) & (int64_t)INT_VAL(rightObj); frame->Push(NEW_INT(result)); @@ -117,16 +137,15 @@ void _Integer::BitwiseAnd(Interpreter*, VMFrame* frame) { void _Integer::BitwiseXor(Interpreter*, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); int64_t result = (int64_t)INT_VAL(leftObj) ^ (int64_t)INT_VAL(rightObj); frame->Push(NEW_INT(result)); } - void _Integer::LeftShift(Interpreter*, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); int64_t result = (int64_t)INT_VAL(leftObj) << (int64_t)INT_VAL(rightObj); frame->Push(NEW_INT(result)); @@ -134,16 +153,15 @@ void _Integer::LeftShift(Interpreter*, VMFrame* frame) { void _Integer::UnsignedRightShift(Interpreter*, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); int64_t result = (int64_t)INT_VAL(leftObj) >> (int64_t)INT_VAL(rightObj); frame->Push(NEW_INT(result)); } - void _Integer::Minus(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "-"); @@ -153,7 +171,7 @@ void _Integer::Minus(Interpreter* interp, VMFrame* frame) { void _Integer::Star(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "*"); @@ -163,7 +181,7 @@ void _Integer::Star(Interpreter* interp, VMFrame* frame) { void _Integer::Slashslash(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "//"); @@ -173,7 +191,7 @@ void _Integer::Slashslash(Interpreter* interp, VMFrame* frame) { void _Integer::Slash(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "/"); @@ -183,7 +201,7 @@ void _Integer::Slash(Interpreter* interp, VMFrame* frame) { void _Integer::Percent(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "%"); @@ -201,7 +219,7 @@ void _Integer::Percent(Interpreter* interp, VMFrame* frame) { void _Integer::Rem(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "%"); @@ -215,7 +233,7 @@ void _Integer::Rem(Interpreter* interp, VMFrame* frame) { void _Integer::And(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "&"); @@ -225,15 +243,16 @@ void _Integer::And(Interpreter* interp, VMFrame* frame) { void _Integer::Equal(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "="); if (IS_TAGGED(rightObj) || CLASS_OF(rightObj) == load_ptr(integerClass)) { - if (INT_VAL(leftObj) == INT_VAL(rightObj)) + if (INT_VAL(leftObj) == INT_VAL(rightObj)) { frame->Push(load_ptr(trueObject)); - else + } else { frame->Push(load_ptr(falseObject)); + } } else if (CLASS_OF(rightObj) == load_ptr(doubleClass)) { assert(false); } else { @@ -243,13 +262,14 @@ void _Integer::Equal(Interpreter* interp, VMFrame* frame) { void _Integer::EqualEqual(Interpreter*, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); if (IS_TAGGED(rightObj) || CLASS_OF(rightObj) == load_ptr(integerClass)) { - if (INT_VAL(leftObj) == INT_VAL(rightObj)) + if (INT_VAL(leftObj) == INT_VAL(rightObj)) { frame->Push(load_ptr(trueObject)); - else + } else { frame->Push(load_ptr(falseObject)); + } } else { frame->Push(load_ptr(falseObject)); } @@ -257,14 +277,15 @@ void _Integer::EqualEqual(Interpreter*, VMFrame* frame) { void _Integer::Lowerthan(Interpreter* interp, VMFrame* frame) { vm_oop_t rightObj = frame->Pop(); - vm_oop_t leftObj = frame->Pop(); + vm_oop_t leftObj = frame->Pop(); CHECK_COERCION(rightObj, leftObj, "<"); - if (INT_VAL(leftObj) < INT_VAL(rightObj)) + if (INT_VAL(leftObj) < INT_VAL(rightObj)) { frame->Push(load_ptr(trueObject)); - else + } else { frame->Push(load_ptr(falseObject)); + } } void _Integer::AsString(Interpreter*, VMFrame* frame) { @@ -272,47 +293,50 @@ void _Integer::AsString(Interpreter*, VMFrame* frame) { long integer = INT_VAL(self); ostringstream Str; Str << integer; - frame->Push(GetUniverse()->NewString( Str.str())); + frame->Push(GetUniverse()->NewString(Str.str())); } void _Integer::AsDouble(Interpreter*, VMFrame* frame) { vm_oop_t self = frame->Pop(); long integer = INT_VAL(self); - frame->Push(GetUniverse()->NewDouble((double) integer)); + frame->Push(GetUniverse()->NewDouble((double)integer)); } void _Integer::As32BitSigned(Interpreter*, VMFrame* frame) { vm_oop_t self = frame->Pop(); int64_t integer = INT_VAL(self); - frame->Push(NEW_INT((int64_t)(int32_t) integer)); + frame->Push(NEW_INT((int64_t)(int32_t)integer)); } void _Integer::As32BitUnsigned(Interpreter*, VMFrame* frame) { vm_oop_t self = frame->Pop(); int64_t integer = INT_VAL(self); - frame->Push(NEW_INT((int64_t)(uint32_t) integer)); + frame->Push(NEW_INT((int64_t)(uint32_t)integer)); } void _Integer::Sqrt(Interpreter*, VMFrame* frame) { vm_oop_t self = frame->Pop(); double result = sqrt((double)INT_VAL(self)); - if (result == rint(result)) - frame->Push(NEW_INT((int64_t) result)); - else + if (result == rint(result)) { + frame->Push(NEW_INT((int64_t)result)); + } else { frame->Push(GetUniverse()->NewDouble(result)); + } } void _Integer::AtRandom(Interpreter*, VMFrame* frame) { vm_oop_t self = frame->Pop(); - int64_t result = INT_VAL(self) * rand(); // NOLINT(clang-analyzer-security.insecureAPI.rand) + int64_t result = + INT_VAL(self) * + rand(); // NOLINT(clang-analyzer-security.insecureAPI.rand) frame->Push(NEW_INT(result)); } void _Integer::FromString(Interpreter*, VMFrame* frame) { - VMString* self = (VMString*) frame->Pop(); + VMString* self = (VMString*)frame->Pop(); frame->Pop(); StdString str = self->GetStdString(); diff --git a/src/primitives/Integer.h b/src/primitives/Integer.h index 841db9a4..ce4f2972 100644 --- a/src/primitives/Integer.h +++ b/src/primitives/Integer.h @@ -29,10 +29,8 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Integer: public PrimitiveContainer { - +class _Integer : public PrimitiveContainer { public: - void Plus(Interpreter*, VMFrame*); void Minus(Interpreter*, VMFrame*); void Star(Interpreter*, VMFrame*); @@ -60,7 +58,6 @@ class _Integer: public PrimitiveContainer { _Integer(void); private: - - void resendAsDouble(Interpreter* interp, const char* op, vm_oop_t left, VMDouble* right); - + void resendAsDouble(Interpreter* interp, const char* op, vm_oop_t left, + VMDouble* right); }; diff --git a/src/primitives/Method.cpp b/src/primitives/Method.cpp index d4fce7be..5f5ac913 100644 --- a/src/primitives/Method.cpp +++ b/src/primitives/Method.cpp @@ -1,19 +1,22 @@ +#include "Method.h" + #include #include "../primitivesCore/PrimitiveContainer.h" #include "../primitivesCore/Routine.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMArray.h" -#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMMethod.h" -#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete -#include "Method.h" +#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete _Method::_Method() : PrimitiveContainer() { - SetPrimitive("signature", new Routine<_Method>(this, &_Method::Signature, false)); - SetPrimitive("holder", new Routine<_Method>(this, &_Method::Holder, false)); - SetPrimitive("invokeOn_with_", new Routine<_Method>(this, &_Method::InvokeOn_With_, false)); + SetPrimitive("signature", + new Routine<_Method>(this, &_Method::Signature, false)); + SetPrimitive("holder", new Routine<_Method>(this, &_Method::Holder, false)); + SetPrimitive("invokeOn_with_", + new Routine<_Method>(this, &_Method::InvokeOn_With_, false)); } void _Method::Holder(Interpreter*, VMFrame* frame) { @@ -28,13 +31,12 @@ void _Method::Signature(Interpreter*, VMFrame* frame) { void _Method::InvokeOn_With_(Interpreter* interp, VMFrame* frame) { // REM: this is a clone with _Primitive::InvokeOn_With_ - VMArray* args = static_cast(frame->Pop()); - vm_oop_t rcvr = static_cast(frame->Pop()); + VMArray* args = static_cast(frame->Pop()); + vm_oop_t rcvr = static_cast(frame->Pop()); VMMethod* mthd = static_cast(frame->Pop()); - - + frame->Push(rcvr); - + size_t num_args = args->GetNumberOfIndexableFields(); for (size_t i = 0; i < num_args; i++) { vm_oop_t arg = args->GetIndexableField(i); diff --git a/src/primitives/Method.h b/src/primitives/Method.h index ed5efa19..b121d8ee 100644 --- a/src/primitives/Method.h +++ b/src/primitives/Method.h @@ -3,12 +3,11 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Method: public PrimitiveContainer { +class _Method : public PrimitiveContainer { public: _Method(void); - + void Signature(Interpreter*, VMFrame*); - void Holder (Interpreter*, VMFrame*); + void Holder(Interpreter*, VMFrame*); void InvokeOn_With_(Interpreter*, VMFrame*); - }; diff --git a/src/primitives/Object.cpp b/src/primitives/Object.cpp index 5ff9aa9b..c523c23e 100644 --- a/src/primitives/Object.cpp +++ b/src/primitives/Object.cpp @@ -24,36 +24,51 @@ THE SOFTWARE. */ +#include "Object.h" + #include #include #include "../primitivesCore/PrimitiveContainer.h" #include "../primitivesCore/Routine.h" #include "../vm/Globals.h" -#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMArray.h" -#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMInvokable.h" #include "../vmobjects/VMObject.h" -#include "Object.h" _Object::_Object() : PrimitiveContainer() { - SetPrimitive("equalequal", new Routine<_Object>(this, &_Object::Equalequal, false)); - SetPrimitive("objectSize", new Routine<_Object>(this, &_Object::ObjectSize, false)); - SetPrimitive("hashcode", new Routine<_Object>(this, &_Object::Hashcode, false)); - SetPrimitive("inspect", new Routine<_Object>(this, &_Object::Inspect, false)); - SetPrimitive("halt", new Routine<_Object>(this, &_Object::Halt, false)); - - SetPrimitive("perform_", new Routine<_Object>(this, &_Object::Perform, false)); - SetPrimitive("perform_withArguments_", new Routine<_Object>(this, &_Object::PerformWithArguments, false)); - SetPrimitive("perform_inSuperclass_", new Routine<_Object>(this, &_Object::PerformInSuperclass, false)); - SetPrimitive("perform_withArguments_inSuperclass_", new Routine<_Object>(this, &_Object::PerformWithArgumentsInSuperclass, false)); - - SetPrimitive("instVarAt_", new Routine<_Object>(this, &_Object::InstVarAt, false)); - SetPrimitive("instVarAt_put_", new Routine<_Object>(this, &_Object::InstVarAtPut, false)); - SetPrimitive("instVarNamed_", new Routine<_Object>(this, &_Object::InstVarNamed, false)); + SetPrimitive("equalequal", + new Routine<_Object>(this, &_Object::Equalequal, false)); + SetPrimitive("objectSize", + new Routine<_Object>(this, &_Object::ObjectSize, false)); + SetPrimitive("hashcode", + new Routine<_Object>(this, &_Object::Hashcode, false)); + SetPrimitive("inspect", + new Routine<_Object>(this, &_Object::Inspect, false)); + SetPrimitive("halt", new Routine<_Object>(this, &_Object::Halt, false)); + + SetPrimitive("perform_", + new Routine<_Object>(this, &_Object::Perform, false)); + SetPrimitive( + "perform_withArguments_", + new Routine<_Object>(this, &_Object::PerformWithArguments, false)); + SetPrimitive( + "perform_inSuperclass_", + new Routine<_Object>(this, &_Object::PerformInSuperclass, false)); + SetPrimitive("perform_withArguments_inSuperclass_", + new Routine<_Object>( + this, &_Object::PerformWithArgumentsInSuperclass, false)); + + SetPrimitive("instVarAt_", + new Routine<_Object>(this, &_Object::InstVarAt, false)); + SetPrimitive("instVarAt_put_", + new Routine<_Object>(this, &_Object::InstVarAtPut, false)); + SetPrimitive("instVarNamed_", + new Routine<_Object>(this, &_Object::InstVarNamed, false)); SetPrimitive("class", new Routine<_Object>(this, &_Object::Class, false)); } @@ -68,16 +83,17 @@ void _Object::Equalequal(Interpreter*, VMFrame* frame) { void _Object::ObjectSize(Interpreter*, VMFrame* frame) { vm_oop_t self = frame->Pop(); - frame->Push(NEW_INT((int64_t) AS_OBJ(self)->GetObjectSize())); + frame->Push(NEW_INT((int64_t)AS_OBJ(self)->GetObjectSize())); } void _Object::Hashcode(Interpreter*, VMFrame* frame) { vm_oop_t self = frame->Pop(); - if (IS_TAGGED(self)) + if (IS_TAGGED(self)) { frame->Push(self); - else + } else { frame->Push(NEW_INT(AS_OBJ(self)->GetHash())); + } } void _Object::Inspect(Interpreter*, VMFrame* frame) { @@ -103,7 +119,7 @@ void _Object::Perform(Interpreter* interp, VMFrame* frame) { } void _Object::PerformInSuperclass(Interpreter* interp, VMFrame* frame) { - VMClass* clazz = (VMClass*) frame->Pop(); + VMClass* clazz = (VMClass*)frame->Pop(); VMSymbol* selector = (VMSymbol*)frame->Pop(); VMInvokable* invokable = clazz->LookupInvokable(selector); @@ -112,7 +128,7 @@ void _Object::PerformInSuperclass(Interpreter* interp, VMFrame* frame) { } void _Object::PerformWithArguments(Interpreter* interp, VMFrame* frame) { - VMArray* args = (VMArray*) frame->Pop(); + VMArray* args = (VMArray*)frame->Pop(); VMSymbol* selector = (VMSymbol*)frame->Pop(); vm_oop_t self = frame->GetStackElement(0); @@ -128,9 +144,10 @@ void _Object::PerformWithArguments(Interpreter* interp, VMFrame* frame) { invokable->Invoke(interp, frame); } -void _Object::PerformWithArgumentsInSuperclass(Interpreter* interp, VMFrame* frame) { - VMClass* clazz = (VMClass*) frame->Pop(); - VMArray* args = (VMArray*) frame->Pop(); +void _Object::PerformWithArgumentsInSuperclass(Interpreter* interp, + VMFrame* frame) { + VMClass* clazz = (VMClass*)frame->Pop(); + VMArray* args = (VMArray*)frame->Pop(); VMSymbol* selector = (VMSymbol*)frame->Pop(); size_t num_args = args->GetNumberOfIndexableFields(); @@ -156,8 +173,8 @@ void _Object::InstVarAt(Interpreter*, VMFrame* frame) { void _Object::InstVarAtPut(Interpreter*, VMFrame* frame) { vm_oop_t value = frame->Pop(); - vm_oop_t idx = frame->Pop(); - vm_oop_t self = frame->GetStackElement(0); + vm_oop_t idx = frame->Pop(); + vm_oop_t self = frame->GetStackElement(0); long field_idx = INT_VAL(idx) - 1; @@ -165,7 +182,7 @@ void _Object::InstVarAtPut(Interpreter*, VMFrame* frame) { } void _Object::InstVarNamed(Interpreter*, VMFrame* frame) { - VMSymbol* name = (VMSymbol*) frame->Pop(); + VMSymbol* name = (VMSymbol*)frame->Pop(); vm_oop_t self = frame->Pop(); long field_idx = AS_OBJ(self)->GetFieldIndex(name); diff --git a/src/primitives/Object.h b/src/primitives/Object.h index b02980e4..4d1cba4f 100644 --- a/src/primitives/Object.h +++ b/src/primitives/Object.h @@ -29,7 +29,7 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Object: public PrimitiveContainer { +class _Object : public PrimitiveContainer { public: _Object(); void Equalequal(Interpreter*, VMFrame*); @@ -46,6 +46,6 @@ class _Object: public PrimitiveContainer { void InstVarAt(Interpreter*, VMFrame*); void InstVarAtPut(Interpreter*, VMFrame*); void InstVarNamed(Interpreter*, VMFrame*); - + void Class(Interpreter*, VMFrame*); }; diff --git a/src/primitives/Primitive.cpp b/src/primitives/Primitive.cpp index d3dd5901..88314d81 100644 --- a/src/primitives/Primitive.cpp +++ b/src/primitives/Primitive.cpp @@ -1,18 +1,23 @@ +#include "Primitive.h" + #include #include "../primitivesCore/PrimitiveContainer.h" #include "../primitivesCore/Routine.h" #include "../vmobjects/ObjectFormats.h" -#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMMethod.h" -#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete -#include "Primitive.h" +#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete _Primitive::_Primitive() : PrimitiveContainer() { - SetPrimitive("signature", new Routine<_Primitive>(this, &_Primitive::Signature, false)); - SetPrimitive("holder", new Routine<_Primitive>(this, &_Primitive::Holder, false)); - SetPrimitive("invokeOn_with_", new Routine<_Primitive>(this, &_Primitive::InvokeOn_With_, false)); + SetPrimitive("signature", + new Routine<_Primitive>(this, &_Primitive::Signature, false)); + SetPrimitive("holder", + new Routine<_Primitive>(this, &_Primitive::Holder, false)); + SetPrimitive( + "invokeOn_with_", + new Routine<_Primitive>(this, &_Primitive::InvokeOn_With_, false)); } void _Primitive::Holder(Interpreter*, VMFrame* frame) { @@ -27,13 +32,12 @@ void _Primitive::Signature(Interpreter*, VMFrame* frame) { void _Primitive::InvokeOn_With_(Interpreter* interp, VMFrame* frame) { // REM: this is a clone with _Primitive::InvokeOn_With_ - VMArray* args = static_cast(frame->Pop()); - vm_oop_t rcvr = static_cast(frame->Pop()); + VMArray* args = static_cast(frame->Pop()); + vm_oop_t rcvr = static_cast(frame->Pop()); VMInvokable* mthd = static_cast(frame->Pop()); - frame->Push(rcvr); - + size_t num_args = args->GetNumberOfIndexableFields(); for (size_t i = 0; i < num_args; i++) { vm_oop_t arg = args->GetIndexableField(i); diff --git a/src/primitives/Primitive.h b/src/primitives/Primitive.h index c04fad65..7416e715 100644 --- a/src/primitives/Primitive.h +++ b/src/primitives/Primitive.h @@ -3,12 +3,11 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Primitive: public PrimitiveContainer { +class _Primitive : public PrimitiveContainer { public: _Primitive(void); - + void Signature(Interpreter*, VMFrame*); - void Holder (Interpreter*, VMFrame*); + void Holder(Interpreter*, VMFrame*); void InvokeOn_With_(Interpreter*, VMFrame*); - }; diff --git a/src/primitives/String.cpp b/src/primitives/String.cpp index f72e8fe3..5af8dc85 100644 --- a/src/primitives/String.cpp +++ b/src/primitives/String.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "String.h" + #include #include #include @@ -37,23 +39,30 @@ #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMString.h" -#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete -#include "String.h" +#include "../vmobjects/VMSymbol.h" // NOLINT(misc-include-cleaner) it's required to make the types complete _String::_String() : PrimitiveContainer() { - SetPrimitive("concatenate_", new Routine<_String>(this, &_String::Concatenate_, false)); - SetPrimitive("asSymbol", new Routine<_String>(this, &_String::AsSymbol, false)); - SetPrimitive("hashcode", new Routine<_String>(this, &_String::Hashcode, false)); - SetPrimitive("length", new Routine<_String>(this, &_String::Length, false)); - SetPrimitive("equal", new Routine<_String>(this, &_String::Equal, false)); - SetPrimitive("primSubstringFrom_to_", new Routine<_String>(this, &_String::PrimSubstringFrom_to_, false)); - SetPrimitive("isWhiteSpace", new Routine<_String>(this, &_String::IsWhiteSpace, false)); - SetPrimitive("isLetters", new Routine<_String>(this, &_String::IsLetters, false)); - SetPrimitive("isDigits", new Routine<_String>(this, &_String::IsDigits, false)); + SetPrimitive("concatenate_", + new Routine<_String>(this, &_String::Concatenate_, false)); + SetPrimitive("asSymbol", + new Routine<_String>(this, &_String::AsSymbol, false)); + SetPrimitive("hashcode", + new Routine<_String>(this, &_String::Hashcode, false)); + SetPrimitive("length", new Routine<_String>(this, &_String::Length, false)); + SetPrimitive("equal", new Routine<_String>(this, &_String::Equal, false)); + SetPrimitive( + "primSubstringFrom_to_", + new Routine<_String>(this, &_String::PrimSubstringFrom_to_, false)); + SetPrimitive("isWhiteSpace", + new Routine<_String>(this, &_String::IsWhiteSpace, false)); + SetPrimitive("isLetters", + new Routine<_String>(this, &_String::IsLetters, false)); + SetPrimitive("isDigits", + new Routine<_String>(this, &_String::IsDigits, false)); } void _String::Concatenate_(Interpreter*, VMFrame* frame) { - VMString* arg = static_cast(frame->Pop()); + VMString* arg = static_cast(frame->Pop()); VMString* self = static_cast(frame->Pop()); // TODO: if this really needs to be optimized, than, well, then, // NewString should allow to construct it correctly and simply copy @@ -81,7 +90,7 @@ void _String::Length(Interpreter*, VMFrame* frame) { VMString* self = static_cast(frame->Pop()); size_t len = self->GetStringLength(); - frame->Push(NEW_INT((int64_t) len)); + frame->Push(NEW_INT((int64_t)len)); } void _String::Equal(Interpreter*, VMFrame* frame) { @@ -94,11 +103,12 @@ void _String::Equal(Interpreter*, VMFrame* frame) { } VMClass* otherClass = CLASS_OF(op1); - if(otherClass == load_ptr(stringClass) || otherClass == load_ptr(symbolClass)) { + if (otherClass == load_ptr(stringClass) || + otherClass == load_ptr(symbolClass)) { StdString s1 = static_cast(op1)->GetStdString(); StdString s2 = op2->GetStdString(); - if(s1 == s2) { + if (s1 == s2) { frame->Push(load_ptr(trueObject)); return; } @@ -107,7 +117,7 @@ void _String::Equal(Interpreter*, VMFrame* frame) { } void _String::PrimSubstringFrom_to_(Interpreter*, VMFrame* frame) { - vm_oop_t end = frame->Pop(); + vm_oop_t end = frame->Pop(); vm_oop_t start = frame->Pop(); VMString* self = static_cast(frame->Pop()); diff --git a/src/primitives/String.h b/src/primitives/String.h index 731d9883..808eadb6 100644 --- a/src/primitives/String.h +++ b/src/primitives/String.h @@ -29,7 +29,7 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _String: public PrimitiveContainer { +class _String : public PrimitiveContainer { public: _String(); void Concatenate_(Interpreter*, VMFrame*); diff --git a/src/primitives/Symbol.cpp b/src/primitives/Symbol.cpp index 9f985da9..bef0d245 100644 --- a/src/primitives/Symbol.cpp +++ b/src/primitives/Symbol.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Symbol.h" + #include #include "../primitivesCore/PrimitiveContainer.h" @@ -31,7 +33,6 @@ #include "../vm/Universe.h" #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMSymbol.h" -#include "Symbol.h" void _Symbol::AsString(Interpreter*, VMFrame* frame) { VMSymbol* sym = static_cast(frame->Pop()); @@ -40,7 +41,7 @@ void _Symbol::AsString(Interpreter*, VMFrame* frame) { frame->Push(GetUniverse()->NewString(str)); } - _Symbol::_Symbol() : PrimitiveContainer() { - SetPrimitive("asString", new Routine<_Symbol>(this, &_Symbol::AsString, false)); + SetPrimitive("asString", + new Routine<_Symbol>(this, &_Symbol::AsString, false)); } diff --git a/src/primitives/Symbol.h b/src/primitives/Symbol.h index 2271db0d..50811857 100644 --- a/src/primitives/Symbol.h +++ b/src/primitives/Symbol.h @@ -29,7 +29,7 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../vmobjects/ObjectFormats.h" -class _Symbol: public PrimitiveContainer { +class _Symbol : public PrimitiveContainer { public: _Symbol(); void AsString(Interpreter*, VMFrame*); diff --git a/src/primitives/System.cpp b/src/primitives/System.cpp index ca25e13e..3808c080 100644 --- a/src/primitives/System.cpp +++ b/src/primitives/System.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "System.h" + #include #include #include @@ -41,15 +43,14 @@ #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMString.h" #include "../vmobjects/VMSymbol.h" -#include "System.h" #if defined(__GNUC__) -#include + #include #else -#include + #include #endif @@ -72,7 +73,7 @@ void _System::Global_put_(Interpreter*, VMFrame* frame) { void _System::HasGlobal_(Interpreter*, VMFrame* frame) { VMSymbol* arg = static_cast(frame->Pop()); - frame->Pop(); // pop self (system) + frame->Pop(); // pop self (system) if (GetUniverse()->HasGlobal(arg)) { frame->Push(load_ptr(trueObject)); @@ -85,18 +86,20 @@ void _System::Load_(Interpreter*, VMFrame* frame) { VMSymbol* arg = static_cast(frame->Pop()); frame->Pop(); VMClass* result = GetUniverse()->LoadClass(arg); - if (result) + if (result) { frame->Push(result); - else + } else { frame->Push(load_ptr(nilObject)); + } } void _System::Exit_(Interpreter*, VMFrame* frame) { vm_oop_t err = frame->Pop(); long err_no = INT_VAL(err); - if (err_no != ERR_SUCCESS) + if (err_no != ERR_SUCCESS) { frame->PrintStackTrace(); + } GetUniverse()->Quit(err_no); } @@ -128,7 +131,6 @@ void _System::ErrorPrintNewline_(Interpreter*, VMFrame* frame) { ErrorPrint(str + "\n"); } - void _System::Time(Interpreter*, VMFrame* frame) { /*VMObject* self = */ frame->Pop(); @@ -136,9 +138,8 @@ void _System::Time(Interpreter*, VMFrame* frame) { gettimeofday(&now, nullptr); - long long diff = - ((now.tv_sec - start_time.tv_sec) * 1000) + //seconds - ((now.tv_usec - start_time.tv_usec) / 1000);// useconds + long long diff = ((now.tv_sec - start_time.tv_sec) * 1000) + // seconds + ((now.tv_usec - start_time.tv_usec) / 1000); // useconds frame->Push(NEW_INT(diff)); } @@ -151,15 +152,17 @@ void _System::Ticks(Interpreter*, VMFrame* frame) { gettimeofday(&now, nullptr); long long diff = - ((now.tv_sec - start_time.tv_sec) * 1000 * 1000) + //seconds - ((now.tv_usec - start_time.tv_usec));// useconds + ((now.tv_sec - start_time.tv_sec) * 1000 * 1000) + // seconds + ((now.tv_usec - start_time.tv_usec)); // useconds frame->Push(NEW_INT(diff)); } void _System::FullGC(Interpreter*, VMFrame* frame) { frame->Pop(); - GetHeap()->requestGC(); // not safe to do it immediatly, will be done when it is ok, i.e., in the interpreter loop + GetHeap() + ->requestGC(); // not safe to do it immediatly, will be done when it is + // ok, i.e., in the interpreter loop frame->Push(load_ptr(trueObject)); } @@ -171,7 +174,7 @@ void _System::LoadFile_(Interpreter*, VMFrame* frame) { if (file.is_open()) { std::stringstream buffer; buffer << file.rdbuf(); - + VMString* result = GetUniverse()->NewString(buffer.str()); frame->Push(result); } else { @@ -186,22 +189,33 @@ void _System::PrintStackTrace(Interpreter*, VMFrame* frame) { _System::_System(void) : PrimitiveContainer() { gettimeofday(&start_time, nullptr); - SetPrimitive("global_", new Routine<_System>(this, &_System::Global_, false)); - SetPrimitive("global_put_", new Routine<_System>(this, &_System::Global_put_, false)); - SetPrimitive("hasGlobal_", new Routine<_System>(this, &_System::HasGlobal_, false)); - SetPrimitive("load_", new Routine<_System>(this, &_System::Load_, false)); - SetPrimitive("exit_", new Routine<_System>(this, &_System::Exit_, false)); - SetPrimitive("printString_", new Routine<_System>(this, &_System::PrintString_, false)); - SetPrimitive("printNewline", new Routine<_System>(this, &_System::PrintNewline, false)); - SetPrimitive("printNewline_",new Routine<_System>(this, &_System::PrintNewline_, false)); - SetPrimitive("errorPrint_", new Routine<_System>(this, &_System::ErrorPrint_, false)); - SetPrimitive("errorPrintln_",new Routine<_System>(this, &_System::ErrorPrintNewline_, false)); - SetPrimitive("time", new Routine<_System>(this, &_System::Time, false)); - SetPrimitive("ticks", new Routine<_System>(this, &_System::Ticks, false)); - SetPrimitive("fullGC", new Routine<_System>(this, &_System::FullGC, false)); - - SetPrimitive("loadFile_", new Routine<_System>(this, &_System::LoadFile_, false)); - SetPrimitive("printStackTrace", new Routine<_System>(this, &_System::PrintStackTrace, false)); + SetPrimitive("global_", + new Routine<_System>(this, &_System::Global_, false)); + SetPrimitive("global_put_", + new Routine<_System>(this, &_System::Global_put_, false)); + SetPrimitive("hasGlobal_", + new Routine<_System>(this, &_System::HasGlobal_, false)); + SetPrimitive("load_", new Routine<_System>(this, &_System::Load_, false)); + SetPrimitive("exit_", new Routine<_System>(this, &_System::Exit_, false)); + SetPrimitive("printString_", + new Routine<_System>(this, &_System::PrintString_, false)); + SetPrimitive("printNewline", + new Routine<_System>(this, &_System::PrintNewline, false)); + SetPrimitive("printNewline_", + new Routine<_System>(this, &_System::PrintNewline_, false)); + SetPrimitive("errorPrint_", + new Routine<_System>(this, &_System::ErrorPrint_, false)); + SetPrimitive( + "errorPrintln_", + new Routine<_System>(this, &_System::ErrorPrintNewline_, false)); + SetPrimitive("time", new Routine<_System>(this, &_System::Time, false)); + SetPrimitive("ticks", new Routine<_System>(this, &_System::Ticks, false)); + SetPrimitive("fullGC", new Routine<_System>(this, &_System::FullGC, false)); + + SetPrimitive("loadFile_", + new Routine<_System>(this, &_System::LoadFile_, false)); + SetPrimitive("printStackTrace", + new Routine<_System>(this, &_System::PrintStackTrace, false)); } _System::~_System() {} diff --git a/src/primitives/System.h b/src/primitives/System.h index d2fa2c6a..3b45f26c 100644 --- a/src/primitives/System.h +++ b/src/primitives/System.h @@ -31,7 +31,7 @@ struct timeval; -class _System: public PrimitiveContainer { +class _System : public PrimitiveContainer { public: _System(void); virtual ~_System(); diff --git a/src/primitivesCore/PrimitiveContainer.cpp b/src/primitivesCore/PrimitiveContainer.cpp index 8167cfd0..b0896bc5 100644 --- a/src/primitivesCore/PrimitiveContainer.cpp +++ b/src/primitivesCore/PrimitiveContainer.cpp @@ -24,18 +24,19 @@ THE SOFTWARE. */ +#include "PrimitiveContainer.h" + #include #include #include "../vmobjects/PrimitiveRoutine.h" -#include "PrimitiveContainer.h" void PrimitiveContainer::SetPrimitive(const char* name, - PrimitiveRoutine* routine) { + PrimitiveRoutine* routine) { methods[std::string(name)] = routine; } PrimitiveRoutine* PrimitiveContainer::GetPrimitive( - const std::string& routineName) { + const std::string& routineName) { return methods[routineName]; } diff --git a/src/primitivesCore/PrimitiveContainer.h b/src/primitivesCore/PrimitiveContainer.h index 9d6361fc..6aa5379f 100644 --- a/src/primitivesCore/PrimitiveContainer.h +++ b/src/primitivesCore/PrimitiveContainer.h @@ -31,22 +31,21 @@ #include "../misc/defs.h" #include "../vmobjects/PrimitiveRoutine.h" -///Base class for all container objects holding SOM++ primitives. -//Primitive container classes need to initialize a std::map in order to map smalltalk message names to the method -//to call. +/// Base class for all container objects holding SOM++ primitives. +// Primitive container classes need to initialize a std::map in order to map smalltalk message names to the method +// to call. class PrimitiveContainer { - public: PrimitiveContainer() = default; virtual ~PrimitiveContainer() = default; - ///Every derived Class must use this method to initialize the methods - //map with the mapping of a StdString with the smalltalk message - //name and the corresponding functor object. The abstract functor object - //class is defined in vmobjects/PrimitiveRoutine. Basically, the only - //requirement for those objects is to implement: - // virtual void operator()(VMObject*, VMFrame*) + /// Every derived Class must use this method to initialize the methods + // map with the mapping of a StdString with the smalltalk message + // name and the corresponding functor object. The abstract functor object + // class is defined in vmobjects/PrimitiveRoutine. Basically, the only + // requirement for those objects is to implement: + // virtual void operator()(VMObject*, VMFrame*) virtual void SetPrimitive(const char* name, PrimitiveRoutine* routine); virtual PrimitiveRoutine* GetPrimitive(const std::string& routineName); diff --git a/src/primitivesCore/PrimitiveLoader.cpp b/src/primitivesCore/PrimitiveLoader.cpp index 38d369e4..a059ff9f 100644 --- a/src/primitivesCore/PrimitiveLoader.cpp +++ b/src/primitivesCore/PrimitiveLoader.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "PrimitiveLoader.h" + #include #include @@ -41,33 +43,33 @@ #include "../vm/Print.h" #include "../vmobjects/PrimitiveRoutine.h" #include "PrimitiveContainer.h" -#include "PrimitiveLoader.h" PrimitiveLoader PrimitiveLoader::loader; PrimitiveLoader::PrimitiveLoader() { - AddPrimitiveObject("Array", new _Array()); - AddPrimitiveObject("Block", new _Block()); - AddPrimitiveObject("Class", new _Class()); - AddPrimitiveObject("Double", new _Double()); - AddPrimitiveObject("Integer", new _Integer()); - AddPrimitiveObject("Method", new _Method()); - AddPrimitiveObject("Object", new _Object()); + AddPrimitiveObject("Array", new _Array()); + AddPrimitiveObject("Block", new _Block()); + AddPrimitiveObject("Class", new _Class()); + AddPrimitiveObject("Double", new _Double()); + AddPrimitiveObject("Integer", new _Integer()); + AddPrimitiveObject("Method", new _Method()); + AddPrimitiveObject("Object", new _Object()); AddPrimitiveObject("Primitive", new _Primitive()); - AddPrimitiveObject("String", new _String()); - AddPrimitiveObject("Symbol", new _Symbol()); - AddPrimitiveObject("System", new _System()); + AddPrimitiveObject("String", new _String()); + AddPrimitiveObject("Symbol", new _Symbol()); + AddPrimitiveObject("System", new _System()); } PrimitiveLoader::~PrimitiveLoader() { - map::iterator it = primitiveObjects.begin(); + map::iterator it = + primitiveObjects.begin(); for (; it != primitiveObjects.end(); ++it) { delete it->second; } } void PrimitiveLoader::AddPrimitiveObject(const std::string& name, - PrimitiveContainer* prim) { + PrimitiveContainer* prim) { primitiveObjects[name] = prim; } @@ -80,12 +82,14 @@ bool PrimitiveLoader::SupportsClass(const std::string& name) { } PrimitiveRoutine* PrimitiveLoader::GetPrimitiveRoutine(const std::string& cname, - const std::string& mname, bool isPrimitive) { + const std::string& mname, + bool isPrimitive) { return loader.getPrimitiveRoutine(cname, mname, isPrimitive); } PrimitiveRoutine* PrimitiveLoader::getPrimitiveRoutine(const std::string& cname, - const std::string& mname, bool isPrimitive) { + const std::string& mname, + bool isPrimitive) { PrimitiveContainer* primitive = primitiveObjects[cname]; if (!primitive) { ErrorPrint("Primitive object not found for name: " + cname + "\n"); @@ -94,10 +98,10 @@ PrimitiveRoutine* PrimitiveLoader::getPrimitiveRoutine(const std::string& cname, PrimitiveRoutine* result = primitive->GetPrimitive(mname); if (!result) { if (isPrimitive) { - ErrorPrint("method " + mname + " not found in class " + cname + "\n"); + ErrorPrint("method " + mname + " not found in class " + cname + + "\n"); } return nullptr; } return result; } - diff --git a/src/primitivesCore/PrimitiveLoader.h b/src/primitivesCore/PrimitiveLoader.h index d21c750b..b988c1d5 100644 --- a/src/primitivesCore/PrimitiveLoader.h +++ b/src/primitivesCore/PrimitiveLoader.h @@ -33,19 +33,20 @@ class PrimitiveContainer; class PrimitiveRoutine; -///Core class for primitive loading. -//In order to implement new primitive libraries, you can use this class. +/// Core class for primitive loading. +// In order to implement new primitive libraries, you can use this class. // -//Libraries have to take care of initializing any needed data or data structures. -//When using the PrimitiveLoader class that is the the std::map primitiveObjects. -//Initialize it by calling the AddPrimitiveObject method, in order to map the -//name of the smalltalk class to the corresponding PrimitiveContainer object. +// Libraries have to take care of initializing any needed data or data +// structures. When using the PrimitiveLoader class that is the the std::map +// primitiveObjects. Initialize it by calling the AddPrimitiveObject method, in +// order to map the name of the smalltalk class to the corresponding +// PrimitiveContainer object. class PrimitiveLoader { public: PrimitiveLoader(); virtual ~PrimitiveLoader(); void AddPrimitiveObject(const std::string& name, PrimitiveContainer*); - + static bool SupportsClass(const std::string& name); static PrimitiveRoutine* GetPrimitiveRoutine(const std::string& cname, const std::string& mname, @@ -57,9 +58,7 @@ class PrimitiveLoader { const std::string& mname, bool isPrimitive); - - std::map primitiveObjects{}; - + static PrimitiveLoader loader; }; diff --git a/src/primitivesCore/Routine.h b/src/primitivesCore/Routine.h index bd693aeb..dd4f44a5 100644 --- a/src/primitivesCore/Routine.h +++ b/src/primitivesCore/Routine.h @@ -30,27 +30,27 @@ class Interpreter; -///Implementation for a functor class with PrimitiveRoutine as base class. -//It stores an object and a pointer to one of its methods. It is invoked -//by calling the Routine's operator "()". -template class Routine: public PrimitiveRoutine { +/// Implementation for a functor class with PrimitiveRoutine as base class. +// It stores an object and a pointer to one of its methods. It is invoked +// by calling the Routine's operator "()". +template +class Routine : public PrimitiveRoutine { private: - void (TClass::*func)(Interpreter*, VMFrame*); // pointer to member function + void (TClass::*func)(Interpreter*, VMFrame*); // pointer to member function TClass* primContainerObj; const bool classSide; public: - - // takes pointer to an object, pointer to a member, and a bool indicating whether it is a class-side primitive or not - Routine(TClass* primContainerObj, void (TClass::*_fpt)(Interpreter*, VMFrame*), - bool classSide) - : PrimitiveRoutine(), func(_fpt), primContainerObj(primContainerObj), classSide(classSide) - {}; + // takes pointer to an object, pointer to a member, and a bool indicating + // whether it is a class-side primitive or not + Routine(TClass* primContainerObj, + void (TClass::*_fpt)(Interpreter*, VMFrame*), bool classSide) + : PrimitiveRoutine(), func(_fpt), primContainerObj(primContainerObj), + classSide(classSide) {}; void Invoke(Interpreter* interp, VMFrame* frm) override { (*primContainerObj.*func)(interp, frm); // execute member function } bool isClassSide() override { return classSide; } - }; diff --git a/src/unitTests/BasicInterpreterTests.h b/src/unitTests/BasicInterpreterTests.h index befa2e17..f84a49d2 100644 --- a/src/unitTests/BasicInterpreterTests.h +++ b/src/unitTests/BasicInterpreterTests.h @@ -8,193 +8,198 @@ using namespace std; -enum ResultType { - INTEGER, CLASS, SYMBOL, DOUBLE -}; - +enum ResultType { INTEGER, CLASS, SYMBOL, DOUBLE }; class TestData { public: - std::string className; - std::string methodName; - void* expectedResult; - ResultType type; - - TestData( - std::string className, - std::string methodName, - intptr_t expectedResult, - ResultType type) : - className(className), - methodName(methodName), - expectedResult((void*) expectedResult), - type(type) {} - - TestData( - std::string className, - std::string methodName, - double const* expectedResult, - ResultType type) : - className(className), - methodName(methodName), - expectedResult((void*) expectedResult), - type(type) {} - - TestData( - std::string className, - std::string methodName, - char const* expectedResult, - ResultType type) : - className(className), - methodName(methodName), - expectedResult((void*) expectedResult), - type(type) {} + std::string className; + std::string methodName; + void* expectedResult; + ResultType type; + + TestData(std::string className, std::string methodName, + intptr_t expectedResult, ResultType type) + : className(className), methodName(methodName), + expectedResult((void*)expectedResult), type(type) {} + + TestData(std::string className, std::string methodName, + double const* expectedResult, ResultType type) + : className(className), methodName(methodName), + expectedResult((void*)expectedResult), type(type) {} + + TestData(std::string className, std::string methodName, + char const* expectedResult, ResultType type) + : className(className), methodName(methodName), + expectedResult((void*)expectedResult), type(type) {} }; static const double dbl375 = 3.75; -std::ostream& operator<<(std::ostream& strm, const TestData& data) -{ - strm << data.className << "." << data.methodName; - return strm; +std::ostream& operator<<(std::ostream& strm, const TestData& data) { + strm << data.className << "." << data.methodName; + return strm; } -class BasicInterpreterTests: public CPPUNIT_NS::TestFixture { - CPPUNIT_TEST_SUITE (BasicInterpreterTests); - CPPUNIT_TEST_PARAMETERIZED (testBasic, { - TestData("MethodCall", "test", 42, INTEGER), - TestData("MethodCall", "test2", 42, INTEGER), - - TestData("NonLocalReturn", "test1", 42, INTEGER), - TestData("NonLocalReturn", "test2", 43, INTEGER), - TestData("NonLocalReturn", "test3", 3, INTEGER), - TestData("NonLocalReturn", "test4", 42, INTEGER), - TestData("NonLocalReturn", "test5", 22, INTEGER), - - TestData("Blocks", "testArg1", 42, INTEGER), - TestData("Blocks", "testArg2", 77, INTEGER), - TestData("Blocks", "testArgAndLocal", 8, INTEGER), - TestData("Blocks", "testArgAndContext", 8, INTEGER), - TestData("Blocks", "testEmptyZeroArg", 1, INTEGER), - TestData("Blocks", "testEmptyOneArg", 1, INTEGER), - TestData("Blocks", "testEmptyTwoArg", 1, INTEGER), - - TestData("Return", "testReturnSelf", "Return", CLASS), - TestData("Return", "testReturnSelfImplicitly", "Return", CLASS), - TestData("Return", "testNoReturnReturnsSelf", "Return", CLASS), - TestData("Return", "testBlockReturnsImplicitlyLastValue", 4, INTEGER), - - TestData("IfTrueIfFalse", "test", 42, INTEGER), - TestData("IfTrueIfFalse", "test2", 33, INTEGER), - TestData("IfTrueIfFalse", "test3", 4, INTEGER), - - TestData("IfTrueIfFalse", "testIfTrueTrueResult", "Integer", CLASS), - TestData("IfTrueIfFalse", "testIfTrueFalseResult", "Nil", CLASS), - TestData("IfTrueIfFalse", "testIfFalseTrueResult", "Nil", CLASS), - TestData("IfTrueIfFalse", "testIfFalseFalseResult", "Integer", CLASS), - - TestData("CompilerSimplification", "testReturnConstantSymbol", "constant", SYMBOL), - TestData("CompilerSimplification", "testReturnConstantInt", 42, INTEGER), - TestData("CompilerSimplification", "testReturnSelf", "CompilerSimplification", CLASS), - TestData("CompilerSimplification", "testReturnSelfImplicitly", "CompilerSimplification", - CLASS), - TestData("CompilerSimplification", "testReturnArgumentN", 55, INTEGER), - TestData("CompilerSimplification", "testReturnArgumentA", 44, INTEGER), - TestData("CompilerSimplification", "testSetField", "foo", SYMBOL), - TestData("CompilerSimplification", "testGetField", 40, INTEGER), - - TestData("Hash", "testHash", 444, INTEGER), - - TestData("Arrays", "testEmptyToInts", 3, INTEGER), - TestData("Arrays", "testPutAllInt", 5, INTEGER), - TestData("Arrays", "testPutAllNil", "Nil", CLASS), - TestData("Arrays", "testPutAllBlock", 3, INTEGER), - TestData("Arrays", "testNewWithAll", 1, INTEGER), - - TestData("BlockInlining", "testNoInlining", 1, INTEGER), - TestData("BlockInlining", "testOneLevelInlining", 1, INTEGER), - TestData("BlockInlining", "testOneLevelInliningWithLocalShadowTrue", 2, INTEGER), - TestData("BlockInlining", "testOneLevelInliningWithLocalShadowFalse", 1, INTEGER), - - TestData("BlockInlining", "testShadowDoesntStoreWrongLocal", 33, INTEGER), - TestData("BlockInlining", "testShadowDoesntReadUnrelated", "Nil", CLASS), - - TestData("BlockInlining", "testBlockNestedInIfTrue", 2, INTEGER), - TestData("BlockInlining", "testBlockNestedInIfFalse", 42, INTEGER), - - TestData("BlockInlining", "testStackDisciplineTrue", 1, INTEGER), - TestData("BlockInlining", "testStackDisciplineFalse", 2, INTEGER), - - TestData("BlockInlining", "testDeepNestedInlinedIfTrue", 3, INTEGER), - TestData("BlockInlining", "testDeepNestedInlinedIfFalse", 42, INTEGER), +class BasicInterpreterTests : public CPPUNIT_NS::TestFixture { + CPPUNIT_TEST_SUITE(BasicInterpreterTests); + CPPUNIT_TEST_PARAMETERIZED( + testBasic, + { + TestData("MethodCall", "test", 42, INTEGER), + TestData("MethodCall", "test2", 42, INTEGER), + + TestData("NonLocalReturn", "test1", 42, INTEGER), + TestData("NonLocalReturn", "test2", 43, INTEGER), + TestData("NonLocalReturn", "test3", 3, INTEGER), + TestData("NonLocalReturn", "test4", 42, INTEGER), + TestData("NonLocalReturn", "test5", 22, INTEGER), + + TestData("Blocks", "testArg1", 42, INTEGER), + TestData("Blocks", "testArg2", 77, INTEGER), + TestData("Blocks", "testArgAndLocal", 8, INTEGER), + TestData("Blocks", "testArgAndContext", 8, INTEGER), + TestData("Blocks", "testEmptyZeroArg", 1, INTEGER), + TestData("Blocks", "testEmptyOneArg", 1, INTEGER), + TestData("Blocks", "testEmptyTwoArg", 1, INTEGER), + + TestData("Return", "testReturnSelf", "Return", CLASS), + TestData("Return", "testReturnSelfImplicitly", "Return", CLASS), + TestData("Return", "testNoReturnReturnsSelf", "Return", CLASS), + TestData("Return", "testBlockReturnsImplicitlyLastValue", 4, + INTEGER), + + TestData("IfTrueIfFalse", "test", 42, INTEGER), + TestData("IfTrueIfFalse", "test2", 33, INTEGER), + TestData("IfTrueIfFalse", "test3", 4, INTEGER), + + TestData("IfTrueIfFalse", "testIfTrueTrueResult", "Integer", CLASS), + TestData("IfTrueIfFalse", "testIfTrueFalseResult", "Nil", CLASS), + TestData("IfTrueIfFalse", "testIfFalseTrueResult", "Nil", CLASS), + TestData("IfTrueIfFalse", "testIfFalseFalseResult", "Integer", + CLASS), + + TestData("CompilerSimplification", "testReturnConstantSymbol", + "constant", SYMBOL), + TestData("CompilerSimplification", "testReturnConstantInt", 42, + INTEGER), + TestData("CompilerSimplification", "testReturnSelf", + "CompilerSimplification", CLASS), + TestData("CompilerSimplification", "testReturnSelfImplicitly", + "CompilerSimplification", CLASS), + TestData("CompilerSimplification", "testReturnArgumentN", 55, + INTEGER), + TestData("CompilerSimplification", "testReturnArgumentA", 44, + INTEGER), + TestData("CompilerSimplification", "testSetField", "foo", SYMBOL), + TestData("CompilerSimplification", "testGetField", 40, INTEGER), + + TestData("Hash", "testHash", 444, INTEGER), + + TestData("Arrays", "testEmptyToInts", 3, INTEGER), + TestData("Arrays", "testPutAllInt", 5, INTEGER), + TestData("Arrays", "testPutAllNil", "Nil", CLASS), + TestData("Arrays", "testPutAllBlock", 3, INTEGER), + TestData("Arrays", "testNewWithAll", 1, INTEGER), + + TestData("BlockInlining", "testNoInlining", 1, INTEGER), + TestData("BlockInlining", "testOneLevelInlining", 1, INTEGER), + TestData("BlockInlining", "testOneLevelInliningWithLocalShadowTrue", + 2, INTEGER), + TestData("BlockInlining", + "testOneLevelInliningWithLocalShadowFalse", 1, INTEGER), + + TestData("BlockInlining", "testShadowDoesntStoreWrongLocal", 33, + INTEGER), + TestData("BlockInlining", "testShadowDoesntReadUnrelated", "Nil", + CLASS), + + TestData("BlockInlining", "testBlockNestedInIfTrue", 2, INTEGER), + TestData("BlockInlining", "testBlockNestedInIfFalse", 42, INTEGER), + + TestData("BlockInlining", "testStackDisciplineTrue", 1, INTEGER), + TestData("BlockInlining", "testStackDisciplineFalse", 2, INTEGER), + + TestData("BlockInlining", "testDeepNestedInlinedIfTrue", 3, + INTEGER), + TestData("BlockInlining", "testDeepNestedInlinedIfFalse", 42, + INTEGER), + + TestData("BlockInlining", "testDeepNestedBlocksInInlinedIfTrue", 5, + INTEGER), + TestData("BlockInlining", "testDeepNestedBlocksInInlinedIfFalse", + 43, INTEGER), + + TestData("BlockInlining", "testDeepDeepNestedTrue", 9, INTEGER), + TestData("BlockInlining", "testDeepDeepNestedFalse", 43, INTEGER), + + TestData("BlockInlining", "testToDoNestDoNestIfTrue", 2, INTEGER), + + TestData("NonLocalVars", "testWriteDifferentTypes", &dbl375, + DOUBLE), + + TestData("ObjectCreation", "test", 1000000, INTEGER), + + TestData("Regressions", "testSymbolEquality", 1, INTEGER), + TestData("Regressions", "testSymbolReferenceEquality", 1, INTEGER), + TestData("Regressions", "testUninitializedLocal", 1, INTEGER), + TestData("Regressions", "testUninitializedLocalInBlock", 1, + INTEGER), + + TestData("BinaryOperation", "test", 11, INTEGER), + + TestData("NumberOfTests", "numberOfTests", 65, INTEGER), + }); + + CPPUNIT_TEST_SUITE_END(); - TestData("BlockInlining", "testDeepNestedBlocksInInlinedIfTrue", 5, INTEGER), - TestData("BlockInlining", "testDeepNestedBlocksInInlinedIfFalse", 43, INTEGER), - - TestData("BlockInlining", "testDeepDeepNestedTrue", 9, INTEGER), - TestData("BlockInlining", "testDeepDeepNestedFalse", 43, INTEGER), - - TestData("BlockInlining", "testToDoNestDoNestIfTrue", 2, INTEGER), - - TestData("NonLocalVars", "testWriteDifferentTypes", &dbl375, DOUBLE), - - TestData("ObjectCreation", "test", 1000000, INTEGER), - - TestData("Regressions", "testSymbolEquality", 1, INTEGER), - TestData("Regressions", "testSymbolReferenceEquality", 1, INTEGER), - TestData("Regressions", "testUninitializedLocal", 1, INTEGER), - TestData("Regressions", "testUninitializedLocalInBlock", 1, INTEGER), - - TestData("BinaryOperation", "test", 11, INTEGER), - - TestData("NumberOfTests", "numberOfTests", 65, INTEGER), - }); - - CPPUNIT_TEST_SUITE_END(); private: - void assertEqualsSOMValue(vm_oop_t actualResult, TestData& data) { - if (data.type == INTEGER) { - int64_t expected = (intptr_t) data.expectedResult; - int64_t actual = INT_VAL(actualResult); - CPPUNIT_ASSERT_EQUAL(expected, actual); - return; - } - - if (data.type == DOUBLE) { - double* expected = (double*) data.expectedResult; - double actual = ((VMDouble*) actualResult)->GetEmbeddedDouble(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(*expected, actual, 1e-15); - return; + void assertEqualsSOMValue(vm_oop_t actualResult, TestData& data) { + if (data.type == INTEGER) { + int64_t expected = (intptr_t)data.expectedResult; + int64_t actual = INT_VAL(actualResult); + CPPUNIT_ASSERT_EQUAL(expected, actual); + return; + } + + if (data.type == DOUBLE) { + double* expected = (double*)data.expectedResult; + double actual = ((VMDouble*)actualResult)->GetEmbeddedDouble(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(*expected, actual, 1e-15); + return; + } + + if (data.type == CLASS) { + char const* expected = (char const*)data.expectedResult; + std::string expectedStr = std::string(expected); + std::string actual = + ((VMClass*)actualResult)->GetName()->GetStdString(); + if (expected != actual) { + CPPUNIT_NS::Asserter::failNotEqual(expected, actual, + CPPUNIT_SOURCELINE()); + } + return; + } + + if (data.type == SYMBOL) { + char const* expected = (char const*)data.expectedResult; + std::string expectedStr = std::string(expected); + std::string actual = ((VMSymbol*)actualResult)->GetStdString(); + if (expected != actual) { + CPPUNIT_NS::Asserter::failNotEqual(expected, actual, + CPPUNIT_SOURCELINE()); + } + return; + } + + CPPUNIT_FAIL("SOM Value handler missing"); } - if (data.type == CLASS) { - char const* expected = (char const*) data.expectedResult; - std::string expectedStr = std::string(expected); - std::string actual = ((VMClass*) actualResult)->GetName()->GetStdString(); - if (expected != actual) { - CPPUNIT_NS::Asserter::failNotEqual(expected, actual, CPPUNIT_SOURCELINE()); - } - return; + void testBasic(TestData data) { + // The Unit Test harness will initialize Universe for a standard run. + // This is different from other SOMs. + vm_oop_t result = + GetUniverse()->interpret(data.className, data.methodName); + CPPUNIT_ASSERT(result != nullptr); + assertEqualsSOMValue(result, data); } - - if (data.type == SYMBOL) { - char const* expected = (char const*) data.expectedResult; - std::string expectedStr = std::string(expected); - std::string actual = ((VMSymbol*) actualResult)->GetStdString(); - if (expected != actual) { - CPPUNIT_NS::Asserter::failNotEqual(expected, actual, CPPUNIT_SOURCELINE()); - } - return; - } - - CPPUNIT_FAIL("SOM Value handler missing"); - } - - void testBasic(TestData data) { - // The Unit Test harness will initialize Universe for a standard run. - // This is different from other SOMs. - vm_oop_t result = GetUniverse()->interpret(data.className, data.methodName); - CPPUNIT_ASSERT(result != nullptr); - assertEqualsSOMValue(result, data); - } }; diff --git a/src/unitTests/BytecodeGenerationTest.cpp b/src/unitTests/BytecodeGenerationTest.cpp index 51388a12..015a8a85 100644 --- a/src/unitTests/BytecodeGenerationTest.cpp +++ b/src/unitTests/BytecodeGenerationTest.cpp @@ -1,3 +1,5 @@ +#include "BytecodeGenerationTest.h" + #include #include #include @@ -8,7 +10,6 @@ #include #include - #include "../compiler/ClassGenerationContext.h" #include "../compiler/Disassembler.h" #include "../compiler/MethodGenerationContext.h" @@ -18,21 +19,24 @@ #include "../misc/debug.h" #include "../vm/Symbols.h" #include "../vmobjects/VMMethod.h" -#include "BytecodeGenerationTest.h" void BytecodeGenerationTest::dump(MethodGenerationContext* mgenc) { Disassembler::DumpMethod(mgenc, ""); } void BytecodeGenerationTest::ensureCGenC() { - if (_cgenc != nullptr) return; + if (_cgenc != nullptr) { + return; + } _cgenc = new ClassGenerationContext(); _cgenc->SetName(SymbolFor("Test")); } void BytecodeGenerationTest::ensureMGenC() { - if (_mgenc != nullptr) return; + if (_mgenc != nullptr) { + return; + } ensureCGenC(); _mgenc = new MethodGenerationContext(*_cgenc); @@ -41,7 +45,9 @@ void BytecodeGenerationTest::ensureMGenC() { } void BytecodeGenerationTest::ensureBGenC() { - if (_bgenc != nullptr) return; + if (_bgenc != nullptr) { + return; + } ensureCGenC(); ensureMGenC(); @@ -54,7 +60,8 @@ void BytecodeGenerationTest::addField(const char* fieldName) { _cgenc->AddInstanceField(SymbolFor(fieldName)); } -std::vector BytecodeGenerationTest::methodToBytecode(const char* source, bool dumpBytecodes) { +std::vector BytecodeGenerationTest::methodToBytecode( + const char* source, bool dumpBytecodes) { ensureMGenC(); istringstream ss(source); @@ -69,7 +76,8 @@ std::vector BytecodeGenerationTest::methodToBytecode(const char* source return _mgenc->GetBytecodes(); } -std::vector BytecodeGenerationTest::blockToBytecode(const char* source, bool dumpBytecodes) { +std::vector BytecodeGenerationTest::blockToBytecode( + const char* source, bool dumpBytecodes) { ensureBGenC(); istringstream ss(source); @@ -88,9 +96,7 @@ std::vector BytecodeGenerationTest::blockToBytecode(const char* source, void BytecodeGenerationTest::testEmptyMethodReturnsSelf() { auto bytecodes = methodToBytecode("test = ( )"); - check(bytecodes, { - BC_PUSH_SELF, - BC_RETURN_LOCAL}); + check(bytecodes, {BC(BC_PUSH_SELF), BC(BC_RETURN_LOCAL)}); } void BytecodeGenerationTest::testPushConstant() { @@ -98,37 +104,22 @@ void BytecodeGenerationTest::testPushConstant() { test = ( 0. 1. nil. #a. true. false. ) )"""); - check(bytecodes, { - BC_PUSH_0, BC_POP, - BC_PUSH_1, BC_POP, - BC_PUSH_NIL, BC_POP, - BC_PUSH_CONSTANT_0, BC_POP, - BC_PUSH_CONSTANT_1, BC_POP, - BC_PUSH_CONSTANT_2, BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_0, BC_POP, BC_PUSH_1, BC_POP, BC_PUSH_NIL, BC_POP, + BC_PUSH_CONSTANT_0, BC_POP, BC_PUSH_CONSTANT_1, BC_POP, + BC_PUSH_CONSTANT_2, BC_POP, BC_PUSH_SELF, BC_RETURN_LOCAL}); } - void BytecodeGenerationTest::testIfPushConstantSame() { auto bytecodes = methodToBytecode(R"""( test = ( #a. #b. #c. #d. true ifFalse: [ #a. #b. #c. #d. ] ) )"""); - check(bytecodes, { - BC_PUSH_CONSTANT_0, BC_POP, - BC_PUSH_CONSTANT_1, BC_POP, - BC_PUSH_CONSTANT_2, BC_POP, - BC_PUSH_CONSTANT, 3, BC_POP, - BC_PUSH_CONSTANT, 4, - BC_PUSH_BLOCK, 5, - BC_SEND, 6, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_CONSTANT_0, BC_POP, BC_PUSH_CONSTANT_1, BC_POP, + BC_PUSH_CONSTANT_2, BC_POP, BC(BC_PUSH_CONSTANT, 3), + BC_POP, BC(BC_PUSH_CONSTANT, 4), BC(BC_PUSH_BLOCK, 5), + BC(BC_SEND, 6), BC_POP, BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testIfPushConstantDifferent() { @@ -137,80 +128,46 @@ void BytecodeGenerationTest::testIfPushConstantDifferent() { #a. #b. #c. #d. true ifFalse: [ #e. #f. #g. #h. ] ) )"""); - check(bytecodes, { - BC_PUSH_CONSTANT_0, BC_POP, - BC_PUSH_CONSTANT_1, BC_POP, - BC_PUSH_CONSTANT_2, BC_POP, - BC_PUSH_CONSTANT, 3, BC_POP, - BC_PUSH_CONSTANT, 4, - BC_PUSH_BLOCK, 5, - BC_SEND, 6, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_CONSTANT_0, BC_POP, BC_PUSH_CONSTANT_1, BC_POP, + BC_PUSH_CONSTANT_2, BC_POP, BC(BC_PUSH_CONSTANT, 3), + BC_POP, BC(BC_PUSH_CONSTANT, 4), BC(BC_PUSH_BLOCK, 5), + BC(BC_SEND, 6), BC_POP, BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testExplicitReturnSelf() { auto bytecodes = methodToBytecode("test = ( ^ self )"); - check(bytecodes, { - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testDupPopArgumentPop() { auto bytecodes = methodToBytecode("test: arg = ( arg := 1. ^ self )"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_ARGUMENT, 1, 0, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC(BC_POP_ARGUMENT, 1, 0), BC_POP, + BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testDupPopArgumentPopImplicitReturnSelf() { auto bytecodes = methodToBytecode("test: arg = ( arg := 1 )"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_ARGUMENT, 1, 0, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC(BC_POP_ARGUMENT, 1, 0), BC_POP, + BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testDupPopLocalPop() { - auto bytecodes = methodToBytecode("test = ( | local | local := 1. ^ self )"); - - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_LOCAL_0, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + auto bytecodes = + methodToBytecode("test = ( | local | local := 1. ^ self )"); + + check(bytecodes, {BC_PUSH_1, BC_DUP, BC_POP_LOCAL_0, BC_POP, BC_PUSH_SELF, + BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testDupPopField0Pop() { addField("field"); auto bytecodes = methodToBytecode("test = ( field := 1. ^ self )"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_FIELD_0, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC_POP_FIELD_0, BC_POP, BC_PUSH_SELF, + BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testDupPopFieldPop() { @@ -221,28 +178,16 @@ void BytecodeGenerationTest::testDupPopFieldPop() { addField("field"); auto bytecodes = methodToBytecode("test = ( field := 1. ^ self )"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_FIELD, 4, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC(BC_POP_FIELD, 4), BC_POP, + BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testDupPopFieldReturnSelf() { addField("field"); auto bytecodes = methodToBytecode("test: val = ( field := val )"); - check(bytecodes, { - BC_PUSH_ARG_1, - BC_DUP, - BC_POP_FIELD_0, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_ARG_1, BC_DUP, BC_POP_FIELD_0, BC_POP, + BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testDupPopFieldNReturnSelf() { @@ -254,106 +199,62 @@ void BytecodeGenerationTest::testDupPopFieldNReturnSelf() { addField("field"); auto bytecodes = methodToBytecode("test: val = ( field := val )"); - check(bytecodes, { - BC_PUSH_ARG_1, - BC_DUP, - BC_POP_FIELD, 5, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_ARG_1, BC_DUP, BC(BC_POP_FIELD, 5), BC_POP, + BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testSendDupPopFieldReturnLocal() { addField("field"); auto bytecodes = methodToBytecode("test = ( ^ field := self method )"); - check(bytecodes, { - BC_PUSH_SELF, - BC_SEND, 0, - BC_DUP, - BC_POP_FIELD_0, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_SELF, BC(BC_SEND, 0), BC_DUP, BC_POP_FIELD_0, + BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testSendDupPopFieldReturnLocalPeriod() { addField("field"); auto bytecodes = methodToBytecode("test = ( ^ field := self method. )"); - check(bytecodes, { - BC_PUSH_SELF, - BC_SEND, 0, - BC_DUP, - BC_POP_FIELD_0, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_SELF, BC(BC_SEND, 0), BC_DUP, BC_POP_FIELD_0, + BC_RETURN_LOCAL}); } - void BytecodeGenerationTest::testBlockDupPopArgumentPopReturnArg() { auto bytecodes = blockToBytecode("[:arg | arg := 1. arg ]"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_ARGUMENT, 1, 0, - BC_POP, - BC_PUSH_ARG_1, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC(BC_POP_ARGUMENT, 1, 0), BC_POP, + BC_PUSH_ARG_1, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testBlockDupPopArgumentImplicitReturn() { auto bytecodes = blockToBytecode("[:arg | arg := 1 ]"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_ARGUMENT, 1, 0, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_1, BC_DUP, BC(BC_POP_ARGUMENT, 1, 0), BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testBlockDupPopArgumentImplicitReturnDot() { auto bytecodes = blockToBytecode("[:arg | arg := 1. ]"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_ARGUMENT, 1, 0, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_1, BC_DUP, BC(BC_POP_ARGUMENT, 1, 0), BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testBlockDupPopLocalReturnLocal() { auto bytecodes = blockToBytecode("[| local | local := 1 ]"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_LOCAL_0, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC_POP_LOCAL_0, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testBlockDupPopFieldReturnLocal() { addField("field"); auto bytecodes = blockToBytecode("[ field := 1 ]"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_FIELD_0, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC_POP_FIELD_0, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testBlockDupPopFieldReturnLocalDot() { addField("field"); auto bytecodes = blockToBytecode("[ field := 1 ]"); - check(bytecodes, { - BC_PUSH_1, - BC_DUP, - BC_POP_FIELD_0, - BC_RETURN_LOCAL - }); + check(bytecodes, {BC_PUSH_1, BC_DUP, BC_POP_FIELD_0, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testPushLocalOpt() { @@ -362,15 +263,10 @@ void BytecodeGenerationTest::testPushLocalOpt() { | l1 l2 l3 l4 | l1. l2. l3. l4. ) )"""); - check(bytecodes, { - BC_PUSH_LOCAL_0, BC_POP, - BC_PUSH_LOCAL_1, BC_POP, - BC_PUSH_LOCAL_2, BC_POP, - BC_PUSH_LOCAL, 3, 0, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_LOCAL_0, BC_POP, BC_PUSH_LOCAL_1, BC_POP, BC_PUSH_LOCAL_2, + BC_POP, BC(BC_PUSH_LOCAL, 3, 0), BC_POP, BC_PUSH_SELF, + BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testPushArgOpt() { @@ -378,15 +274,10 @@ void BytecodeGenerationTest::testPushArgOpt() { test: a1 and: a2 and: a3 and: a4 = ( self. a1. a2. a3. a4. ) )"""); - check(bytecodes, { - BC_PUSH_SELF, BC_POP, - BC_PUSH_ARG_1, BC_POP, - BC_PUSH_ARG_2, BC_POP, - BC_PUSH_ARGUMENT, 3, 0, BC_POP, - BC_PUSH_ARGUMENT, 4, 0, BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_SELF, BC_POP, BC_PUSH_ARG_1, BC_POP, BC_PUSH_ARG_2, BC_POP, + BC(BC_PUSH_ARGUMENT, 3, 0), BC_POP, BC(BC_PUSH_ARGUMENT, 4, 0), + BC_POP, BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testPushFieldOpt() { @@ -395,14 +286,10 @@ void BytecodeGenerationTest::testPushFieldOpt() { addField("f3"); addField("f4"); auto bytecodes = methodToBytecode("test = ( f1. f2. f3. f4 )"); - check(bytecodes, { - BC_PUSH_FIELD_0, BC_POP, - BC_PUSH_FIELD_1, BC_POP, - BC_PUSH_FIELD, 2, BC_POP, - BC_PUSH_FIELD, 3, BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check( + bytecodes, + {BC_PUSH_FIELD_0, BC_POP, BC_PUSH_FIELD_1, BC_POP, BC(BC_PUSH_FIELD, 2), + BC_POP, BC(BC_PUSH_FIELD, 3), BC_POP, BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testBlockPushFieldOpt() { @@ -412,13 +299,10 @@ void BytecodeGenerationTest::testBlockPushFieldOpt() { addField("f4"); auto bytecodes = blockToBytecode("[ f1. f2. f3. f4 ]"); - check(bytecodes, { - BC_PUSH_FIELD_0, BC_POP, - BC_PUSH_FIELD_1, BC_POP, - BC_PUSH_FIELD, 2, BC_POP, - BC_PUSH_FIELD, 3, - BC_RETURN_LOCAL - }); + check( + bytecodes, + {BC_PUSH_FIELD_0, BC_POP, BC_PUSH_FIELD_1, BC_POP, BC(BC_PUSH_FIELD, 2), + BC_POP, BC(BC_PUSH_FIELD, 3), BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testPopLocalOpt() { @@ -431,15 +315,13 @@ void BytecodeGenerationTest::testPopLocalOpt() { l4 := 1. l5 := 1. ) )"""); - check(bytecodes, { - BC_PUSH_1, BC_DUP, BC_POP_LOCAL_0, BC_POP, - BC_PUSH_1, BC_DUP, BC_POP_LOCAL_1, BC_POP, - BC_PUSH_1, BC_DUP, BC_POP_LOCAL_2, BC_POP, - BC_PUSH_1, BC_DUP, BC_POP_LOCAL, 3, 0, BC_POP, - BC_PUSH_1, BC_DUP, BC_POP_LOCAL, 4, 0, BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_1, BC_DUP, BC_POP_LOCAL_0, BC_POP, + BC_PUSH_1, BC_DUP, BC_POP_LOCAL_1, BC_POP, + BC_PUSH_1, BC_DUP, BC_POP_LOCAL_2, BC_POP, + BC_PUSH_1, BC_DUP, BC(BC_POP_LOCAL, 3, 0), BC_POP, + BC_PUSH_1, BC_DUP, BC(BC_POP_LOCAL, 4, 0), BC_POP, + BC_PUSH_SELF, BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testPopFieldOpt() { @@ -454,64 +336,80 @@ void BytecodeGenerationTest::testPopFieldOpt() { f3 := 1. f4 := 1. ) )"""); - check(bytecodes, { - BC_PUSH_1, BC_DUP, BC_POP_FIELD_0, BC_POP, - BC_PUSH_1, BC_DUP, BC_POP_FIELD_1, BC_POP, - BC_PUSH_1, BC_DUP, BC_POP_FIELD, 2, BC_POP, - BC_PUSH_1, BC_DUP, BC_POP_FIELD, 3, BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_1, BC_DUP, BC_POP_FIELD_0, BC_POP, BC_PUSH_1, BC_DUP, + BC_POP_FIELD_1, BC_POP, BC_PUSH_1, BC_DUP, BC(BC_POP_FIELD, 2), + BC_POP, BC_PUSH_1, BC_DUP, BC(BC_POP_FIELD, 3), BC_POP, BC_PUSH_SELF, + BC_RETURN_LOCAL}); } -void BytecodeGenerationTest::check(std::vector actual, std::vector expected) { - if (expected.size() != actual.size()) { - dump(_mgenc); - } - - for (size_t i = 0; i < actual.size() && i < expected.size(); i += 1) { - uint8_t actualBc = actual.at(i); +void BytecodeGenerationTest::check(std::vector actual, + std::vector + expected) { + size_t i = 0; + size_t bci = 0; + for (; bci < actual.size() && i < expected.size();) { + uint8_t actualBc = actual.at(bci); uint8_t bcLength = Bytecode::GetBytecodeLength(actualBc); - uint8_t expectedBc = expected.at(i); + BC expectedBc = expected.at(i); char msg[1000]; - snprintf(msg, 1000, "Bytecode %zu expected %s but got %s", - i, - Bytecode::GetBytecodeName(expectedBc), + snprintf(msg, 1000, "Bytecode %zu expected %s but got %s", i, + Bytecode::GetBytecodeName(expectedBc.bytecode), Bytecode::GetBytecodeName(actualBc)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, expectedBc, actualBc); + if (expectedBc.bytecode != actualBc) { + dump(_mgenc); + } + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, expectedBc.bytecode, actualBc); - if (bcLength > 1) { - snprintf(msg, 1000, "Bytecode %zu (%s), arg1 expected %hhu but got %hhu", - i, - Bytecode::GetBytecodeName(expectedBc), - expected.at(i + 1), - actual.at(i + 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, expected.at(i + 1), actual.at(i + 1)); + snprintf( + msg, 1000, + "Bytecode %zu (%s) was expected to have length %zu, but had %zu", i, + Bytecode::GetBytecodeName(actualBc), expectedBc.size, + (size_t)bcLength); + + if (expectedBc.size != bcLength) { + dump(_mgenc); + } + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, expectedBc.size, (size_t)bcLength); - i += 1; + if (bcLength > 1) { + snprintf(msg, 1000, + "Bytecode %zu (%s), arg1 expected %hhu but got %hhu", i, + Bytecode::GetBytecodeName(expectedBc.bytecode), + expectedBc.arg1, actual.at(bci + 1)); + if (expectedBc.arg1 != actual.at(bci + 1)) { + dump(_mgenc); + } + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, expectedBc.arg1, + actual.at(bci + 1)); if (bcLength > 2) { - snprintf(msg, 1000, "Bytecode %zu (%s), arg2 expected %hhu but got %hhu", - i, - Bytecode::GetBytecodeName(expectedBc), - expected.at(i + 1), - actual.at(i + 1)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, expected.at(i + 1), actual.at(i + 1)); - - i += 1; + snprintf(msg, 1000, + "Bytecode %zu (%s), arg2 expected %hhu but got %hhu", + i, Bytecode::GetBytecodeName(expectedBc.bytecode), + expectedBc.arg2, actual.at(bci + 2)); + if (expectedBc.arg2 != actual.at(bci + 2)) { + dump(_mgenc); + } + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, expectedBc.arg2, + actual.at(bci + 2)); } } + + i += 1; + bci += bcLength; } - CPPUNIT_ASSERT_EQUAL_MESSAGE("Number of bytecodes", - expected.size(), actual.size()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("All expected bytecodes covered", + expected.size(), i); + CPPUNIT_ASSERT_EQUAL_MESSAGE("All actual bytecodes covered", actual.size(), + bci); } - - -void BytecodeGenerationTest::testWhileInlining(const char* selector, uint8_t jumpBytecode) { +void BytecodeGenerationTest::testWhileInlining(const char* selector, + uint8_t jumpBytecode) { std::string source = R"""( test: arg = ( #start. [ true ] SELECTOR [ arg ]. @@ -521,25 +419,19 @@ void BytecodeGenerationTest::testWhileInlining(const char* selector, uint8_t jum assert(wasReplaced); auto bytecodes = methodToBytecode(source.data()); - check(bytecodes, { - BC_PUSH_CONSTANT_0, BC_POP, - BC_PUSH_CONSTANT_1, - jumpBytecode, 8, 0, - BC_PUSH_ARG_1, - BC_POP, - BC_JUMP_BACKWARD, 6, 0, - BC_PUSH_NIL, - BC_POP, - BC_PUSH_CONSTANT_2, - BC_POP, - BC_PUSH_SELF, - BC_RETURN_LOCAL - }); + check( + bytecodes, + {BC_PUSH_CONSTANT_0, BC_POP, BC_PUSH_CONSTANT_1, BC(jumpBytecode, 8, 0), + BC_PUSH_ARG_1, BC_POP, BC(BC_JUMP_BACKWARD, 6, 0), BC_PUSH_NIL, BC_POP, + BC_PUSH_CONSTANT_2, BC_POP, BC_PUSH_SELF, BC_RETURN_LOCAL}); } -/** This test checks whether the jumps in the while loop are correct after it got inlined. */ +/** This test checks whether the jumps in the while loop are correct after it + * got inlined. */ void BytecodeGenerationTest::testInliningWhileLoopsWithExpandingBranches() { - DebugPrint("\nTODO: testInliningWhileLoopsWithExpandingBranches is currently ignored, because we do not yet support inlining if #ifTrue:\n"); + DebugPrint( + "\nTODO: testInliningWhileLoopsWithExpandingBranches is currently " + "ignored, because we do not yet support inlining if #ifTrue:\n"); return; auto bytecodes = methodToBytecode(R"""( @@ -553,87 +445,83 @@ void BytecodeGenerationTest::testInliningWhileLoopsWithExpandingBranches() { ^ #end ) )"""); - check(bytecodes, { - BC_PUSH_CONSTANT_0, BC_POP, - BC_PUSH_CONSTANT_1, BC_POP, - BC_PUSH_CONSTANT_2, BC_POP, - BC_PUSH_0, - - // jump offset, to jump to the pop BC after the if/right before the push #end - BC_JUMP_ON_FALSE_TOP_NIL, 27, 0, - BC_PUSH_CONSTANT, 3, BC_POP, - BC_PUSH_CONSTANT, 4, BC_POP, - BC_PUSH_CONSTANT, 5, BC_POP, - - // jump offset, jump to push_nil as result of whileTrue - BC_JUMP_ON_FALSE_POP, 15, - BC_PUSH_CONSTANT, 6, BC_POP, - BC_PUSH_CONSTANT, 7, BC_POP, - BC_PUSH_CONSTANT, 8, BC_POP, - - // jump offset, jump back to the first PUSH_CONST inside if body, pushing #const3 - BC_PUSH_NIL, - BC_POP, - - BC_PUSH_CONSTANT, 9, - BC_RETURN_LOCAL - }); + check(bytecodes, + {BC_PUSH_CONSTANT_0, BC_POP, BC_PUSH_CONSTANT_1, BC_POP, + BC_PUSH_CONSTANT_2, BC_POP, BC_PUSH_0, + + // jump offset, to jump to the pop BC after the if/right before the + // push #end + BC(BC_JUMP_ON_FALSE_TOP_NIL, 27, 0), BC(BC_PUSH_CONSTANT, 3), BC_POP, + BC(BC_PUSH_CONSTANT, 4), BC_POP, BC(BC_PUSH_CONSTANT, 5), BC_POP, + + // jump offset, jump to push_nil as result of whileTrue + BC(BC_JUMP_ON_FALSE_POP, 15), BC(BC_PUSH_CONSTANT, 6), BC_POP, + BC(BC_PUSH_CONSTANT, 7), BC_POP, BC(BC_PUSH_CONSTANT, 8), BC_POP, + + // jump offset, jump back to the first PUSH_CONST inside if body, + // pushing #const3 + BC_PUSH_NIL, BC_POP, + + BC(BC_PUSH_CONSTANT, 9), BC_RETURN_LOCAL}); } void BytecodeGenerationTest::testInliningWhileLoopsWithContractingBranches() { - DebugPrint("\nTODO: testInliningWhileLoopsWithContractingBranches is currently ignored, because we do not yet support inlining if #ifTrue:\n"); - - //def test_inlining_while_loop_with_contracting_branches(mgenc): - // """ - // This test checks whether the jumps in the while loop are correct after it got inlined. - // The challenge here is - // """ - // bytecodes = method_to_bytecodes( - // mgenc, - // """ - // test = ( - // 0 ifTrue: [ - // [ ^ 1 ] - // whileTrue: [ - // ^ 0 ] - // ]. - // ^ #end - // ) - // """, - // ) + DebugPrint( + "\nTODO: testInliningWhileLoopsWithContractingBranches is currently " + "ignored, because we do not yet support inlining if #ifTrue:\n"); + + // def test_inlining_while_loop_with_contracting_branches(mgenc): + // """ + // This test checks whether the jumps in the while loop are correct + // after it got inlined. The challenge here is + // """ + // bytecodes = method_to_bytecodes( + // mgenc, + // """ + // test = ( + // 0 ifTrue: [ + // [ ^ 1 ] + // whileTrue: [ + // ^ 0 ] + // ]. + // ^ #end + // ) + // """, + // ) // - // assert len(bytecodes) == 19 - // check( - // bytecodes, - // [ - // Bytecodes.push_0, - // BC( - // Bytecodes.jump_on_false_top_nil, - // 15, - // note="jump offset to jump to the pop after the if, before pushing #end", - // ), - // Bytecodes.push_1, - // Bytecodes.return_local, - // BC( - // Bytecodes.jump_on_false_pop, - // 9, - // note="jump offset, jump to push_nil as result of whileTrue", - // ), - // Bytecodes.push_0, - // Bytecodes.return_local, - // Bytecodes.pop, - // BC( - // Bytecodes.jump_backward, - // 8, - // note="jump offset, to the push_1 of the condition", - // ), - // Bytecodes.push_nil, - // Bytecodes.pop, - // ], - // ) + // assert len(bytecodes) == 19 + // check( + // bytecodes, + // [ + // Bytecodes.push_0, + // BC( + // Bytecodes.jump_on_false_top_nil, + // 15, + // note="jump offset to jump to the pop after the if, before + // pushing #end", + // ), + // Bytecodes.push_1, + // Bytecodes.return_local, + // BC( + // Bytecodes.jump_on_false_pop, + // 9, + // note="jump offset, jump to push_nil as result of + // whileTrue", + // ), + // Bytecodes.push_0, + // Bytecodes.return_local, + // Bytecodes.pop, + // BC( + // Bytecodes.jump_backward, + // 8, + // note="jump offset, to the push_1 of the condition", + // ), + // Bytecodes.push_nil, + // Bytecodes.pop, + // ], + // ) }; - /* @@ -654,7 +542,8 @@ void BytecodeGenerationTest::testInliningWhileLoopsWithContractingBranches() { ], ) def test_inc_dec_bytecodes(mgenc, operator, bytecode): - bytecodes = method_to_bytecodes(mgenc, "test = ( 1 OP 1 )".replace("OP", operator)) + bytecodes = method_to_bytecodes(mgenc, "test = ( 1 OP 1 )".replace("OP", + operator)) assert len(bytecodes) == 3 check(bytecodes, [Bytecodes.push_1, bytecode, Bytecodes.return_self]) @@ -1294,9 +1183,8 @@ void BytecodeGenerationTest::testInliningWhileLoopsWithContractingBranches() { ], ) def test_trivial_method_inlining(mgenc, source, bytecode): - bytecodes = method_to_bytecodes(mgenc, "test = ( true ifTrue: [ " + source + " ] )") - check( - bytecodes, + bytecodes = method_to_bytecodes(mgenc, "test = ( true ifTrue: [ " + source + + " ] )") check( bytecodes, [ Bytecodes.push_constant_0, Bytecodes.jump_on_false_top_nil, @@ -1368,7 +1256,8 @@ void BytecodeGenerationTest::testInliningWhileLoopsWithContractingBranches() { field_name = "field" + str(field_num) bytecodes = method_to_bytecodes( - mgenc, "test = ( #foo. ^ " + field_name + " := " + field_name + " + 1 )" + mgenc, "test = ( #foo. ^ " + field_name + " := " + field_name + " + 1 + )" ) check( bytecodes, @@ -1427,7 +1316,8 @@ void BytecodeGenerationTest::testInliningWhileLoopsWithContractingBranches() { add_field(cgenc, "field6") field_name = "field" + str(field_num) - bytecodes = method_to_bytecodes(mgenc, "test = ( 1. ^ " + field_name + " )") + bytecodes = method_to_bytecodes(mgenc, "test = ( 1. ^ " + field_name + " + )") check( bytecodes, @@ -1516,29 +1406,36 @@ void BytecodeGenerationTest::testJumpQueuesOrdering() { jumps.emplace(Jump(8, BC_JUMP, 0)); jumps.emplace(Jump(2, BC_JUMP, 0)); - CPPUNIT_ASSERT_EQUAL((size_t) 1, jumps.top().originalJumpTargetIdx); jumps.pop(); - CPPUNIT_ASSERT_EQUAL((size_t) 2, jumps.top().originalJumpTargetIdx); jumps.pop(); - CPPUNIT_ASSERT_EQUAL((size_t) 5, jumps.top().originalJumpTargetIdx); jumps.pop(); - CPPUNIT_ASSERT_EQUAL((size_t) 8, jumps.top().originalJumpTargetIdx); jumps.pop(); - + CPPUNIT_ASSERT_EQUAL((size_t)1, jumps.top().originalJumpTargetIdx); + jumps.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)2, jumps.top().originalJumpTargetIdx); + jumps.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)5, jumps.top().originalJumpTargetIdx); + jumps.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)8, jumps.top().originalJumpTargetIdx); + jumps.pop(); std::priority_queue backJumps; backJumps.emplace(BackJump(13, 9)); backJumps.emplace(BackJump(3, 12)); backJumps.emplace(BackJump(54, 54)); - CPPUNIT_ASSERT_EQUAL((size_t) 3, backJumps.top().loopBeginIdx); backJumps.pop(); - CPPUNIT_ASSERT_EQUAL((size_t) 13, backJumps.top().loopBeginIdx); backJumps.pop(); - CPPUNIT_ASSERT_EQUAL((size_t) 54, backJumps.top().loopBeginIdx); backJumps.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)3, backJumps.top().loopBeginIdx); + backJumps.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)13, backJumps.top().loopBeginIdx); + backJumps.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)54, backJumps.top().loopBeginIdx); + backJumps.pop(); std::priority_queue backJumpsToPatch; backJumpsToPatch.emplace(BackJumpPatch(3, 2)); backJumpsToPatch.emplace(BackJumpPatch(32, 44)); backJumpsToPatch.emplace(BackJumpPatch(12, 55)); - - CPPUNIT_ASSERT_EQUAL((size_t) 3, backJumpsToPatch.top().backwardsJumpIdx); backJumpsToPatch.pop(); - CPPUNIT_ASSERT_EQUAL((size_t) 12, backJumpsToPatch.top().backwardsJumpIdx); backJumpsToPatch.pop(); - CPPUNIT_ASSERT_EQUAL((size_t) 32, backJumpsToPatch.top().backwardsJumpIdx); backJumpsToPatch.pop(); - + CPPUNIT_ASSERT_EQUAL((size_t)3, backJumpsToPatch.top().backwardsJumpIdx); + backJumpsToPatch.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)12, backJumpsToPatch.top().backwardsJumpIdx); + backJumpsToPatch.pop(); + CPPUNIT_ASSERT_EQUAL((size_t)32, backJumpsToPatch.top().backwardsJumpIdx); + backJumpsToPatch.pop(); } diff --git a/src/unitTests/BytecodeGenerationTest.h b/src/unitTests/BytecodeGenerationTest.h index fc1efb7a..70332f8d 100644 --- a/src/unitTests/BytecodeGenerationTest.h +++ b/src/unitTests/BytecodeGenerationTest.h @@ -6,14 +6,30 @@ #include "../compiler/MethodGenerationContext.h" #include "../interpreter/bytecodes.h" -class BytecodeGenerationTest: public CPPUNIT_NS::TestCase { +class BC { +public: + BC(uint8_t bytecode) : bytecode(bytecode), arg1(0), arg2(0), size(1) {} + + BC(uint8_t bytecode, uint8_t arg1) + : bytecode(bytecode), arg1(arg1), arg2(0), size(2) {} + + BC(uint8_t bytecode, uint8_t arg1, uint8_t arg2) + : bytecode(bytecode), arg1(arg1), arg2(arg2), size(3) {} + + uint8_t bytecode; + uint8_t arg1; + uint8_t arg2; + + size_t size; +}; +class BytecodeGenerationTest : public CPPUNIT_NS::TestCase { CPPUNIT_TEST_SUITE(BytecodeGenerationTest); CPPUNIT_TEST(testEmptyMethodReturnsSelf); CPPUNIT_TEST(testPushConstant); CPPUNIT_TEST(testIfPushConstantSame); CPPUNIT_TEST(testIfPushConstantDifferent); - + CPPUNIT_TEST(testExplicitReturnSelf); CPPUNIT_TEST(testDupPopArgumentPop); CPPUNIT_TEST(testDupPopArgumentPopImplicitReturnSelf); @@ -47,16 +63,15 @@ class BytecodeGenerationTest: public CPPUNIT_NS::TestCase { CPPUNIT_TEST_SUITE_END(); public: - inline void setUp(void) { - } - + inline void setUp(void) {} + inline void tearDown(void) { delete _cgenc; _cgenc = nullptr; - + delete _mgenc; _mgenc = nullptr; - + delete _bgenc; _bgenc = nullptr; } @@ -65,21 +80,23 @@ class BytecodeGenerationTest: public CPPUNIT_NS::TestCase { ClassGenerationContext* _cgenc; MethodGenerationContext* _mgenc; MethodGenerationContext* _bgenc; - + void ensureCGenC(); void ensureMGenC(); void ensureBGenC(); void addField(const char* fieldName); - - std::vector methodToBytecode(const char* source, bool dumpBytecodes = false); - std::vector blockToBytecode(const char* source, bool dumpBytecodes = false); - + + std::vector methodToBytecode(const char* source, + bool dumpBytecodes = false); + std::vector blockToBytecode(const char* source, + bool dumpBytecodes = false); + void testEmptyMethodReturnsSelf(); - + void testPushConstant(); void testIfPushConstantSame(); void testIfPushConstantDifferent(); - + void testExplicitReturnSelf(); void testDupPopArgumentPop(); void testDupPopArgumentPopImplicitReturnSelf(); @@ -90,14 +107,14 @@ class BytecodeGenerationTest: public CPPUNIT_NS::TestCase { void testDupPopFieldNReturnSelf(); void testSendDupPopFieldReturnLocal(); void testSendDupPopFieldReturnLocalPeriod(); - + void testBlockDupPopArgumentPopReturnArg(); void testBlockDupPopArgumentImplicitReturn(); void testBlockDupPopArgumentImplicitReturnDot(); void testBlockDupPopLocalReturnLocal(); void testBlockDupPopFieldReturnLocal(); void testBlockDupPopFieldReturnLocalDot(); - + void testPushLocalOpt(); void testPushArgOpt(); void testPushFieldOpt(); @@ -121,6 +138,6 @@ class BytecodeGenerationTest: public CPPUNIT_NS::TestCase { void testJumpQueuesOrdering(); void dump(MethodGenerationContext* mgenc); - - void check(std::vector actual, std::vector expected); + + void check(std::vector actual, std::vector expected); }; diff --git a/src/unitTests/CloneObjectsTest.cpp b/src/unitTests/CloneObjectsTest.cpp index a242c0b0..863c51a8 100644 --- a/src/unitTests/CloneObjectsTest.cpp +++ b/src/unitTests/CloneObjectsTest.cpp @@ -5,6 +5,8 @@ * Author: christian */ +#include "CloneObjectsTest.h" + #include #include #include @@ -27,21 +29,21 @@ #include "../vmobjects/VMPrimitive.h" #include "../vmobjects/VMString.h" #include "../vmobjects/VMSymbol.h" -#include "CloneObjectsTest.h" - void CloneObjectsTest::testCloneObject() { VMObject* orig = new (GetHeap(), 0) VMObject(0, sizeof(VMObject)); VMObject* clone = orig->CloneForMovingGC(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->GetClass(), - clone->GetClass()); + clone->GetClass()); CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->GetObjectSize(), - clone->GetObjectSize()); + clone->GetObjectSize()); CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", - orig->GetNumberOfFields(), clone->GetNumberOfFields()); + orig->GetNumberOfFields(), + clone->GetNumberOfFields()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneInteger() { @@ -49,10 +51,13 @@ void CloneObjectsTest::testCloneInteger() { VMInteger* clone = orig->CloneForMovingGC(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); - CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->GetClass(), clone->GetClass()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("integer value differs!!", orig->embeddedInteger, clone->embeddedInteger); + CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->GetClass(), + clone->GetClass()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("integer value differs!!", + orig->embeddedInteger, clone->embeddedInteger); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneDouble() { @@ -60,10 +65,13 @@ void CloneObjectsTest::testCloneDouble() { VMDouble* clone = orig->CloneForMovingGC(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); - CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->GetClass(), clone->GetClass()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("double value differs!!", orig->embeddedDouble, clone->embeddedDouble); + CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->GetClass(), + clone->GetClass()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("double value differs!!", orig->embeddedDouble, + clone->embeddedDouble); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneString() { @@ -72,13 +80,16 @@ void CloneObjectsTest::testCloneString() { CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->GetClass(), - clone->GetClass()); + clone->GetClass()); CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->GetObjectSize(), - clone->GetObjectSize()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("string differs!!!", orig->GetStdString(), clone->GetStdString()); + clone->GetObjectSize()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("string differs!!!", orig->GetStdString(), + clone->GetStdString()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); - CPPUNIT_ASSERT_MESSAGE("internal string was not copied", (intptr_t)orig->chars != (intptr_t)clone->chars); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); + CPPUNIT_ASSERT_MESSAGE("internal string was not copied", + (intptr_t)orig->chars != (intptr_t)clone->chars); // change the string orig->chars[0] = 'm'; @@ -95,11 +106,13 @@ void CloneObjectsTest::testCloneSymbol() { CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->GetClass(), - clone->GetClass()); + clone->GetClass()); CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->GetObjectSize(), - clone->GetObjectSize()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("string differs!!!", orig->GetPlainString(), clone->GetPlainString()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + clone->GetObjectSize()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("string differs!!!", orig->GetPlainString(), + clone->GetPlainString()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneArray() { @@ -111,68 +124,91 @@ void CloneObjectsTest::testCloneArray() { CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz); - CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", - orig->totalObjectSize, + CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->totalObjectSize, clone->totalObjectSize); - CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields); - CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->GetNumberOfIndexableFields(), clone->GetNumberOfIndexableFields()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", + orig->numberOfFields, clone->numberOfFields); + CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", + orig->GetNumberOfIndexableFields(), + clone->GetNumberOfIndexableFields()); CPPUNIT_ASSERT_EQUAL_MESSAGE("field 0 differs", orig->GetIndexableField(0), - clone->GetIndexableField(0)); + clone->GetIndexableField(0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("field 1 differs", orig->GetIndexableField(1), - clone->GetIndexableField(1)); + clone->GetIndexableField(1)); CPPUNIT_ASSERT_EQUAL_MESSAGE("field 2 differs", orig->GetIndexableField(2), - clone->GetIndexableField(2)); + clone->GetIndexableField(2)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneBlock() { VMSymbol* methodSymbol = NewSymbol("someMethod"); vector inlinedLoops; - VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), inlinedLoops); - VMBlock* orig = GetUniverse()->NewBlock(method, - GetUniverse()->GetInterpreter()->GetFrame(), - method->GetNumberOfArguments()); + VMMethod* method = GetUniverse()->NewMethod( + methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), + inlinedLoops); + VMBlock* orig = GetUniverse()->NewBlock( + method, GetUniverse()->GetInterpreter()->GetFrame(), + method->GetNumberOfArguments()); VMBlock* clone = orig->CloneForMovingGC(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz); - CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->totalObjectSize, clone->totalObjectSize); - CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields); - CPPUNIT_ASSERT_EQUAL_MESSAGE("blockMethod differs!!", orig->blockMethod, clone->blockMethod); - CPPUNIT_ASSERT_EQUAL_MESSAGE("context differs!!", orig->context, clone->context); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->totalObjectSize, + clone->totalObjectSize); + CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", + orig->numberOfFields, clone->numberOfFields); + CPPUNIT_ASSERT_EQUAL_MESSAGE("blockMethod differs!!", orig->blockMethod, + clone->blockMethod); + CPPUNIT_ASSERT_EQUAL_MESSAGE("context differs!!", orig->context, + clone->context); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testClonePrimitive() { VMSymbol* primitiveSymbol = NewSymbol("myPrimitive"); VMPrimitive* orig = VMPrimitive::GetEmptyPrimitive(primitiveSymbol, false); VMPrimitive* clone = orig->CloneForMovingGC(); - CPPUNIT_ASSERT_EQUAL_MESSAGE("signature differs!!", orig->signature, clone->signature); - CPPUNIT_ASSERT_EQUAL_MESSAGE("holder differs!!", orig->holder, clone->holder); + CPPUNIT_ASSERT_EQUAL_MESSAGE("signature differs!!", orig->signature, + clone->signature); + CPPUNIT_ASSERT_EQUAL_MESSAGE("holder differs!!", orig->holder, + clone->holder); CPPUNIT_ASSERT_EQUAL_MESSAGE("empty differs!!", orig->empty, clone->empty); - CPPUNIT_ASSERT_EQUAL_MESSAGE("routine differs!!", orig->routine, clone->routine); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("routine differs!!", orig->routine, + clone->routine); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneEvaluationPrimitive() { - VMEvaluationPrimitive* orig = new (GetHeap(), 0) VMEvaluationPrimitive(1); + VMEvaluationPrimitive* orig = + new (GetHeap(), 0) VMEvaluationPrimitive(1); VMEvaluationPrimitive* clone = orig->CloneForMovingGC(); - CPPUNIT_ASSERT_EQUAL_MESSAGE("signature differs!!", orig->signature, clone->signature); - CPPUNIT_ASSERT_EQUAL_MESSAGE("holder differs!!", orig->holder, clone->holder); + CPPUNIT_ASSERT_EQUAL_MESSAGE("signature differs!!", orig->signature, + clone->signature); + CPPUNIT_ASSERT_EQUAL_MESSAGE("holder differs!!", orig->holder, + clone->holder); CPPUNIT_ASSERT_EQUAL_MESSAGE("empty differs!!", orig->empty, clone->empty); - CPPUNIT_ASSERT_EQUAL_MESSAGE("routine differs!!", orig->routine, clone->routine); - CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfArguments differs!!", orig->numberOfArguments, clone->numberOfArguments); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("routine differs!!", orig->routine, + clone->routine); + CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfArguments differs!!", + orig->numberOfArguments, + clone->numberOfArguments); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneFrame() { VMSymbol* methodSymbol = NewSymbol("frameMethod"); vector inlinedLoops; - VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), inlinedLoops); + VMMethod* method = GetUniverse()->NewMethod( + methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), + inlinedLoops); VMFrame* orig = GetUniverse()->NewFrame(nullptr, method); VMFrame* context = orig->CloneForMovingGC(); @@ -183,37 +219,53 @@ void CloneObjectsTest::testCloneFrame() { CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz); - CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->totalObjectSize, clone->totalObjectSize); - CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields); - CPPUNIT_ASSERT_EQUAL_MESSAGE("GetPreviousFrame differs!!", orig->GetPreviousFrame(), clone->GetPreviousFrame()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("GetContext differs!!", orig->GetContext(), clone->GetContext()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOGetMethodfFields differs!!", orig->GetMethod(), clone->GetMethod()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("bytecodeIndex differs!!", orig->bytecodeIndex, clone->bytecodeIndex); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->totalObjectSize, + clone->totalObjectSize); + CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", + orig->numberOfFields, clone->numberOfFields); + CPPUNIT_ASSERT_EQUAL_MESSAGE("GetPreviousFrame differs!!", + orig->GetPreviousFrame(), + clone->GetPreviousFrame()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("GetContext differs!!", orig->GetContext(), + clone->GetContext()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOGetMethodfFields differs!!", + orig->GetMethod(), clone->GetMethod()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bytecodeIndex differs!!", orig->bytecodeIndex, + clone->bytecodeIndex); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } void CloneObjectsTest::testCloneMethod() { VMSymbol* methodSymbol = NewSymbol("myMethod"); vector inlinedLoops; - VMMethod* orig = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), inlinedLoops); + VMMethod* orig = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, + new LexicalScope(nullptr, {}, {}), + inlinedLoops); VMMethod* clone = orig->CloneForMovingGC(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfLocals differs!!", - orig->numberOfLocals, clone->numberOfLocals); - CPPUNIT_ASSERT_EQUAL_MESSAGE("bcLength differs!!", - orig->bcLength, clone->bcLength); + orig->numberOfLocals, clone->numberOfLocals); + CPPUNIT_ASSERT_EQUAL_MESSAGE("bcLength differs!!", orig->bcLength, + clone->bcLength); CPPUNIT_ASSERT_EQUAL_MESSAGE("maximumNumberOfStackElements differs!!", - orig->maximumNumberOfStackElements, clone->maximumNumberOfStackElements); + orig->maximumNumberOfStackElements, + clone->maximumNumberOfStackElements); CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfArguments differs!!", - orig->numberOfArguments, clone->numberOfArguments); + orig->numberOfArguments, + clone->numberOfArguments); CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfConstants differs!!", - orig->numberOfConstants, clone->numberOfConstants); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("GetHolder() differs!!", orig->GetHolder(), clone->GetHolder()); - CPPUNIT_ASSERT_EQUAL_MESSAGE("GetSignature() differs!!", orig->GetSignature(), clone->GetSignature()); + orig->numberOfConstants, + clone->numberOfConstants); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("GetHolder() differs!!", orig->GetHolder(), + clone->GetHolder()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("GetSignature() differs!!", + orig->GetSignature(), clone->GetSignature()); } void CloneObjectsTest::testCloneClass() { @@ -226,11 +278,18 @@ void CloneObjectsTest::testCloneClass() { CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz); - CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->totalObjectSize, clone->totalObjectSize); - CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", orig->numberOfFields, clone->numberOfFields); - CPPUNIT_ASSERT_EQUAL_MESSAGE("superClass differs!!", orig->superClass, clone->superClass); + CPPUNIT_ASSERT_EQUAL_MESSAGE("objectSize differs!!", orig->totalObjectSize, + clone->totalObjectSize); + CPPUNIT_ASSERT_EQUAL_MESSAGE("numberOfFields differs!!", + orig->numberOfFields, clone->numberOfFields); + CPPUNIT_ASSERT_EQUAL_MESSAGE("superClass differs!!", orig->superClass, + clone->superClass); CPPUNIT_ASSERT_EQUAL_MESSAGE("name differs!!", orig->name, clone->name); - CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceFields differs!!", orig->instanceFields, clone->instanceFields); - CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceInvokables differs!!", orig->instanceInvokables, clone->instanceInvokables); - CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceFields differs!!", + orig->instanceFields, clone->instanceFields); + CPPUNIT_ASSERT_EQUAL_MESSAGE("instanceInvokables differs!!", + orig->instanceInvokables, + clone->instanceInvokables); + CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), + clone->GetHash()); } diff --git a/src/unitTests/CloneObjectsTest.h b/src/unitTests/CloneObjectsTest.h index f1edb937..2cd42dbf 100644 --- a/src/unitTests/CloneObjectsTest.h +++ b/src/unitTests/CloneObjectsTest.h @@ -8,26 +8,26 @@ #include -class CloneObjectsTest: public CPPUNIT_NS::TestCase { - CPPUNIT_TEST_SUITE (CloneObjectsTest); - CPPUNIT_TEST (testCloneObject); - CPPUNIT_TEST (testCloneInteger); - CPPUNIT_TEST (testCloneDouble); - CPPUNIT_TEST (testCloneString); - CPPUNIT_TEST (testCloneSymbol); - CPPUNIT_TEST (testCloneArray); - CPPUNIT_TEST (testCloneMethod); - CPPUNIT_TEST (testCloneBlock); - CPPUNIT_TEST (testClonePrimitive); - CPPUNIT_TEST (testCloneClass); - CPPUNIT_TEST (testCloneFrame); - CPPUNIT_TEST (testCloneEvaluationPrimitive);CPPUNIT_TEST_SUITE_END(); +class CloneObjectsTest : public CPPUNIT_NS::TestCase { + CPPUNIT_TEST_SUITE(CloneObjectsTest); + CPPUNIT_TEST(testCloneObject); + CPPUNIT_TEST(testCloneInteger); + CPPUNIT_TEST(testCloneDouble); + CPPUNIT_TEST(testCloneString); + CPPUNIT_TEST(testCloneSymbol); + CPPUNIT_TEST(testCloneArray); + CPPUNIT_TEST(testCloneMethod); + CPPUNIT_TEST(testCloneBlock); + CPPUNIT_TEST(testClonePrimitive); + CPPUNIT_TEST(testCloneClass); + CPPUNIT_TEST(testCloneFrame); + CPPUNIT_TEST(testCloneEvaluationPrimitive); + CPPUNIT_TEST_SUITE_END(); public: - inline void setUp(void) { - } - inline void tearDown(void) { - } + inline void setUp(void) {} + inline void tearDown(void) {} + private: void testCloneObject(); void testCloneInteger(); diff --git a/src/unitTests/WalkObjectsTest.cpp b/src/unitTests/WalkObjectsTest.cpp index eeab6d1a..bc2b10aa 100644 --- a/src/unitTests/WalkObjectsTest.cpp +++ b/src/unitTests/WalkObjectsTest.cpp @@ -4,6 +4,8 @@ * Created on: 12.01.2011 * Author: christian */ +#include "WalkObjectsTest.h" + #include #include #include @@ -27,7 +29,6 @@ #include "../vmobjects/VMMethod.h" #include "../vmobjects/VMPrimitive.h" #include "../vmobjects/VMSymbol.h" -#include "WalkObjectsTest.h" static const size_t NoOfFields_Object = 1; static const size_t NoOfFields_String = 0; @@ -55,8 +56,8 @@ gc_oop_t collectMembers(gc_oop_t obj) { * Helper function that searches the result vector for a field */ bool WalkerHasFound(gc_oop_t obj) { - return find(walkedObjects.begin(), walkedObjects.end(), obj) - != walkedObjects.end(); + return find(walkedObjects.begin(), walkedObjects.end(), obj) != + walkedObjects.end(); } void WalkObjectsTest::testWalkInteger() { @@ -64,7 +65,7 @@ void WalkObjectsTest::testWalkInteger() { VMInteger* int1 = GetUniverse()->NewInteger(42); int1->WalkObjects(collectMembers); - //Integers have no additional members + // Integers have no additional members CPPUNIT_ASSERT_EQUAL(NoOfFields_Integer, walkedObjects.size()); } @@ -73,14 +74,15 @@ void WalkObjectsTest::testWalkDouble() { VMDouble* d1 = GetUniverse()->NewDouble(432.1); d1->WalkObjects(collectMembers); - //Doubles have no additional members + // Doubles have no additional members CPPUNIT_ASSERT_EQUAL(NoOfFields_Double, walkedObjects.size()); } void WalkObjectsTest::testWalkEvaluationPrimitive() { walkedObjects.clear(); - VMEvaluationPrimitive* evPrim = new (GetHeap(), 0) VMEvaluationPrimitive(1); + VMEvaluationPrimitive* evPrim = + new (GetHeap(), 0) VMEvaluationPrimitive(1); evPrim->SetHolder(load_ptr(classClass)); evPrim->WalkObjects(collectMembers); @@ -96,7 +98,7 @@ void WalkObjectsTest::testWalkObject() { VMObject* obj = new (GetHeap(), 0) VMObject(0, sizeof(VMObject)); obj->WalkObjects(collectMembers); - //Objects should only have one member -> Class + // Objects should only have one member -> Class CPPUNIT_ASSERT_EQUAL(NoOfFields_Object, walkedObjects.size()); CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(obj->GetClass()))); } @@ -123,7 +125,7 @@ void WalkObjectsTest::testWalkClass() { meta->superClass = stringClass; meta->WalkObjects(collectMembers); - //Now check if we found all class fields + // Now check if we found all class fields CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(meta->GetClass()))); CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(meta->GetSuperClass()))); CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(meta->GetName()))); @@ -149,7 +151,9 @@ void WalkObjectsTest::testWalkFrame() { VMSymbol* methodSymbol = NewSymbol("frameMethod"); vector inlinedLoops; - VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), inlinedLoops); + VMMethod* method = GetUniverse()->NewMethod( + methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), + inlinedLoops); VMFrame* frame = GetUniverse()->NewFrame(nullptr, method); frame->SetPreviousFrame(frame->CloneForMovingGC()); @@ -161,11 +165,12 @@ void WalkObjectsTest::testWalkFrame() { CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(frame->GetPreviousFrame()))); CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(frame->GetContext()))); CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(frame->GetMethod()))); - //CPPUNIT_ASSERT(WalkerHasFound(frame->bytecodeIndex)); + // CPPUNIT_ASSERT(WalkerHasFound(frame->bytecodeIndex)); CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(dummyArg))); CPPUNIT_ASSERT_EQUAL( - (long) (NoOfFields_Frame + method->GetNumberOfArguments()), - (long) walkedObjects.size() + 1); // + 1 for the class field that's still in there + (long)(NoOfFields_Frame + method->GetNumberOfArguments()), + (long)walkedObjects.size() + + 1); // + 1 for the class field that's still in there } Variable makeVar(const char* const name, bool isArgument) { @@ -175,7 +180,8 @@ Variable makeVar(const char* const name, bool isArgument) { void WalkObjectsTest::testWalkMethod() { walkedObjects.clear(); - // First, we're setting up lexical scopes, just to see that we reach those, too + // First, we're setting up lexical scopes, just to see that we reach those, + // too vector argsInner; vector localsInner; @@ -196,11 +202,11 @@ void WalkObjectsTest::testWalkMethod() { LexicalScope* inner = new LexicalScope(nullptr, argsInner, localsInner); LexicalScope* scope = new LexicalScope(inner, args, locals); - VMSymbol* methodSymbol = NewSymbol("myMethod"); vector inlinedLoops; - VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, scope, inlinedLoops); + VMMethod* method = + GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, scope, inlinedLoops); method->SetHolder(load_ptr(symbolClass)); method->WalkObjects(collectMembers); @@ -218,11 +224,13 @@ void WalkObjectsTest::testWalkBlock() { VMSymbol* methodSymbol = NewSymbol("someMethod"); vector inlinedLoops; - VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), inlinedLoops); + VMMethod* method = GetUniverse()->NewMethod( + methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), + inlinedLoops); - VMBlock* block = GetUniverse()->NewBlock(method, - GetUniverse()->GetInterpreter()->GetFrame(), - method->GetNumberOfArguments()); + VMBlock* block = GetUniverse()->NewBlock( + method, GetUniverse()->GetInterpreter()->GetFrame(), + method->GetNumberOfArguments()); block->WalkObjects(collectMembers); CPPUNIT_ASSERT_EQUAL(NoOfFields_Block, walkedObjects.size()); CPPUNIT_ASSERT(WalkerHasFound(tmp_ptr(block->GetClass()))); diff --git a/src/unitTests/WalkObjectsTest.h b/src/unitTests/WalkObjectsTest.h index 7404f9cb..3b1430e7 100644 --- a/src/unitTests/WalkObjectsTest.h +++ b/src/unitTests/WalkObjectsTest.h @@ -21,27 +21,25 @@ using namespace std; -class WalkObjectsTest: public CPPUNIT_NS::TestCase { - - CPPUNIT_TEST_SUITE (WalkObjectsTest); - CPPUNIT_TEST (testWalkArray); - CPPUNIT_TEST (testWalkBlock); - CPPUNIT_TEST (testWalkClass); - CPPUNIT_TEST (testWalkDouble); - CPPUNIT_TEST (testWalkEvaluationPrimitive); - CPPUNIT_TEST (testWalkFrame); - CPPUNIT_TEST (testWalkInteger); - CPPUNIT_TEST (testWalkString); - CPPUNIT_TEST (testWalkMethod); - CPPUNIT_TEST (testWalkObject); - CPPUNIT_TEST (testWalkPrimitive); - CPPUNIT_TEST (testWalkSymbol);CPPUNIT_TEST_SUITE_END(); +class WalkObjectsTest : public CPPUNIT_NS::TestCase { + CPPUNIT_TEST_SUITE(WalkObjectsTest); + CPPUNIT_TEST(testWalkArray); + CPPUNIT_TEST(testWalkBlock); + CPPUNIT_TEST(testWalkClass); + CPPUNIT_TEST(testWalkDouble); + CPPUNIT_TEST(testWalkEvaluationPrimitive); + CPPUNIT_TEST(testWalkFrame); + CPPUNIT_TEST(testWalkInteger); + CPPUNIT_TEST(testWalkString); + CPPUNIT_TEST(testWalkMethod); + CPPUNIT_TEST(testWalkObject); + CPPUNIT_TEST(testWalkPrimitive); + CPPUNIT_TEST(testWalkSymbol); + CPPUNIT_TEST_SUITE_END(); public: - inline void setUp(void) { - } - inline void tearDown(void) { - } + inline void setUp(void) {} + inline void tearDown(void) {} private: void testWalkArray(); @@ -56,5 +54,4 @@ class WalkObjectsTest: public CPPUNIT_NS::TestCase { void testWalkObject(); void testWalkPrimitive(); void testWalkSymbol(); - }; diff --git a/src/unitTests/WriteBarrierTest.cpp b/src/unitTests/WriteBarrierTest.cpp index d415a727..53ce1a61 100644 --- a/src/unitTests/WriteBarrierTest.cpp +++ b/src/unitTests/WriteBarrierTest.cpp @@ -1,39 +1,40 @@ #include "../misc/defs.h" -#if GC_TYPE==GENERATIONAL - -#include -#include - -#include "../memory/Heap.h" -#include "../vm/Globals.h" -#include "../vm/Symbols.h" -#include "../vm/Universe.h" -#include "../vmobjects/ObjectFormats.h" -#include "../vmobjects/VMArray.h" -#include "../vmobjects/VMBlock.h" -#include "../vmobjects/VMClass.h" -#include "../vmobjects/VMDouble.h" -#include "../vmobjects/VMEvaluationPrimitive.h" -#include "../vmobjects/VMFrame.h" -#include "../vmobjects/VMInteger.h" -#include "../vmobjects/VMMethod.h" -#include "../vmobjects/VMString.h" -#include "../vmobjects/VMSymbol.h" -#include "WriteBarrierTest.h" - - -#define TEST_WB_CALLED(msg, hld, ref) \ - CPPUNIT_ASSERT_MESSAGE(msg, \ - GetHeap()->writeBarrierCalledOn.find(make_pair(hld, ref)) != \ - GetHeap()->writeBarrierCalledOn.end()); +#if GC_TYPE == GENERATIONAL + + #include + #include + + #include "../memory/Heap.h" + #include "../vm/Globals.h" + #include "../vm/Symbols.h" + #include "../vm/Universe.h" + #include "../vmobjects/ObjectFormats.h" + #include "../vmobjects/VMArray.h" + #include "../vmobjects/VMBlock.h" + #include "../vmobjects/VMClass.h" + #include "../vmobjects/VMDouble.h" + #include "../vmobjects/VMEvaluationPrimitive.h" + #include "../vmobjects/VMFrame.h" + #include "../vmobjects/VMInteger.h" + #include "../vmobjects/VMMethod.h" + #include "../vmobjects/VMString.h" + #include "../vmobjects/VMSymbol.h" + #include "WriteBarrierTest.h" + + #define TEST_WB_CALLED(msg, hld, ref) \ + CPPUNIT_ASSERT_MESSAGE( \ + msg, \ + GetHeap()->writeBarrierCalledOn.find(make_pair( \ + hld, ref)) != GetHeap()->writeBarrierCalledOn.end()); void WriteBarrierTest::testWriteArray() { if (!DEBUG) { - CPPUNIT_FAIL("WriteBarrier tests only work in DEBUG builds for speed reasons"); + CPPUNIT_FAIL( + "WriteBarrier tests only work in DEBUG builds for speed reasons"); } - //reset set... + // reset set... GetHeap()->writeBarrierCalledOn.clear(); VMArray* arr = GetUniverse()->NewArray(3); VMInteger* newInt = GetUniverse()->NewInteger(12345); @@ -47,106 +48,134 @@ void WriteBarrierTest::testWriteArray() { arr->SetIndexableField(1, str); arr->SetIndexableField(2, doub); - //test for obvious writeBarrier calls - TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, newInt); - TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, str); - TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, doub); - TEST_WB_CALLED("VMArray failed to call writeBarrier for clazz", arr, load_ptr(arrayClass)); - TEST_WB_CALLED("VMArray failed to call writeBarrier for clazz", arr, cloneClass); - TEST_WB_CALLED("VMArray failed to call writeBarrier for clazz", arr, clone2Class); - //nilObject is assigned in constructor - TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, load_ptr(nilObject)); + // test for obvious writeBarrier calls + TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, + newInt); + TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, + str); + TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, + doub); + TEST_WB_CALLED("VMArray failed to call writeBarrier for clazz", arr, + load_ptr(arrayClass)); + TEST_WB_CALLED("VMArray failed to call writeBarrier for clazz", arr, + cloneClass); + TEST_WB_CALLED("VMArray failed to call writeBarrier for clazz", arr, + clone2Class); + // nilObject is assigned in constructor + TEST_WB_CALLED("VMArray failed to call writeBarrier for an element", arr, + load_ptr(nilObject)); } void WriteBarrierTest::testWriteBlock() { if (!DEBUG) { - CPPUNIT_FAIL("WriteBarrier tests only work in DEBUG builds for speed reasons"); + CPPUNIT_FAIL( + "WriteBarrier tests only work in DEBUG builds for speed reasons"); } - //reset set... + // reset set... GetHeap()->writeBarrierCalledOn.clear(); VMSymbol* methodSymbol = NewSymbol("someMethod"); vector inlinedLoops; - VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), inlinedLoops); + VMMethod* method = GetUniverse()->NewMethod( + methodSymbol, 0, 0, 0, 0, new LexicalScope(nullptr, {}, {}), + inlinedLoops); - VMBlock* block = GetUniverse()->NewBlock(method, - GetUniverse()->GetInterpreter()->GetFrame(), - method->GetNumberOfArguments()); + VMBlock* block = GetUniverse()->NewBlock( + method, GetUniverse()->GetInterpreter()->GetFrame(), + method->GetNumberOfArguments()); TEST_WB_CALLED("VMBlock failed to call writeBarrier when creating", block, - block->GetClass()); + block->GetClass()); TEST_WB_CALLED("VMBlock failed to call writeBarrier when creating", block, - block->GetMethod()); + block->GetMethod()); TEST_WB_CALLED("VMBlock failed to call writeBarrier when creating", block, - block->GetContext()); + block->GetContext()); } void WriteBarrierTest::testWriteFrame() { if (!DEBUG) { - CPPUNIT_FAIL("WriteBarrier tests only work in DEBUG builds for speed reasons"); + CPPUNIT_FAIL( + "WriteBarrier tests only work in DEBUG builds for speed reasons"); } // reset set... GetHeap()->writeBarrierCalledOn.clear(); - VMFrame* frame = GetUniverse()->GetInterpreter()->GetFrame()->CloneForMovingGC(); + VMFrame* frame = + GetUniverse()->GetInterpreter()->GetFrame()->CloneForMovingGC(); frame->SetContext(frame->CloneForMovingGC()); frame->SetPreviousFrame(GetUniverse()->GetInterpreter()->GetFrame()); - TEST_WB_CALLED("VMFrame failed to call writeBarrier on SetPreviousFrame", frame, GetUniverse()->GetInterpreter()->GetFrame()); + TEST_WB_CALLED("VMFrame failed to call writeBarrier on SetPreviousFrame", + frame, GetUniverse()->GetInterpreter()->GetFrame()); frame->SetContext(frame->GetContext()->CloneForMovingGC()); - TEST_WB_CALLED("VMFrame failed to call writeBarrier on SetContext", frame, frame->GetContext()); + TEST_WB_CALLED("VMFrame failed to call writeBarrier on SetContext", frame, + frame->GetContext()); frame->ClearPreviousFrame(); - TEST_WB_CALLED("VMFrame failed to call writeBarrier on ClearPreviousFrame", frame, load_ptr(nilObject)); + TEST_WB_CALLED("VMFrame failed to call writeBarrier on ClearPreviousFrame", + frame, load_ptr(nilObject)); } void WriteBarrierTest::testWriteMethod() { if (!DEBUG) { - CPPUNIT_FAIL("WriteBarrier tests only work in DEBUG builds for speed reasons"); + CPPUNIT_FAIL( + "WriteBarrier tests only work in DEBUG builds for speed reasons"); } // reset set... GetHeap()->writeBarrierCalledOn.clear(); - VMMethod* method = GetUniverse()->GetInterpreter()->GetFrame()->GetMethod()->CloneForMovingGC(); + VMMethod* method = GetUniverse() + ->GetInterpreter() + ->GetFrame() + ->GetMethod() + ->CloneForMovingGC(); method->SetHolder(load_ptr(integerClass)); - TEST_WB_CALLED("VMMethod failed to call writeBarrier on SetHolder", method, load_ptr(integerClass)); + TEST_WB_CALLED("VMMethod failed to call writeBarrier on SetHolder", method, + load_ptr(integerClass)); } void WriteBarrierTest::testWriteEvaluationPrimitive() { if (!DEBUG) { - CPPUNIT_FAIL("WriteBarrier tests only work in DEBUG builds for speed reasons"); + CPPUNIT_FAIL( + "WriteBarrier tests only work in DEBUG builds for speed reasons"); } - //reset set... + // reset set... GetHeap()->writeBarrierCalledOn.clear(); - VMEvaluationPrimitive* evPrim = new (GetHeap(), 0) VMEvaluationPrimitive(1); - TEST_WB_CALLED("VMEvaluationPrimitive failed to call writeBarrier when creating", evPrim, evPrim->GetClass()); + VMEvaluationPrimitive* evPrim = + new (GetHeap(), 0) VMEvaluationPrimitive(1); + TEST_WB_CALLED( + "VMEvaluationPrimitive failed to call writeBarrier when creating", + evPrim, evPrim->GetClass()); } void WriteBarrierTest::testWriteClass() { if (!DEBUG) { - CPPUNIT_FAIL("WriteBarrier tests only work in DEBUG builds for speed reasons"); + CPPUNIT_FAIL( + "WriteBarrier tests only work in DEBUG builds for speed reasons"); } - //reset set... + // reset set... GetHeap()->writeBarrierCalledOn.clear(); VMClass* cl = load_ptr(integerClass)->CloneForMovingGC(); - //now test all methods that change members + // now test all methods that change members cl->SetSuperClass(load_ptr(integerClass)); TEST_WB_CALLED("VMClass failed to call writeBarrier on SetSuperClass", cl, - load_ptr(integerClass)); + load_ptr(integerClass)); VMSymbol* newName = NewSymbol("andererName"); cl->SetName(newName); TEST_WB_CALLED("VMClass failed to call writeBarrier on SetName", cl, - newName); + newName); VMArray* newInstFields = cl->GetInstanceFields()->CloneForMovingGC(); cl->SetInstanceFields(newInstFields); - TEST_WB_CALLED("VMClass failed to call writeBarrier on SetInstanceFields", cl, - newName); - VMArray* newInstInvokables = cl->GetInstanceInvokables()->CloneForMovingGC(); + TEST_WB_CALLED("VMClass failed to call writeBarrier on SetInstanceFields", + cl, newName); + VMArray* newInstInvokables = + cl->GetInstanceInvokables()->CloneForMovingGC(); cl->SetInstanceInvokables(newInstInvokables); - TEST_WB_CALLED("VMClass failed to call writeBarrier on SetInstanceInvokables", cl, - newName); + TEST_WB_CALLED( + "VMClass failed to call writeBarrier on SetInstanceInvokables", cl, + newName); } #endif diff --git a/src/unitTests/WriteBarrierTest.h b/src/unitTests/WriteBarrierTest.h index 7e0ff6c8..d99e7dd6 100644 --- a/src/unitTests/WriteBarrierTest.h +++ b/src/unitTests/WriteBarrierTest.h @@ -6,21 +6,19 @@ using namespace std; -class WriteBarrierTest: public CPPUNIT_NS::TestCase { - - CPPUNIT_TEST_SUITE (WriteBarrierTest); - CPPUNIT_TEST (testWriteArray); - CPPUNIT_TEST (testWriteClass); - CPPUNIT_TEST (testWriteBlock); - CPPUNIT_TEST (testWriteFrame); - CPPUNIT_TEST (testWriteEvaluationPrimitive); - CPPUNIT_TEST (testWriteMethod);CPPUNIT_TEST_SUITE_END(); +class WriteBarrierTest : public CPPUNIT_NS::TestCase { + CPPUNIT_TEST_SUITE(WriteBarrierTest); + CPPUNIT_TEST(testWriteArray); + CPPUNIT_TEST(testWriteClass); + CPPUNIT_TEST(testWriteBlock); + CPPUNIT_TEST(testWriteFrame); + CPPUNIT_TEST(testWriteEvaluationPrimitive); + CPPUNIT_TEST(testWriteMethod); + CPPUNIT_TEST_SUITE_END(); public: - inline void setUp(void) { - } - inline void tearDown(void) { - } + inline void setUp(void) {} + inline void tearDown(void) {} private: void testWriteArray(); @@ -29,5 +27,4 @@ class WriteBarrierTest: public CPPUNIT_NS::TestCase { void testWriteFrame(); void testWriteMethod(); void testWriteEvaluationPrimitive(); - }; diff --git a/src/unitTests/main.cpp b/src/unitTests/main.cpp index 529e8870..cdeb15c0 100644 --- a/src/unitTests/main.cpp +++ b/src/unitTests/main.cpp @@ -5,8 +5,6 @@ * Author: christian */ -#include - #include #include #include @@ -15,6 +13,7 @@ #include #include #include +#include #include "../misc/defs.h" #include "../vm/Universe.h" @@ -23,19 +22,19 @@ #include "CloneObjectsTest.h" #include "WalkObjectsTest.h" -#if GC_TYPE==GENERATIONAL -#include "WriteBarrierTest.h" +#if GC_TYPE == GENERATIONAL + #include "WriteBarrierTest.h" #endif -CPPUNIT_TEST_SUITE_REGISTRATION (WalkObjectsTest); -CPPUNIT_TEST_SUITE_REGISTRATION (CloneObjectsTest); -#if GC_TYPE==GENERATIONAL +CPPUNIT_TEST_SUITE_REGISTRATION(WalkObjectsTest); +CPPUNIT_TEST_SUITE_REGISTRATION(CloneObjectsTest); +#if GC_TYPE == GENERATIONAL CPPUNIT_TEST_SUITE_REGISTRATION(WriteBarrierTest); #endif -CPPUNIT_TEST_SUITE_REGISTRATION (BytecodeGenerationTest); -CPPUNIT_TEST_SUITE_REGISTRATION (BasicInterpreterTests); +CPPUNIT_TEST_SUITE_REGISTRATION(BytecodeGenerationTest); +CPPUNIT_TEST_SUITE_REGISTRATION(BasicInterpreterTests); -int main(int ac, char **av) { +int main(int ac, char** av) { Universe::Start(ac, av); //--- Create the event manager and test controller diff --git a/src/vm/Globals.cpp b/src/vm/Globals.cpp index ab57f9ce..c95d46f2 100644 --- a/src/vm/Globals.cpp +++ b/src/vm/Globals.cpp @@ -1,6 +1,7 @@ -#include "../vmobjects/ObjectFormats.h" #include "Globals.h" +#include "../vmobjects/ObjectFormats.h" + GCObject* nilObject; GCObject* trueObject; GCObject* falseObject; diff --git a/src/vm/IsValidObject.cpp b/src/vm/IsValidObject.cpp index 1320b370..5819f1e7 100644 --- a/src/vm/IsValidObject.cpp +++ b/src/vm/IsValidObject.cpp @@ -1,3 +1,5 @@ +#include "IsValidObject.h" + #include #include "../memory/Heap.h" @@ -6,7 +8,7 @@ #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMArray.h" #include "../vmobjects/VMBlock.h" -#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vmobjects/VMClass.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "../vmobjects/VMDouble.h" #include "../vmobjects/VMEvaluationPrimitive.h" #include "../vmobjects/VMFrame.h" @@ -15,7 +17,6 @@ #include "../vmobjects/VMString.h" #include "../vmobjects/VMSymbol.h" #include "Globals.h" -#include "IsValidObject.h" void* vt_array; void* vt_block; @@ -35,51 +36,47 @@ bool IsValidObject(vm_oop_t obj) { return true; } - if (obj == nullptr) + if (obj == nullptr) { return true; + } - if (IS_TAGGED(obj)) + if (IS_TAGGED(obj)) { return true; + } - if (vt_symbol == nullptr) // initialization not yet completed + if (vt_symbol == nullptr) { // initialization not yet completed return true; + } if (obj == INVALID_VM_POINTER) { - assert(obj == INVALID_VM_POINTER && "Expected pointer to not be marker for invalid pointers."); + assert(obj == INVALID_VM_POINTER && + "Expected pointer to not be marker for invalid pointers."); return false; } - void* vt = *(void**) obj; - bool b = vt == vt_array || - vt == vt_block || - vt == vt_class || - vt == vt_double || - vt == vt_eval_primitive || - vt == vt_frame || - vt == vt_integer || - vt == vt_method || - vt == vt_object || - vt == vt_primitive || - vt == vt_string || - vt == vt_symbol; + void* vt = *(void**)obj; + bool b = vt == vt_array || vt == vt_block || vt == vt_class || + vt == vt_double || vt == vt_eval_primitive || vt == vt_frame || + vt == vt_integer || vt == vt_method || vt == vt_object || + vt == vt_primitive || vt == vt_string || vt == vt_symbol; if (!b) { assert(b && "Expected vtable to be one of the known ones."); return false; } -# if GC_TYPE == COPYING || GC_TYPE == DEBUG_COPYING +#if GC_TYPE == COPYING || GC_TYPE == DEBUG_COPYING if (AS_OBJ(obj)->GetGCField() != 0) { // this is a properly forwarded object return true; } -# elif GC_TYPE == GENERATIONAL +#elif GC_TYPE == GENERATIONAL if (!(AS_OBJ(obj)->GetGCField() & MASK_OBJECT_IS_OLD)) { if (AS_OBJ(obj)->GetGCField() != 0) { // this is a properly forwarded object return true; } } -# endif +#endif b = !AS_OBJ(obj)->IsMarkedInvalid(); assert(b && "Expected object not to be marked as invalid."); @@ -87,22 +84,22 @@ bool IsValidObject(vm_oop_t obj) { } void set_vt_to_null() { - vt_array = nullptr; - vt_block = nullptr; - vt_class = nullptr; - vt_double = nullptr; + vt_array = nullptr; + vt_block = nullptr; + vt_class = nullptr; + vt_double = nullptr; vt_eval_primitive = nullptr; - vt_frame = nullptr; - vt_integer = nullptr; - vt_method = nullptr; - vt_object = nullptr; - vt_primitive = nullptr; - vt_string = nullptr; - vt_symbol = nullptr; + vt_frame = nullptr; + vt_integer = nullptr; + vt_method = nullptr; + vt_object = nullptr; + vt_primitive = nullptr; + vt_string = nullptr; + vt_symbol = nullptr; } static void* get_vtable(AbstractVMObject* obj) { - return *(void**) obj; + return *(void**)obj; } bool IsVMInteger(vm_oop_t obj) { @@ -116,35 +113,39 @@ bool IsVMSymbol(vm_oop_t obj) { } void obtain_vtables_of_known_classes(VMSymbol* className) { - // These objects are allocated on the heap. So, they will get GC'ed soon enough. - VMArray* arr = new (GetHeap(), 0) VMArray(0, 0); - vt_array = get_vtable(arr); + // These objects are allocated on the heap. So, they will get GC'ed soon + // enough. + VMArray* arr = new (GetHeap(), 0) VMArray(0, 0); + vt_array = get_vtable(arr); VMBlock* blck = new (GetHeap(), 0) VMBlock(nullptr, nullptr); - vt_block = get_vtable(blck); + vt_block = get_vtable(blck); - vt_class = get_vtable(load_ptr(symbolClass)); + vt_class = get_vtable(load_ptr(symbolClass)); VMDouble* dbl = new (GetHeap(), 0) VMDouble(0.0); - vt_double = get_vtable(dbl); + vt_double = get_vtable(dbl); - VMEvaluationPrimitive* ev = new (GetHeap(), 0) VMEvaluationPrimitive(1); + VMEvaluationPrimitive* ev = + new (GetHeap(), 0) VMEvaluationPrimitive(1); vt_eval_primitive = get_vtable(ev); - VMFrame* frm = new (GetHeap(), 0) VMFrame(0, 0); - vt_frame = get_vtable(frm); + VMFrame* frm = new (GetHeap(), 0) VMFrame(0, 0); + vt_frame = get_vtable(frm); - VMInteger* i = new (GetHeap(), 0) VMInteger(0); - vt_integer = get_vtable(i); + VMInteger* i = new (GetHeap(), 0) VMInteger(0); + vt_integer = get_vtable(i); - VMMethod* mth = new (GetHeap(), 0) VMMethod(nullptr, 0, 0, 0, 0, nullptr, nullptr); - vt_method = get_vtable(mth); - vt_object = get_vtable(load_ptr(nilObject)); + VMMethod* mth = new (GetHeap(), 0) + VMMethod(nullptr, 0, 0, 0, 0, nullptr, nullptr); + vt_method = get_vtable(mth); + vt_object = get_vtable(load_ptr(nilObject)); VMPrimitive* prm = new (GetHeap(), 0) VMPrimitive(className); - vt_primitive = get_vtable(prm); + vt_primitive = get_vtable(prm); - VMString* str = new (GetHeap(), PADDED_SIZE(1)) VMString(0, nullptr); - vt_string = get_vtable(str); - vt_symbol = get_vtable(className); + VMString* str = + new (GetHeap(), PADDED_SIZE(1)) VMString(0, nullptr); + vt_string = get_vtable(str); + vt_symbol = get_vtable(className); } diff --git a/src/vm/IsValidObject.h b/src/vm/IsValidObject.h index 7d4da42f..d6a8c5de 100644 --- a/src/vm/IsValidObject.h +++ b/src/vm/IsValidObject.h @@ -11,4 +11,3 @@ bool IsVMSymbol(vm_oop_t obj); void set_vt_to_null(); void obtain_vtables_of_known_classes(VMSymbol* className); - diff --git a/src/vm/LogAllocation.cpp b/src/vm/LogAllocation.cpp index 7ec01ee8..ff88541a 100644 --- a/src/vm/LogAllocation.cpp +++ b/src/vm/LogAllocation.cpp @@ -1,15 +1,15 @@ #ifdef GENERATE_ALLOCATION_STATISTICS -#include -#include + #include "LogAllocation.h" -#include "LogAllocation.h" + #include + #include std::map allocationStats; #endif void InitializeAllocationLog() { #ifdef GENERATE_ALLOCATION_STATISTICS - allocationStats["VMArray"] = {0,0}; + allocationStats["VMArray"] = {0, 0}; #endif } @@ -20,10 +20,10 @@ void OutputAllocationLogFile() { fstream file_alloc_stats(file_name_allocation.c_str(), ios::out); map::iterator iter; - for (iter = allocationStats.begin(); iter != allocationStats.end(); iter++) - { - file_alloc_stats << iter->first << ", " << iter->second.noObjects << ", " << iter->second.sizeObjects << std::endl; + for (iter = allocationStats.begin(); iter != allocationStats.end(); + iter++) { + file_alloc_stats << iter->first << ", " << iter->second.noObjects + << ", " << iter->second.sizeObjects << std::endl; } #endif } - diff --git a/src/vm/LogAllocation.h b/src/vm/LogAllocation.h index e0aa2d05..81dbc37f 100644 --- a/src/vm/LogAllocation.h +++ b/src/vm/LogAllocation.h @@ -1,11 +1,20 @@ #pragma once #ifdef GENERATE_ALLOCATION_STATISTICS -struct alloc_data {long noObjects; long sizeObjects;}; +struct alloc_data { + long noObjects; + long sizeObjects; +}; std::map allocationStats; -#define LOG_ALLOCATION(TYPE,SIZE) {struct alloc_data tmp=allocationStats[TYPE];tmp.noObjects++;tmp.sizeObjects+=(SIZE);allocationStats[TYPE]=tmp;} + #define LOG_ALLOCATION(TYPE, SIZE) \ + { \ + struct alloc_data tmp = allocationStats[TYPE]; \ + tmp.noObjects++; \ + tmp.sizeObjects += (SIZE); \ + allocationStats[TYPE] = tmp; \ + } #else -#define LOG_ALLOCATION(TYPE,SIZE) + #define LOG_ALLOCATION(TYPE, SIZE) #endif void InitializeAllocationLog(); diff --git a/src/vm/Print.cpp b/src/vm/Print.cpp index 392df865..7d693c43 100644 --- a/src/vm/Print.cpp +++ b/src/vm/Print.cpp @@ -1,8 +1,9 @@ +#include "Print.h" + #include #include #include "../misc/defs.h" -#include "Print.h" using namespace std; diff --git a/src/vm/Print.h b/src/vm/Print.h index fa398187..ce0278ca 100644 --- a/src/vm/Print.h +++ b/src/vm/Print.h @@ -4,4 +4,3 @@ void Print(StdString str); void ErrorPrint(StdString str); - diff --git a/src/vm/Shell.cpp b/src/vm/Shell.cpp index 0db3620c..5d6d1f43 100644 --- a/src/vm/Shell.cpp +++ b/src/vm/Shell.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Shell.h" + #include #include #include @@ -35,7 +37,6 @@ #include "../vmobjects/VMInvokable.h" #include "../vmobjects/VMMethod.h" #include "Globals.h" -#include "Shell.h" #include "Symbols.h" #include "Universe.h" @@ -71,7 +72,7 @@ void Shell::Start(Interpreter* interp) { long bytecodeIndex, counter = 0; VMFrame* currentFrame; VMClass* runClass; - vm_oop_t it = load_ptr(nilObject); // last evaluation result. + vm_oop_t it = load_ptr(nilObject); // last evaluation result. cout << "SOM Shell. Type \"" << QUIT_CMD << "\" to exit.\n"; @@ -96,7 +97,9 @@ void Shell::Start(Interpreter* interp) { inp = std::string(inbuf); - if (inp.length() == 0) continue; + if (inp.length() == 0) { + continue; + } // Generate a temporary class with a run method stringstream ss; @@ -106,7 +109,7 @@ void Shell::Start(Interpreter* interp) { ++counter; runClass = GetUniverse()->LoadShellClass(statement); // Compile and load the newly generated class - if(runClass == nullptr) { + if (runClass == nullptr) { cout << "can't compile statement."; continue; } @@ -141,4 +144,3 @@ void Shell::Start(Interpreter* interp) { it = currentFrame->Pop(); } } - diff --git a/src/vm/Shell.h b/src/vm/Shell.h index 3e453c82..bbff65c3 100644 --- a/src/vm/Shell.h +++ b/src/vm/Shell.h @@ -26,22 +26,18 @@ THE SOFTWARE. */ +#include "../interpreter/Interpreter.h" #include "../vmobjects/ObjectFormats.h" class Shell { public: Shell(); - Shell (VMMethod*); + Shell(VMMethod*); ~Shell(); - void SetBootstrapMethod(VMMethod* bsm) { - bootstrapMethod = bsm; - } - ; - VMMethod* GetBootstrapMethod() const { - return bootstrapMethod; - } - ; + void SetBootstrapMethod(VMMethod* bsm) { bootstrapMethod = bsm; }; + VMMethod* GetBootstrapMethod() const { return bootstrapMethod; }; void Start(Interpreter*); + private: VMMethod* bootstrapMethod; }; diff --git a/src/vm/Symbols.cpp b/src/vm/Symbols.cpp index efc70d40..aa8fcaa5 100644 --- a/src/vm/Symbols.cpp +++ b/src/vm/Symbols.cpp @@ -1,3 +1,5 @@ +#include "Symbols.h" + #include #include #include @@ -7,7 +9,6 @@ #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMSymbol.h" #include "LogAllocation.h" -#include "Symbols.h" map symbolsMap; @@ -19,7 +20,8 @@ GCSymbol* symbolIfTrue; GCSymbol* symbolIfFalse; VMSymbol* NewSymbol(const size_t length, const char* str) { - VMSymbol* result = new (GetHeap(), PADDED_SIZE(length)) VMSymbol(length, str); + VMSymbol* result = + new (GetHeap(), PADDED_SIZE(length)) VMSymbol(length, str); symbolsMap[StdString(str, length)] = store_root(result); LOG_ALLOCATION("VMSymbol", result->GetObjectSize()); @@ -31,32 +33,31 @@ VMSymbol* NewSymbol(const std::string& str) { } VMSymbol* SymbolFor(const std::string& str) { - map::iterator it = symbolsMap.find(str); + map::iterator it = symbolsMap.find(str); return (it == symbolsMap.end()) ? NewSymbol(str) : load_ptr(it->second); } void InitializeSymbols() { - symbolSelf = store_root(SymbolFor("self")); - symbolSuper = store_root(SymbolFor("super")); + symbolSelf = store_root(SymbolFor("self")); + symbolSuper = store_root(SymbolFor("super")); symbolBlockSelf = store_root(SymbolFor("$blockSelf")); - symbolIfTrue = store_root(SymbolFor("ifTrue:")); + symbolIfTrue = store_root(SymbolFor("ifTrue:")); symbolIfFalse = store_root(SymbolFor("ifFalse:")); } void WalkSymbols(walk_heap_fn walk) { // walk all entries in symbols map map::iterator symbolIter; - for (symbolIter = symbolsMap.begin(); - symbolIter != symbolsMap.end(); + for (symbolIter = symbolsMap.begin(); symbolIter != symbolsMap.end(); symbolIter++) { - //insert overwrites old entries inside the internal map + // insert overwrites old entries inside the internal map symbolIter->second = static_cast(walk(symbolIter->second)); } // reassign symbols - symbolSelf = static_cast(walk(symbolSelf)); - symbolSuper = static_cast(walk(symbolSuper)); + symbolSelf = static_cast(walk(symbolSelf)); + symbolSuper = static_cast(walk(symbolSuper)); symbolBlockSelf = static_cast(walk(symbolBlockSelf)); - symbolIfTrue = static_cast(walk(symbolIfTrue)); + symbolIfTrue = static_cast(walk(symbolIfTrue)); symbolIfFalse = static_cast(walk(symbolIfFalse)); } diff --git a/src/vm/Universe.cpp b/src/vm/Universe.cpp index 26fb7026..5b241c4f 100644 --- a/src/vm/Universe.cpp +++ b/src/vm/Universe.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "Universe.h" + #include #include #include @@ -63,7 +65,6 @@ #include "Print.h" #include "Shell.h" #include "Symbols.h" -#include "Universe.h" #if CACHE_INTEGER gc_oop_t prebuildInts[INT_CACHE_MAX_VALUE - INT_CACHE_MIN_VALUE + 1]; @@ -82,27 +83,27 @@ std::string bm_name; map integerHist; - void Universe::Start(long argc, char** argv) { BasicInit(); theUniverse->initialize(argc, argv); } void Universe::BasicInit() { - assert(Bytecode::BytecodeDefinitionsAreConsistent()); - theUniverse = new Universe(); + assert(Bytecode::BytecodeDefinitionsAreConsistent()); + theUniverse = new Universe(); } - - __attribute__((noreturn)) void Universe::Quit(long err) { - ErrorPrint("Time spent in GC: [" + to_string(Timer::GCTimer->GetTotalTime()) + "] msec\n"); + ErrorPrint("Time spent in GC: [" + + to_string(Timer::GCTimer->GetTotalTime()) + "] msec\n"); #ifdef GENERATE_INTEGER_HISTOGRAM std::string file_name_hist = std::string(bm_name); file_name_hist.append("_integer_histogram.csv"); fstream hist_csv(file_name_hist.c_str(), ios::out); - for (map::iterator it = integerHist.begin(); it != integerHist.end(); it++) { + for (map::iterator it = integerHist.begin(); + it != integerHist.end(); + it++) { hist_csv << it->first << ", " << it->second << endl; } #endif @@ -111,24 +112,38 @@ __attribute__((noreturn)) void Universe::Quit(long err) { std::string file_name_receivers = std::string(bm_name); file_name_receivers.append("_receivers.csv"); fstream receivers(file_name_receivers.c_str(), ios::out); - for (map::iterator it = theUniverse->receiverTypes.begin(); it != theUniverse->receiverTypes.end(); it++) - receivers << it->first << ", " << it->second << endl; + for (map::iterator it = theUniverse->receiverTypes.begin(); + it != theUniverse->receiverTypes.end(); + it++) { + receivers << it->first << ", " << it->second << endl; + } std::string file_name_send_types = std::string(bm_name); file_name_send_types.append("_send_types.csv"); fstream send_stat(file_name_send_types.c_str(), ios::out); - send_stat << "#name, percentage_primitive_calls, no_primitive_calls, no_non_primitive_calls" << endl; - for (map::iterator it = theUniverse->callStats.begin(); it != theUniverse->callStats.end(); it++) - send_stat << it->first << ", " << setiosflags(ios::fixed) << setprecision(2) << (double)(it->second.noPrimitiveCalls) / (double)(it->second.noCalls) << - ", " << it->second.noPrimitiveCalls << ", " << it->second.noCalls - it->second.noPrimitiveCalls << endl; + send_stat << "#name, percentage_primitive_calls, no_primitive_calls, " + "no_non_primitive_calls" + << endl; + for (map::iterator it = + theUniverse->callStats.begin(); + it != theUniverse->callStats.end(); + it++) { + send_stat << it->first << ", " << setiosflags(ios::fixed) + << setprecision(2) + << (double)(it->second.noPrimitiveCalls) / + (double)(it->second.noCalls) + << ", " << it->second.noPrimitiveCalls << ", " + << it->second.noCalls - it->second.noPrimitiveCalls << endl; + } #endif OutputAllocationLogFile(); - if (theUniverse) + if (theUniverse) { delete (theUniverse); + } - exit((int) err); + exit((int)err); } __attribute__((noreturn)) void Universe::ErrorExit(const char* err) { @@ -139,13 +154,13 @@ __attribute__((noreturn)) void Universe::ErrorExit(const char* err) { vector Universe::handleArguments(long argc, char** argv) { vector vmArgs = vector(); dumpBytecodes = 0; - gcVerbosity = 0; + gcVerbosity = 0; for (long i = 1; i < argc; ++i) { - if (strncmp(argv[i], "-cp", 3) == 0) { - if ((argc == i + 1) || classPath.size() > 0) + if ((argc == i + 1) || classPath.size() > 0) { printUsageAndExit(argv[0]); + } setupClassPath(StdString(argv[++i])); } else if (strncmp(argv[i], "-d", 2) == 0) { ++dumpBytecodes; @@ -155,15 +170,17 @@ vector Universe::handleArguments(long argc, char** argv) { long heap_size = 0; char unit[3]; if (sscanf(argv[i], "-H%ld%2s", &heap_size, unit) == 2) { - if (strcmp(unit, "KB") == 0) + if (strcmp(unit, "KB") == 0) { heapSize = heap_size * 1024; - else if (strcmp(unit, "MB") == 0) + } else if (strcmp(unit, "MB") == 0) { heapSize = heap_size * 1024 * 1024; - } else + } + } else { printUsageAndExit(argv[0]); + } - } else if ((strncmp(argv[i], "-h", 2) == 0) - || (strncmp(argv[i], "--help", 6) == 0)) { + } else if ((strncmp(argv[i], "-h", 2) == 0) || + (strncmp(argv[i], "--help", 6) == 0)) { printUsageAndExit(argv[0]); } else { vector extPathTokens = vector(2); @@ -171,12 +188,13 @@ vector Universe::handleArguments(long argc, char** argv) { if (getClassPathExt(extPathTokens, tmpString) == ERR_SUCCESS) { addClassPath(extPathTokens[0]); } - //Different from CSOM!!!: - //In CSOM there is an else, where the original filename is pushed into the vm_args. - //But unlike the class name in extPathTokens (extPathTokens[1]) that could - //still have the .som suffix though. - //So in SOM++ getClassPathExt will strip the suffix and add it to extPathTokens - //even if there is no new class path present. So we can in any case do the following: + // Different from CSOM!!!: + // In CSOM there is an else, where the original filename is pushed + // into the vm_args. But unlike the class name in extPathTokens + // (extPathTokens[1]) that could still have the .som suffix though. + // So in SOM++ getClassPathExt will strip the suffix and add it to + // extPathTokens even if there is no new class path present. So we + // can in any case do the following: vmArgs.push_back(extPathTokens[1]); } } @@ -186,28 +204,29 @@ vector Universe::handleArguments(long argc, char** argv) { } long Universe::getClassPathExt(vector& tokens, - const StdString& arg) const { + const StdString& arg) const { #define EXT_TOKENS 2 long result = ERR_SUCCESS; size_t fpIndex = arg.find_last_of(fileSeparator); size_t ssepIndex = arg.find(".som"); - if (fpIndex == StdString::npos) { //no new path - //different from CSOM (see also HandleArguments): - //we still want to strip the suffix from the filename, so - //we set the start to -1, in order to start the substring - //from character 0. npos is -1 too, but this is to make sure + if (fpIndex == StdString::npos) { // no new path + // different from CSOM (see also HandleArguments): + // we still want to strip the suffix from the filename, so + // we set the start to -1, in order to start the substring + // from character 0. npos is -1 too, but this is to make sure fpIndex = -1; - //instead of returning here directly, we have to remember that - //there is no new class path and return it later + // instead of returning here directly, we have to remember that + // there is no new class path and return it later result = ERR_FAIL; - } else + } else { tokens[0] = arg.substr(0, fpIndex); + } - //adding filename (minus ".som" if present) to second slot - ssepIndex = - ((ssepIndex != StdString::npos) && (ssepIndex > fpIndex)) ? - (ssepIndex - 1) : arg.length(); + // adding filename (minus ".som" if present) to second slot + ssepIndex = ((ssepIndex != StdString::npos) && (ssepIndex > fpIndex)) + ? (ssepIndex - 1) + : arg.length(); tokens[1] = arg.substr(fpIndex + 1, ssepIndex - (fpIndex)); return result; } @@ -255,10 +274,13 @@ Universe::Universe() { interpreter = nullptr; } -VMMethod* Universe::createBootstrapMethod(VMClass* holder, long numArgsOfMsgSend) { +VMMethod* Universe::createBootstrapMethod(VMClass* holder, + long numArgsOfMsgSend) { vector inlinedLoops; LexicalScope* bootStrapScope = new LexicalScope(nullptr, {}, {}); - VMMethod* bootstrapMethod = NewMethod(SymbolFor("bootstrap"), 1, 0, 0, numArgsOfMsgSend, bootStrapScope, inlinedLoops); + VMMethod* bootstrapMethod = + NewMethod(SymbolFor("bootstrap"), 1, 0, 0, numArgsOfMsgSend, + bootStrapScope, inlinedLoops); bootstrapMethod->SetBytecode(0, BC_HALT); bootstrapMethod->SetHolder(holder); @@ -266,55 +288,56 @@ VMMethod* Universe::createBootstrapMethod(VMClass* holder, long numArgsOfMsgSend } vm_oop_t Universe::interpret(StdString className, StdString methodName) { - // This method assumes that SOM++ was already initialized by executing a - // Hello World program as part of the unittest main. + // This method assumes that SOM++ was already initialized by executing a + // Hello World program as part of the unittest main. - bm_name = "BasicInterpreterTests"; + bm_name = "BasicInterpreterTests"; - interpreter = new Interpreter(); + interpreter = new Interpreter(); - VMSymbol* classNameSym = SymbolFor(className); - VMClass* clazz = LoadClass(classNameSym); + VMSymbol* classNameSym = SymbolFor(className); + VMClass* clazz = LoadClass(classNameSym); - // Lookup the method to be executed on the class - VMMethod* initialize = - (VMMethod*) clazz->GetClass()->LookupInvokable(SymbolFor(methodName)); + // Lookup the method to be executed on the class + VMMethod* initialize = + (VMMethod*)clazz->GetClass()->LookupInvokable(SymbolFor(methodName)); - if (initialize == nullptr) { - ErrorPrint("Lookup of " + className + ">>#" + methodName + " failed"); - return nullptr; - } + if (initialize == nullptr) { + ErrorPrint("Lookup of " + className + ">>#" + methodName + " failed"); + return nullptr; + } - return interpretMethod(clazz, initialize, nullptr); + return interpretMethod(clazz, initialize, nullptr); } -vm_oop_t Universe::interpretMethod(VMObject* receiver, VMInvokable* initialize, VMArray* argumentsArray) { - /* only trace bootstrap if the number of cmd-line "-d"s is > 2 */ - short trace = 2 - dumpBytecodes; - if (!(trace > 0)) { - dumpBytecodes = 1; - } +vm_oop_t Universe::interpretMethod(VMObject* receiver, VMInvokable* initialize, + VMArray* argumentsArray) { + /* only trace bootstrap if the number of cmd-line "-d"s is > 2 */ + short trace = 2 - dumpBytecodes; + if (!(trace > 0)) { + dumpBytecodes = 1; + } - VMMethod* bootstrapMethod = createBootstrapMethod(load_ptr(systemClass), 2); + VMMethod* bootstrapMethod = createBootstrapMethod(load_ptr(systemClass), 2); - VMFrame* bootstrapFrame = interpreter->PushNewFrame(bootstrapMethod); - bootstrapFrame->Push(receiver); + VMFrame* bootstrapFrame = interpreter->PushNewFrame(bootstrapMethod); + bootstrapFrame->Push(receiver); - if (argumentsArray != nullptr) { - bootstrapFrame->Push(argumentsArray); - } + if (argumentsArray != nullptr) { + bootstrapFrame->Push(argumentsArray); + } - initialize->Invoke(interpreter, bootstrapFrame); + initialize->Invoke(interpreter, bootstrapFrame); - // reset "-d" indicator - if (!(trace > 0)) { - dumpBytecodes = 2 - trace; - } + // reset "-d" indicator + if (!(trace > 0)) { + dumpBytecodes = 2 - trace; + } - if (dumpBytecodes > 1) { - return interpreter->StartAndPrintBytecodes(); - } - return interpreter->Start(); + if (dumpBytecodes > 1) { + return interpreter->StartAndPrintBytecodes(); + } + return interpreter->Start(); } void Universe::initialize(long _argc, char** _argv) { @@ -325,8 +348,9 @@ void Universe::initialize(long _argc, char** _argv) { vector argv = handleArguments(_argc, _argv); // remember file that was executed (for writing statistics) - if (argv.size() > 0) + if (argv.size() > 0) { bm_name = argv[0]; + } Heap::InitializeHeap(heapSize); @@ -335,41 +359,42 @@ void Universe::initialize(long _argc, char** _argv) { #if CACHE_INTEGER // create prebuilt integers for (long it = INT_CACHE_MIN_VALUE; it <= INT_CACHE_MAX_VALUE; ++it) { - prebuildInts[(unsigned long)(it - INT_CACHE_MIN_VALUE)] = store_root(new (GetHeap(), 0) VMInteger(it)); + prebuildInts[(unsigned long)(it - INT_CACHE_MIN_VALUE)] = + store_root(new (GetHeap(), 0) VMInteger(it)); } #endif VMObject* systemObject = InitializeGlobals(); if (argv.size() == 0) { - VMMethod* bootstrapMethod = createBootstrapMethod(load_ptr(systemClass), 2); + VMMethod* bootstrapMethod = + createBootstrapMethod(load_ptr(systemClass), 2); Shell* shell = new Shell(bootstrapMethod); shell->Start(interpreter); return; } - VMInvokable* initialize = load_ptr(systemClass)->LookupInvokable( - SymbolFor("initialize:")); + VMInvokable* initialize = + load_ptr(systemClass)->LookupInvokable(SymbolFor("initialize:")); VMArray* argumentsArray = NewArrayFromStrings(argv); interpretMethod(systemObject, initialize, argumentsArray); } Universe::~Universe() { - if (interpreter) + if (interpreter) { delete (interpreter); + } // check done inside Heap::DestroyHeap(); } - - VMObject* Universe::InitializeGlobals() { set_vt_to_null(); // - //allocate nil object + // allocate nil object // VMObject* nil = NewInstanceWithoutFields(); nilObject = store_root(nil); @@ -379,30 +404,37 @@ VMObject* Universe::InitializeGlobals() { metaClassClass = store_root(NewMetaclassClass()); - objectClass = store_root(NewSystemClass()); - nilClass = store_root(NewSystemClass()); - classClass = store_root(NewSystemClass()); - arrayClass = store_root(NewSystemClass()); - symbolClass = store_root(NewSystemClass()); - methodClass = store_root(NewSystemClass()); - integerClass = store_root(NewSystemClass()); - primitiveClass = store_root(NewSystemClass()); - stringClass = store_root(NewSystemClass()); - doubleClass = store_root(NewSystemClass()); + objectClass = store_root(NewSystemClass()); + nilClass = store_root(NewSystemClass()); + classClass = store_root(NewSystemClass()); + arrayClass = store_root(NewSystemClass()); + symbolClass = store_root(NewSystemClass()); + methodClass = store_root(NewSystemClass()); + integerClass = store_root(NewSystemClass()); + primitiveClass = store_root(NewSystemClass()); + stringClass = store_root(NewSystemClass()); + doubleClass = store_root(NewSystemClass()); nil->SetClass(load_ptr(nilClass)); - InitializeSystemClass(load_ptr(objectClass), nullptr, "Object"); - InitializeSystemClass(load_ptr(classClass), load_ptr(objectClass), "Class"); - InitializeSystemClass(load_ptr(metaClassClass), load_ptr(classClass), "Metaclass"); - InitializeSystemClass(load_ptr(nilClass), load_ptr(objectClass), "Nil"); - InitializeSystemClass(load_ptr(arrayClass), load_ptr(objectClass), "Array"); - InitializeSystemClass(load_ptr(methodClass), load_ptr(arrayClass), "Method"); - InitializeSystemClass(load_ptr(stringClass), load_ptr(objectClass), "String"); - InitializeSystemClass(load_ptr(symbolClass), load_ptr(stringClass), "Symbol"); - InitializeSystemClass(load_ptr(integerClass), load_ptr(objectClass), "Integer"); - InitializeSystemClass(load_ptr(primitiveClass), load_ptr(objectClass), "Primitive"); - InitializeSystemClass(load_ptr(doubleClass), load_ptr(objectClass), "Double"); + InitializeSystemClass(load_ptr(objectClass), nullptr, "Object"); + InitializeSystemClass(load_ptr(classClass), load_ptr(objectClass), "Class"); + InitializeSystemClass(load_ptr(metaClassClass), load_ptr(classClass), + "Metaclass"); + InitializeSystemClass(load_ptr(nilClass), load_ptr(objectClass), "Nil"); + InitializeSystemClass(load_ptr(arrayClass), load_ptr(objectClass), "Array"); + InitializeSystemClass(load_ptr(methodClass), load_ptr(arrayClass), + "Method"); + InitializeSystemClass(load_ptr(stringClass), load_ptr(objectClass), + "String"); + InitializeSystemClass(load_ptr(symbolClass), load_ptr(stringClass), + "Symbol"); + InitializeSystemClass(load_ptr(integerClass), load_ptr(objectClass), + "Integer"); + InitializeSystemClass(load_ptr(primitiveClass), load_ptr(objectClass), + "Primitive"); + InitializeSystemClass(load_ptr(doubleClass), load_ptr(objectClass), + "Double"); // Fix up objectClass load_ptr(objectClass)->SetSuperClass(nil); @@ -429,24 +461,23 @@ VMObject* Universe::InitializeGlobals() { blockClass = store_root(LoadClass(SymbolFor("Block"))); VMSymbol* trueClassName = SymbolFor("True"); - trueClass = store_root(LoadClass(trueClassName)); + trueClass = store_root(LoadClass(trueClassName)); load_ptr(trueObject)->SetClass(load_ptr(trueClass)); VMSymbol* falseClassName = SymbolFor("False"); - falseClass = store_root(LoadClass(falseClassName)); + falseClass = store_root(LoadClass(falseClassName)); load_ptr(falseObject)->SetClass(load_ptr(falseClass)); systemClass = store_root(LoadClass(SymbolFor("System"))); - VMObject* systemObject = NewInstance(load_ptr(systemClass)); - SetGlobal(SymbolFor("nil"), load_ptr(nilObject)); - SetGlobal(SymbolFor("true"), load_ptr(trueObject)); - SetGlobal(SymbolFor("false"), load_ptr(falseObject)); + SetGlobal(SymbolFor("nil"), load_ptr(nilObject)); + SetGlobal(SymbolFor("true"), load_ptr(trueObject)); + SetGlobal(SymbolFor("false"), load_ptr(falseObject)); SetGlobal(SymbolFor("system"), systemObject); SetGlobal(SymbolFor("System"), load_ptr(systemClass)); - SetGlobal(SymbolFor("Block"), load_ptr(blockClass)); + SetGlobal(SymbolFor("Block"), load_ptr(blockClass)); return systemObject; } @@ -463,9 +494,10 @@ VMClass* Universe::GetBlockClass() const { VMClass* Universe::GetBlockClassWithArgs(long numberOfArguments) { map::iterator it = - blockClassesByNoOfArgs.find(numberOfArguments); - if (it != blockClassesByNoOfArgs.end()) + blockClassesByNoOfArgs.find(numberOfArguments); + if (it != blockClassesByNoOfArgs.end()) { return load_ptr(it->second); + } Assert(numberOfArguments < 10); @@ -474,7 +506,8 @@ VMClass* Universe::GetBlockClassWithArgs(long numberOfArguments) { VMSymbol* name = SymbolFor(Str.str()); VMClass* result = LoadClassBasic(name, nullptr); - result->AddInstancePrimitive(new (GetHeap(), 0) VMEvaluationPrimitive(numberOfArguments)); + result->AddInstancePrimitive(new (GetHeap(), 0) + VMEvaluationPrimitive(numberOfArguments)); SetGlobal(name, result); blockClassesByNoOfArgs[numberOfArguments] = store_root(result); @@ -500,8 +533,8 @@ bool Universe::HasGlobal(VMSymbol* name) { } } -void Universe::InitializeSystemClass(VMClass* systemClass, -VMClass* superClass, const char* name) { +void Universe::InitializeSystemClass(VMClass* systemClass, VMClass* superClass, + const char* name) { StdString s_name(name); if (superClass != nullptr) { @@ -541,8 +574,8 @@ VMClass* Universe::LoadClass(VMSymbol* name) { result = LoadClassBasic(name, nullptr); if (!result) { - // we fail silently, it is not fatal that loading a class failed - return (VMClass*) nilObject; + // we fail silently, it is not fatal that loading a class failed + return (VMClass*)nilObject; } if (result->HasPrimitives() || result->GetClass()->HasPrimitives()) { @@ -559,8 +592,10 @@ VMClass* Universe::LoadClassBasic(VMSymbol* name, VMClass* systemClass) { VMClass* result; for (vector::iterator i = classPath.begin(); - i != classPath.end(); ++i) { - result = SourcecodeCompiler::CompileClass(*i, name->GetStdString(), systemClass); + i != classPath.end(); + ++i) { + result = SourcecodeCompiler::CompileClass(*i, name->GetStdString(), + systemClass); if (result) { if (dumpBytecodes) { Disassembler::Dump(result->GetClass()); @@ -574,8 +609,9 @@ VMClass* Universe::LoadClassBasic(VMSymbol* name, VMClass* systemClass) { VMClass* Universe::LoadShellClass(StdString& stmt) { VMClass* result = SourcecodeCompiler::CompileClassString(stmt, nullptr); - if(dumpBytecodes) + if (dumpBytecodes) { Disassembler::Dump(result); + } return result; } @@ -601,10 +637,14 @@ VMArray* Universe::NewArray(size_t size) const { #if GC_TYPE == GENERATIONAL // if the array is too big for the nursery, we will directly allocate a // mature object - outsideNursery = additionalBytes + sizeof(VMArray) > GetHeap()->GetMaxNurseryObjectSize(); + outsideNursery = additionalBytes + sizeof(VMArray) > + GetHeap()->GetMaxNurseryObjectSize(); #endif - VMArray* result = new (GetHeap(), additionalBytes ALLOC_OUTSIDE_NURSERY(outsideNursery)) VMArray(size, additionalBytes); + VMArray* result = + new (GetHeap(), + additionalBytes ALLOC_OUTSIDE_NURSERY(outsideNursery)) + VMArray(size, additionalBytes); if ((GC_TYPE == GENERATIONAL) && outsideNursery) { result->SetGCField(MASK_OBJECT_IS_OLD); } @@ -615,7 +655,8 @@ VMArray* Universe::NewArray(size_t size) const { return result; } -VMArray* Universe::NewArrayFromStrings(const vector& strings) const { +VMArray* Universe::NewArrayFromStrings( + const vector& strings) const { VMArray* result = NewArray(strings.size()); size_t j = 0; for (const std::string& str : strings) { @@ -625,7 +666,8 @@ VMArray* Universe::NewArrayFromStrings(const vector& strings) const return result; } -VMArray* Universe::NewArrayOfSymbolsFromStrings(const vector& strings) const { +VMArray* Universe::NewArrayOfSymbolsFromStrings( + const vector& strings) const { VMArray* result = NewArray(strings.size()); size_t j = 0; for (const std::string& str : strings) { @@ -636,12 +678,12 @@ VMArray* Universe::NewArrayOfSymbolsFromStrings(const vector& strin } VMArray* Universe::NewArrayList(std::vector& list) const { - std::vector& objList = (std::vector&) list; + std::vector& objList = (std::vector&)list; return NewArrayList(objList); } VMArray* Universe::NewArrayList(std::vector& list) const { - std::vector& objList = (std::vector&) list; + std::vector& objList = (std::vector&)list; return NewArrayList(objList); } @@ -658,7 +700,8 @@ VMArray* Universe::NewArrayList(std::vector& list) const { return result; } -VMBlock* Universe::NewBlock(VMMethod* method, VMFrame* context, long arguments) { +VMBlock* Universe::NewBlock(VMMethod* method, VMFrame* context, + long arguments) { VMBlock* result = new (GetHeap(), 0) VMBlock(method, context); result->SetClass(GetBlockClassWithArgs(arguments)); @@ -672,7 +715,8 @@ VMClass* Universe::NewClass(VMClass* classOfClass) const { if (numFields) { size_t additionalBytes = numFields * sizeof(VMObject*); - result = new (GetHeap(), additionalBytes) VMClass(numFields, additionalBytes); + result = new (GetHeap(), additionalBytes) + VMClass(numFields, additionalBytes); } else { result = new (GetHeap(), 0) VMClass; } @@ -699,12 +743,13 @@ VMFrame* Universe::NewFrame(VMFrame* previousFrame, VMMethod* method) const { } #endif size_t length = method->GetNumberOfArguments() + - method->GetNumberOfLocals() + - method->GetMaximumNumberOfStackElements(); + method->GetNumberOfLocals() + + method->GetMaximumNumberOfStackElements(); size_t additionalBytes = length * sizeof(VMObject*); - result = new (GetHeap(), additionalBytes) VMFrame(length, additionalBytes); - result->method = store_root(method); + result = new (GetHeap(), additionalBytes) + VMFrame(length, additionalBytes); + result->method = store_root(method); result->previousFrame = store_root(previousFrame); result->ResetStackPointer(); @@ -714,28 +759,30 @@ VMFrame* Universe::NewFrame(VMFrame* previousFrame, VMMethod* method) const { VMObject* Universe::NewInstance(VMClass* classOfInstance) const { long numOfFields = classOfInstance->GetNumberOfInstanceFields(); - //the additional space needed is calculated from the number of fields + // the additional space needed is calculated from the number of fields long additionalBytes = numOfFields * sizeof(VMObject*); - VMObject* result = new (GetHeap(), additionalBytes) VMObject(numOfFields, additionalBytes + sizeof(VMObject)); + VMObject* result = new (GetHeap(), additionalBytes) + VMObject(numOfFields, additionalBytes + sizeof(VMObject)); result->SetClass(classOfInstance); - LOG_ALLOCATION(classOfInstance->GetName()->GetStdString(), result->GetObjectSize()); + LOG_ALLOCATION(classOfInstance->GetName()->GetStdString(), + result->GetObjectSize()); return result; } VMObject* Universe::NewInstanceWithoutFields() const { - VMObject* result = new (GetHeap(), 0) VMObject(0, sizeof(VMObject)); + VMObject* result = + new (GetHeap(), 0) VMObject(0, sizeof(VMObject)); return result; } VMInteger* Universe::NewInteger(int64_t value) const { - #ifdef GENERATE_INTEGER_HISTOGRAM - integerHist[value/INT_HIST_SIZE] = integerHist[value/INT_HIST_SIZE]+1; + integerHist[value / INT_HIST_SIZE] = integerHist[value / INT_HIST_SIZE] + 1; #endif #if CACHE_INTEGER - size_t index = (size_t) value - (size_t)INT_CACHE_MIN_VALUE; + size_t index = (size_t)value - (size_t)INT_CACHE_MIN_VALUE; if (index < (size_t)(INT_CACHE_MAX_VALUE - INT_CACHE_MIN_VALUE)) { return static_cast(load_ptr(prebuildInts[index])); } @@ -756,39 +803,40 @@ VMClass* Universe::NewMetaclassClass() const { } void Universe::WalkGlobals(walk_heap_fn walk) { - nilObject = static_cast(walk(nilObject)); - trueObject = static_cast(walk(trueObject)); + nilObject = static_cast(walk(nilObject)); + trueObject = static_cast(walk(trueObject)); falseObject = static_cast(walk(falseObject)); #if USE_TAGGING GlobalBox::WalkGlobals(walk); #endif - objectClass = static_cast(walk(objectClass)); - classClass = static_cast(walk(classClass)); + objectClass = static_cast(walk(objectClass)); + classClass = static_cast(walk(classClass)); metaClassClass = static_cast(walk(metaClassClass)); - nilClass = static_cast(walk(nilClass)); - integerClass = static_cast(walk(integerClass)); - arrayClass = static_cast(walk(arrayClass)); - methodClass = static_cast(walk(methodClass)); - symbolClass = static_cast(walk(symbolClass)); - primitiveClass = static_cast(walk(primitiveClass)); - stringClass = static_cast(walk(stringClass)); - systemClass = static_cast(walk(systemClass)); - blockClass = static_cast(walk(blockClass)); - doubleClass = static_cast(walk(doubleClass)); - - trueClass = static_cast(walk(trueClass)); + nilClass = static_cast(walk(nilClass)); + integerClass = static_cast(walk(integerClass)); + arrayClass = static_cast(walk(arrayClass)); + methodClass = static_cast(walk(methodClass)); + symbolClass = static_cast(walk(symbolClass)); + primitiveClass = static_cast(walk(primitiveClass)); + stringClass = static_cast(walk(stringClass)); + systemClass = static_cast(walk(systemClass)); + blockClass = static_cast(walk(blockClass)); + doubleClass = static_cast(walk(doubleClass)); + + trueClass = static_cast(walk(trueClass)); falseClass = static_cast(walk(falseClass)); #if CACHE_INTEGER - for (unsigned long i = 0; i < (INT_CACHE_MAX_VALUE - INT_CACHE_MIN_VALUE); i++) -#if USE_TAGGING + for (unsigned long i = 0; i < (INT_CACHE_MAX_VALUE - INT_CACHE_MIN_VALUE); + i++) + #if USE_TAGGING prebuildInts[i] = TAG_INTEGER(INT_CACHE_MIN_VALUE + i); -#else + #else prebuildInts[i] = walk(prebuildInts[i]); -#endif + #endif #endif // walk all entries in globals map @@ -805,7 +853,6 @@ void Universe::WalkGlobals(walk_heap_fn walk) { WalkSymbols(walk); - map::iterator bcIter; for (bcIter = blockClassesByNoOfArgs.begin(); bcIter != blockClassesByNoOfArgs.end(); @@ -816,9 +863,12 @@ void Universe::WalkGlobals(walk_heap_fn walk) { interpreter->WalkGlobals(walk); } -VMMethod* Universe::NewMethod(VMSymbol* signature, - size_t numberOfBytecodes, size_t numberOfConstants, size_t numLocals, size_t maxStackDepth, LexicalScope* lexicalScope, vector& inlinedLoops) const { - assert(lexicalScope != nullptr && "A method is expected to have a lexical scope"); +VMMethod* Universe::NewMethod(VMSymbol* signature, size_t numberOfBytecodes, + size_t numberOfConstants, size_t numLocals, + size_t maxStackDepth, LexicalScope* lexicalScope, + vector& inlinedLoops) const { + assert(lexicalScope != nullptr && + "A method is expected to have a lexical scope"); // turn inlined loops vector into a nullptr terminated array BackJump* inlinedLoopsArr; @@ -835,9 +885,11 @@ VMMethod* Universe::NewMethod(VMSymbol* signature, } // method needs space for the bytecodes and the pointers to the constants - size_t additionalBytes = PADDED_SIZE(numberOfBytecodes + numberOfConstants*sizeof(VMObject*)); - VMMethod* result = new (GetHeap(),additionalBytes) - VMMethod(signature, numberOfBytecodes, numberOfConstants, numLocals, maxStackDepth, lexicalScope, inlinedLoopsArr); + size_t additionalBytes = + PADDED_SIZE(numberOfBytecodes + numberOfConstants * sizeof(VMObject*)); + VMMethod* result = new (GetHeap(), additionalBytes) + VMMethod(signature, numberOfBytecodes, numberOfConstants, numLocals, + maxStackDepth, lexicalScope, inlinedLoopsArr); LOG_ALLOCATION("VMMethod", result->GetObjectSize()); return result; @@ -848,7 +900,8 @@ VMString* Universe::NewString(const StdString& str) const { } VMString* Universe::NewString(const size_t length, const char* str) const { - VMString* result = new (GetHeap(), PADDED_SIZE(length)) VMString(length, str); + VMString* result = + new (GetHeap(), PADDED_SIZE(length)) VMString(length, str); LOG_ALLOCATION("VMString", result->GetObjectSize()); return result; diff --git a/src/vm/Universe.h b/src/vm/Universe.h index 90842a45..a507f910 100644 --- a/src/vm/Universe.h +++ b/src/vm/Universe.h @@ -35,7 +35,6 @@ #include "../misc/defs.h" #include "../vmobjects/ObjectFormats.h" - class SourcecodeCompiler; // for runtime debug @@ -47,7 +46,7 @@ class Universe { public: inline Universe* operator->(); - //static methods + // static methods static void Start(long argc, char** argv); static void BasicInit(); __attribute__((noreturn)) static void Quit(long); @@ -57,13 +56,12 @@ class Universe { long setupClassPath(const StdString& cp); - Interpreter* GetInterpreter() { - return interpreter; - } + Interpreter* GetInterpreter() { return interpreter; } void Assert(bool) const; - //VMObject instanciation methods. These should probably be refactored to a new class + // VMObject instanciation methods. These should probably be refactored to a + // new class VMArray* NewArray(size_t) const; VMArray* NewArrayList(std::vector& list) const; @@ -76,7 +74,10 @@ class Universe { VMBlock* NewBlock(VMMethod*, VMFrame*, long); VMClass* NewClass(VMClass*) const; VMFrame* NewFrame(VMFrame*, VMMethod*) const; - VMMethod* NewMethod(VMSymbol*, size_t numberOfBytecodes, size_t numberOfConstants, size_t numLocals, size_t maxStackDepth, LexicalScope*, vector& inlinedLoops) const; + VMMethod* NewMethod(VMSymbol*, size_t numberOfBytecodes, + size_t numberOfConstants, size_t numLocals, + size_t maxStackDepth, LexicalScope*, + vector& inlinedLoops) const; VMObject* NewInstance(VMClass*) const; VMObject* NewInstanceWithoutFields() const; VMInteger* NewInteger(int64_t) const; @@ -114,7 +115,8 @@ class Universe { // private: - vm_oop_t interpretMethod(VMObject* receiver, VMInvokable* initialize, VMArray* argumentsArray); + vm_oop_t interpretMethod(VMObject* receiver, VMInvokable* initialize, + VMArray* argumentsArray); vector handleArguments(long argc, char** argv); long getClassPathExt(vector& tokens, const StdString& arg) const; @@ -138,11 +140,12 @@ class Universe { Interpreter* interpreter; }; -//Singleton accessor -inline Universe* GetUniverse() __attribute__ ((always_inline)); +// Singleton accessor +inline Universe* GetUniverse() __attribute__((always_inline)); Universe* GetUniverse() { if (DEBUG && Universe::theUniverse == nullptr) { - Universe::ErrorExit("Trying to access uninitialized Universe, exiting."); + Universe::ErrorExit( + "Trying to access uninitialized Universe, exiting."); } return Universe::theUniverse; } diff --git a/src/vmobjects/AbstractObject.cpp b/src/vmobjects/AbstractObject.cpp index 94946e3f..509dc6eb 100644 --- a/src/vmobjects/AbstractObject.cpp +++ b/src/vmobjects/AbstractObject.cpp @@ -5,18 +5,20 @@ * Author: christian */ +#include "AbstractObject.h" + #include #include "../interpreter/Interpreter.h" #include "../vm/Symbols.h" #include "../vmobjects/ObjectFormats.h" -#include "AbstractObject.h" #include "VMClass.h" #include "VMFrame.h" #include "VMInvokable.h" #include "VMSymbol.h" -void AbstractVMObject::Send(Interpreter* interp, std::string selectorString, vm_oop_t* arguments, long argc) { +void AbstractVMObject::Send(Interpreter* interp, std::string selectorString, + vm_oop_t* arguments, long argc) { VMFrame* frame = interp->GetFrame(); VMSymbol* selector = SymbolFor(selectorString); frame->Push(this); diff --git a/src/vmobjects/AbstractObject.h b/src/vmobjects/AbstractObject.h index 82c0e6d5..94c61be8 100644 --- a/src/vmobjects/AbstractObject.h +++ b/src/vmobjects/AbstractObject.h @@ -23,15 +23,15 @@ using namespace std; class Interpreter; -//this is the base class for all VMObjects -class AbstractVMObject: public VMObjectBase { +// this is the base class for all VMObjects +class AbstractVMObject : public VMObjectBase { public: typedef GCAbstractObject Stored; virtual int64_t GetHash() const = 0; virtual VMClass* GetClass() const = 0; virtual AbstractVMObject* CloneForMovingGC() const = 0; - void Send(Interpreter*, StdString, vm_oop_t*, long); + void Send(Interpreter*, StdString, vm_oop_t*, long); /** Size in bytes of the object. */ virtual size_t GetObjectSize() const = 0; @@ -41,9 +41,7 @@ class AbstractVMObject: public VMObjectBase { virtual StdString AsDebugString() const = 0; - AbstractVMObject() { - gcfield = 0; - } + AbstractVMObject() { gcfield = 0; } ~AbstractVMObject() override = default; inline virtual long GetNumberOfFields() const { @@ -68,30 +66,34 @@ class AbstractVMObject: public VMObjectBase { * usage: new( , ) VMObject( ) * num_bytes parameter is set by the compiler. * parameter additional_bytes (a_b) is used for: - * - fields in VMObject, a_b must be set to (numberOfFields*sizeof(VMObject*)) + * - fields in VMObject, a_b must be set to + * (numberOfFields*sizeof(VMObject*)) * - chars in VMString/VMSymbol, a_b must be set to (Stringlength + 1) - * - array size in VMArray; a_b must be set to (size_of_array*sizeof(VMObect*)) - * - fields in VMMethod, a_b must be set to (number_of_bc + number_of_csts*sizeof(VMObject*)) + * - array size in VMArray; a_b must be set to + * (size_of_array*sizeof(VMObect*)) + * - fields in VMMethod, a_b must be set to (number_of_bc + + * number_of_csts*sizeof(VMObject*)) */ void* operator new(size_t numBytes, HEAP_CLS* heap, - size_t additionalBytes ALLOC_OUTSIDE_NURSERY_DECL) { + size_t additionalBytes ALLOC_OUTSIDE_NURSERY_DECL) { // if outsideNursery flag is set or object is too big for nursery, we // allocate a mature object assert(IS_PADDED_SIZE(additionalBytes)); void* result = nullptr; -#if GC_TYPE==GENERATIONAL +#if GC_TYPE == GENERATIONAL if (outsideNursery) { - result = (void*) heap->AllocateMatureObject(numBytes + additionalBytes); + result = + (void*)heap->AllocateMatureObject(numBytes + additionalBytes); } else { - result = (void*) heap->AllocateNurseryObject(numBytes + additionalBytes); + result = + (void*)heap->AllocateNurseryObject(numBytes + additionalBytes); } #else - result = (void*) heap->AllocateObject(numBytes + additionalBytes); + result = (void*)heap->AllocateObject(numBytes + additionalBytes); #endif assert(result != INVALID_VM_POINTER); return result; } - }; diff --git a/src/vmobjects/IntegerBox.cpp b/src/vmobjects/IntegerBox.cpp index 5d1819a8..0ab30e19 100644 --- a/src/vmobjects/IntegerBox.cpp +++ b/src/vmobjects/IntegerBox.cpp @@ -1,4 +1,5 @@ #include "IntegerBox.h" + #include "ObjectFormats.h" #include "VMInteger.h" diff --git a/src/vmobjects/IntegerBox.h b/src/vmobjects/IntegerBox.h index dfee5352..05261825 100644 --- a/src/vmobjects/IntegerBox.h +++ b/src/vmobjects/IntegerBox.h @@ -5,7 +5,7 @@ class GlobalBox { public: static VMInteger* IntegerBox(); - + static void WalkGlobals(walk_heap_fn walk); private: diff --git a/src/vmobjects/ObjectFormats.h b/src/vmobjects/ObjectFormats.h index 9baf8aa5..e954c5e1 100644 --- a/src/vmobjects/ObjectFormats.h +++ b/src/vmobjects/ObjectFormats.h @@ -27,13 +27,13 @@ */ #include "../misc/defs.h" -//some MACROS for integer tagging +// some MACROS for integer tagging /** * max value for tagged integers * 01111111 11111111 ... 11111111 1111111X * */ -#define VMTAGGEDINTEGER_MAX 0x3FFFFFFFFFFFFFFFLL +#define VMTAGGEDINTEGER_MAX 0x3FFFFFFFFFFFFFFFLL /** * min value for tagged integers @@ -42,17 +42,29 @@ #define VMTAGGEDINTEGER_MIN (-0x4000000000000000LL) #if ADDITIONAL_ALLOCATION -#define TAG_INTEGER(X) (((X) >= VMTAGGEDINTEGER_MIN && (X) <= VMTAGGEDINTEGER_MAX && GetUniverse()->NewInteger(0)) ? ((vm_oop_t)(((X) << 1) | 1)) : (GetUniverse()->NewInteger(X))) + #define TAG_INTEGER(X) \ + (((X) >= VMTAGGEDINTEGER_MIN && (X) <= VMTAGGEDINTEGER_MAX && \ + GetUniverse()->NewInteger(0)) \ + ? ((vm_oop_t)(((X) << 1) | 1)) \ + : (GetUniverse()->NewInteger(X))) #else -#define TAG_INTEGER(X) (((X) >= VMTAGGEDINTEGER_MIN && (X) <= VMTAGGEDINTEGER_MAX) ? ((vm_oop_t)((((uint64_t)(X)) << 1) | 1U)) : (GetUniverse()->NewInteger(X))) + #define TAG_INTEGER(X) \ + (((X) >= VMTAGGEDINTEGER_MIN && (X) <= VMTAGGEDINTEGER_MAX) \ + ? ((vm_oop_t)((((uint64_t)(X)) << 1) | 1U)) \ + : (GetUniverse()->NewInteger(X))) #endif #if USE_TAGGING - #define INT_VAL(X) (IS_TAGGED(X) ? ((int64_t)(X)>>1) : (((VMInteger*)(X))->GetEmbeddedInteger())) + #define INT_VAL(X) \ + (IS_TAGGED(X) ? ((int64_t)(X) >> 1) \ + : (((VMInteger*)(X))->GetEmbeddedInteger())) #define NEW_INT(X) (TAG_INTEGER((X))) - #define IS_TAGGED(X) ((int64_t)X&1) - #define CLASS_OF(X) (IS_TAGGED(X)?load_ptr(integerClass):((AbstractVMObject*)(X))->GetClass()) - #define AS_OBJ(X) (IS_TAGGED(X)?GlobalBox::IntegerBox():((AbstractVMObject*)(X))) + #define IS_TAGGED(X) ((int64_t)X & 1) + #define CLASS_OF(X) \ + (IS_TAGGED(X) ? load_ptr(integerClass) \ + : ((AbstractVMObject*)(X))->GetClass()) + #define AS_OBJ(X) \ + (IS_TAGGED(X) ? GlobalBox::IntegerBox() : ((AbstractVMObject*)(X))) #else #define INT_VAL(X) (static_cast(X)->GetEmbeddedInteger()) #define NEW_INT(X) (GetUniverse()->NewInteger(X)) @@ -61,7 +73,6 @@ #define AS_OBJ(X) ((AbstractVMObject*)(X)) #endif - // Forward definitions of VM object classes class AbstractVMObject; class VMArray; @@ -90,20 +101,24 @@ class VMOop { /* With the current class hierarchy, we need to force the compiler to create a VTable early, otherwise, the object layout is having vtables in the body of the objects, and casting is messed up, - leading to offset pointers to the vtables of subclasses. */ }; + leading to offset pointers to the vtables of subclasses. */ + }; + public: typedef GCOop Stored; virtual ~VMOop() = default; }; -class GCOop { public: typedef VMOop Loaded; }; + +class GCOop { +public: + typedef VMOop Loaded; +}; // oop_t: Ordinary Object Pointer type // an oop_t can refer to tagged integers as well as normal AbstractVMObjects typedef VMOop* vm_oop_t; typedef GCOop* gc_oop_t; - - /** We need to distinguish between pointers that need to be handled with a read barrier, and between pointers that already went through it. @@ -114,52 +129,55 @@ typedef GCOop* gc_oop_t; And all the stuff that was already processed: loaded values, or VM* pointers. */ -class GCAbstractObject : public GCOop { public: typedef AbstractVMObject Loaded; }; -class GCObject : public GCAbstractObject { public: typedef VMObject Loaded; }; -class GCFrame : public GCObject { public: typedef VMFrame Loaded; }; -class GCClass : public GCObject { public: typedef VMClass Loaded; }; -class GCArray : public GCObject { public: typedef VMArray Loaded; }; -class GCBlock : public GCObject { public: typedef VMBlock Loaded; }; -class GCDouble : public GCAbstractObject { public: typedef VMDouble Loaded; }; -class GCInteger : public GCAbstractObject { public: typedef VMInteger Loaded; }; -class GCInvokable : public GCAbstractObject { public: typedef VMInvokable Loaded; }; -class GCMethod : public GCInvokable { public: typedef VMMethod Loaded; }; -class GCPrimitive : public GCInvokable { public: typedef VMPrimitive Loaded; }; +// clang-format off +class GCAbstractObject : public GCOop { public: typedef AbstractVMObject Loaded; }; +class GCObject : public GCAbstractObject { public: typedef VMObject Loaded; }; +class GCFrame : public GCObject { public: typedef VMFrame Loaded; }; +class GCClass : public GCObject { public: typedef VMClass Loaded; }; +class GCArray : public GCObject { public: typedef VMArray Loaded; }; +class GCBlock : public GCObject { public: typedef VMBlock Loaded; }; +class GCDouble : public GCAbstractObject { public: typedef VMDouble Loaded; }; +class GCInteger : public GCAbstractObject { public: typedef VMInteger Loaded; }; +class GCInvokable : public GCAbstractObject { public: typedef VMInvokable Loaded; }; +class GCMethod : public GCInvokable { public: typedef VMMethod Loaded; }; +class GCPrimitive : public GCInvokable { public: typedef VMPrimitive Loaded; }; class GCEvaluationPrimitive : public GCPrimitive { public: typedef VMEvaluationPrimitive Loaded; }; -class GCString : public GCAbstractObject { public: typedef VMString Loaded; }; -class GCSymbol : public GCString { public: typedef VMSymbol Loaded; }; - - +class GCString : public GCAbstractObject { public: typedef VMString Loaded; }; +class GCSymbol : public GCString { public: typedef VMSymbol Loaded; }; +// clang-format on // Used to mark object fields as invalid #define INVALID_VM_POINTER ((VMObject*)0x101010) #define INVALID_GC_POINTER ((GCObject*)0x101010) - -template +template inline typename T::Loaded* load_ptr(T* gc_val) { - return (typename T::Loaded*) gc_val; + return (typename T::Loaded*)gc_val; } /** To store object into a root. */ -template +template inline typename T::Stored* store_root(T* vm_val) { - return (typename T::Stored*) vm_val; + return (typename T::Stored*)vm_val; } -/** For temporary use, but can't be stored, and can't be alive across GC invocations. */ -template +/** For temporary use, but can't be stored, and can't be alive across GC + * invocations. */ +template inline typename T::Stored* tmp_ptr(T* vm_val) { - return (typename T::Stored*) vm_val; + return (typename T::Stored*)vm_val; } -/** To store object a field, needs special care to correctly call `write_barrier()` separately. */ -template +/** To store object a field, needs special care to correctly call + * `write_barrier()` separately. */ +template inline typename T::Stored* store_with_separate_barrier(T* vm_val) { - return (typename T::Stored*) vm_val; + return (typename T::Stored*)vm_val; } /** Standard assignment of pointer to field, including write barrier. */ -#define store_ptr(field, val) field = store_with_separate_barrier(val); write_barrier(this, val) +#define store_ptr(field, val) \ + field = store_with_separate_barrier(val); \ + write_barrier(this, val) typedef gc_oop_t (*walk_heap_fn)(gc_oop_t); diff --git a/src/vmobjects/PrimitiveRoutine.h b/src/vmobjects/PrimitiveRoutine.h index b2031d0c..52985429 100644 --- a/src/vmobjects/PrimitiveRoutine.h +++ b/src/vmobjects/PrimitiveRoutine.h @@ -40,7 +40,7 @@ class PrimitiveRoutine { // Typedefs for Primitive loading typedef PrimitiveRoutine* CreatePrimitive(const std::string&, - const std::string&, bool isPrimitive); + const std::string&, bool isPrimitive); typedef bool SupportsClass(const char*); typedef void TearDown(); typedef void Setup(); diff --git a/src/vmobjects/Signature.cpp b/src/vmobjects/Signature.cpp index 999b058a..908b8260 100644 --- a/src/vmobjects/Signature.cpp +++ b/src/vmobjects/Signature.cpp @@ -24,19 +24,22 @@ THE SOFTWARE. */ +#include "Signature.h" + #include -#include "Signature.h" #include "VMSymbol.h" bool Signature::IsBinary(VMSymbol* sig) { return sig->numberOfArgumentsOfSignature == 2; } -int Signature::DetermineNumberOfArguments(const char* sig, const size_t length) { +int Signature::DetermineNumberOfArguments(const char* sig, + const size_t length) { // check default binaries - if (Signature::IsBinary(sig, length)) + if (Signature::IsBinary(sig, length)) { return 2; + } // colons in str int numColons = 0; @@ -52,23 +55,24 @@ bool Signature::IsBinary(const char* sig, const size_t length) { if (length == 0) { return false; } - switch(sig[0]) { - case '~' : - case '&' : - case '|' : - case '*' : - case '/' : - case '@' : - case '+' : - case '-' : - case '=' : - case '>' : - case '<' : - case ',' : - case '%' : + switch (sig[0]) { + case '~': + case '&': + case '|': + case '*': + case '/': + case '@': + case '+': + case '-': + case '=': + case '>': + case '<': + case ',': + case '%': case '\\': - return true; - default: break; + return true; + default: + break; } return false; } diff --git a/src/vmobjects/Signature.h b/src/vmobjects/Signature.h index b980e641..1ab04776 100644 --- a/src/vmobjects/Signature.h +++ b/src/vmobjects/Signature.h @@ -38,7 +38,7 @@ class Signature { } static bool IsBinary(VMSymbol* sig); - + static int DetermineNumberOfArguments(const char* sig, const size_t length); static bool IsBinary(const char* sig, const size_t length); }; diff --git a/src/vmobjects/VMArray.cpp b/src/vmobjects/VMArray.cpp index 1a6fd1d2..58758937 100644 --- a/src/vmobjects/VMArray.cpp +++ b/src/vmobjects/VMArray.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "../vmobjects/VMArray.h" + #include #include #include @@ -33,13 +35,14 @@ #include "../misc/defs.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" -#include "../vmobjects/VMArray.h" #include "../vmobjects/VMObject.h" const size_t VMArray::VMArrayNumberOfFields = 0; -VMArray::VMArray(size_t arraySize, size_t additionalBytes) : - VMObject(arraySize + 0 /* VMArray is not allowed to have any fields itself */, additionalBytes + sizeof(VMArray)) { +VMArray::VMArray(size_t arraySize, size_t additionalBytes) + : VMObject( + arraySize + 0 /* VMArray is not allowed to have any fields itself */, + additionalBytes + sizeof(VMArray)) { assert(VMArrayNumberOfFields == 0); nilInitializeFields(); } @@ -48,7 +51,8 @@ vm_oop_t VMArray::GetIndexableField(size_t idx) const { if (unlikely(idx > GetNumberOfIndexableFields())) { Universe::ErrorExit(("Array index out of bounds: Accessing " + to_string(idx) + ", but array size is only " + - to_string(GetNumberOfIndexableFields()) + "\n").c_str()); + to_string(GetNumberOfIndexableFields()) + "\n") + .c_str()); } return GetField(idx); } @@ -57,7 +61,8 @@ void VMArray::SetIndexableField(size_t idx, vm_oop_t value) { if (unlikely(idx > GetNumberOfIndexableFields())) { Universe::ErrorExit(("Array index out of bounds: Accessing " + to_string(idx) + ", but array size is only " + - to_string(GetNumberOfIndexableFields()) + "\n").c_str()); + to_string(GetNumberOfIndexableFields()) + "\n") + .c_str()); } SetField(idx, value); } @@ -72,8 +77,9 @@ VMArray* VMArray::CopyAndExtendWith(vm_oop_t item) const { VMArray* VMArray::CloneForMovingGC() const { const size_t addSpace = totalObjectSize - sizeof(VMArray); - auto* clone = new (GetHeap(), addSpace ALLOC_MATURE) VMArray(*this); - void* destination = SHIFTED_PTR(clone, sizeof(VMArray)); + auto* clone = + new (GetHeap(), addSpace ALLOC_MATURE) VMArray(*this); + void* destination = SHIFTED_PTR(clone, sizeof(VMArray)); const void* source = SHIFTED_PTR(this, sizeof(VMArray)); memcpy(destination, source, addSpace); return clone; diff --git a/src/vmobjects/VMArray.h b/src/vmobjects/VMArray.h index 22dd226e..642ede21 100644 --- a/src/vmobjects/VMArray.h +++ b/src/vmobjects/VMArray.h @@ -31,10 +31,11 @@ #include "../vmobjects/VMObject.h" /** - * For the VMArray, we assume that there are no subclasses, and that `Array` doesn't - * have any fields itself. This way, we just used the fields as indexable fields. + * For the VMArray, we assume that there are no subclasses, and that `Array` + * doesn't have any fields itself. This way, we just used the fields as + * indexable fields. */ -class VMArray: public VMObject { +class VMArray : public VMObject { public: typedef GCArray Stored; @@ -43,9 +44,7 @@ class VMArray: public VMObject { // VMArray doesn't need to customize `void WalkObjects(walk_heap_fn)`, // because it doesn't need anything special. - inline size_t GetNumberOfIndexableFields() const { - return numberOfFields; - } + inline size_t GetNumberOfIndexableFields() const { return numberOfFields; } VMArray* CopyAndExtendWith(vm_oop_t) const; vm_oop_t GetIndexableField(size_t idx) const; diff --git a/src/vmobjects/VMBlock.cpp b/src/vmobjects/VMBlock.cpp index f52d3a59..3be3feb0 100644 --- a/src/vmobjects/VMBlock.cpp +++ b/src/vmobjects/VMBlock.cpp @@ -24,22 +24,23 @@ THE SOFTWARE. */ +#include "VMBlock.h" + #include #include "../memory/Heap.h" #include "../misc/defs.h" #include "ObjectFormats.h" -#include "VMBlock.h" #include "VMEvaluationPrimitive.h" #include "VMMethod.h" #include "VMObject.h" const int VMBlock::VMBlockNumberOfFields = 2; -VMBlock::VMBlock(VMMethod* method, VMFrame* context) : - VMObject(VMBlockNumberOfFields, sizeof(VMBlock)), - blockMethod(store_with_separate_barrier(method)), - context(store_with_separate_barrier(context)) { +VMBlock::VMBlock(VMMethod* method, VMFrame* context) + : VMObject(VMBlockNumberOfFields, sizeof(VMBlock)), + blockMethod(store_with_separate_barrier(method)), + context(store_with_separate_barrier(context)) { write_barrier(this, method); write_barrier(this, context); } @@ -55,7 +56,8 @@ VMMethod* VMBlock::GetMethod() const { } VMEvaluationPrimitive* VMBlock::GetEvaluationPrimitive(int numberOfArguments) { - return new (GetHeap(), 0) VMEvaluationPrimitive(numberOfArguments); + return new (GetHeap(), 0) + VMEvaluationPrimitive(numberOfArguments); } std::string VMBlock::AsDebugString() const { diff --git a/src/vmobjects/VMBlock.h b/src/vmobjects/VMBlock.h index 26faacab..0c5bf96b 100644 --- a/src/vmobjects/VMBlock.h +++ b/src/vmobjects/VMBlock.h @@ -29,25 +29,25 @@ #include "VMFrame.h" #include "VMObject.h" -class VMBlock: public VMObject { +class VMBlock : public VMObject { public: typedef GCBlock Stored; VMBlock(VMMethod* method, VMFrame* context); - VMMethod* GetMethod() const; - - inline VMFrame* GetContext() const { - return load_ptr(context); - } + VMMethod* GetMethod() const; - VMBlock* CloneForMovingGC() const override; + inline VMFrame* GetContext() const { return load_ptr(context); } + + VMBlock* CloneForMovingGC() const override; StdString AsDebugString() const override; static VMEvaluationPrimitive* GetEvaluationPrimitive(int); -private_testable: +private: + make_testable(public); + GCMethod* blockMethod; GCFrame* context; diff --git a/src/vmobjects/VMClass.cpp b/src/vmobjects/VMClass.cpp index 277f51c6..7c2df159 100644 --- a/src/vmobjects/VMClass.cpp +++ b/src/vmobjects/VMClass.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMClass.h" + #include #include #include @@ -38,7 +40,6 @@ #include "ObjectFormats.h" #include "PrimitiveRoutine.h" #include "VMArray.h" -#include "VMClass.h" #include "VMInvokable.h" #include "VMObject.h" #include "VMPrimitive.h" @@ -46,53 +47,61 @@ const size_t VMClass::VMClassNumberOfFields = 4; -VMClass::VMClass() : - VMObject(VMClassNumberOfFields, sizeof(VMClass)), name(nullptr), instanceFields( - nullptr), instanceInvokables(nullptr), superClass(nullptr) { -} +VMClass::VMClass() + : VMObject(VMClassNumberOfFields, sizeof(VMClass)), name(nullptr), + instanceFields(nullptr), instanceInvokables(nullptr), + superClass(nullptr) {} VMClass* VMClass::CloneForMovingGC() const { - VMClass* clone = new (GetHeap(), totalObjectSize - sizeof(VMClass) ALLOC_MATURE) VMClass(*this); - memcpy(SHIFTED_PTR(clone,sizeof(VMObject)), - SHIFTED_PTR(this,sizeof(VMObject)), GetObjectSize() - - sizeof(VMObject)); + VMClass* clone = + new (GetHeap(), + totalObjectSize - sizeof(VMClass) ALLOC_MATURE) VMClass(*this); + memcpy(SHIFTED_PTR(clone, sizeof(VMObject)), + SHIFTED_PTR(this, sizeof(VMObject)), + GetObjectSize() - sizeof(VMObject)); return clone; } -VMClass::VMClass(size_t numberOfFields, size_t additionalBytes) : - VMObject(numberOfFields + VMClassNumberOfFields, additionalBytes + sizeof(VMClass)) { -} +VMClass::VMClass(size_t numberOfFields, size_t additionalBytes) + : VMObject(numberOfFields + VMClassNumberOfFields, + additionalBytes + sizeof(VMClass)) {} bool VMClass::AddInstanceInvokable(VMInvokable* ptr) { if (ptr == nullptr) { - GetUniverse()->ErrorExit("Error: trying to add non-invokable to invokables array"); + GetUniverse()->ErrorExit( + "Error: trying to add non-invokable to invokables array"); return false; } - //Check whether an invokable with the same signature exists and replace it if that's the case + // Check whether an invokable with the same signature exists and replace it + // if that's the case VMArray* instInvokables = load_ptr(instanceInvokables); size_t numIndexableFields = instInvokables->GetNumberOfIndexableFields(); for (size_t i = 0; i < numIndexableFields; ++i) { - VMInvokable* inv = static_cast(instInvokables->GetIndexableField(i)); + VMInvokable* inv = + static_cast(instInvokables->GetIndexableField(i)); if (inv != nullptr) { if (ptr->GetSignature() == inv->GetSignature()) { SetInstanceInvokable(i, ptr); return false; } } else { - GetUniverse()->ErrorExit("Invokables array corrupted. " - "Either NULL pointer added or pointer to non-invokable."); + GetUniverse()->ErrorExit( + "Invokables array corrupted. " + "Either NULL pointer added or pointer to non-invokable."); return false; } } - //it's a new invokable so we need to expand the invokables array. - store_ptr(instanceInvokables, instInvokables->CopyAndExtendWith((vm_oop_t) ptr)); + // it's a new invokable so we need to expand the invokables array. + store_ptr(instanceInvokables, + instInvokables->CopyAndExtendWith((vm_oop_t)ptr)); return true; } void VMClass::AddInstancePrimitive(VMPrimitive* ptr) { if (AddInstanceInvokable(ptr)) { - //cout << "Warn: Primitive "<GetSignature<<" is not in class definition for class " << name->GetStdString() << endl; + // cout << "Warn: Primitive "<GetSignature<<" is not in class + // definition for class " << name->GetStdString() << endl; } } @@ -100,10 +109,11 @@ VMSymbol* VMClass::GetInstanceFieldName(long index) const { long numSuperInstanceFields = numberOfSuperInstanceFields(); if (index >= numSuperInstanceFields) { index -= numSuperInstanceFields; - return static_cast(load_ptr(instanceFields)->GetIndexableField(index)); + return static_cast( + load_ptr(instanceFields)->GetIndexableField(index)); } assert(HasSuperClass()); - return ((VMClass*) load_ptr(superClass))->GetInstanceFieldName(index); + return ((VMClass*)load_ptr(superClass))->GetInstanceFieldName(index); } void VMClass::SetInstanceInvokables(VMArray* invokables) { @@ -113,10 +123,10 @@ void VMClass::SetInstanceInvokables(VMArray* invokables) { size_t numInvokables = GetNumberOfInstanceInvokables(); for (size_t i = 0; i < numInvokables; ++i) { vm_oop_t invo = load_ptr(instanceInvokables)->GetIndexableField(i); - //check for Nil object + // check for Nil object if (invo != nil) { - //not Nil, so this actually is an invokable - VMInvokable* inv = (VMInvokable*) invo; + // not Nil, so this actually is an invokable + VMInvokable* inv = (VMInvokable*)invo; inv->SetHolder(this); } } @@ -127,7 +137,8 @@ size_t VMClass::GetNumberOfInstanceInvokables() const { } VMInvokable* VMClass::GetInstanceInvokable(long index) const { - return static_cast(load_ptr(instanceInvokables)->GetIndexableField(index)); + return static_cast( + load_ptr(instanceInvokables)->GetIndexableField(index)); } void VMClass::SetInstanceInvokable(long index, VMInvokable* invokable) { @@ -141,8 +152,9 @@ VMInvokable* VMClass::LookupInvokable(VMSymbol* name) const { assert(IsValidObject(const_cast(this))); VMInvokable* invokable = name->GetCachedInvokable(this); - if (invokable != nullptr) + if (invokable != nullptr) { return invokable; + } long numInvokables = GetNumberOfInstanceInvokables(); for (long i = 0; i < numInvokables; ++i) { @@ -155,7 +167,7 @@ VMInvokable* VMClass::LookupInvokable(VMSymbol* name) const { // look in super class if (HasSuperClass()) { - return ((VMClass*) load_ptr(superClass))->LookupInvokable(name); + return ((VMClass*)load_ptr(superClass))->LookupInvokable(name); } // invokable not found @@ -174,15 +186,17 @@ long VMClass::LookupFieldIndex(VMSymbol* name) const { } size_t VMClass::GetNumberOfInstanceFields() const { - return load_ptr(instanceFields)->GetNumberOfIndexableFields() - + numberOfSuperInstanceFields(); + return load_ptr(instanceFields)->GetNumberOfIndexableFields() + + numberOfSuperInstanceFields(); } bool VMClass::HasPrimitives() const { long numInvokables = GetNumberOfInstanceInvokables(); for (long i = 0; i < numInvokables; ++i) { VMInvokable* invokable = GetInstanceInvokable(i); - if (invokable->IsPrimitive()) return true; + if (invokable->IsPrimitive()) { + return true; + } } return false; } @@ -198,7 +212,7 @@ void VMClass::LoadPrimitives() { size_t VMClass::numberOfSuperInstanceFields() const { if (HasSuperClass()) { - return ((VMClass*) load_ptr(superClass))->GetNumberOfInstanceFields(); + return ((VMClass*)load_ptr(superClass))->GetNumberOfInstanceFields(); } return 0; } @@ -211,12 +225,12 @@ bool VMClass::hasPrimitivesFor(const std::string& cl) const { * set the routines for primitive marked invokables of the given class */ void VMClass::setPrimitives(const std::string& cname, bool classSide) { - VMObject* current = this; - // Try loading class-specific primitives for all super class' methods as well. + // Try loading class-specific primitives for all super class' methods as + // well. while (current != load_ptr(nilObject)) { - VMClass* currentClass = (VMClass*) current; + VMClass* currentClass = (VMClass*)current; // iterate invokables long numInvokables = currentClass->GetNumberOfInstanceInvokables(); @@ -224,7 +238,7 @@ void VMClass::setPrimitives(const std::string& cname, bool classSide) { VMInvokable* anInvokable = currentClass->GetInstanceInvokable(i); #ifdef __DEBUG ErrorPrint("cname: >" + cname + "<\n" + - anInvokable->GetSignature()->GetStdString() + "\n"); + anInvokable->GetSignature()->GetStdString() + "\n"); #endif VMSymbol* sig = anInvokable->GetSignature(); @@ -238,7 +252,8 @@ void VMClass::setPrimitives(const std::string& cname, bool classSide) { if (this == current && anInvokable->IsPrimitive()) { thePrimitive = static_cast(anInvokable); } else { - thePrimitive = VMPrimitive::GetEmptyPrimitive(sig, classSide); + thePrimitive = + VMPrimitive::GetEmptyPrimitive(sig, classSide); AddInstancePrimitive(thePrimitive); } @@ -247,9 +262,8 @@ void VMClass::setPrimitives(const std::string& cname, bool classSide) { } else { if (anInvokable->IsPrimitive() && current == this) { if (!routine || routine->isClassSide() == classSide) { - ErrorPrint("could not load primitive '" + - selector + "' for class " + - cname + "\n"); + ErrorPrint("could not load primitive '" + selector + + "' for class " + cname + "\n"); GetUniverse()->Quit(ERR_FAIL); } } diff --git a/src/vmobjects/VMClass.h b/src/vmobjects/VMClass.h index f277bab1..b29eeba3 100644 --- a/src/vmobjects/VMClass.h +++ b/src/vmobjects/VMClass.h @@ -33,43 +33,44 @@ #include "../vm/IsValidObject.h" #include "VMObject.h" -#if defined(_MSC_VER) //Visual Studio -#include -#include "../primitives/Core.h" +#if defined(_MSC_VER) // Visual Studio + #include + + #include "../primitives/Core.h" #endif class ClassGenerationContext; -class VMClass: public VMObject { +class VMClass : public VMObject { public: typedef GCClass Stored; VMClass(); VMClass(size_t numberOfFields, size_t additionalBytes); - VMObject* GetSuperClass() const; - void SetSuperClass(VMObject*); - bool HasSuperClass() const; - VMSymbol* GetName() const; - void SetName(VMSymbol*); - VMArray* GetInstanceFields() const; - void SetInstanceFields(VMArray*); - VMArray* GetInstanceInvokables() const; - void SetInstanceInvokables(VMArray*); - size_t GetNumberOfInstanceInvokables() const; - VMInvokable* GetInstanceInvokable(long) const; - void SetInstanceInvokable(long, VMInvokable*); - VMInvokable* LookupInvokable(VMSymbol*) const; - long LookupFieldIndex(VMSymbol*) const; - bool AddInstanceInvokable(VMInvokable*); - void AddInstancePrimitive(VMPrimitive*); - VMSymbol* GetInstanceFieldName(long)const; - size_t GetNumberOfInstanceFields() const; - bool HasPrimitives() const; - void LoadPrimitives(); - VMClass* CloneForMovingGC() const override; - - StdString AsDebugString() const override; + VMObject* GetSuperClass() const; + void SetSuperClass(VMObject*); + bool HasSuperClass() const; + VMSymbol* GetName() const; + void SetName(VMSymbol*); + VMArray* GetInstanceFields() const; + void SetInstanceFields(VMArray*); + VMArray* GetInstanceInvokables() const; + void SetInstanceInvokables(VMArray*); + size_t GetNumberOfInstanceInvokables() const; + VMInvokable* GetInstanceInvokable(long) const; + void SetInstanceInvokable(long, VMInvokable*); + VMInvokable* LookupInvokable(VMSymbol*) const; + long LookupFieldIndex(VMSymbol*) const; + bool AddInstanceInvokable(VMInvokable*); + void AddInstancePrimitive(VMPrimitive*); + VMSymbol* GetInstanceFieldName(long) const; + size_t GetNumberOfInstanceFields() const; + bool HasPrimitives() const; + void LoadPrimitives(); + VMClass* CloneForMovingGC() const override; + + StdString AsDebugString() const override; private: bool hasPrimitivesFor(const StdString& cl) const; @@ -78,7 +79,8 @@ class VMClass: public VMObject { static const size_t VMClassNumberOfFields; -private_testable: + make_testable(public); + // Remember to update Parser::superclass when the fields are changed GCSymbol* name; GCArray* instanceFields; diff --git a/src/vmobjects/VMDouble.cpp b/src/vmobjects/VMDouble.cpp index ff101967..6051d96d 100644 --- a/src/vmobjects/VMDouble.cpp +++ b/src/vmobjects/VMDouble.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMDouble.h" + #include #include "../memory/Heap.h" @@ -31,7 +33,6 @@ #include "../vm/Globals.h" #include "ObjectFormats.h" #include "VMClass.h" -#include "VMDouble.h" VMDouble* VMDouble::CloneForMovingGC() const { return new (GetHeap(), 0 ALLOC_MATURE) VMDouble(*this); diff --git a/src/vmobjects/VMDouble.h b/src/vmobjects/VMDouble.h index 32d20566..11882639 100644 --- a/src/vmobjects/VMDouble.h +++ b/src/vmobjects/VMDouble.h @@ -28,21 +28,21 @@ #include "AbstractObject.h" -class VMDouble: public AbstractVMObject { +class VMDouble : public AbstractVMObject { public: typedef GCDouble Stored; VMDouble(double val) : AbstractVMObject(), embeddedDouble(val) {} VMDouble* CloneForMovingGC() const override; - inline double GetEmbeddedDouble() const; + inline double GetEmbeddedDouble() const; VMClass* GetClass() const override; inline size_t GetObjectSize() const override; inline int64_t GetHash() const override { // try to avoid a smart cast of the double value. // instead, try to get to the bit pattern as a int64_t - return (*(int64_t*) &embeddedDouble); + return (*(int64_t*)&embeddedDouble); } void MarkObjectAsInvalid() override; @@ -50,7 +50,9 @@ class VMDouble: public AbstractVMObject { StdString AsDebugString() const override; -private_testable: +private: + make_testable(public); + double embeddedDouble; }; diff --git a/src/vmobjects/VMEvaluationPrimitive.cpp b/src/vmobjects/VMEvaluationPrimitive.cpp index 83b03bdf..7ccdaf17 100644 --- a/src/vmobjects/VMEvaluationPrimitive.cpp +++ b/src/vmobjects/VMEvaluationPrimitive.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMEvaluationPrimitive.h" + #include #include #include @@ -32,20 +34,21 @@ #include "../misc/defs.h" #include "../primitivesCore/Routine.h" #include "../vm/Symbols.h" -#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "ObjectFormats.h" #include "VMBlock.h" -#include "VMEvaluationPrimitive.h" #include "VMFrame.h" #include "VMPrimitive.h" #include "VMSymbol.h" -VMEvaluationPrimitive::VMEvaluationPrimitive(size_t argc) : VMPrimitive(computeSignatureString(argc)), numberOfArguments(argc) { +VMEvaluationPrimitive::VMEvaluationPrimitive(size_t argc) + : VMPrimitive(computeSignatureString(argc)), numberOfArguments(argc) { SetRoutine(new EvaluationRoutine(this), false); } VMEvaluationPrimitive* VMEvaluationPrimitive::CloneForMovingGC() const { - VMEvaluationPrimitive* evPrim = new (GetHeap(), 0 ALLOC_MATURE) VMEvaluationPrimitive(*this); + VMEvaluationPrimitive* evPrim = + new (GetHeap(), 0 ALLOC_MATURE) VMEvaluationPrimitive(*this); return evPrim; } @@ -57,23 +60,24 @@ void VMEvaluationPrimitive::WalkObjects(walk_heap_fn walk) { VMSymbol* VMEvaluationPrimitive::computeSignatureString(long argc) { #define VALUE_S "value" #define VALUE_LEN 5 -#define WITH_S "with:" -#define WITH_LEN (4+1) +#define WITH_S "with:" +#define WITH_LEN (4 + 1) #define COLON_S ":" assert(argc > 0); std::string signatureString; // Compute the signature string - if (argc==1) { + if (argc == 1) { signatureString += VALUE_S; } else { signatureString += VALUE_S; signatureString += COLON_S; --argc; - while (--argc) + while (--argc) { // Add extra value: selector elements if necessary signatureString += WITH_S; + } } // Return the signature string diff --git a/src/vmobjects/VMEvaluationPrimitive.h b/src/vmobjects/VMEvaluationPrimitive.h index f4097ae2..653a794d 100644 --- a/src/vmobjects/VMEvaluationPrimitive.h +++ b/src/vmobjects/VMEvaluationPrimitive.h @@ -28,7 +28,7 @@ #include "VMPrimitive.h" -class VMEvaluationPrimitive: public VMPrimitive { +class VMEvaluationPrimitive : public VMPrimitive { public: typedef GCEvaluationPrimitive Stored; @@ -39,7 +39,7 @@ class VMEvaluationPrimitive: public VMPrimitive { StdString AsDebugString() const override; int64_t GetNumberOfArguments() { return numberOfArguments; } - + inline size_t GetObjectSize() const override { return sizeof(VMEvaluationPrimitive); } @@ -50,22 +50,24 @@ class VMEvaluationPrimitive: public VMPrimitive { private: static VMSymbol* computeSignatureString(long argc); void evaluationRoutine(Interpreter*, VMFrame*); -private_testable: - size_t numberOfArguments; + make_testable(public); + + size_t numberOfArguments; }; class EvaluationRoutine : public PrimitiveRoutine { private: GCEvaluationPrimitive* evalPrim; + public: EvaluationRoutine(VMEvaluationPrimitive* prim) : PrimitiveRoutine(), - // the store without barrier is fine here, - // because it's a cyclic structure with `prim` itself, - // which will be store in another object, - // which will then have a barrier - evalPrim(store_with_separate_barrier(prim)) {}; + // the store without barrier is fine here, + // because it's a cyclic structure with `prim` itself, + // which will be store in another object, + // which will then have a barrier + evalPrim(store_with_separate_barrier(prim)) {}; void WalkObjects(walk_heap_fn); bool isClassSide() override { return false; } void Invoke(Interpreter* interp, VMFrame* frame) override; diff --git a/src/vmobjects/VMFrame.cpp b/src/vmobjects/VMFrame.cpp index 5198c798..dfd7213e 100644 --- a/src/vmobjects/VMFrame.cpp +++ b/src/vmobjects/VMFrame.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMFrame.h" + #include #include #include @@ -36,7 +38,6 @@ #include "../vm/Print.h" #include "ObjectFormats.h" #include "VMClass.h" -#include "VMFrame.h" #include "VMMethod.h" #include "VMObject.h" #include "VMObjectBase.h" @@ -47,21 +48,21 @@ // depth is calculated. In that case this method is called. VMFrame* VMFrame::EmergencyFrameFrom(VMFrame* from, long extraLength) { VMMethod* method = from->GetMethod(); - long length = method->GetNumberOfArguments() - + method->GetNumberOfLocals() - + method->GetMaximumNumberOfStackElements() - + extraLength; + long length = method->GetNumberOfArguments() + method->GetNumberOfLocals() + + method->GetMaximumNumberOfStackElements() + extraLength; size_t additionalBytes = length * sizeof(VMObject*); - VMFrame* result = new (GetHeap(), additionalBytes) VMFrame(length, additionalBytes); + VMFrame* result = new (GetHeap(), additionalBytes) + VMFrame(length, additionalBytes); - result->clazz = nullptr; // result->SetClass(from->GetClass()); + result->clazz = nullptr; // result->SetClass(from->GetClass()); // set Frame members result->SetPreviousFrame(from->GetPreviousFrame()); result->SetMethod(method); result->SetContext(from->GetContext()); - result->stack_ptr = (gc_oop_t*)SHIFTED_PTR(result, (size_t)from->stack_ptr - (size_t)from); + result->stack_ptr = + (gc_oop_t*)SHIFTED_PTR(result, (size_t)from->stack_ptr - (size_t)from); result->bytecodeIndex = from->bytecodeIndex; // result->arguments is set in VMFrame constructor @@ -69,8 +70,9 @@ VMFrame* VMFrame::EmergencyFrameFrom(VMFrame* from, long extraLength) { // all other fields are indexable via arguments // --> until end of Frame - gc_oop_t* from_end = (gc_oop_t*) SHIFTED_PTR(from, from->GetObjectSize()); - gc_oop_t* result_end = (gc_oop_t*) SHIFTED_PTR(result, result->GetObjectSize()); + gc_oop_t* from_end = (gc_oop_t*)SHIFTED_PTR(from, from->GetObjectSize()); + gc_oop_t* result_end = + (gc_oop_t*)SHIFTED_PTR(result, result->GetObjectSize()); long i = 0; @@ -89,43 +91,49 @@ VMFrame* VMFrame::EmergencyFrameFrom(VMFrame* from, long extraLength) { VMFrame* VMFrame::CloneForMovingGC() const { size_t addSpace = totalObjectSize - sizeof(VMFrame); - VMFrame* clone = new (GetHeap(), addSpace ALLOC_MATURE) VMFrame(*this); + VMFrame* clone = + new (GetHeap(), addSpace ALLOC_MATURE) VMFrame(*this); void* destination = SHIFTED_PTR(clone, sizeof(VMFrame)); const void* source = SHIFTED_PTR(this, sizeof(VMFrame)); memcpy(destination, source, addSpace); - clone->arguments = (gc_oop_t*)&(clone->stack_ptr)+1; //field after stack_ptr + clone->arguments = + (gc_oop_t*)&(clone->stack_ptr) + 1; // field after stack_ptr - // Use of GetMethod() is problematic here, because it may be invalid object while cloning/moving within GC - // Use of GetMethod()->GetNumberOfArguments() is problematic here, because it may be invalid object while cloning/moving within GC + // Use of GetMethod() is problematic here, because it may be invalid object + // while cloning/moving within GC Use of GetMethod()->GetNumberOfArguments() + // is problematic here, because it may be invalid object while + // cloning/moving within GC #if GC_TYPE == GENERATIONAL || GC_TYPE == COPYING || GC_TYPE == DEBUG_COPYING VMMethod* meth = load_ptr(method); if (meth->GetGCField() != 0 && meth->GetGCField() != MASK_OBJECT_IS_OLD) { - meth = (VMMethod*) meth->GetGCField(); + meth = (VMMethod*)meth->GetGCField(); } -// int64_t numArgs = meth->GetNumberOfArgumentsPossiblyFollowingForwardingPointer(); +// int64_t numArgs = +// meth->GetNumberOfArgumentsPossiblyFollowingForwardingPointer(); #else VMMethod* meth = GetMethod(); #endif int64_t numArgs = meth->GetNumberOfArguments(); clone->locals = clone->arguments + numArgs; - clone->stack_ptr = (gc_oop_t*)SHIFTED_PTR(clone, (size_t)stack_ptr - (size_t)this); + clone->stack_ptr = + (gc_oop_t*)SHIFTED_PTR(clone, (size_t)stack_ptr - (size_t)this); return clone; } const long VMFrame::VMFrameNumberOfFields = 0; -VMFrame::VMFrame(size_t, size_t additionalBytes) : - VMObject(0, additionalBytes + sizeof(VMFrame)), bytecodeIndex(0), previousFrame(nullptr), context( - nullptr), method(nullptr) { - arguments = (gc_oop_t*)&(stack_ptr)+1; +VMFrame::VMFrame(size_t, size_t additionalBytes) + : VMObject(0, additionalBytes + sizeof(VMFrame)), bytecodeIndex(0), + previousFrame(nullptr), context(nullptr), method(nullptr) { + arguments = (gc_oop_t*)&(stack_ptr) + 1; locals = arguments; stack_ptr = locals; // initilize all other fields // --> until end of Frame - gc_oop_t* end = (gc_oop_t*) SHIFTED_PTR(this, totalObjectSize); + gc_oop_t* end = (gc_oop_t*)SHIFTED_PTR(this, totalObjectSize); size_t i = 0; while (arguments + i < end) { arguments[i] = nilObject; @@ -155,8 +163,8 @@ VMFrame* VMFrame::GetOuterContext() { } void VMFrame::WalkObjects(walk_heap_fn walk) { - // VMFrame is not a proper SOM object any longer, we don't have a class for it. - // clazz = (VMClass*) walk(clazz); + // VMFrame is not a proper SOM object any longer, we don't have a class for + // it. clazz = (VMClass*) walk(clazz); if (previousFrame) { previousFrame = static_cast(walk(previousFrame)); @@ -180,8 +188,8 @@ void VMFrame::WalkObjects(walk_heap_fn walk) { long VMFrame::RemainingStackSize() const { // - 1 because the stack pointer points at the top entry, // so the next entry would be put at stackPointer+1 - size_t size = ((size_t) this + totalObjectSize - size_t(stack_ptr)) - / sizeof(VMObject*); + size_t size = ((size_t)this + totalObjectSize - size_t(stack_ptr)) / + sizeof(VMObject*); return size - 1; } @@ -190,23 +198,23 @@ void VMFrame::PrintBytecode() const { } static void print_oop(gc_oop_t vmo) { - if (vmo == nullptr) + if (vmo == nullptr) { Print("nullptr\n"); - else if (vmo == nilObject) + } else if (vmo == nilObject) { Print("NIL_OBJECT\n"); - else { + } else { AbstractVMObject* o = AS_OBJ(vmo); Print(o->AsDebugString() + "\n"); } } void VMFrame::PrintStack() const { - Print(GetMethod()->AsDebugString() + ", bc: " + - to_string(GetBytecodeIndex()) + "\n" + "Args: " + - to_string(GetMethod()->GetNumberOfArguments()) + - " Locals: " + to_string(GetMethod()->GetNumberOfLocals()) + - " MaxStack:" + to_string(GetMethod()->GetMaximumNumberOfStackElements()) + - "\n"); + Print(GetMethod()->AsDebugString() + + ", bc: " + to_string(GetBytecodeIndex()) + "\n" + + "Args: " + to_string(GetMethod()->GetNumberOfArguments()) + + " Locals: " + to_string(GetMethod()->GetNumberOfLocals()) + + " MaxStack:" + + to_string(GetMethod()->GetMaximumNumberOfStackElements()) + "\n"); for (size_t i = 0; i < GetMethod()->GetNumberOfArguments(); i++) { Print(" arg " + to_string(i) + ": "); @@ -230,7 +238,7 @@ void VMFrame::PrintStack() const { print_oop(locals[local_offset + i]); } - gc_oop_t* end = (gc_oop_t*) SHIFTED_PTR(this, totalObjectSize); + gc_oop_t* end = (gc_oop_t*)SHIFTED_PTR(this, totalObjectSize); size_t i = 0; while (&locals[local_offset + max + i] < end) { if (stack_ptr == &locals[local_offset + max + i]) { diff --git a/src/vmobjects/VMFrame.h b/src/vmobjects/VMFrame.h index 64872237..0dfb4abf 100644 --- a/src/vmobjects/VMFrame.h +++ b/src/vmobjects/VMFrame.h @@ -31,8 +31,9 @@ class Universe; -class VMFrame: public VMObject { +class VMFrame : public VMObject { friend class Universe; + public: typedef GCFrame Stored; @@ -59,18 +60,14 @@ class VMFrame: public VMObject { return result; } - inline void PopVoid() { - stack_ptr--; - } + inline void PopVoid() { stack_ptr--; } inline vm_oop_t Top() { vm_oop_t result = load_ptr(*stack_ptr); return result; } - inline void SetTop(gc_oop_t val) { - *stack_ptr = val; - } + inline void SetTop(gc_oop_t val) { *stack_ptr = val; } inline void Push(vm_oop_t obj) { assert(RemainingStackSize() > 0); @@ -132,7 +129,8 @@ class VMFrame: public VMObject { StdString AsDebugString() const override; -private_testable: + make_testable(public); + long bytecodeIndex; private: diff --git a/src/vmobjects/VMInteger.cpp b/src/vmobjects/VMInteger.cpp index f0b99dfc..be23394e 100644 --- a/src/vmobjects/VMInteger.cpp +++ b/src/vmobjects/VMInteger.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMInteger.h" + #include #include "../memory/Heap.h" @@ -31,7 +33,6 @@ #include "../vm/Globals.h" #include "ObjectFormats.h" #include "VMClass.h" -#include "VMInteger.h" VMInteger* VMInteger::CloneForMovingGC() const { return new (GetHeap(), 0 ALLOC_MATURE) VMInteger(*this); diff --git a/src/vmobjects/VMInteger.h b/src/vmobjects/VMInteger.h index 2a7098b8..7a1890f9 100644 --- a/src/vmobjects/VMInteger.h +++ b/src/vmobjects/VMInteger.h @@ -26,12 +26,11 @@ THE SOFTWARE. */ +#include "../misc/defs.h" #include "AbstractObject.h" #include "IntegerBox.h" -#include "../misc/defs.h" - -class VMInteger: public AbstractVMObject { +class VMInteger : public AbstractVMObject { public: typedef GCInteger Stored; @@ -43,16 +42,15 @@ class VMInteger: public AbstractVMObject { VMClass* GetClass() const override; inline size_t GetObjectSize() const override; - inline int64_t GetHash() const override { - return (int64_t) embeddedInteger; - } + inline int64_t GetHash() const override { return (int64_t)embeddedInteger; } void MarkObjectAsInvalid() override; bool IsMarkedInvalid() const override; StdString AsDebugString() const override; -private_testable: + make_testable(public); + int64_t embeddedInteger; }; @@ -61,6 +59,6 @@ int64_t VMInteger::GetEmbeddedInteger() const { } size_t VMInteger::GetObjectSize() const { - //no need to pad -> sizeof returns padded size anyway + // no need to pad -> sizeof returns padded size anyway return sizeof(VMInteger); } diff --git a/src/vmobjects/VMInvokable.cpp b/src/vmobjects/VMInvokable.cpp index 98b2c6cf..08f594f0 100644 --- a/src/vmobjects/VMInvokable.cpp +++ b/src/vmobjects/VMInvokable.cpp @@ -24,9 +24,10 @@ THE SOFTWARE. */ +#include "VMInvokable.h" + #include "ObjectFormats.h" #include "VMClass.h" -#include "VMInvokable.h" #include "VMSymbol.h" bool VMInvokable::IsPrimitive() const { diff --git a/src/vmobjects/VMInvokable.h b/src/vmobjects/VMInvokable.h index 9d00a7c1..38248194 100644 --- a/src/vmobjects/VMInvokable.h +++ b/src/vmobjects/VMInvokable.h @@ -30,26 +30,28 @@ #include "VMObject.h" #include "VMSymbol.h" -class VMInvokable: public AbstractVMObject { +class VMInvokable : public AbstractVMObject { public: typedef GCInvokable Stored; - explicit VMInvokable(VMSymbol* sig) : hash((intptr_t) this), signature(store_with_separate_barrier(sig)) {} + explicit VMInvokable(VMSymbol* sig) + : hash((intptr_t)this), signature(store_with_separate_barrier(sig)) {} int64_t GetHash() const override { return hash; } - virtual void Invoke(Interpreter*, VMFrame*) = 0; + virtual void Invoke(Interpreter*, VMFrame*) = 0; - virtual bool IsPrimitive() const; - VMSymbol* GetSignature() const; - VMClass* GetHolder() const; - virtual void SetHolder(VMClass* hld); + virtual bool IsPrimitive() const; + VMSymbol* GetSignature() const; + VMClass* GetHolder() const; + virtual void SetHolder(VMClass* hld); void WalkObjects(walk_heap_fn) override; -protected_testable: + make_testable(public); + int64_t hash; GCSymbol* signature; - GCClass* holder{nullptr}; + GCClass* holder{nullptr}; }; diff --git a/src/vmobjects/VMMethod.cpp b/src/vmobjects/VMMethod.cpp index f068c2fa..53297cb2 100644 --- a/src/vmobjects/VMMethod.cpp +++ b/src/vmobjects/VMMethod.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMMethod.h" + #include #include #include @@ -40,17 +42,25 @@ #include "../memory/Heap.h" #include "../misc/defs.h" #include "../vm/Globals.h" -#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) it's required to make the types complete +#include "../vm/Universe.h" // NOLINT(misc-include-cleaner) it's required to make the types complete #include "ObjectFormats.h" #include "Signature.h" #include "VMClass.h" #include "VMFrame.h" -#include "VMMethod.h" #include "VMObject.h" #include "VMSymbol.h" -VMMethod::VMMethod(VMSymbol* signature, size_t bcCount, size_t numberOfConstants, size_t numLocals, size_t maxStackDepth, LexicalScope* lexicalScope, BackJump* inlinedLoops) : - VMInvokable(signature), numberOfLocals(numLocals), maximumNumberOfStackElements(maxStackDepth), bcLength(bcCount), numberOfArguments(signature == nullptr ? 0 : Signature::GetNumberOfArguments(signature)), numberOfConstants(numberOfConstants), lexicalScope(lexicalScope), inlinedLoops(inlinedLoops) { +VMMethod::VMMethod(VMSymbol* signature, size_t bcCount, + size_t numberOfConstants, size_t numLocals, + size_t maxStackDepth, LexicalScope* lexicalScope, + BackJump* inlinedLoops) + : VMInvokable(signature), numberOfLocals(numLocals), + maximumNumberOfStackElements(maxStackDepth), bcLength(bcCount), + numberOfArguments(signature == nullptr + ? 0 + : Signature::GetNumberOfArguments(signature)), + numberOfConstants(numberOfConstants), lexicalScope(lexicalScope), + inlinedLoops(inlinedLoops) { #ifdef UNSAFE_FRAME_OPTIMIZATION cachedFrame = nullptr; #endif @@ -65,17 +75,20 @@ VMMethod::VMMethod(VMSymbol* signature, size_t bcCount, size_t numberOfConstants } VMMethod* VMMethod::CloneForMovingGC() const { - VMMethod* clone = new (GetHeap(), GetObjectSize() - sizeof(VMMethod) ALLOC_MATURE) VMMethod(*this); - memcpy(SHIFTED_PTR(clone, sizeof(VMObject)), SHIFTED_PTR(this, - sizeof(VMObject)), GetObjectSize() - - sizeof(VMObject)); + VMMethod* clone = + new (GetHeap(), + GetObjectSize() - sizeof(VMMethod) ALLOC_MATURE) VMMethod(*this); + memcpy(SHIFTED_PTR(clone, sizeof(VMObject)), + SHIFTED_PTR(this, sizeof(VMObject)), + GetObjectSize() - sizeof(VMObject)); clone->indexableFields = (gc_oop_t*)(&(clone->indexableFields) + 2); - size_t numIndexableFields = GetNumberOfIndexableFields(); - clone->bytecodes = (uint8_t*)(&(clone->indexableFields) + 2 + numIndexableFields); + clone->bytecodes = + (uint8_t*)(&(clone->indexableFields) + 2 + numIndexableFields); - // Use of GetNumberOfIndexableFields() is problematic here, because it may be invalid object while cloning/moving within GC + // Use of GetNumberOfIndexableFields() is problematic here, because it may + // be invalid object while cloning/moving within GC return clone; } @@ -83,8 +96,9 @@ void VMMethod::WalkObjects(walk_heap_fn walk) { VMInvokable::WalkObjects(walk); #ifdef UNSAFE_FRAME_OPTIMIZATION - if (cachedFrame != nullptr) + if (cachedFrame != nullptr) { cachedFrame = static_cast(walk(cachedFrame)); + } #endif size_t numIndexableFields = GetNumberOfIndexableFields(); @@ -116,7 +130,7 @@ void VMMethod::Invoke(Interpreter* interp, VMFrame* frame) { frm->CopyArgumentsFrom(frame); } -void VMMethod::SetHolder(VMClass *hld) { +void VMMethod::SetHolder(VMClass* hld) { VMInvokable::SetHolder(hld); SetHolderAll(hld); } @@ -142,7 +156,8 @@ std::string VMMethod::AsDebugString() const { } else { holder_str = holder->GetName()->GetStdString(); } - return "Method(" + holder_str + ">>#" + GetSignature()->GetStdString() + ")"; + return "Method(" + holder_str + ">>#" + GetSignature()->GetStdString() + + ")"; } void VMMethod::InlineInto(MethodGenerationContext& mgenc) { @@ -163,7 +178,8 @@ std::priority_queue VMMethod::createBackJumpHeap() { } void VMMethod::inlineInto(MethodGenerationContext& mgenc) { - std::priority_queue jumps; // priority queue sorted by originalJumpTargetIdx + std::priority_queue + jumps; // priority queue sorted by originalJumpTargetIdx std::priority_queue backJumps = createBackJumpHeap(); std::priority_queue backJumpsToPatch; @@ -191,17 +207,34 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { idx = bytecodes[i + 1]; } else { switch (bytecode) { - case BC_PUSH_FIELD_0: { idx = 0; break; } - case BC_PUSH_FIELD_1: { idx = 1; break; } - case BC_POP_FIELD_0: { idx = 0; break; } - case BC_POP_FIELD_1: { idx = 1; break; } + case BC_PUSH_FIELD_0: { + idx = 0; + break; + } + case BC_PUSH_FIELD_1: { + idx = 1; + break; + } + case BC_POP_FIELD_0: { + idx = 0; + break; + } + case BC_POP_FIELD_1: { + idx = 1; + break; + } } } - if (bytecode == BC_PUSH_FIELD || bytecode == BC_PUSH_FIELD_0 || bytecode == BC_PUSH_FIELD_1) { - EmitPushFieldWithIndex(mgenc, idx, 0 /* dummy, self is looked up dynamically at the moment. */); + if (bytecode == BC_PUSH_FIELD || bytecode == BC_PUSH_FIELD_0 || + bytecode == BC_PUSH_FIELD_1) { + EmitPushFieldWithIndex( + mgenc, idx, + 0 /* dummy, self is looked up dynamically at the moment. */); } else { - EmitPopFieldWithIndex(mgenc, idx, 0 /* dummy, self is looked up dynamically at the moment. */); + EmitPopFieldWithIndex( + mgenc, idx, + 0 /* dummy, self is looked up dynamically at the moment. */); } break; } @@ -274,7 +307,7 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { } case BC_PUSH_BLOCK: { - VMMethod* blockMethod = (VMMethod*) GetConstant(i); + VMMethod* blockMethod = (VMMethod*)GetConstant(i); blockMethod->AdaptAfterOuterInlined(1, mgenc); EmitPUSHBLOCK(mgenc, blockMethod); break; @@ -300,7 +333,8 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { } case BC_POP: { // TODO: PySOM simply does Emit1 - // not sure whether EmitPOP might cause issues if we try to do optimizations here again + // not sure whether EmitPOP might cause issues if we try to do + // optimizations here again EmitPOP(mgenc); break; } @@ -310,7 +344,7 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { break; } case BC_PUSH_GLOBAL: { - VMSymbol* const sym = (VMSymbol*) GetConstant(i); + VMSymbol* const sym = (VMSymbol*)GetConstant(i); EmitPUSHGLOBAL(mgenc, sym); break; } @@ -319,12 +353,12 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { case BC_SEND_2: case BC_SEND_3: case BC_SEND_N: { - VMSymbol* const sym = (VMSymbol*) GetConstant(i); + VMSymbol* const sym = (VMSymbol*)GetConstant(i); EmitSEND(mgenc, sym); break; } case BC_SUPER_SEND: { - VMSymbol* const sym = (VMSymbol*) GetConstant(i); + VMSymbol* const sym = (VMSymbol*)GetConstant(i); EmitSUPERSEND(mgenc, sym); break; } @@ -350,7 +384,8 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { case BC_JUMP2_ON_FALSE_TOP_NIL: { // emit the jump, but instead of the offset, emit a dummy const size_t idx = Emit3WithDummy(mgenc, bytecode, 0); - const size_t offset = ComputeOffset(bytecodes[i + 1], bytecodes[i + 2]); + const size_t offset = + ComputeOffset(bytecodes[i + 1], bytecodes[i + 2]); jumps.emplace(Jump(i + offset, bytecode, idx)); break; @@ -361,15 +396,16 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { case BC_JUMP2_ON_FALSE_POP: { // emit the jump, but instead of the offset, emit a dummy const size_t idx = Emit3WithDummy(mgenc, bytecode, -1); - const size_t offset = ComputeOffset(bytecodes[i + 1], bytecodes[i + 2]); + const size_t offset = + ComputeOffset(bytecodes[i + 1], bytecodes[i + 2]); jumps.emplace(Jump(i + offset, bytecode, idx)); break; } case BC_JUMP_BACKWARD: case BC_JUMP2_BACKWARD: { const size_t loopBeginIdx = backJumpsToPatch.top().loopBeginIdx; - assert(backJumpsToPatch.top().backwardsJumpIdx == i - && "the jump should match with the jump instructions"); + assert(backJumpsToPatch.top().backwardsJumpIdx == i && + "the jump should match with the jump instructions"); backJumpsToPatch.pop(); mgenc.EmitBackwardsJumpOffsetToTarget(loopBeginIdx); @@ -385,13 +421,21 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { case BC_RETURN_FIELD_1: case BC_RETURN_FIELD_2: { char msg[120]; - snprintf(msg, 120, "inlineInto: Found %s bytecode, but it's not expected in a block method", Bytecode::GetBytecodeName(bytecode)); + snprintf( + msg, 120, + "inlineInto: Found %s bytecode, but it's not expected in a " + "block method", + Bytecode::GetBytecodeName(bytecode)); Universe::ErrorExit(msg); break; } default: { char msg[120]; - snprintf(msg, 120, "inlineInto: Found %s bytecode, but inlining of it is not yet supported.", Bytecode::GetBytecodeName(bytecode)); + snprintf(msg, 120, + "inlineInto: Found %s bytecode, but inlining of it is " + "not yet " + "supported.", + Bytecode::GetBytecodeName(bytecode)); Universe::ErrorExit(msg); break; } @@ -403,27 +447,40 @@ void VMMethod::inlineInto(MethodGenerationContext& mgenc) { assert(jumps.empty()); } -void VMMethod::patchJumpToCurrentAddress(size_t i, std::priority_queue& jumps, MethodGenerationContext& mgenc) { +void VMMethod::patchJumpToCurrentAddress(size_t i, + std::priority_queue& jumps, + MethodGenerationContext& mgenc) { while (!jumps.empty() && jumps.top().originalJumpTargetIdx <= i) { Jump jump = jumps.top(); jumps.pop(); - assert(jump.originalJumpTargetIdx == i && "we use the less or equal, but actually expect it to be strictly equal"); + assert( + jump.originalJumpTargetIdx == i && + "we use the less or equal, but actually expect it to be strictly " + "equal"); mgenc.PatchJumpOffsetToPointToNextInstruction(jump.idx); } } -void VMMethod::prepareBackJumpToCurrentAddress(std::priority_queue& backJumps, std::priority_queue& backJumpsToPatch, size_t i, MethodGenerationContext& mgenc) { +void VMMethod::prepareBackJumpToCurrentAddress( + std::priority_queue& backJumps, + std::priority_queue& backJumpsToPatch, size_t i, + MethodGenerationContext& mgenc) { while (!backJumps.empty() && backJumps.top().loopBeginIdx <= i) { BackJump jump = backJumps.top(); backJumps.pop(); - assert(jump.loopBeginIdx == i && "we use the less or equal, but actually expect it to be strictly equal"); - backJumpsToPatch.emplace(BackJumpPatch(jump.backwardJumpIdx, mgenc.OffsetOfNextInstruction())); + assert( + jump.loopBeginIdx == i && + "we use the less or equal, but actually expect it to be strictly " + "equal"); + backJumpsToPatch.emplace(BackJumpPatch( + jump.backwardJumpIdx, mgenc.OffsetOfNextInstruction())); } } -void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationContext& mgencWithInlined) { +void VMMethod::AdaptAfterOuterInlined( + uint8_t removedCtxLevel, MethodGenerationContext& mgencWithInlined) { size_t i = 0; long numBytecodes = GetNumberOfBytecodes(); @@ -440,7 +497,7 @@ void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationC case BC_PUSH_0: case BC_PUSH_1: case BC_PUSH_NIL: - case BC_PUSH_GLOBAL: // BC_PUSH_GLOBAL doesn't encode context + case BC_PUSH_GLOBAL: // BC_PUSH_GLOBAL doesn't encode context case BC_PUSH_FIELD: case BC_POP_FIELD: case BC_POP: @@ -465,7 +522,8 @@ void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationC case BC_JUMP2_ON_FALSE_TOP_NIL: case BC_JUMP2_ON_FALSE_POP: case BC_JUMP2_BACKWARD: { - // these bytecodes do not use context and don't need to be adapted + // these bytecodes do not use context and don't need to be + // adapted break; } @@ -482,7 +540,8 @@ void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationC case BC_PUSH_BLOCK: { VMMethod* blockMethod = static_cast(GetConstant(i)); - blockMethod->AdaptAfterOuterInlined(removedCtxLevel + 1, mgencWithInlined); + blockMethod->AdaptAfterOuterInlined(removedCtxLevel + 1, + mgencWithInlined); break; } @@ -497,7 +556,8 @@ void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationC // at this point, the lexical scope has not been changed // so, we should still be able to find the right one auto* oldVar = lexicalScope->GetLocal(idx, ctxLevel); - uint8_t newIdx = mgencWithInlined.GetInlinedLocalIdx(oldVar); + uint8_t newIdx = + mgencWithInlined.GetInlinedLocalIdx(oldVar); bytecodes[i + 1] = newIdx; } else if (ctxLevel > removedCtxLevel) { bytecodes[i + 2] = ctxLevel - 1; @@ -515,7 +575,7 @@ void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationC case BC_PUSH_FIELD_1: case BC_POP_LOCAL_0: case BC_POP_LOCAL_1: - case BC_POP_LOCAL_2: + case BC_POP_LOCAL_2: case BC_POP_FIELD_0: case BC_POP_FIELD_1: { break; @@ -527,13 +587,21 @@ void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationC case BC_RETURN_FIELD_1: case BC_RETURN_FIELD_2: { char msg[120]; - snprintf(msg, 120, "AdaptAfterOuterInlined: Found %s bytecode, but it's not expected in a block method", Bytecode::GetBytecodeName(bytecode)); + snprintf( + msg, 120, + "AdaptAfterOuterInlined: Found %s bytecode, but it's not " + "expected in a block method", + Bytecode::GetBytecodeName(bytecode)); Universe::ErrorExit(msg); } default: { char msg[120]; - snprintf(msg, 120, "Found %s bytecode, but AdaptAfterOuterInlined does not yet support it.", Bytecode::GetBytecodeName(bytecode)); + snprintf(msg, 120, + "Found %s bytecode, but AdaptAfterOuterInlined does " + "not yet " + "support it.", + Bytecode::GetBytecodeName(bytecode)); Universe::ErrorExit(msg); } } @@ -547,13 +615,13 @@ void VMMethod::AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationC } bool operator<(const Jump& a, const Jump& b) { - return a.originalJumpTargetIdx > b.originalJumpTargetIdx; + return a.originalJumpTargetIdx > b.originalJumpTargetIdx; } bool operator<(const BackJump& a, const BackJump& b) { - return a.loopBeginIdx > b.loopBeginIdx; + return a.loopBeginIdx > b.loopBeginIdx; } bool operator<(const BackJumpPatch& a, const BackJumpPatch& b) { - return a.backwardsJumpIdx > b.backwardsJumpIdx; + return a.backwardsJumpIdx > b.backwardsJumpIdx; } diff --git a/src/vmobjects/VMMethod.h b/src/vmobjects/VMMethod.h index 2ac80acc..f6f46039 100644 --- a/src/vmobjects/VMMethod.h +++ b/src/vmobjects/VMMethod.h @@ -40,74 +40,70 @@ class Interpreter; class Jump { public: - Jump(size_t originalJumpTargetIdx, uint8_t jumpBc, size_t idx) : originalJumpTargetIdx(originalJumpTargetIdx), jumpBc(jumpBc), idx(idx) {} + Jump(size_t originalJumpTargetIdx, uint8_t jumpBc, size_t idx) + : originalJumpTargetIdx(originalJumpTargetIdx), jumpBc(jumpBc), + idx(idx) {} -// Jump(Jump&& jmp) = default; -// Jump(const Jump& jmp) = default; + // Jump(Jump&& jmp) = default; + // Jump(const Jump& jmp) = default; - size_t originalJumpTargetIdx; // order by + size_t originalJumpTargetIdx; // order by uint8_t jumpBc; - size_t idx; + size_t idx; }; bool operator<(const Jump& a, const Jump& b); - class BackJump { public: - BackJump(size_t loopBeginIdx, size_t backwardJumpIdx) : loopBeginIdx(loopBeginIdx), backwardJumpIdx(backwardJumpIdx) {} + BackJump(size_t loopBeginIdx, size_t backwardJumpIdx) + : loopBeginIdx(loopBeginIdx), backwardJumpIdx(backwardJumpIdx) {} BackJump(const BackJump& jmp) = default; BackJump() : loopBeginIdx(-1), backwardJumpIdx(-1) {} - size_t loopBeginIdx; // order by + size_t loopBeginIdx; // order by size_t backwardJumpIdx; - bool IsValid() const { - return loopBeginIdx != -1; - } + bool IsValid() const { return loopBeginIdx != -1; } }; bool operator<(const BackJump& a, const BackJump& b); - class BackJumpPatch { public: - BackJumpPatch(size_t backwardsJumpIdx, size_t loopBeginIdx) : backwardsJumpIdx(backwardsJumpIdx), loopBeginIdx(loopBeginIdx) {} + BackJumpPatch(size_t backwardsJumpIdx, size_t loopBeginIdx) + : backwardsJumpIdx(backwardsJumpIdx), loopBeginIdx(loopBeginIdx) {} BackJumpPatch(const BackJumpPatch& patch) = default; - size_t backwardsJumpIdx; // order by + size_t backwardsJumpIdx; // order by size_t loopBeginIdx; }; bool operator<(const BackJumpPatch& a, const BackJumpPatch& b); - -class VMMethod: public VMInvokable { +class VMMethod : public VMInvokable { friend class Interpreter; friend class Disassembler; public: typedef GCMethod Stored; - VMMethod(VMSymbol* signature, size_t bcCount, size_t numberOfConstants, size_t numLocals, size_t maxStackDepth, LexicalScope* lexicalScope, BackJump* inlinedLoops); + VMMethod(VMSymbol* signature, size_t bcCount, size_t numberOfConstants, + size_t numLocals, size_t maxStackDepth, LexicalScope* lexicalScope, + BackJump* inlinedLoops); - ~VMMethod() override { - delete lexicalScope; - } + ~VMMethod() override { delete lexicalScope; } - inline size_t GetNumberOfLocals() const { - return numberOfLocals; - } + inline size_t GetNumberOfLocals() const { return numberOfLocals; } - VMClass* GetClass() const override { - return load_ptr(methodClass); - } + VMClass* GetClass() const override { return load_ptr(methodClass); } inline size_t GetObjectSize() const override { - size_t additionalBytes = PADDED_SIZE(bcLength + numberOfConstants*sizeof(VMObject*)); + size_t additionalBytes = + PADDED_SIZE(bcLength + numberOfConstants * sizeof(VMObject*)); return additionalBytes + sizeof(VMMethod); } @@ -115,33 +111,25 @@ class VMMethod: public VMInvokable { return maximumNumberOfStackElements; } - inline size_t GetNumberOfArguments() const { - return numberOfArguments; - } + inline size_t GetNumberOfArguments() const { return numberOfArguments; } - size_t GetNumberOfBytecodes() const { - return bcLength; - } - void SetHolder(VMClass* hld) override; - void SetHolderAll(VMClass* hld); - - inline vm_oop_t GetConstant(size_t bytecodeIndex) const { - const uint8_t bc = bytecodes[bytecodeIndex + 1]; - if (bc >= GetNumberOfIndexableFields()) { - ErrorPrint("Error: Constant index out of range\n"); - return nullptr; - } - return GetIndexableField(bc); - } - - inline uint8_t GetBytecode(long indx) const { - return bytecodes[indx]; - } + size_t GetNumberOfBytecodes() const { return bcLength; } + void SetHolder(VMClass* hld) override; + void SetHolderAll(VMClass* hld); - inline void SetBytecode(long indx, uint8_t val) { - bytecodes[indx] = val; + inline vm_oop_t GetConstant(size_t bytecodeIndex) const { + const uint8_t bc = bytecodes[bytecodeIndex + 1]; + if (bc >= GetNumberOfIndexableFields()) { + ErrorPrint("Error: Constant index out of range\n"); + return nullptr; + } + return GetIndexableField(bc); } + inline uint8_t GetBytecode(long indx) const { return bytecodes[indx]; } + + inline void SetBytecode(long indx, uint8_t val) { bytecodes[indx] = val; } + #ifdef UNSAFE_FRAME_OPTIMIZATION void SetCachedFrame(VMFrame* frame); VMFrame* GetCachedFrame() const; @@ -149,49 +137,54 @@ class VMMethod: public VMInvokable { void WalkObjects(walk_heap_fn) override; - inline size_t GetNumberOfIndexableFields() const { + inline size_t GetNumberOfIndexableFields() const { return numberOfConstants; } VMMethod* CloneForMovingGC() const override; - inline void SetIndexableField(long idx, vm_oop_t item) { + inline void SetIndexableField(long idx, vm_oop_t item) { store_ptr(indexableFields[idx], item); } void Invoke(Interpreter* interp, VMFrame* frame) override; void MarkObjectAsInvalid() override { - indexableFields = (gc_oop_t*) INVALID_GC_POINTER; + indexableFields = (gc_oop_t*)INVALID_GC_POINTER; } bool IsMarkedInvalid() const override { - return indexableFields == (gc_oop_t*) INVALID_GC_POINTER; + return indexableFields == (gc_oop_t*)INVALID_GC_POINTER; } StdString AsDebugString() const override; void InlineInto(MethodGenerationContext& mgenc); - void AdaptAfterOuterInlined(uint8_t removedCtxLevel, MethodGenerationContext& mgencWithInlined); + void AdaptAfterOuterInlined(uint8_t removedCtxLevel, + MethodGenerationContext& mgencWithInlined); private: void inlineInto(MethodGenerationContext& mgenc); std::priority_queue createBackJumpHeap(); - inline uint8_t* GetBytecodes() const { - return bytecodes; - } + inline uint8_t* GetBytecodes() const { return bytecodes; } inline vm_oop_t GetIndexableField(long idx) const { return load_ptr(indexableFields[idx]); } - static void prepareBackJumpToCurrentAddress(std::priority_queue& backJumps, std::priority_queue& backJumpsToPatch, size_t i, MethodGenerationContext& mgenc); + static void prepareBackJumpToCurrentAddress( + std::priority_queue& backJumps, + std::priority_queue& backJumpsToPatch, size_t i, + MethodGenerationContext& mgenc); + + static void patchJumpToCurrentAddress(size_t i, + std::priority_queue& jumps, + MethodGenerationContext& mgenc); - static void patchJumpToCurrentAddress(size_t i, std::priority_queue& jumps, MethodGenerationContext& mgenc); + make_testable(public); -private_testable: const size_t numberOfLocals; const size_t maximumNumberOfStackElements; const size_t bcLength; @@ -200,7 +193,7 @@ class VMMethod: public VMInvokable { private: LexicalScope* lexicalScope; - BackJump* inlinedLoops; + BackJump* inlinedLoops; #ifdef UNSAFE_FRAME_OPTIMIZATION GCFrame* cachedFrame; diff --git a/src/vmobjects/VMObject.cpp b/src/vmobjects/VMObject.cpp index 89d77467..0289ffc1 100644 --- a/src/vmobjects/VMObject.cpp +++ b/src/vmobjects/VMObject.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMObject.h" + #include #include #include @@ -36,27 +38,31 @@ #include "ObjectFormats.h" #include "VMClass.h" #include "VMFrame.h" -#include "VMObject.h" #include "VMSymbol.h" // clazz is the only field of VMObject so const size_t VMObject::VMObjectNumberOfFields = 0; -VMObject::VMObject(size_t numSubclassFields, size_t totalObjectSize) : totalObjectSize(totalObjectSize), numberOfFields(VMObjectNumberOfFields + numSubclassFields) { +VMObject::VMObject(size_t numSubclassFields, size_t totalObjectSize) + : totalObjectSize(totalObjectSize), + numberOfFields(VMObjectNumberOfFields + numSubclassFields) { assert(IS_PADDED_SIZE(totalObjectSize)); assert(totalObjectSize >= sizeof(VMObject)); // this line would be needed if the VMObject** is used instead of the macro: // FIELDS = (VMObject**)&clazz; - hash = (size_t) this; + hash = (size_t)this; nilInitializeFields(); } VMObject* VMObject::CloneForMovingGC() const { - VMObject* clone = new (GetHeap(), totalObjectSize - sizeof(VMObject) ALLOC_MATURE) VMObject(*this); + VMObject* clone = + new (GetHeap(), + totalObjectSize - sizeof(VMObject) ALLOC_MATURE) VMObject(*this); memcpy(SHIFTED_PTR(clone, sizeof(VMObject)), - SHIFTED_PTR(this, sizeof(VMObject)), totalObjectSize - sizeof(VMObject)); + SHIFTED_PTR(this, sizeof(VMObject)), + totalObjectSize - sizeof(VMObject)); return clone; } @@ -88,7 +94,7 @@ void VMObject::WalkObjects(walk_heap_fn walk) { } void VMObject::MarkObjectAsInvalid() { - clazz = (GCClass*) INVALID_GC_POINTER; + clazz = (GCClass*)INVALID_GC_POINTER; long numFields = GetNumberOfFields(); for (long i = 0; i < numFields; ++i) { diff --git a/src/vmobjects/VMObject.h b/src/vmobjects/VMObject.h index d75a0d8a..34279146 100644 --- a/src/vmobjects/VMObject.h +++ b/src/vmobjects/VMObject.h @@ -36,7 +36,7 @@ #include "ObjectFormats.h" // this macro returns a shifted ptr by offset bytes -#define SHIFTED_PTR(ptr, offset) ((void*)((size_t)(ptr)+(size_t)(offset))) +#define SHIFTED_PTR(ptr, offset) ((void*)((size_t)(ptr) + (size_t)(offset))) /* chbol: this table is not correct anymore because of introduction of * class AbstractVMObject @@ -57,8 +57,7 @@ // FIELDS starts indexing after the clazz field #define FIELDS (((gc_oop_t*)&clazz) + 1) -class VMObject: public AbstractVMObject { - +class VMObject : public AbstractVMObject { public: typedef GCObject Stored; @@ -69,10 +68,10 @@ class VMObject: public AbstractVMObject { ~VMObject() override = default; int64_t GetHash() const override { return hash; } - inline VMClass* GetClass() const override; - void SetClass(VMClass* cl) override; - VMSymbol* GetFieldName(long index) const override; - inline long GetNumberOfFields() const override; + inline VMClass* GetClass() const override; + void SetClass(VMClass* cl) override; + VMSymbol* GetFieldName(long index) const override; + inline long GetNumberOfFields() const override; inline vm_oop_t GetField(size_t index) const { vm_oop_t result = load_ptr(FIELDS[index]); @@ -85,19 +84,17 @@ class VMObject: public AbstractVMObject { store_ptr(FIELDS[index], value); } - virtual void Assert(bool value) const; - void WalkObjects(walk_heap_fn walk) override; + virtual void Assert(bool value) const; + void WalkObjects(walk_heap_fn walk) override; VMObject* CloneForMovingGC() const override; - + /** The total size of the object on the heap. */ - inline size_t GetObjectSize() const override { - return totalObjectSize; - } + inline size_t GetObjectSize() const override { return totalObjectSize; } - void MarkObjectAsInvalid() override; - bool IsMarkedInvalid() const final; + void MarkObjectAsInvalid() override; + bool IsMarkedInvalid() const final; - StdString AsDebugString() const override; + StdString AsDebugString() const override; protected: void nilInitializeFields(); @@ -105,11 +102,14 @@ class VMObject: public AbstractVMObject { // VMObject essentials int64_t hash; -protected_testable: + make_testable(public); + /** Size of the object in the heap, */ size_t totalObjectSize; - /** Number of fields, excluding `class` but including fields of any subclass. */ + /** Number of fields, excluding `class` but including fields of any + * subclass. + */ size_t numberOfFields; GCClass* clazz{nullptr}; @@ -122,7 +122,7 @@ class VMObject: public AbstractVMObject { }; VMClass* VMObject::GetClass() const { - assert(IsValidObject((VMObject*) load_ptr(clazz))); + assert(IsValidObject((VMObject*)load_ptr(clazz))); return load_ptr(clazz); } diff --git a/src/vmobjects/VMObjectBase.h b/src/vmobjects/VMObjectBase.h index 39282a6d..50167fe6 100644 --- a/src/vmobjects/VMObjectBase.h +++ b/src/vmobjects/VMObjectBase.h @@ -3,13 +3,15 @@ #define MASK_OBJECT_IS_MARKED (1U << 0U) #define MASK_OBJECT_IS_OLD (1U << 1U) #define MASK_SEEN_BY_WRITE_BARRIER (1U << 2U) -#define MASK_BITS_ALL (MASK_OBJECT_IS_MARKED | MASK_OBJECT_IS_OLD | MASK_SEEN_BY_WRITE_BARRIER) +#define MASK_BITS_ALL \ + (MASK_OBJECT_IS_MARKED | MASK_OBJECT_IS_OLD | MASK_SEEN_BY_WRITE_BARRIER) #include class VMObjectBase : public VMOop { protected: size_t gcfield{0}; + public: inline size_t GetGCField() const; inline void SetGCField(size_t); @@ -21,11 +23,11 @@ size_t VMObjectBase::GetGCField() const { return gcfield; } void VMObjectBase::SetGCField(size_t val) { - // if gcfield is used as a forwarding pointer it should not be overwritten - // with simple mark bits, because the object itself is garbage but the - // forwarding address needs to be maintained incase any object still points - // to the garbage object. - #define GCFIELD_IS_NOT_FORWARDING_POINTER (gcfield <= MASK_BITS_ALL) +// if gcfield is used as a forwarding pointer it should not be overwritten +// with simple mark bits, because the object itself is garbage but the +// forwarding address needs to be maintained incase any object still points +// to the garbage object. +#define GCFIELD_IS_NOT_FORWARDING_POINTER (gcfield <= MASK_BITS_ALL) #if GC_TYPE != MARK_SWEEP assert(GCFIELD_IS_NOT_FORWARDING_POINTER || val > MASK_BITS_ALL); #endif diff --git a/src/vmobjects/VMPrimitive.cpp b/src/vmobjects/VMPrimitive.cpp index c1e13c1d..40c0be24 100644 --- a/src/vmobjects/VMPrimitive.cpp +++ b/src/vmobjects/VMPrimitive.cpp @@ -24,31 +24,36 @@ THE SOFTWARE. */ +#include "VMPrimitive.h" + #include #include "../memory/Heap.h" #include "../misc/defs.h" #include "../primitivesCore/Routine.h" -#include "../vm/Globals.h" // NOLINT (misc-include-cleaner) +#include "../vm/Globals.h" // NOLINT (misc-include-cleaner) #include "../vm/Print.h" #include "ObjectFormats.h" #include "VMClass.h" #include "VMFrame.h" -#include "VMPrimitive.h" #include "VMSymbol.h" VMPrimitive* VMPrimitive::GetEmptyPrimitive(VMSymbol* sig, bool classSide) { VMPrimitive* prim = new (GetHeap(), 0) VMPrimitive(sig); - prim->SetRoutine(new Routine(prim, &VMPrimitive::EmptyRoutine, classSide), true); + prim->SetRoutine( + new Routine(prim, &VMPrimitive::EmptyRoutine, classSide), + true); return prim; } -VMPrimitive::VMPrimitive(VMSymbol* signature) : VMInvokable(signature), routine(nullptr), empty(false) { +VMPrimitive::VMPrimitive(VMSymbol* signature) + : VMInvokable(signature), routine(nullptr), empty(false) { write_barrier(this, signature); } VMPrimitive* VMPrimitive::CloneForMovingGC() const { - VMPrimitive* prim = new (GetHeap(), 0 ALLOC_MATURE) VMPrimitive(*this); + VMPrimitive* prim = + new (GetHeap(), 0 ALLOC_MATURE) VMPrimitive(*this); return prim; } @@ -58,6 +63,6 @@ void VMPrimitive::EmptyRoutine(Interpreter*, VMFrame*) { } std::string VMPrimitive::AsDebugString() const { - return "Primitive(" + GetClass()->GetName()->GetStdString() + ">>#" - + GetSignature()->GetStdString() + ")"; + return "Primitive(" + GetClass()->GetName()->GetStdString() + ">>#" + + GetSignature()->GetStdString() + ")"; } diff --git a/src/vmobjects/VMPrimitive.h b/src/vmobjects/VMPrimitive.h index 9de2e9c1..1badf432 100644 --- a/src/vmobjects/VMPrimitive.h +++ b/src/vmobjects/VMPrimitive.h @@ -30,7 +30,7 @@ #include "VMInvokable.h" #include "VMObject.h" -class VMPrimitive: public VMInvokable { +class VMPrimitive : public VMInvokable { public: typedef GCPrimitive Stored; @@ -38,38 +38,32 @@ class VMPrimitive: public VMInvokable { VMPrimitive(VMSymbol* sig); - VMClass* GetClass() const override { - return load_ptr(primitiveClass); - } + VMClass* GetClass() const override { return load_ptr(primitiveClass); } - inline size_t GetObjectSize() const override { - return sizeof(VMPrimitive); - } + inline size_t GetObjectSize() const override { return sizeof(VMPrimitive); } - inline bool IsEmpty() const { - return empty; - } + inline bool IsEmpty() const { return empty; } - inline void SetRoutine(PrimitiveRoutine* rtn, bool empty) { + inline void SetRoutine(PrimitiveRoutine* rtn, bool empty) { routine = rtn; this->empty = empty; } - void SetEmpty(bool value) {empty = value;}; - VMPrimitive* CloneForMovingGC() const override; + void SetEmpty(bool value) { empty = value; }; + VMPrimitive* CloneForMovingGC() const override; void Invoke(Interpreter* interp, VMFrame* frm) override { routine->Invoke(interp, frm); }; - bool IsPrimitive() const override {return true;}; + bool IsPrimitive() const override { return true; }; void MarkObjectAsInvalid() override { - routine = (PrimitiveRoutine*) INVALID_GC_POINTER; + routine = (PrimitiveRoutine*)INVALID_GC_POINTER; } bool IsMarkedInvalid() const override { - return routine == (PrimitiveRoutine*) INVALID_GC_POINTER; + return routine == (PrimitiveRoutine*)INVALID_GC_POINTER; } StdString AsDebugString() const override; @@ -77,12 +71,11 @@ class VMPrimitive: public VMInvokable { private: void EmptyRoutine(Interpreter*, VMFrame*); -protected_testable: - // protected to be able to access the field in subclass, - // for instance VMEvaluationPrimitive needs to GC the primitive object - // hold in the special routine subclass +public: PrimitiveRoutine* routine; -private_testable: +private: + make_testable(public); + bool empty; }; diff --git a/src/vmobjects/VMString.cpp b/src/vmobjects/VMString.cpp index adf3a069..107b98ef 100644 --- a/src/vmobjects/VMString.cpp +++ b/src/vmobjects/VMString.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMString.h" + #include #include @@ -31,39 +33,39 @@ #include "../misc/defs.h" #include "AbstractObject.h" #include "ObjectFormats.h" -#include "VMString.h" extern GCClass* stringClass; -//this macro could replace the chars member variable -//#define CHARS ((char*)&clazz+sizeof(VMObject*)) +// this macro could replace the chars member variable +// #define CHARS ((char*)&clazz+sizeof(VMObject*)) -VMString::VMString(const size_t length, const char* str) : - AbstractVMObject(), length(length), - // set the chars-pointer to point at the position of the first character - chars((char*) &chars + sizeof(char*)) { +VMString::VMString(const size_t length, const char* str) + : AbstractVMObject(), length(length), + // set the chars-pointer to point at the position of the first character + chars((char*)&chars + sizeof(char*)) { for (size_t i = 0; i < length; i++) { chars[i] = str[i]; } } VMString* VMString::CloneForMovingGC() const { - return new (GetHeap(), PADDED_SIZE(length) ALLOC_MATURE) VMString(length, chars); + return new (GetHeap(), PADDED_SIZE(length) ALLOC_MATURE) + VMString(length, chars); } void VMString::MarkObjectAsInvalid() { for (size_t i = 0; i < length; i++) { chars[i] = 'z'; } - chars = (char*) INVALID_GC_POINTER; + chars = (char*)INVALID_GC_POINTER; } bool VMString::IsMarkedInvalid() const { - return chars == (char*) INVALID_GC_POINTER; + return chars == (char*)INVALID_GC_POINTER; } void VMString::WalkObjects(walk_heap_fn) { - //nothing to do + // nothing to do } size_t VMString::GetObjectSize() const { @@ -80,8 +82,9 @@ size_t VMString::GetStringLength() const { } std::string VMString::GetStdString() const { - if (chars == 0) + if (chars == 0) { return std::string(""); + } return std::string(chars, length); } diff --git a/src/vmobjects/VMString.h b/src/vmobjects/VMString.h index af51e1a8..92e5e954 100644 --- a/src/vmobjects/VMString.h +++ b/src/vmobjects/VMString.h @@ -28,7 +28,7 @@ #include "AbstractObject.h" -class VMString: public AbstractVMObject { +class VMString : public AbstractVMObject { public: typedef GCString Stored; @@ -41,7 +41,7 @@ class VMString: public AbstractVMObject { hash = ((hash << 5U) + hash) + chars[i]; } - return (int64_t) hash; + return (int64_t)hash; } inline char* GetRawChars() const; @@ -58,16 +58,19 @@ class VMString: public AbstractVMObject { StdString AsDebugString() const override; -protected_testable: - //this could be replaced by the CHARS macro in VMString.cpp - //in order to decrease the object size + make_testable(public); + + // this could be replaced by the CHARS macro in VMString.cpp + // in order to decrease the object size const size_t length; char* chars; + protected: - VMString(char* const adaptedCharsPointer, const size_t length) : - // set the chars-pointer to point at the position of the first character - // as determined in the VMSymbol constructor - length(length), chars(adaptedCharsPointer) {}; //constructor to use by VMSymbol + VMString(char* const adaptedCharsPointer, const size_t length) + : // set the chars-pointer to point at the position of the first + // character as determined in the VMSymbol constructor + length(length), + chars(adaptedCharsPointer) {}; // constructor to use by VMSymbol }; char* VMString::GetRawChars() const { diff --git a/src/vmobjects/VMSymbol.cpp b/src/vmobjects/VMSymbol.cpp index 3c72bcb0..a62ca662 100644 --- a/src/vmobjects/VMSymbol.cpp +++ b/src/vmobjects/VMSymbol.cpp @@ -24,6 +24,8 @@ THE SOFTWARE. */ +#include "VMSymbol.h" + #include #include #include @@ -37,12 +39,13 @@ #include "VMClass.h" #include "VMInvokable.h" #include "VMString.h" -#include "VMSymbol.h" -VMSymbol::VMSymbol(const size_t length, const char* const str) : - // set the chars-pointer to point at the position of the first character - VMString((char*) ((intptr_t)&cachedInvokable + (3 * sizeof(VMInvokable*))), length), - numberOfArgumentsOfSignature(Signature::DetermineNumberOfArguments(str, length)) { +VMSymbol::VMSymbol(const size_t length, const char* const str) + : // set the chars-pointer to point at the position of the first character + VMString((char*)((intptr_t)&cachedInvokable + (3 * sizeof(VMInvokable*))), + length), + numberOfArgumentsOfSignature( + Signature::DetermineNumberOfArguments(str, length)) { nextCachePos = 0; size_t i = 0; for (; i < length; ++i) { @@ -58,7 +61,9 @@ size_t VMSymbol::GetObjectSize() const { } VMSymbol* VMSymbol::CloneForMovingGC() const { - VMSymbol* result = new (GetHeap(), PADDED_SIZE(length) ALLOC_MATURE) VMSymbol(length, chars); + VMSymbol* result = + new (GetHeap(), PADDED_SIZE(length) ALLOC_MATURE) + VMSymbol(length, chars); return result; } @@ -73,56 +78,56 @@ std::string VMSymbol::GetPlainString() const { for (size_t i = 0; i < length; i++) { char c = chars[i]; switch (c) { - case '~': - str << "tilde"; - break; - case '&': - str << "and"; - break; - case '|': - str << "bar"; - break; - case '*': - str << "star"; - break; - case '/': - str << "slash"; - break; - case '@': - str << "at"; - break; - case '+': - str << "plus"; - break; - case '-': - str << "minus"; - break; - case '=': - str << "equal"; - break; - case '>': - str << "greaterthan"; - break; - case '<': - str << "lowerthan"; - break; - case ',': - str << "comma"; - break; - case '%': - str << "percent"; - break; - case '\\': - str << "backslash"; - break; - case ':': - str << '_'; - break; - default: - if (c != 0) { - str << c; - } - break; + case '~': + str << "tilde"; + break; + case '&': + str << "and"; + break; + case '|': + str << "bar"; + break; + case '*': + str << "star"; + break; + case '/': + str << "slash"; + break; + case '@': + str << "at"; + break; + case '+': + str << "plus"; + break; + case '-': + str << "minus"; + break; + case '=': + str << "equal"; + break; + case '>': + str << "greaterthan"; + break; + case '<': + str << "lowerthan"; + break; + case ',': + str << "comma"; + break; + case '%': + str << "percent"; + break; + case '\\': + str << "backslash"; + break; + case ':': + str << '_'; + break; + default: + if (c != 0) { + str << c; + } + break; } } std::string st = str.str(); @@ -132,9 +137,10 @@ std::string VMSymbol::GetPlainString() const { void VMSymbol::WalkObjects(walk_heap_fn walk) { for (long i = 0; i < nextCachePos; i++) { - cachedClass_invokable[i] = static_cast(walk( - const_cast(cachedClass_invokable[i]))); - cachedInvokable[i] = static_cast(walk(cachedInvokable[i])); + cachedClass_invokable[i] = static_cast( + walk(const_cast(cachedClass_invokable[i]))); + cachedInvokable[i] = + static_cast(walk(cachedInvokable[i])); } } @@ -143,12 +149,13 @@ std::string VMSymbol::AsDebugString() const { } VMInvokable* VMSymbol::GetCachedInvokable(const VMClass* cls) const { - if (cls == load_ptr(cachedClass_invokable[0])) + if (cls == load_ptr(cachedClass_invokable[0])) { return load_ptr(cachedInvokable[0]); - else if (cls == load_ptr(cachedClass_invokable[1])) + } else if (cls == load_ptr(cachedClass_invokable[1])) { return load_ptr(cachedInvokable[1]); - else if (cls == load_ptr(cachedClass_invokable[2])) + } else if (cls == load_ptr(cachedClass_invokable[2])) { return load_ptr(cachedInvokable[2]); + } return nullptr; } diff --git a/src/vmobjects/VMSymbol.h b/src/vmobjects/VMSymbol.h index e76e1cab..460731f6 100644 --- a/src/vmobjects/VMSymbol.h +++ b/src/vmobjects/VMSymbol.h @@ -31,8 +31,7 @@ #include "VMObject.h" #include "VMString.h" -class VMSymbol: public VMString { - +class VMSymbol : public VMString { public: typedef GCSymbol Stored; @@ -55,7 +54,7 @@ class VMSymbol: public VMString { friend class Signature; friend class VMClass; -private_testable: - void WalkObjects(walk_heap_fn) override; + make_testable(public); + void WalkObjects(walk_heap_fn) override; }; From f6396f228990274b8b90067477746f4c387ab97e Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Thu, 1 Aug 2024 16:26:01 +0100 Subject: [PATCH 2/6] Fix bytecode definitions --- src/interpreter/bytecodes.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/interpreter/bytecodes.cpp b/src/interpreter/bytecodes.cpp index a3b927bc..6c2c56cb 100644 --- a/src/interpreter/bytecodes.cpp +++ b/src/interpreter/bytecodes.cpp @@ -60,7 +60,7 @@ const uint8_t Bytecode::bytecodeLengths[] = { 3, // BC_POP_ARGUMENT 2, // BC_POP_FIELD 1, // BC_POP_FIELD_0 - 2, // BC_POP_FIELD_1 + 1, // BC_POP_FIELD_1 2, // BC_SEND 2, // BC_SUPER_SEND 1, // BC_RETURN_LOCAL @@ -71,14 +71,14 @@ const uint8_t Bytecode::bytecodeLengths[] = { 3, // BC_JUMP_ON_FALSE_TOP_NIL 3, // BC_JUMP_ON_TRUE_POP 3, // BC_JUMP_ON_FALSE_POP - 3, // BC_JUMP_BACKWARDS + 3, // BC_JUMP_BACKWARD 3, // BC_JUMP2 3, // BC_JUMP2_ON_TRUE_TOP_NIL 3, // BC_JUMP2_ON_FALSE_TOP_NIL 3, // BC_JUMP2_ON_TRUE_POP 3, // BC_JUMP2_ON_FALSE_POP - 3, // BC_JUMP2_BACKWARDS + 3, // BC_JUMP2_BACKWARD }; const char* Bytecode::bytecodeNames[] = { @@ -102,11 +102,11 @@ const char* Bytecode::bytecodeNames[] = { "RETURN_NON_LOCAL", "BC_JUMP ", "BC_JUMP_ON_TRUE_TOP_NIL", "BC_JUMP_ON_FALSE_TOP_NIL", "BC_JUMP_ON_TRUE_POP", "BC_JUMP_ON_FALSE_POP", - "BC_JUMP_BACKWARDS", + "BC_JUMP_BACKWARD", "BC_JUMP2 ", "BC_JUMP2_ON_TRUE_TOP_NIL", "BC_JUMP2_ON_FALSE_TOP_NIL", "BC_JUMP2_ON_TRUE_POP", - "BC_JUMP2_ON_FALSE_POP", "BC_JUMP2_BACKWARDS", + "BC_JUMP2_ON_FALSE_POP", "BC_JUMP2_BACKWARD", }; bool IsJumpBytecode(uint8_t bc) { From 2132ba73cad5f16e1651691c54b6852f19e09928 Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Thu, 1 Aug 2024 17:17:02 +0100 Subject: [PATCH 3/6] Add Clang Format settings, and add it to GHA --- .clang-format | 270 +++++++++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 10 +- 2 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..b061d26b --- /dev/null +++ b/.clang-format @@ -0,0 +1,270 @@ +Language: Cpp +# BasedOnStyle: Chromium +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: true +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^<.*' + Priority: 1 + SortPriority: 1 + CaseSensitive: true + - Regex: '.*' + Priority: 3 + SortPriority: 3 + CaseSensitive: true +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: BeforeHash +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: true +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +PPIndentWidth: 2 +QualifierAlignment: Leave +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: pb + BasedOnStyle: google +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0aa48efe..188df323 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,9 +32,12 @@ jobs: sudo add-apt-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" sudo apt-get update sudo apt-get install -y clang-18 clang-tidy-18 - # clang-format-17 if: matrix.compiler == 'clang' + - name: Install Clang Format + run: sudo apt-get install -y clang-format-18 + if: matrix.compiler == 'clang' && matrix.gc == 'GENERATIONAL' + - name: Build SOM VM run: | if [ "${{ matrix.compiler }}" = "clang" ] @@ -67,6 +70,11 @@ jobs: run: | clang-tidy-18 --config-file=.clang-tidy src/**/*.cpp -- -fdiagnostics-absolute-paths -DGC_TYPE=${{ matrix.gc}} ${{ matrix.integers }} -DUNITTESTS + - name: Clang Format + if: matrix.compiler == 'clang' && matrix.gc == 'GENERATIONAL' + run: | + clang-format-18 --dry-run --style=file --Werror src/*.cpp src/**/*.cpp src/**/*.h + # Disabled because it's too slow with the sanitizers # - name: Test SomSom # run: | From f36a7dce20e6744b2733bb1cab7f1b1524d50ec9 Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Thu, 1 Aug 2024 17:17:17 +0100 Subject: [PATCH 4/6] Make clang tidy warnings errors --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index e613bd3a..06e44d63 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -41,7 +41,7 @@ Checks: '*include*, # -hicpp-special-member-functions, # -cppcoreguidelines-pro-bounds-pointer-arithmetic, # -cppcoreguidelines-owning-memory, -WarningsAsErrors: '' +WarningsAsErrors: '*' HeaderFilterRegex: '^(?!.*cppunit).*$' # AnalyzeTemporaryDtors: false FormatStyle: none From e4d56b1808e10ecb16964f3c64953426104c73fe Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Thu, 1 Aug 2024 17:30:22 +0100 Subject: [PATCH 5/6] Fix lint issues --- src/compiler/Variable.h | 2 +- src/unitTests/WriteBarrierTest.cpp | 2 ++ src/vm/IsValidObject.cpp | 1 + src/vmobjects/VMFrame.cpp | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/Variable.h b/src/compiler/Variable.h index ae64498a..fe0531c8 100644 --- a/src/compiler/Variable.h +++ b/src/compiler/Variable.h @@ -14,7 +14,7 @@ class Variable { assert(index != 0xff); } - Variable() : name(nullptr), index(0xff) {} + Variable() : name({}), index(0xff) {} Variable(const Variable* old, size_t newIndex, bool isArgument) : name(old->name), index(newIndex), isArgument(isArgument), diff --git a/src/unitTests/WriteBarrierTest.cpp b/src/unitTests/WriteBarrierTest.cpp index 53ce1a61..d409a101 100644 --- a/src/unitTests/WriteBarrierTest.cpp +++ b/src/unitTests/WriteBarrierTest.cpp @@ -4,7 +4,9 @@ #include #include + #include + #include "../compiler/LexicalScope.h" #include "../memory/Heap.h" #include "../vm/Globals.h" #include "../vm/Symbols.h" diff --git a/src/vm/IsValidObject.cpp b/src/vm/IsValidObject.cpp index 5819f1e7..9498d0a0 100644 --- a/src/vm/IsValidObject.cpp +++ b/src/vm/IsValidObject.cpp @@ -14,6 +14,7 @@ #include "../vmobjects/VMFrame.h" #include "../vmobjects/VMInteger.h" #include "../vmobjects/VMMethod.h" +#include "../vmobjects/VMObjectBase.h" // NOLINT(misc-include-cleaner) needed for some GCs #include "../vmobjects/VMString.h" #include "../vmobjects/VMSymbol.h" #include "Globals.h" diff --git a/src/vmobjects/VMFrame.cpp b/src/vmobjects/VMFrame.cpp index dfd7213e..c9b9c63c 100644 --- a/src/vmobjects/VMFrame.cpp +++ b/src/vmobjects/VMFrame.cpp @@ -40,7 +40,7 @@ #include "VMClass.h" #include "VMMethod.h" #include "VMObject.h" -#include "VMObjectBase.h" +#include "VMObjectBase.h" // NOLINT(misc-include-cleaner) needed for some GCs #include "VMSymbol.h" // when doesNotUnderstand or UnknownGlobal is sent, additional stack slots might From da89ab08c8690242a299bebd3c0972cddb97c8bb Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Thu, 1 Aug 2024 17:30:51 +0100 Subject: [PATCH 6/6] Update development lint script --- lint.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lint.sh b/lint.sh index 4023762f..7062b2ad 100755 --- a/lint.sh +++ b/lint.sh @@ -1,7 +1,5 @@ #!/bin/sh -CFLAGS+=' -fdiagnostics-absolute-paths' -# clang-tidy-mp-18 --config-file=.clang-tidy ./src/compiler/Lexer.cpp -- -I/opt/local/include/ -DGC_TYPE=COPYING -DUNITTESTS -fdiagnostics-absolute-paths - -# -header-filter=.* -# src/**/*.cpp -clang-tidy-mp-18 --config-file=.clang-tidy src/**/*.cpp -- -I/opt/local/include/ -fdiagnostics-absolute-paths -DGC_TYPE=COPYING -DUNITTESTS +clang-format-mp-18 -i --style=file --Werror src/*.cpp src/**/*.cpp src/**/*.h +clang-tidy-mp-18 --config-file=.clang-tidy src/**/*.cpp -- \ + -I/opt/local/include/ -fdiagnostics-absolute-paths \ + -DGC_TYPE=GENERATIONAL -DUSE_TAGGING=false -DCACHE_INTEGER=false -DUNITTESTS