diff --git a/SOM.xcodeproj/project.pbxproj b/SOM.xcodeproj/project.pbxproj index 50aa4f97..6e335377 100644 --- a/SOM.xcodeproj/project.pbxproj +++ b/SOM.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -49,6 +49,10 @@ 0A1887451832C62100A2CBCA /* Smalltalk in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0A18873E1832C62100A2CBCA /* Smalltalk */; }; 0A1887471832C62100A2CBCA /* TestSuite in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0A1887401832C62100A2CBCA /* TestSuite */; }; 0A1C98582C3DD88500735850 /* unitTests/BytecodeGenerationTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A1C98572C3DD88500735850 /* unitTests/BytecodeGenerationTest.cpp */; }; + 0A1C98672C4D340300735850 /* Symbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A1C98652C4D340300735850 /* Symbols.cpp */; }; + 0A1C98682C4D340300735850 /* Symbols.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A1C98652C4D340300735850 /* Symbols.cpp */; }; + 0A1C986B2C4D363A00735850 /* LogAllocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A1C986A2C4D363A00735850 /* LogAllocation.cpp */; }; + 0A1C986C2C4D363A00735850 /* LogAllocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A1C986A2C4D363A00735850 /* LogAllocation.cpp */; }; 0A32B7FE199D6143002825DF /* IntegerBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A32B7FC199D6143002825DF /* IntegerBox.cpp */; }; 0A3A3C921A5D546D004CB03B /* Array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F5203120FA6624C00E75857 /* Array.cpp */; }; 0A3A3C931A5D546D004CB03B /* Block.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F5203160FA6624C00E75857 /* Block.cpp */; }; @@ -186,6 +190,10 @@ 0A1C98562C3DD87300735850 /* unitTests/BytecodeGenerationTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unitTests/BytecodeGenerationTest.h; sourceTree = ""; }; 0A1C98572C3DD88500735850 /* unitTests/BytecodeGenerationTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = unitTests/BytecodeGenerationTest.cpp; sourceTree = ""; }; 0A1C98592C432E0E00735850 /* VectorUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VectorUtil.h; sourceTree = ""; }; + 0A1C98642C4D33F300735850 /* Symbols.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Symbols.h; sourceTree = ""; }; + 0A1C98652C4D340300735850 /* Symbols.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Symbols.cpp; sourceTree = ""; }; + 0A1C98692C4D35BB00735850 /* LogAllocation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogAllocation.h; sourceTree = ""; }; + 0A1C986A2C4D363A00735850 /* LogAllocation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LogAllocation.cpp; sourceTree = ""; }; 0A32B7FC199D6143002825DF /* IntegerBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntegerBox.cpp; sourceTree = ""; }; 0A32B7FD199D6143002825DF /* IntegerBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntegerBox.h; sourceTree = ""; }; 0A32B80119A12A03002825DF /* VMObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VMObjectBase.h; sourceTree = ""; }; @@ -581,6 +589,10 @@ 0AB80AD52C392BAD006B6419 /* Print.h */, 0AB80AD62C3947F7006B6419 /* Globals.h */, 0AB80AD72C394806006B6419 /* Globals.cpp */, + 0A1C98642C4D33F300735850 /* Symbols.h */, + 0A1C98652C4D340300735850 /* Symbols.cpp */, + 0A1C98692C4D35BB00735850 /* LogAllocation.h */, + 0A1C986A2C4D363A00735850 /* LogAllocation.cpp */, ); path = vm; sourceTree = ""; @@ -799,7 +811,8 @@ 3F5202740FA661D900E75857 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1130; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1520; }; buildConfigurationList = 3F5202770FA661D900E75857 /* Build configuration list for PBXProject "SOM" */; compatibilityVersion = "Xcode 3.2"; @@ -831,6 +844,7 @@ 0A1887361832C10E00A2CBCA /* MarkSweepHeap.cpp in Sources */, 0A1886DD1832BCC800A2CBCA /* ClassGenerationContext.cpp in Sources */, 0A3A3C941A5D546D004CB03B /* Class.cpp in Sources */, + 0A1C98672C4D340300735850 /* Symbols.cpp in Sources */, 0A18870B1832C0E400A2CBCA /* AbstractObject.cpp in Sources */, 0AB80AD82C394806006B6419 /* Globals.cpp in Sources */, 0A3A3C991A5D546D004CB03B /* Primitive.cpp in Sources */, @@ -868,6 +882,7 @@ 0A1886FC1832BCF500A2CBCA /* VMClass.cpp in Sources */, 0A1886DF1832BCC800A2CBCA /* Lexer.cpp in Sources */, 0A1886F51832BCED00A2CBCA /* Shell.cpp in Sources */, + 0A1C986B2C4D363A00735850 /* LogAllocation.cpp in Sources */, 0A1887321832C10E00A2CBCA /* CopyingHeap.cpp in Sources */, 0A1887061832BCFA00A2CBCA /* VMSymbol.cpp in Sources */, 0A1887011832BCFA00A2CBCA /* VMInvokable.cpp in Sources */, @@ -934,7 +949,9 @@ 0A67EA8819ACD74800830E3B /* VMPrimitive.cpp in Sources */, 0A3A3CA21A5D546D004CB03B /* Block.cpp in Sources */, 0A3A3CA91A5D546D004CB03B /* String.cpp in Sources */, + 0A1C986C2C4D363A00735850 /* LogAllocation.cpp in Sources */, 0A67EA9319ACD83200830E3B /* SourcecodeCompiler.cpp in Sources */, + 0A1C98682C4D340300735850 /* Symbols.cpp in Sources */, 0AB80AD42C392B78006B6419 /* Print.cpp in Sources */, 0A3A3CA41A5D546D004CB03B /* Double.cpp in Sources */, 0A67EA8519ACD74800830E3B /* VMInteger.cpp in Sources */, @@ -959,6 +976,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + DEAD_CODE_STRIPPING = YES; GCC_C_LANGUAGE_STANDARD = c17; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; @@ -998,6 +1016,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = c17; @@ -1034,6 +1053,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + DEAD_CODE_STRIPPING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; @@ -1084,6 +1104,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1116,6 +1137,7 @@ 3F5202750FA661D900E75857 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -1128,14 +1150,17 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; @@ -1158,6 +1183,7 @@ 3F5202760FA661D900E75857 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -1170,13 +1196,16 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; @@ -1198,7 +1227,9 @@ 3F5202870FA661FF00E75857 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; PRODUCT_NAME = make; @@ -1208,7 +1239,9 @@ 3F5202880FA661FF00E75857 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; PRODUCT_NAME = make; ZERO_LINK = NO; diff --git a/src/compiler/BytecodeGenerator.cpp b/src/compiler/BytecodeGenerator.cpp index ec150279..6b8ca1ab 100644 --- a/src/compiler/BytecodeGenerator.cpp +++ b/src/compiler/BytecodeGenerator.cpp @@ -30,37 +30,37 @@ #include "../interpreter/bytecodes.h" #include "../vm/Globals.h" -#include "../vm/Universe.h" +#include "../vm/Symbols.h" #include "../vmobjects/ObjectFormats.h" #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) { - mgenc->AddBytecode(bytecode, 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) { - mgenc->AddBytecode(bytecode, stackEffect); - mgenc->AddBytecodeArgument(idx); +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) { - mgenc->AddBytecode(bytecode, stackEffect); - mgenc->AddBytecodeArgument(idx); - mgenc->AddBytecodeArgument(ctx); +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); } -void EmitHALT(MethodGenerationContext* mgenc) { +void EmitHALT(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_HALT, 0); } -void EmitDUP(MethodGenerationContext* mgenc) { +void EmitDUP(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_DUP, 1); } -void EmitPUSHLOCAL(MethodGenerationContext* mgenc, long idx, +void EmitPUSHLOCAL(MethodGenerationContext& mgenc, long idx, int ctx) { assert(idx >= 0); assert(ctx >= 0); @@ -81,22 +81,22 @@ void EmitPUSHLOCAL(MethodGenerationContext* mgenc, long idx, Emit3(mgenc, BC_PUSH_LOCAL, idx, ctx, 1); } -void EmitPUSHARGUMENT(MethodGenerationContext* mgenc, +void EmitPUSHARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx) { assert(idx >= 0); assert(ctx >= 0); - + if (ctx == 0) { if (idx == 0) { Emit1(mgenc, BC_PUSH_SELF, 1); return; } - + if (idx == 1) { Emit1(mgenc, BC_PUSH_ARG_1, 1); return; } - + if (idx == 2) { Emit1(mgenc, BC_PUSH_ARG_2, 1); return; @@ -105,8 +105,8 @@ void EmitPUSHARGUMENT(MethodGenerationContext* mgenc, Emit3(mgenc, BC_PUSH_ARGUMENT, idx, ctx, 1); } -void EmitPUSHFIELD(MethodGenerationContext* mgenc, VMSymbol* field) { - uint8_t idx = mgenc->GetFieldIndex(field); +void EmitPUSHFIELD(MethodGenerationContext& mgenc, VMSymbol* field) { + const uint8_t idx = mgenc.GetFieldIndex(field); if (idx == 0) { Emit1(mgenc, BC_PUSH_FIELD_0, 1); } else if (idx == 1) { @@ -116,12 +116,12 @@ void EmitPUSHFIELD(MethodGenerationContext* mgenc, VMSymbol* field) { } } -void EmitPUSHBLOCK(MethodGenerationContext* mgenc, VMMethod* block) { - int8_t idx = mgenc->AddLiteralIfAbsent(block); +void EmitPUSHBLOCK(MethodGenerationContext& mgenc, VMMethod* block) { + const int8_t idx = mgenc.AddLiteralIfAbsent(block); Emit2(mgenc, BC_PUSH_BLOCK, idx, 1); } -void EmitPUSHCONSTANT(MethodGenerationContext* mgenc, vm_oop_t cst) { +void EmitPUSHCONSTANT(MethodGenerationContext& mgenc, vm_oop_t cst) { if (CLASS_OF(cst) == load_ptr(integerClass)) { if (INT_VAL(cst) == 0ll) { Emit1(mgenc, BC_PUSH_0, 1); @@ -132,13 +132,13 @@ void EmitPUSHCONSTANT(MethodGenerationContext* mgenc, vm_oop_t cst) { return; } } - + if (cst == load_ptr(nilObject)) { Emit1(mgenc, BC_PUSH_NIL, 1); return; } - - int8_t idx = mgenc->AddLiteralIfAbsent(cst); + + const int8_t idx = mgenc.AddLiteralIfAbsent(cst); if (idx == 0) { Emit1(mgenc, BC_PUSH_CONSTANT_0, 1); return; @@ -151,38 +151,38 @@ void EmitPUSHCONSTANT(MethodGenerationContext* mgenc, vm_oop_t cst) { Emit1(mgenc, BC_PUSH_CONSTANT_2, 1); return; } - + Emit2(mgenc, BC_PUSH_CONSTANT, idx, 1); } -void EmitPUSHCONSTANT(MethodGenerationContext* mgenc, +void EmitPUSHCONSTANT(MethodGenerationContext& mgenc, uint8_t literalIndex) { Emit2(mgenc, BC_PUSH_CONSTANT, literalIndex, 1); } -void EmitPUSHCONSTANTString(MethodGenerationContext* mgenc, +void EmitPUSHCONSTANTString(MethodGenerationContext& mgenc, VMString* str) { - Emit2(mgenc, BC_PUSH_CONSTANT, mgenc->FindLiteralIndex(str), 1); + Emit2(mgenc, BC_PUSH_CONSTANT, mgenc.FindLiteralIndex(str), 1); } -void EmitPUSHGLOBAL(MethodGenerationContext* mgenc, VMSymbol* global) { - if (global == GetUniverse()->SymbolFor("nil")) { +void EmitPUSHGLOBAL(MethodGenerationContext& mgenc, VMSymbol* global) { + if (global == SymbolFor("nil")) { EmitPUSHCONSTANT(mgenc, load_ptr(nilObject)); - } else if (global == GetUniverse()->SymbolFor("true")) { + } else if (global == SymbolFor("true")) { EmitPUSHCONSTANT(mgenc, load_ptr(trueObject)); - } else if (global == GetUniverse()->SymbolFor("false")) { + } else if (global == SymbolFor("false")) { EmitPUSHCONSTANT(mgenc, load_ptr(falseObject)); } else { - int8_t idx = mgenc->AddLiteralIfAbsent(global); + const int8_t idx = mgenc.AddLiteralIfAbsent(global); Emit2(mgenc, BC_PUSH_GLOBAL, idx, 1); } } -void EmitPOP(MethodGenerationContext* mgenc) { +void EmitPOP(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_POP, -1); } -void EmitPOPLOCAL(MethodGenerationContext* mgenc, long idx, +void EmitPOPLOCAL(MethodGenerationContext& mgenc, long idx, int ctx) { assert(idx >= 0); assert(ctx >= 0); @@ -191,29 +191,29 @@ void EmitPOPLOCAL(MethodGenerationContext* mgenc, long idx, Emit1(mgenc, BC_POP_LOCAL_0, -1); return; } - + if (idx == 1) { Emit1(mgenc, BC_POP_LOCAL_1, -1); return; } - + if (idx == 2) { Emit1(mgenc, BC_POP_LOCAL_2, -1); return; } } - + Emit3(mgenc, BC_POP_LOCAL, idx, ctx, -1); } -void EmitPOPARGUMENT(MethodGenerationContext* mgenc, +void EmitPOPARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx) { Emit3(mgenc, BC_POP_ARGUMENT, idx, ctx, -1); } -void EmitPOPFIELD(MethodGenerationContext* mgenc, VMSymbol* field) { - uint8_t idx = mgenc->GetFieldIndex(field); - +void EmitPOPFIELD(MethodGenerationContext& mgenc, VMSymbol* field) { + const uint8_t idx = mgenc.GetFieldIndex(field); + if (idx == 0) { Emit1(mgenc, BC_POP_FIELD_0, -1); } else if (idx == 1) { @@ -223,28 +223,28 @@ void EmitPOPFIELD(MethodGenerationContext* mgenc, VMSymbol* field) { } } -void EmitSEND(MethodGenerationContext* mgenc, VMSymbol* msg) { - int8_t idx = mgenc->AddLiteralIfAbsent(msg); - - int numArgs = Signature::GetNumberOfArguments(msg); - size_t stackEffect = -numArgs + 1; // +1 for the result - +void EmitSEND(MethodGenerationContext& mgenc, VMSymbol* msg) { + const int8_t idx = mgenc.AddLiteralIfAbsent(msg); + + const int numArgs = Signature::GetNumberOfArguments(msg); + const size_t stackEffect = -numArgs + 1; // +1 for the result + Emit2(mgenc, BC_SEND, idx, stackEffect); } -void EmitSUPERSEND(MethodGenerationContext* mgenc, VMSymbol* msg) { - int8_t idx = mgenc->AddLiteralIfAbsent(msg); - - int numArgs = Signature::GetNumberOfArguments(msg); - size_t stackEffect = -numArgs + 1; // +1 for the result - +void EmitSUPERSEND(MethodGenerationContext& mgenc, VMSymbol* msg) { + const int8_t idx = mgenc.AddLiteralIfAbsent(msg); + + const int numArgs = Signature::GetNumberOfArguments(msg); + const size_t stackEffect = -numArgs + 1; // +1 for the result + Emit2(mgenc, BC_SUPER_SEND, idx, stackEffect); } -void EmitRETURNLOCAL(MethodGenerationContext* mgenc) { +void EmitRETURNLOCAL(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_RETURN_LOCAL, 0); } -void EmitRETURNNONLOCAL(MethodGenerationContext* mgenc) { +void EmitRETURNNONLOCAL(MethodGenerationContext& mgenc) { Emit1(mgenc, BC_RETURN_NON_LOCAL, 0); } diff --git a/src/compiler/BytecodeGenerator.h b/src/compiler/BytecodeGenerator.h index fe152397..1040c30f 100644 --- a/src/compiler/BytecodeGenerator.h +++ b/src/compiler/BytecodeGenerator.h @@ -32,26 +32,26 @@ #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 EmitHALT(MethodGenerationContext* mgenc); -void EmitDUP(MethodGenerationContext* mgenc); -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); -void EmitPUSHCONSTANT(MethodGenerationContext* mgenc, vm_oop_t cst); -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 EmitPOPARGUMENT(MethodGenerationContext* mgenc, long idx, int ctx); -void EmitPOPFIELD(MethodGenerationContext* mgenc, VMSymbol* field); -void EmitSEND(MethodGenerationContext* mgenc, VMSymbol* msg); -void EmitSUPERSEND(MethodGenerationContext* mgenc, VMSymbol* msg); -void EmitRETURNLOCAL(MethodGenerationContext* mgenc); -void EmitRETURNNONLOCAL(MethodGenerationContext* mgenc); +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 EmitPUSHARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx); +void EmitPUSHFIELD(MethodGenerationContext& mgenc, VMSymbol* field); +void EmitPUSHBLOCK(MethodGenerationContext& mgenc, VMMethod* block); +void EmitPUSHCONSTANT(MethodGenerationContext& mgenc, vm_oop_t cst); +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 EmitPOPARGUMENT(MethodGenerationContext& mgenc, long idx, int ctx); +void EmitPOPFIELD(MethodGenerationContext& mgenc, VMSymbol* field); +void EmitSEND(MethodGenerationContext& mgenc, VMSymbol* msg); +void EmitSUPERSEND(MethodGenerationContext& mgenc, VMSymbol* msg); +void EmitRETURNLOCAL(MethodGenerationContext& mgenc); +void EmitRETURNNONLOCAL(MethodGenerationContext& mgenc); diff --git a/src/compiler/ClassGenerationContext.cpp b/src/compiler/ClassGenerationContext.cpp index 30b1b266..68d091f7 100644 --- a/src/compiler/ClassGenerationContext.cpp +++ b/src/compiler/ClassGenerationContext.cpp @@ -29,6 +29,7 @@ #include "../misc/VectorUtil.h" #include "../vm/Globals.h" +#include "../vm/Symbols.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMArray.h" @@ -39,14 +40,8 @@ ClassGenerationContext::ClassGenerationContext() : - instanceFields(), instanceMethods(), classFields(), classMethods() { - name = nullptr; - superName = nullptr; - classSide = false; -} - -ClassGenerationContext::~ClassGenerationContext() { -} + instanceFields(), instanceMethods(), classFields(), classMethods(), + name(nullptr), superName(nullptr), classSide(false) { } void ClassGenerationContext::AddClassField(VMSymbol* field) { classFields.push_back(field); @@ -75,17 +70,15 @@ void ClassGenerationContext::SetClassFieldsOfSuper(VMArray* fields) { bool ClassGenerationContext::HasField(VMSymbol* field) { if (IsClassSide()) { return Contains(classFields, field); - } else { - return Contains(instanceFields, field); } + return Contains(instanceFields, field); } int16_t ClassGenerationContext::GetFieldIndex(VMSymbol* field) { if (IsClassSide()) { return IndexOf(classFields, field); - } else { - return IndexOf(instanceFields, field); } + return IndexOf(instanceFields, field); } void ClassGenerationContext::AddInstanceMethod(VMInvokable* method) { @@ -109,7 +102,7 @@ VMClass* ClassGenerationContext::Assemble() { // Initialize the class of the resulting class resultClass->SetInstanceFields(GetUniverse()->NewArrayList(classFields)); resultClass->SetInstanceInvokables(GetUniverse()->NewArrayList(classMethods)); - resultClass->SetName(GetUniverse()->SymbolFor(ccname)); + resultClass->SetName(SymbolFor(ccname)); VMClass* superMClass = superClass->GetClass(); resultClass->SetSuperClass(superMClass); @@ -130,9 +123,8 @@ void ClassGenerationContext::AssembleSystemClass(VMClass* systemClass) { systemClass->SetInstanceInvokables(GetUniverse()->NewArrayList (instanceMethods)); systemClass->SetInstanceFields(GetUniverse()->NewArrayList(instanceFields)); - // class-bound == class-instance-bound + // class-bound == class-instance-bound 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 83356300..5ee67428 100644 --- a/src/compiler/ClassGenerationContext.h +++ b/src/compiler/ClassGenerationContext.h @@ -36,7 +36,7 @@ class ClassGenerationContext { public: ClassGenerationContext(); - ~ClassGenerationContext(); + ~ClassGenerationContext() = default; VMClass* Assemble(); void AssembleSystemClass(VMClass* systemClass); @@ -51,9 +51,9 @@ class ClassGenerationContext { VMSymbol* GetName(void) {return name;}; VMSymbol* GetSuperName(void) {return superName;}; bool IsClassSide(void) {return classSide;}; - + int16_t GetFieldIndex(VMSymbol* field); - + void SetInstanceFieldsOfSuper(VMArray* fields); void SetClassFieldsOfSuper(VMArray* fields); diff --git a/src/compiler/Disassembler.cpp b/src/compiler/Disassembler.cpp index 6ee8d2b9..e78715af 100644 --- a/src/compiler/Disassembler.cpp +++ b/src/compiler/Disassembler.cpp @@ -32,6 +32,7 @@ #include "../misc/debug.h" #include "../misc/defs.h" #include "../vm/Globals.h" +#include "../vm/Symbols.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/Signature.h" @@ -45,38 +46,39 @@ #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) + if (o == nullptr) { return; // nullptr isn't interesting. - else if (o == load_ptr(nilObject)) + } else if (o == load_ptr(nilObject)) { DebugPrint("{Nil}"); - else if (o == load_ptr(trueObject)) + } else if (o == load_ptr(trueObject)) { DebugPrint("{True}"); - else if (o == load_ptr(falseObject)) + } else if (o == load_ptr(falseObject)) { DebugPrint("{False}"); - else if (o == load_ptr(systemClass)) + } else if (o == load_ptr(systemClass)) { DebugPrint("{System Class object}"); - else if (o == load_ptr(blockClass)) + } else if (o == load_ptr(blockClass)) { DebugPrint("{Block Class object}"); - else if (o == GetUniverse()->GetGlobal(GetUniverse()->SymbolFor("system"))) + } else if (o == GetUniverse()->GetGlobal(SymbolFor("system"))) { DebugPrint("{System}"); - else { + } 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)) + } 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)) { + } else if(c == load_ptr(symbolClass)) { DebugPrint("#%s", static_cast(o)->GetStdString().c_str()); - } else + } else { DebugPrint("address: %p", (void*)o); + } } } @@ -119,7 +121,7 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons long max_stack = method->GetMaximumNumberOfStackElements(); DebugDump("%s<%d locals, %d stack, %d bc_count>\n", indent, locals, max_stack, method->GetNumberOfBytecodes()); - + #ifdef _DEBUG Print("bytecodes: "); for (long i = 0; i < numberOfBytecodes; ++i) { @@ -142,18 +144,23 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons DebugPrint("\n"); continue; } - + switch(bytecode) { - case BC_PUSH_LOCAL_0: + case BC_PUSH_LOCAL_0: { DebugPrint("local: 0, context: 0\n"); break; - case BC_PUSH_LOCAL_1: + } + case BC_PUSH_LOCAL_1: { DebugPrint("local: 1, context: 0\n"); break; - case BC_PUSH_LOCAL_2: + } + case BC_PUSH_LOCAL_2: { DebugPrint("local: 2, context: 0\n"); break; - case BC_PUSH_LOCAL: + } + case BC_PUSH_LOCAL: { DebugPrint("local: %d, context: %d\n", bytecodes[bc_idx+1], bytecodes[bc_idx+2]); break; - case BC_PUSH_ARGUMENT: + } + case BC_PUSH_ARGUMENT: { 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]; if (method != nullptr) { @@ -168,7 +175,7 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons break; } } - + DebugPrint("(index: %d)\n", bytecodes[bc_idx+1]); break; } @@ -176,7 +183,7 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons size_t indent_size = strlen(indent)+1+1; char* nindent = new char[indent_size]; DebugPrint("block: (index: %d) ", bytecodes[bc_idx+1]); - + if (method != nullptr) { snprintf(nindent, indent_size, "%s\t", indent); Disassembler::DumpMethod(static_cast(method->GetConstant(bc_idx)), nindent); @@ -191,7 +198,7 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons vm_oop_t constant = method->GetConstant(bc_idx); VMClass* cl = CLASS_OF(constant); VMSymbol* cname = cl->GetName(); - + DebugPrint("(index: %d) value: (%s) ", bytecodes[bc_idx+1], cname->GetStdString().c_str()); dispatch(constant); @@ -268,8 +275,9 @@ void Disassembler::dumpMethod(uint8_t* bytecodes, size_t numberOfBytecodes, cons DebugPrint("(target: %d)\n", target); break; } - default: + default: { DebugPrint("\n"); + } } } DebugDump("%s)\n", indent); @@ -357,7 +365,7 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { DebugPrint("Unexpected bytecode"); return; } - + vm_oop_t o = frame->GetLocal(bc1, bc2); VMClass* c = CLASS_OF(o); VMSymbol* cname = c->GetName(); @@ -390,7 +398,7 @@ void Disassembler::DumpBytecode(VMFrame* frame, VMMethod* method, long bc_idx) { VMFrame* ctxt = frame->GetOuterContext(); vm_oop_t arg = ctxt->GetArgumentInCurrentContext(0); uint8_t field_index = BC_1; - + vm_oop_t o = ((VMObject*) arg)->GetField(field_index); VMClass* c = CLASS_OF(o); VMSymbol* cname = c->GetName(); diff --git a/src/compiler/MethodGenerationContext.cpp b/src/compiler/MethodGenerationContext.cpp index b96e9a42..e074a98c 100644 --- a/src/compiler/MethodGenerationContext.cpp +++ b/src/compiler/MethodGenerationContext.cpp @@ -31,6 +31,7 @@ #include #include "../misc/VectorUtil.h" +#include "../vm/Symbols.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMMethod.h" @@ -38,16 +39,10 @@ #include "../vmobjects/VMSymbol.h" #include "MethodGenerationContext.h" -MethodGenerationContext::MethodGenerationContext() { - signature = nullptr; - holderGenc = 0; - outerGenc = 0; - primitive = false; - blockMethod = false; - finished = false; - currentStackDepth = 0; - maxStackDepth = 0; -} +MethodGenerationContext::MethodGenerationContext() : + signature(nullptr), holderGenc(nullptr), outerGenc(nullptr), + primitive(false), blockMethod(false), finished(false), + currentStackDepth(0), maxStackDepth(0) { } VMMethod* MethodGenerationContext::Assemble() { // create a method instance with the given number of bytecodes and literals @@ -139,12 +134,12 @@ void MethodGenerationContext::SetPrimitive(bool prim) { } void MethodGenerationContext::AddArgument(const std::string& arg) { - VMSymbol* argSym = GetUniverse()->SymbolFor(arg); + VMSymbol* argSym = SymbolFor(arg); arguments.push_back(argSym); } void MethodGenerationContext::AddLocal(const std::string& local) { - VMSymbol* localSym = GetUniverse()->SymbolFor(local); + VMSymbol* localSym =SymbolFor(local); locals.push_back(localSym); } @@ -160,7 +155,7 @@ void MethodGenerationContext::UpdateLiteral(vm_oop_t oldValue, uint8_t index, vm } bool MethodGenerationContext::AddArgumentIfAbsent(const std::string& arg) { - VMSymbol* argSym = GetUniverse()->SymbolFor(arg); + VMSymbol* argSym = SymbolFor(arg); if (Contains(locals, argSym)) { return false; } @@ -169,7 +164,7 @@ bool MethodGenerationContext::AddArgumentIfAbsent(const std::string& arg) { } bool MethodGenerationContext::AddLocalIfAbsent(const std::string& local) { - VMSymbol* localSym = GetUniverse()->SymbolFor(local); + VMSymbol* localSym = SymbolFor(local); if (Contains(locals, localSym)) { return false; } @@ -221,7 +216,7 @@ bool MethodGenerationContext::HasBytecodes() { size_t MethodGenerationContext::AddBytecode(uint8_t bc, size_t stackEffect) { currentStackDepth += stackEffect; maxStackDepth = max(maxStackDepth, currentStackDepth); - + bytecode.push_back(bc); return bytecode.size(); } @@ -230,4 +225,3 @@ size_t MethodGenerationContext::AddBytecodeArgument(uint8_t bc) { bytecode.push_back(bc); return bytecode.size(); } - diff --git a/src/compiler/Parser.cpp b/src/compiler/Parser.cpp index 2073e488..30b8205d 100644 --- a/src/compiler/Parser.cpp +++ b/src/compiler/Parser.cpp @@ -38,6 +38,7 @@ #include "../misc/defs.h" #include "../vm/Globals.h" #include "../vm/Print.h" +#include "../vm/Symbols.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMClass.h" @@ -112,9 +113,10 @@ bool Parser::symIsIdentifier() { } bool Parser::expect(Symbol s) { - if (accept(s)) + if (accept(s)) { return true; - + } + parseError("Unexpected symbol. Expected %(expected)s, but found %(found)s\n", s); return false; } @@ -123,11 +125,11 @@ bool Parser::expectOneOf(Symbol* ss) { if (acceptOneOf(ss)) return true; parseError("Unexpected symbol. Expected one of %(expected)s, but found %(found)s\n", ss); - + return false; } -void Parser::genPushVariable(MethodGenerationContext* mgenc, +void Parser::genPushVariable(MethodGenerationContext& mgenc, VMSymbol* 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 @@ -137,14 +139,14 @@ void Parser::genPushVariable(MethodGenerationContext* mgenc, int context = 0; bool is_argument = false; - if (mgenc->FindVar(var, &index, &context, &is_argument)) { + if (mgenc.FindVar(var, &index, &context, &is_argument)) { if (is_argument) { EmitPUSHARGUMENT(mgenc, index, context); } else { EmitPUSHLOCAL(mgenc, index, context); } } else { - if (mgenc->HasField(var)) { + if (mgenc.HasField(var)) { EmitPUSHFIELD(mgenc, var); } else { EmitPUSHGLOBAL(mgenc, var); @@ -152,7 +154,7 @@ void Parser::genPushVariable(MethodGenerationContext* mgenc, } } -void Parser::genPopVariable(MethodGenerationContext* mgenc, VMSymbol* var) { +void Parser::genPopVariable(MethodGenerationContext& mgenc, VMSymbol* var) { // The purpose of this function is to find out whether the variable to be // popped off the stack is a local variable, argument, or object field. This // is done by examining all available lexical contexts, starting with the @@ -161,7 +163,7 @@ void Parser::genPopVariable(MethodGenerationContext* mgenc, VMSymbol* var) { int context = 0; bool is_argument = false; - if (mgenc->FindVar(var, &index, &context, &is_argument)) { + if (mgenc.FindVar(var, &index, &context, &is_argument)) { if (is_argument) EmitPOPARGUMENT(mgenc, index, context); else @@ -182,8 +184,8 @@ Symbol binaryOpSyms[] = { Or, Comma, Minus, Equal, Not, And, Or, Star, Div, Mod, Symbol keywordSelectorSyms[] = { Keyword, KeywordSequence }; -void Parser::Classdef(ClassGenerationContext* cgenc) { - cgenc->SetName(GetUniverse()->SymbolFor(text)); +void Parser::Classdef(ClassGenerationContext& cgenc) { + cgenc.SetName(SymbolFor(text)); expect(Identifier); expect(Equal); @@ -196,52 +198,54 @@ void Parser::Classdef(ClassGenerationContext* cgenc) { symIn(binaryOpSyms)) { MethodGenerationContext mgenc; - mgenc.SetHolder(cgenc); + mgenc.SetHolder(&cgenc); mgenc.AddArgument("self"); - method(&mgenc); + method(mgenc); - if(mgenc.IsPrimitive()) - cgenc->AddInstanceMethod(mgenc.AssemblePrimitive(false)); - else - cgenc->AddInstanceMethod(mgenc.Assemble()); + if(mgenc.IsPrimitive()) { + cgenc.AddInstanceMethod(mgenc.AssemblePrimitive(false)); + } else { + cgenc.AddInstanceMethod(mgenc.Assemble()); + } } if (accept(Separator)) { - cgenc->SetClassSide(true); + cgenc.SetClassSide(true); classFields(cgenc); while (symIsIdentifier() || sym == Keyword || sym == OperatorSequence || symIn(binaryOpSyms)) { MethodGenerationContext mgenc; - mgenc.SetHolder(cgenc); + mgenc.SetHolder(&cgenc); mgenc.AddArgument("self"); - method(&mgenc); + method(mgenc); - if(mgenc.IsPrimitive()) - cgenc->AddClassMethod(mgenc.AssemblePrimitive(true)); - else - cgenc->AddClassMethod(mgenc.Assemble()); + if(mgenc.IsPrimitive()) { + cgenc.AddClassMethod(mgenc.AssemblePrimitive(true)); + } else { + cgenc.AddClassMethod(mgenc.Assemble()); + } } } expect(EndTerm); } -void Parser::superclass(ClassGenerationContext *cgenc) { +void Parser::superclass(ClassGenerationContext& cgenc) { VMSymbol* superName; if (sym == Identifier) { - superName = GetUniverse()->SymbolFor(text); + superName = SymbolFor(text); accept(Identifier); } else { - superName = GetUniverse()->SymbolFor("Object"); + superName = SymbolFor("Object"); } - cgenc->SetSuperName(superName); - + cgenc.SetSuperName(superName); + // Load the super class, if it is not nil (break the dependency cycle) - if (superName != GetUniverse()->SymbolFor("nil")) { + if (superName != SymbolFor("nil")) { VMClass* superClass = GetUniverse()->LoadClass(superName); - cgenc->SetInstanceFieldsOfSuper(superClass->GetInstanceFields()); - cgenc->SetClassFieldsOfSuper(superClass->GetClass()->GetInstanceFields()); + cgenc.SetInstanceFieldsOfSuper(superClass->GetInstanceFields()); + cgenc.SetClassFieldsOfSuper(superClass->GetClass()->GetInstanceFields()); } else { // we hardcode here the field names for Class // since Object class superclass = Class @@ -251,46 +255,47 @@ void Parser::superclass(ClassGenerationContext *cgenc) { vector fieldNamesOfClass{ "class", "superClass", "name", "instanceFields", "instanceInvokables" }; VMArray* fieldNames = GetUniverse()->NewArrayFromStrings(fieldNamesOfClass); - cgenc->SetClassFieldsOfSuper(fieldNames); + cgenc.SetClassFieldsOfSuper(fieldNames); } } -void Parser::instanceFields(ClassGenerationContext* cgenc) { +void Parser::instanceFields(ClassGenerationContext& cgenc) { if (accept(Or)) { while (symIsIdentifier()) { StdString var = variable(); - cgenc->AddInstanceField(GetUniverse()->SymbolFor(var)); + cgenc.AddInstanceField(SymbolFor(var)); } expect(Or); } } -void Parser::classFields(ClassGenerationContext* cgenc) { +void Parser::classFields(ClassGenerationContext& cgenc) { if (accept(Or)) { while (symIsIdentifier()) { StdString var = variable(); - cgenc->AddClassField(GetUniverse()->SymbolFor(var)); + cgenc.AddClassField(SymbolFor(var)); } expect(Or); } } -void Parser::method(MethodGenerationContext* mgenc) { +void Parser::method(MethodGenerationContext& mgenc) { pattern(mgenc); expect(Equal); if (sym == Primitive) { - mgenc->SetPrimitive(true); + mgenc.SetPrimitive(true); primitiveBlock(); - } else + } else { methodBlock(mgenc); + } } -void Parser::primitiveBlock(void) { +void Parser::primitiveBlock() { expect(Primitive); } -void Parser::pattern(MethodGenerationContext* mgenc) { +void Parser::pattern(MethodGenerationContext& mgenc) { switch (sym) { case Identifier: case Primitive: @@ -305,81 +310,81 @@ void Parser::pattern(MethodGenerationContext* mgenc) { } } -void Parser::unaryPattern(MethodGenerationContext* mgenc) { - mgenc->SetSignature(unarySelector()); +void Parser::unaryPattern(MethodGenerationContext& mgenc) { + mgenc.SetSignature(unarySelector()); } -void Parser::binaryPattern(MethodGenerationContext* mgenc) { - mgenc->SetSignature(binarySelector()); - mgenc->AddArgumentIfAbsent(argument()); +void Parser::binaryPattern(MethodGenerationContext& mgenc) { + mgenc.SetSignature(binarySelector()); + mgenc.AddArgumentIfAbsent(argument()); } -void Parser::keywordPattern(MethodGenerationContext* mgenc) { +void Parser::keywordPattern(MethodGenerationContext& mgenc) { StdString kw; do { kw.append(keyword()); - mgenc->AddArgumentIfAbsent(argument()); + mgenc.AddArgumentIfAbsent(argument()); } while (sym == Keyword); - mgenc->SetSignature(GetUniverse()->SymbolFor(kw)); + mgenc.SetSignature(SymbolFor(kw)); } -void Parser::methodBlock(MethodGenerationContext* mgenc) { +void Parser::methodBlock(MethodGenerationContext& mgenc) { expect(NewTerm); blockContents(mgenc, false); // if no return has been generated so far, we can be sure there was no . // terminating the last expression, so the last expression's value must be // popped off the stack and a ^self be generated - if (!mgenc->IsFinished()) { + if (!mgenc.IsFinished()) { EmitPOP(mgenc); EmitPUSHARGUMENT(mgenc, 0, 0); EmitRETURNLOCAL(mgenc); - mgenc->SetFinished(); + mgenc.SetFinished(); } expect(EndTerm); } -VMSymbol* Parser::unarySelector(void) { - return GetUniverse()->SymbolFor(identifier()); +VMSymbol* Parser::unarySelector() { + return SymbolFor(identifier()); } -VMSymbol* Parser::binarySelector(void) { +VMSymbol* Parser::binarySelector() { StdString s(text); - if(acceptOneOf(singleOpSyms)) - ; - else if(accept(OperatorSequence)) - ; - else - expect(NONE); + if(acceptOneOf(singleOpSyms)) {} + else if(accept(OperatorSequence)) {} + else { + expect(NONE); + } - VMSymbol* symb = GetUniverse()->SymbolFor(s); + VMSymbol* symb = SymbolFor(s); return symb; } -StdString Parser::identifier(void) { +StdString Parser::identifier() { StdString s(text); - if (accept(Primitive)) - ; // text is set - else + if (accept(Primitive)) { + // text is set + } else { expect(Identifier); + } return s; } -StdString Parser::keyword(void) { +StdString Parser::keyword() { StdString s(text); expect(Keyword); return s; } -StdString Parser::argument(void) { +StdString Parser::argument() { return variable(); } -void Parser::blockContents(MethodGenerationContext* mgenc, bool is_inlined) { +void Parser::blockContents(MethodGenerationContext& mgenc, bool is_inlined) { if (accept(Or)) { locals(mgenc); expect(Or); @@ -387,28 +392,29 @@ void Parser::blockContents(MethodGenerationContext* mgenc, bool is_inlined) { blockBody(mgenc, false, is_inlined); } -void Parser::locals(MethodGenerationContext* mgenc) { +void Parser::locals(MethodGenerationContext& mgenc) { while (symIsIdentifier()) - mgenc->AddLocalIfAbsent(variable()); + mgenc.AddLocalIfAbsent(variable()); } -void Parser::blockBody(MethodGenerationContext* mgenc, bool seen_period, bool is_inlined) { - if (accept(Exit)) +void Parser::blockBody(MethodGenerationContext& mgenc, bool seen_period, bool is_inlined) { + if (accept(Exit)) { result(mgenc); + } 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 // was terminated with a . or not) - mgenc->RemoveLastBytecode(); + mgenc.RemoveLastBytecode(); } if (!is_inlined) { // if the block is empty, we need to return nil - if (mgenc->IsBlockMethod() && !mgenc->HasBytecodes()) { + if (mgenc.IsBlockMethod() && !mgenc.HasBytecodes()) { EmitPUSHCONSTANT(mgenc, load_ptr(nilObject)); } EmitRETURNLOCAL(mgenc); - mgenc->SetFinished(); + mgenc.SetFinished(); } } else if (sym == EndTerm) { // it does not matter whether a period has been seen, as the end of the @@ -416,7 +422,7 @@ void Parser::blockBody(MethodGenerationContext* mgenc, bool seen_period, bool is // self" EmitPUSHARGUMENT(mgenc, 0, 0); EmitRETURNLOCAL(mgenc); - mgenc->SetFinished(); + mgenc.SetFinished(); } else { expression(mgenc); if (accept(Period)) { @@ -426,58 +432,63 @@ void Parser::blockBody(MethodGenerationContext* mgenc, bool seen_period, bool is } } -void Parser::result(MethodGenerationContext* mgenc) { +void Parser::result(MethodGenerationContext& mgenc) { expression(mgenc); - if (mgenc->IsBlockMethod()) + if (mgenc.IsBlockMethod()) { EmitRETURNNONLOCAL(mgenc); - else + } else { EmitRETURNLOCAL(mgenc); + } - mgenc->SetFinished(true); + mgenc.SetFinished(true); accept(Period); } -void Parser::expression(MethodGenerationContext* mgenc) { +void Parser::expression(MethodGenerationContext& mgenc) { Peek(); - if (nextSym == Assign) + if (nextSym == Assign) { assignation(mgenc); - else + } else { evaluation(mgenc); + } } -void Parser::assignation(MethodGenerationContext* mgenc) { +void Parser::assignation(MethodGenerationContext& mgenc) { list l; assignments(mgenc, l); evaluation(mgenc); list::iterator i; - for (i = l.begin(); i != l.end(); ++i) + for (i = l.begin(); i != l.end(); ++i) { EmitDUP(mgenc); - for (i = l.begin(); i != l.end(); ++i) - genPopVariable(mgenc, (*i)); + } + for (i = l.begin(); i != l.end(); ++i) { + genPopVariable(mgenc, (*i)); + } } -void Parser::assignments(MethodGenerationContext* mgenc, list& l) { +void Parser::assignments(MethodGenerationContext& mgenc, list& l) { if (symIsIdentifier()) { l.push_back(assignment(mgenc)); Peek(); - - if (nextSym == Assign) + + if (nextSym == Assign) { assignments(mgenc, l); + } } } -VMSymbol* Parser::assignment(MethodGenerationContext* mgenc) { +VMSymbol* Parser::assignment(MethodGenerationContext& mgenc) { StdString v = variable(); expect(Assign); - return GetUniverse()->SymbolFor(v); + return SymbolFor(v); } -void Parser::evaluation(MethodGenerationContext* mgenc) { +void Parser::evaluation(MethodGenerationContext& mgenc) { bool super = primary(mgenc); if (symIsIdentifier() || sym == Keyword || sym == OperatorSequence || symIn(binaryOpSyms)) { @@ -485,7 +496,7 @@ void Parser::evaluation(MethodGenerationContext* mgenc) { } } -bool Parser::primary(MethodGenerationContext* mgenc) { +bool Parser::primary(MethodGenerationContext& mgenc) { bool super = false; switch (sym) { case Primitive: @@ -497,23 +508,22 @@ bool Parser::primary(MethodGenerationContext* mgenc) { v = StdString("self"); } - genPushVariable(mgenc, GetUniverse()->SymbolFor(v)); + genPushVariable(mgenc, SymbolFor(v)); break; } case NewTerm: nestedTerm(mgenc); break; case NewBlock: { - MethodGenerationContext* bgenc = new MethodGenerationContext(); - bgenc->SetIsBlockMethod(true); - bgenc->SetHolder(mgenc->GetHolder()); - bgenc->SetOuter(mgenc); + MethodGenerationContext bgenc{}; + bgenc.SetIsBlockMethod(true); + bgenc.SetHolder(mgenc.GetHolder()); + bgenc.SetOuter(&mgenc); nestedBlock(bgenc); - VMMethod* block_method = bgenc->Assemble(); - EmitPUSHBLOCK(mgenc, block_method); - delete (bgenc); + VMMethod* blockMethod = bgenc.Assemble(); + EmitPUSHBLOCK(mgenc, blockMethod); break; } default: @@ -524,11 +534,11 @@ bool Parser::primary(MethodGenerationContext* mgenc) { return super; } -StdString Parser::variable(void) { +StdString Parser::variable() { return identifier(); } -void Parser::messages(MethodGenerationContext* mgenc, bool super) { +void Parser::messages(MethodGenerationContext& mgenc, bool super) { if (symIsIdentifier()) { do { // only the first message in a sequence can be a super send @@ -558,7 +568,7 @@ void Parser::messages(MethodGenerationContext* mgenc, bool super) { } } -void Parser::unaryMessage(MethodGenerationContext* mgenc, bool super) { +void Parser::unaryMessage(MethodGenerationContext& mgenc, bool super) { VMSymbol* msg = unarySelector(); if (super) { @@ -568,19 +578,19 @@ void Parser::unaryMessage(MethodGenerationContext* mgenc, bool super) { } } -void Parser::binaryMessage(MethodGenerationContext* mgenc, bool super) { +void Parser::binaryMessage(MethodGenerationContext& mgenc, bool super) { VMSymbol* msg = binarySelector(); binaryOperand(mgenc); - if (super) + if (super) { EmitSUPERSEND(mgenc, msg); - else + } else { EmitSEND(mgenc, msg); - + } } -bool Parser::binaryOperand(MethodGenerationContext* mgenc) { +bool Parser::binaryOperand(MethodGenerationContext& mgenc) { bool super = primary(mgenc); while (symIsIdentifier()) { @@ -592,25 +602,25 @@ bool Parser::binaryOperand(MethodGenerationContext* mgenc) { } -void Parser::keywordMessage(MethodGenerationContext* mgenc, bool super) { +void Parser::keywordMessage(MethodGenerationContext& mgenc, bool super) { StdString kw = keyword(); - + formula(mgenc); while (sym == Keyword) { kw.append(keyword()); formula(mgenc); } - VMSymbol* msg = GetUniverse()->SymbolFor(kw); + VMSymbol* msg = SymbolFor(kw); - if (super) + if (super) { EmitSUPERSEND(mgenc, msg); - else + } else { EmitSEND(mgenc, msg); - + } } -void Parser::formula(MethodGenerationContext* mgenc) { +void Parser::formula(MethodGenerationContext& mgenc) { bool super = binaryOperand(mgenc); // only the first message in a sequence can be a super send @@ -623,13 +633,13 @@ void Parser::formula(MethodGenerationContext* mgenc) { } } -void Parser::nestedTerm(MethodGenerationContext* mgenc) { +void Parser::nestedTerm(MethodGenerationContext& mgenc) { expect(NewTerm); expression(mgenc); expect(EndTerm); } -void Parser::literal(MethodGenerationContext* mgenc) { +void Parser::literal(MethodGenerationContext& mgenc) { switch (sym) { case Pound: PeekForNextSymbolFromLexerIfNecessary(); @@ -655,7 +665,7 @@ vm_oop_t Parser::literalNumberOop() { return literalDecimal(false); } -void Parser::literalNumber(MethodGenerationContext* mgenc) { +void Parser::literalNumber(MethodGenerationContext& mgenc) { vm_oop_t lit = literalNumberOop(); EmitPUSHCONSTANT(mgenc, lit); } @@ -668,7 +678,7 @@ vm_oop_t Parser::literalDecimal(bool negateValue) { } } -vm_oop_t Parser::negativeDecimal(void) { +vm_oop_t Parser::negativeDecimal() { expect(Minus); return literalDecimal(true); } @@ -688,12 +698,12 @@ vm_oop_t Parser::literalDouble(bool negateValue) { return GetUniverse()->NewDouble(d); } -void Parser::literalSymbol(MethodGenerationContext* mgenc) { +void Parser::literalSymbol(MethodGenerationContext& mgenc) { VMSymbol* symb; expect(Pound); if (sym == STString) { StdString s = _string(); - symb = GetUniverse()->SymbolFor(s); + symb = SymbolFor(s); } else { symb = selector(); @@ -701,16 +711,16 @@ void Parser::literalSymbol(MethodGenerationContext* mgenc) { EmitPUSHCONSTANT(mgenc, symb); } -void Parser::literalArray(MethodGenerationContext* mgenc) { +void Parser::literalArray(MethodGenerationContext& mgenc) { expect(Pound); expect(NewTerm); - VMSymbol* arrayClassName = GetUniverse()->SymbolFor("Array"); - VMSymbol* arraySizePlaceholder = GetUniverse()->SymbolFor("ArraySizeLiteralPlaceholder"); - VMSymbol* newMessage = GetUniverse()->SymbolFor("new:"); - VMSymbol* atPutMessage = GetUniverse()->SymbolFor("at:put:"); + VMSymbol* arrayClassName = SymbolFor("Array"); + VMSymbol* arraySizePlaceholder = SymbolFor("ArraySizeLiteralPlaceholder"); + 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); @@ -728,19 +738,19 @@ 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); } -void Parser::literalString(MethodGenerationContext* mgenc) { +void Parser::literalString(MethodGenerationContext& mgenc) { StdString s = _string(); VMString* str = GetUniverse()->NewString(s); EmitPUSHCONSTANT(mgenc, str); } -VMSymbol* Parser::selector(void) { +VMSymbol* Parser::selector() { if(sym == OperatorSequence || symIn(singleOpSyms)) return binarySelector(); else if(sym == Keyword || sym == KeywordSequence) @@ -749,21 +759,21 @@ VMSymbol* Parser::selector(void) { return unarySelector(); } -VMSymbol* Parser::keywordSelector(void) { +VMSymbol* Parser::keywordSelector() { StdString s(text); expectOneOf(keywordSelectorSyms); - VMSymbol* symb = GetUniverse()->SymbolFor(s); + VMSymbol* symb = SymbolFor(s); return symb; } -StdString Parser::_string(void) { +StdString Parser::_string() { StdString s(text); expect(STString); return s; // <-- Literal strings are At Most BUFSIZ chars long. } -void Parser::nestedBlock(MethodGenerationContext* mgenc) { - mgenc->AddArgumentIfAbsent("$block self"); +void Parser::nestedBlock(MethodGenerationContext& mgenc) { + mgenc.AddArgumentIfAbsent("$block self"); expect(NewBlock); if (sym == Colon) @@ -771,37 +781,37 @@ void Parser::nestedBlock(MethodGenerationContext* mgenc) { // generate Block signature StdString block_sig = "$blockMethod@" + to_string(lexer->GetCurrentLineNumber()); - size_t arg_size = mgenc->GetNumberOfArguments(); + size_t arg_size = mgenc.GetNumberOfArguments(); for (size_t i = 1; i < arg_size; i++) block_sig += ":"; - mgenc->SetSignature(GetUniverse()->SymbolFor(block_sig)); + mgenc.SetSignature(SymbolFor(block_sig)); blockContents(mgenc, false); // if no return has been generated, we can be sure that the last expression // in the block was not terminated by ., and can generate a return - if (!mgenc->IsFinished()) { - if (!mgenc->HasBytecodes()) { + if (!mgenc.IsFinished()) { + if (!mgenc.HasBytecodes()) { // if the block is empty, we need to return nil EmitPUSHCONSTANT(mgenc, load_ptr(nilObject)); } EmitRETURNLOCAL(mgenc); - mgenc->SetFinished(true); + mgenc.SetFinished(true); } expect(EndBlock); } -void Parser::blockPattern(MethodGenerationContext* mgenc) { +void Parser::blockPattern(MethodGenerationContext& mgenc) { blockArguments(mgenc); expect(Or); } -void Parser::blockArguments(MethodGenerationContext* mgenc) { +void Parser::blockArguments(MethodGenerationContext& mgenc) { do { expect(Colon); - mgenc->AddArgumentIfAbsent(argument()); + mgenc.AddArgumentIfAbsent(argument()); } while (sym == Colon); } @@ -811,7 +821,7 @@ static bool replace(StdString& str, const char* pattern, StdString& replacement) if (pos == std::string::npos) { return false; } - + str.replace(pos, strlen(pattern), replacement); return true; } @@ -824,24 +834,24 @@ __attribute__((noreturn)) void Parser::parseError(const char* msg, Symbol expect __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) { foundStr = symnames[sym] + StdString(" (") + text + ")"; } else { foundStr = symnames[sym]; } - + replace(msgWithMeta, "%(file)s", fname); StdString line = std::to_string(lexer->GetCurrentLineNumber()); replace(msgWithMeta, "%(line)d", line); - + StdString column = std::to_string(lexer->getCurrentColumn()); replace(msgWithMeta, "%(column)d", column); replace(msgWithMeta, "%(expected)s", expected); replace(msgWithMeta, "%(found)s", foundStr); - + ErrorPrint(msgWithMeta); GetUniverse()->Quit(ERR_FAIL); } @@ -849,7 +859,7 @@ __attribute__((noreturn)) void Parser::parseError(const char* msg, StdString exp __attribute__((noreturn)) void Parser::parseError(const char* msg, Symbol* expected) { bool first = true; StdString expectedStr = ""; - + Symbol* next = expected; while (*next) { if (first) { @@ -857,10 +867,10 @@ __attribute__((noreturn)) void Parser::parseError(const char* msg, Symbol* expec } else { expectedStr += ", "; } - + expectedStr += symnames[*next]; next += 1; } - + parseError(msg, expectedStr); } diff --git a/src/compiler/Parser.h b/src/compiler/Parser.h index 6c85d78c..af7684db 100644 --- a/src/compiler/Parser.h +++ b/src/compiler/Parser.h @@ -42,9 +42,9 @@ class Parser { Parser(istream& file, StdString& fname); ~Parser(); - void Classdef(ClassGenerationContext* cgenc); - void method(MethodGenerationContext* mgenc); - void nestedBlock(MethodGenerationContext* mgenc); + void Classdef(ClassGenerationContext& cgenc); + void method(MethodGenerationContext& mgenc); + void nestedBlock(MethodGenerationContext& mgenc); private: __attribute__((noreturn)) void parseError(const char* msg, Symbol expected); @@ -65,55 +65,56 @@ class Parser { bool expect(Symbol s); bool expectOneOf(Symbol* ss); void SingleOperator(void); - void superclass(ClassGenerationContext* cgenc); - void instanceFields(ClassGenerationContext* cgenc); - void classFields(ClassGenerationContext* cgenc); + void superclass(ClassGenerationContext& cgenc); + void instanceFields(ClassGenerationContext& cgenc); + void classFields(ClassGenerationContext& cgenc); void primitiveBlock(void); - void pattern(MethodGenerationContext* mgenc); - void unaryPattern(MethodGenerationContext* mgenc); - void binaryPattern(MethodGenerationContext* mgenc); - void keywordPattern(MethodGenerationContext* mgenc); - void methodBlock(MethodGenerationContext* mgenc);VMSymbol* unarySelector(void); - VMSymbol* binarySelector(void); - StdString identifier(void); - StdString keyword(void); - StdString argument(void); - void blockContents(MethodGenerationContext* mgenc, bool is_inlined); - void locals(MethodGenerationContext* mgenc); - void blockBody(MethodGenerationContext* mgenc, bool seen_period, bool is_inlined); - void result(MethodGenerationContext* mgenc); - void expression(MethodGenerationContext* mgenc); - void assignation(MethodGenerationContext* mgenc); - void assignments(MethodGenerationContext* mgenc, list& l); - VMSymbol* assignment(MethodGenerationContext* mgenc); - void evaluation(MethodGenerationContext* mgenc); - bool primary(MethodGenerationContext* mgenc); - StdString variable(void); - void messages(MethodGenerationContext* mgenc, bool super); - void unaryMessage(MethodGenerationContext* mgenc, bool super); - void binaryMessage(MethodGenerationContext* mgenc, bool super); - bool binaryOperand(MethodGenerationContext* mgenc); - void keywordMessage(MethodGenerationContext* mgenc, bool super); + void pattern(MethodGenerationContext& mgenc); + void unaryPattern(MethodGenerationContext& mgenc); + void binaryPattern(MethodGenerationContext& mgenc); + void keywordPattern(MethodGenerationContext& mgenc); + void methodBlock(MethodGenerationContext& mgenc); + VMSymbol* unarySelector(); + VMSymbol* binarySelector(); + StdString identifier(); + StdString keyword(); + StdString argument(); + void blockContents(MethodGenerationContext& mgenc, bool is_inlined); + void locals(MethodGenerationContext& mgenc); + void blockBody(MethodGenerationContext& mgenc, bool seen_period, bool is_inlined); + void result(MethodGenerationContext& mgenc); + void expression(MethodGenerationContext& mgenc); + void assignation(MethodGenerationContext& mgenc); + void assignments(MethodGenerationContext& mgenc, list& l); + VMSymbol* assignment(MethodGenerationContext& mgenc); + void evaluation(MethodGenerationContext& mgenc); + bool primary(MethodGenerationContext& mgenc); + StdString variable(); + void messages(MethodGenerationContext& mgenc, bool super); + void unaryMessage(MethodGenerationContext& mgenc, bool super); + void binaryMessage(MethodGenerationContext& mgenc, bool super); + bool binaryOperand(MethodGenerationContext& mgenc); + void keywordMessage(MethodGenerationContext& mgenc, bool super); - void formula(MethodGenerationContext* mgenc); - void nestedTerm(MethodGenerationContext* mgenc); - void literal(MethodGenerationContext* mgenc); - void literalNumber(MethodGenerationContext* mgenc); + void formula(MethodGenerationContext& mgenc); + void nestedTerm(MethodGenerationContext& mgenc); + void literal(MethodGenerationContext& mgenc); + void literalNumber(MethodGenerationContext& mgenc); vm_oop_t literalNumberOop(); vm_oop_t literalDecimal(bool negateValue); vm_oop_t negativeDecimal(void); vm_oop_t literalInteger(bool negateValue); vm_oop_t literalDouble(bool negateValue); - void literalArray(MethodGenerationContext* mgenc); - void literalSymbol(MethodGenerationContext* mgenc); - void literalString(MethodGenerationContext* mgenc); - VMSymbol* selector(void); - VMSymbol* keywordSelector(void); - StdString _string(void); - void blockPattern(MethodGenerationContext* mgenc); - void blockArguments(MethodGenerationContext* mgenc); - void genPushVariable(MethodGenerationContext*, VMSymbol*); - void genPopVariable(MethodGenerationContext*, VMSymbol*); + void literalArray(MethodGenerationContext& mgenc); + void literalSymbol(MethodGenerationContext& mgenc); + void literalString(MethodGenerationContext& mgenc); + VMSymbol* selector(); + VMSymbol* keywordSelector(); + StdString _string(); + void blockPattern(MethodGenerationContext& mgenc); + void blockArguments(MethodGenerationContext& mgenc); + void genPushVariable(MethodGenerationContext&, VMSymbol*); + void genPopVariable(MethodGenerationContext&, VMSymbol*); Lexer* lexer; StdString& fname; diff --git a/src/compiler/SourcecodeCompiler.cpp b/src/compiler/SourcecodeCompiler.cpp index 1a6fe246..38eec45b 100644 --- a/src/compiler/SourcecodeCompiler.cpp +++ b/src/compiler/SourcecodeCompiler.cpp @@ -39,15 +39,6 @@ #include "SourcecodeCompiler.h" -SourcecodeCompiler::SourcecodeCompiler() { - parser = nullptr; -} - -SourcecodeCompiler::~SourcecodeCompiler() { - if (parser != nullptr) - delete (parser); -} - VMClass* SourcecodeCompiler::CompileClass( const std::string& path, const std::string& file, VMClass* systemClass ) { @@ -55,15 +46,14 @@ VMClass* SourcecodeCompiler::CompileClass( const std::string& path, std::string fname = path + fileSeparator + file + ".som"; - ifstream* fp = new ifstream(); - fp->open(fname.c_str(), std::ios_base::in); - if (!fp->is_open()) { + ifstream fp{}; + fp.open(fname.c_str(), std::ios_base::in); + if (!fp.is_open()) { return nullptr; } - if (parser != nullptr) delete(parser); - parser = new Parser(*fp, fname); - result = compile(systemClass); + Parser parser(fp, fname); + result = compile(parser, systemClass); VMSymbol* cname = result->GetName(); StdString cnameC = cname->GetStdString(); @@ -76,9 +66,7 @@ VMClass* SourcecodeCompiler::CompileClass( const std::string& path, showCompilationError(file, Str.str().c_str()); return nullptr; } - delete(parser); - parser = nullptr; - delete(fp); + #ifdef COMPILER_DEBUG ErrorPrint("Compilation finished\n"); #endif @@ -87,17 +75,12 @@ VMClass* SourcecodeCompiler::CompileClass( const std::string& path, VMClass* SourcecodeCompiler::CompileClassString( const StdString& stream, VMClass* systemClass ) { - istringstream* ss = new istringstream(stream); - if (parser != nullptr) delete(parser); + istringstream ss(stream); StdString fileName = "repl"; - parser = new Parser(*ss, fileName); - - VMClass* result = compile(systemClass); - delete(parser); - parser = nullptr; - delete(ss); + Parser parser(ss, fileName); + VMClass* result = compile(parser, systemClass); return result; } @@ -107,23 +90,18 @@ void SourcecodeCompiler::showCompilationError(const StdString& filename, message + "\n"); } -VMClass* SourcecodeCompiler::compile(VMClass* systemClass) { - if (parser == nullptr) { - ErrorPrint("Parser not initiated\n"); - GetUniverse()->ErrorExit("Compiler error"); - return nullptr; - } +VMClass* SourcecodeCompiler::compile(Parser& parser, VMClass* systemClass) { ClassGenerationContext cgc; VMClass* result = systemClass; - parser->Classdef(&cgc); + parser.Classdef(cgc); - if (systemClass == nullptr) + if (systemClass == nullptr) { result = cgc.Assemble(); - else + } else { cgc.AssembleSystemClass(result); + } return result; } - diff --git a/src/compiler/SourcecodeCompiler.h b/src/compiler/SourcecodeCompiler.h index d79a62e2..44525497 100644 --- a/src/compiler/SourcecodeCompiler.h +++ b/src/compiler/SourcecodeCompiler.h @@ -32,14 +32,10 @@ class SourcecodeCompiler { public: - SourcecodeCompiler(); - ~SourcecodeCompiler(); - - VMClass* CompileClass(const StdString& path, const StdString& file, + static VMClass* CompileClass(const StdString& path, const StdString& file, VMClass* systemClass); - VMClass* CompileClassString(const StdString& stream, VMClass* systemClass); + static VMClass* CompileClassString(const StdString& stream, VMClass* systemClass); private: - void showCompilationError(const StdString& filename, const char* message); - VMClass* compile(VMClass* systemClass); - Parser* parser; + static void showCompilationError(const StdString& filename, const char* message); + static VMClass* compile(Parser& parser, VMClass* systemClass); }; diff --git a/src/memory/CopyingCollector.cpp b/src/memory/CopyingCollector.cpp index 4db9cb17..a0c3ea71 100644 --- a/src/memory/CopyingCollector.cpp +++ b/src/memory/CopyingCollector.cpp @@ -17,7 +17,7 @@ static gc_oop_t copy_if_necessary(gc_oop_t oop) { // don't process tagged objects if (IS_TAGGED(oop)) return oop; - + AbstractVMObject* obj = AS_OBJ(oop); assert(IsValidObject(obj)); @@ -27,15 +27,14 @@ static gc_oop_t copy_if_necessary(gc_oop_t oop) { //if someone has moved before, return the moved object if (gcField != 0) return (gc_oop_t) gcField; - + // we have to clone ourselves AbstractVMObject* newObj = obj->Clone(); - + if (DEBUG) obj->MarkObjectAsInvalid(); - + obj->SetGCField((long)newObj); -#warning not sure about the use of _store_ptr here, or whether it should be a plain cast return _store_ptr(newObj); } @@ -62,7 +61,7 @@ void CopyingCollector::Collect() { if (heap->currentBuffer == nullptr) GetUniverse()->ErrorExit("unable to allocate more memory"); } - + // init currentBuffer with zeros memset(heap->currentBuffer, 0x0, (size_t)(heap->currentBufferEnd) - (size_t)(heap->currentBuffer)); @@ -74,7 +73,7 @@ void CopyingCollector::Collect() { curObject->WalkObjects(copy_if_necessary); curObject = (AbstractVMObject*)((size_t)curObject + curObject->GetObjectSize()); } - + //increase memory if scheduled in collection before if (increaseMemory) { increaseMemory = false; diff --git a/src/primitives/String.cpp b/src/primitives/String.cpp index 6b27e1d8..c2fc11ac 100644 --- a/src/primitives/String.cpp +++ b/src/primitives/String.cpp @@ -32,6 +32,7 @@ #include "../primitivesCore/PrimitiveContainer.h" #include "../primitivesCore/Routine.h" #include "../vm/Globals.h" +#include "../vm/Symbols.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMFrame.h" @@ -68,7 +69,7 @@ void _String::Concatenate_(Interpreter*, VMFrame* frame) { void _String::AsSymbol(Interpreter*, VMFrame* frame) { VMString* self = static_cast(frame->Pop()); StdString result = self->GetStdString(); - frame->Push(GetUniverse()->SymbolFor(result)); + frame->Push(SymbolFor(result)); } void _String::Hashcode(Interpreter*, VMFrame* frame) { diff --git a/src/unitTests/BytecodeGenerationTest.cpp b/src/unitTests/BytecodeGenerationTest.cpp index f32e7bf3..9c1fc364 100644 --- a/src/unitTests/BytecodeGenerationTest.cpp +++ b/src/unitTests/BytecodeGenerationTest.cpp @@ -11,7 +11,7 @@ #include "../compiler/MethodGenerationContext.h" #include "../compiler/Parser.h" #include "../interpreter/bytecodes.h" -#include "../vm/Universe.h" +#include "../vm/Symbols.h" #include "BytecodeGenerationTest.h" void BytecodeGenerationTest::dump(MethodGenerationContext* mgenc) { @@ -20,15 +20,15 @@ void BytecodeGenerationTest::dump(MethodGenerationContext* mgenc) { void BytecodeGenerationTest::ensureCGenC() { if (_cgenc != nullptr) return; - + _cgenc = new ClassGenerationContext(); - _cgenc->SetName(GetUniverse()->SymbolFor("Test")); + _cgenc->SetName(SymbolFor("Test")); } void BytecodeGenerationTest::ensureMGenC() { if (_mgenc != nullptr) return; ensureCGenC(); - + _mgenc = new MethodGenerationContext(); _mgenc->SetHolder(_cgenc); _mgenc->AddArgument("self"); @@ -38,8 +38,8 @@ void BytecodeGenerationTest::ensureBGenC() { if (_bgenc != nullptr) return; ensureCGenC(); ensureMGenC(); - - _mgenc->SetSignature(GetUniverse()->SymbolFor("test")); + + _mgenc->SetSignature(SymbolFor("test")); _bgenc = new MethodGenerationContext(); _bgenc->SetHolder(_cgenc); _bgenc->SetOuter(_mgenc); @@ -47,18 +47,18 @@ void BytecodeGenerationTest::ensureBGenC() { void BytecodeGenerationTest::addField(const char* fieldName) { ensureCGenC(); - _cgenc->AddInstanceField(GetUniverse()->SymbolFor(fieldName)); + _cgenc->AddInstanceField(SymbolFor(fieldName)); } std::vector BytecodeGenerationTest::methodToBytecode(const char* source, bool dumpBytecodes) { ensureMGenC(); - + istringstream ss(source); - + StdString fileName = "test"; Parser parser(ss, fileName); - parser.method(_mgenc); - + parser.method(*_mgenc); + if (dumpBytecodes) { dump(_mgenc); } @@ -67,14 +67,14 @@ std::vector BytecodeGenerationTest::methodToBytecode(const char* source std::vector BytecodeGenerationTest::blockToBytecode(const char* source, bool dumpBytecodes) { ensureBGenC(); - + istringstream ss(source); - + StdString fileName = "test"; Parser parser(ss, fileName); - - parser.nestedBlock(_bgenc); - + + parser.nestedBlock(*_bgenc); + if (dumpBytecodes) { dump(_bgenc); } @@ -83,7 +83,7 @@ std::vector BytecodeGenerationTest::blockToBytecode(const char* source, void BytecodeGenerationTest::testEmptyMethodReturnsSelf() { auto bytecodes = methodToBytecode("test = ( )"); - + check(bytecodes, { BC_PUSH_SELF, BC_RETURN_LOCAL}); @@ -149,7 +149,7 @@ void BytecodeGenerationTest::testIfPushConstantDifferent() { void BytecodeGenerationTest::testExplicitReturnSelf() { auto bytecodes = methodToBytecode("test = ( ^ self )"); - + check(bytecodes, { BC_PUSH_SELF, BC_RETURN_LOCAL @@ -158,7 +158,7 @@ void BytecodeGenerationTest::testExplicitReturnSelf() { void BytecodeGenerationTest::testDupPopArgumentPop() { auto bytecodes = methodToBytecode("test: arg = ( arg := 1. ^ self )"); - + check(bytecodes, { BC_PUSH_1, BC_DUP, @@ -171,7 +171,7 @@ void BytecodeGenerationTest::testDupPopArgumentPop() { void BytecodeGenerationTest::testDupPopArgumentPopImplicitReturnSelf() { auto bytecodes = methodToBytecode("test: arg = ( arg := 1 )"); - + check(bytecodes, { BC_PUSH_1, BC_DUP, @@ -184,7 +184,7 @@ void BytecodeGenerationTest::testDupPopArgumentPopImplicitReturnSelf() { void BytecodeGenerationTest::testDupPopLocalPop() { auto bytecodes = methodToBytecode("test = ( | local | local := 1. ^ self )"); - + check(bytecodes, { BC_PUSH_1, BC_DUP, @@ -198,7 +198,7 @@ void BytecodeGenerationTest::testDupPopLocalPop() { void BytecodeGenerationTest::testDupPopField0Pop() { addField("field"); auto bytecodes = methodToBytecode("test = ( field := 1. ^ self )"); - + check(bytecodes, { BC_PUSH_1, BC_DUP, @@ -216,7 +216,7 @@ void BytecodeGenerationTest::testDupPopFieldPop() { addField("d"); addField("field"); auto bytecodes = methodToBytecode("test = ( field := 1. ^ self )"); - + check(bytecodes, { BC_PUSH_1, BC_DUP, @@ -230,7 +230,7 @@ void BytecodeGenerationTest::testDupPopFieldPop() { void BytecodeGenerationTest::testDupPopFieldReturnSelf() { addField("field"); auto bytecodes = methodToBytecode("test: val = ( field := val )"); - + check(bytecodes, { BC_PUSH_ARG_1, BC_DUP, @@ -249,7 +249,7 @@ void BytecodeGenerationTest::testDupPopFieldNReturnSelf() { addField("e"); addField("field"); auto bytecodes = methodToBytecode("test: val = ( field := val )"); - + check(bytecodes, { BC_PUSH_ARG_1, BC_DUP, @@ -263,7 +263,7 @@ void BytecodeGenerationTest::testDupPopFieldNReturnSelf() { void BytecodeGenerationTest::testSendDupPopFieldReturnLocal() { addField("field"); auto bytecodes = methodToBytecode("test = ( ^ field := self method )"); - + check(bytecodes, { BC_PUSH_SELF, BC_SEND, 0, @@ -276,7 +276,7 @@ void BytecodeGenerationTest::testSendDupPopFieldReturnLocal() { void BytecodeGenerationTest::testSendDupPopFieldReturnLocalPeriod() { addField("field"); auto bytecodes = methodToBytecode("test = ( ^ field := self method. )"); - + check(bytecodes, { BC_PUSH_SELF, BC_SEND, 0, @@ -289,7 +289,7 @@ void BytecodeGenerationTest::testSendDupPopFieldReturnLocalPeriod() { void BytecodeGenerationTest::testBlockDupPopArgumentPopReturnArg() { auto bytecodes = blockToBytecode("[:arg | arg := 1. arg ]"); - + check(bytecodes, { BC_PUSH_1, BC_DUP, @@ -407,7 +407,7 @@ void BytecodeGenerationTest::testBlockPushFieldOpt() { addField("f3"); addField("f4"); auto bytecodes = blockToBytecode("[ f1. f2. f3. f4 ]"); - + check(bytecodes, { BC_PUSH_FIELD_0, BC_POP, BC_PUSH_FIELD_1, BC_POP, @@ -464,20 +464,20 @@ void BytecodeGenerationTest::check(std::vector actual, std::vector 1) { snprintf(msg, 1000, "Bytecode %zu (%s), arg1 expected %hhu but got %hhu", i, @@ -485,9 +485,9 @@ void BytecodeGenerationTest::check(std::vector actual, std::vector 2) { snprintf(msg, 1000, "Bytecode %zu (%s), arg2 expected %hhu but got %hhu", i, @@ -495,12 +495,12 @@ void BytecodeGenerationTest::check(std::vector actual, std::vector actual, std::vector actual, std::vectorNewSymbol("foobar"); + VMSymbol* orig = NewSymbol("foobar"); VMSymbol* clone = orig->Clone(); CPPUNIT_ASSERT((intptr_t)orig != (intptr_t)clone); @@ -109,7 +110,7 @@ void CloneObjectsTest::testCloneArray() { } void CloneObjectsTest::testCloneBlock() { - VMSymbol* methodSymbol = GetUniverse()->NewSymbol("someMethod"); + VMSymbol* methodSymbol = NewSymbol("someMethod"); VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0); VMBlock* orig = GetUniverse()->NewBlock(method, GetUniverse()->GetInterpreter()->GetFrame(), @@ -124,7 +125,7 @@ void CloneObjectsTest::testCloneBlock() { CPPUNIT_ASSERT_EQUAL_MESSAGE("context differs!!", orig->context, clone->context); } void CloneObjectsTest::testClonePrimitive() { - VMSymbol* primitiveSymbol = GetUniverse()->NewSymbol("myPrimitive"); + VMSymbol* primitiveSymbol = NewSymbol("myPrimitive"); VMPrimitive* orig = VMPrimitive::GetEmptyPrimitive(primitiveSymbol, false); VMPrimitive* clone = orig->Clone(); CPPUNIT_ASSERT_EQUAL_MESSAGE("class differs!!", orig->clazz, clone->clazz); @@ -151,7 +152,7 @@ void CloneObjectsTest::testCloneEvaluationPrimitive() { } void CloneObjectsTest::testCloneFrame() { - VMSymbol* methodSymbol = GetUniverse()->NewSymbol("frameMethod"); + VMSymbol* methodSymbol = NewSymbol("frameMethod"); VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0); VMFrame* orig = GetUniverse()->NewFrame(nullptr, method); VMFrame* context = orig->Clone(); @@ -172,7 +173,7 @@ void CloneObjectsTest::testCloneFrame() { } void CloneObjectsTest::testCloneMethod() { - VMSymbol* methodSymbol = GetUniverse()->NewSymbol("myMethod"); + VMSymbol* methodSymbol = NewSymbol("myMethod"); VMMethod* orig = GetUniverse()->NewMethod(methodSymbol, 0, 0); VMMethod* clone = orig->Clone(); @@ -203,7 +204,7 @@ void CloneObjectsTest::testCloneMethod() { void CloneObjectsTest::testCloneClass() { VMClass* orig = GetUniverse()->NewClass(load_ptr(integerClass)); - orig->SetName(GetUniverse()->NewSymbol("MyClass")); + orig->SetName(NewSymbol("MyClass")); orig->SetSuperClass(load_ptr(doubleClass)); orig->SetInstanceFields(GetUniverse()->NewArray(2)); orig->SetInstanceInvokables(GetUniverse()->NewArray(4)); diff --git a/src/unitTests/WalkObjectsTest.cpp b/src/unitTests/WalkObjectsTest.cpp index 73d4a765..c63d0611 100644 --- a/src/unitTests/WalkObjectsTest.cpp +++ b/src/unitTests/WalkObjectsTest.cpp @@ -12,6 +12,7 @@ #include "../memory/Heap.h" #include "../misc/defs.h" #include "../vm/Globals.h" +#include "../vm/Symbols.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMArray.h" @@ -110,7 +111,7 @@ void WalkObjectsTest::testWalkString() { void WalkObjectsTest::testWalkSymbol() { walkedObjects.clear(); - VMSymbol* sym = GetUniverse()->NewSymbol("symbol"); + VMSymbol* sym = NewSymbol("symbol"); sym->WalkObjects(collectMembers); CPPUNIT_ASSERT_EQUAL(NoOfFields_Symbol, walkedObjects.size()); @@ -133,7 +134,7 @@ void WalkObjectsTest::testWalkClass() { void WalkObjectsTest::testWalkPrimitive() { walkedObjects.clear(); - VMSymbol* primitiveSymbol = GetUniverse()->NewSymbol("myPrimitive"); + VMSymbol* primitiveSymbol = NewSymbol("myPrimitive"); VMPrimitive* prim = VMPrimitive::GetEmptyPrimitive(primitiveSymbol, false); prim->WalkObjects(collectMembers); @@ -145,7 +146,7 @@ void WalkObjectsTest::testWalkPrimitive() { void WalkObjectsTest::testWalkFrame() { walkedObjects.clear(); - VMSymbol* methodSymbol = GetUniverse()->NewSymbol("frameMethod"); + VMSymbol* methodSymbol = NewSymbol("frameMethod"); VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0); VMFrame* frame = GetUniverse()->NewFrame(nullptr, method); frame->SetPreviousFrame(frame->Clone()); @@ -167,7 +168,7 @@ void WalkObjectsTest::testWalkFrame() { void WalkObjectsTest::testWalkMethod() { walkedObjects.clear(); - VMSymbol* methodSymbol = GetUniverse()->NewSymbol("myMethod"); + VMSymbol* methodSymbol = NewSymbol("myMethod"); VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0); method->WalkObjects(collectMembers); @@ -185,7 +186,7 @@ void WalkObjectsTest::testWalkMethod() { void WalkObjectsTest::testWalkBlock() { walkedObjects.clear(); - VMSymbol* methodSymbol = GetUniverse()->NewSymbol("someMethod"); + VMSymbol* methodSymbol = NewSymbol("someMethod"); VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0); VMBlock* block = GetUniverse()->NewBlock(method, GetUniverse()->GetInterpreter()->GetFrame(), diff --git a/src/unitTests/WriteBarrierTest.cpp b/src/unitTests/WriteBarrierTest.cpp index 10864f7d..306f857a 100644 --- a/src/unitTests/WriteBarrierTest.cpp +++ b/src/unitTests/WriteBarrierTest.cpp @@ -7,6 +7,7 @@ #include "../memory/Heap.h" #include "../vm/Globals.h" +#include "../vm/Symbols.h" #include "../vm/Universe.h" #include "../vmobjects/ObjectFormats.h" #include "../vmobjects/VMArray.h" @@ -65,7 +66,7 @@ void WriteBarrierTest::testWriteBlock() { //reset set... GetHeap()->writeBarrierCalledOn.clear(); - VMSymbol* methodSymbol = GetUniverse()->NewSymbol("someMethod"); + VMSymbol* methodSymbol = NewSymbol("someMethod"); VMMethod* method = GetUniverse()->NewMethod(methodSymbol, 0, 0); VMBlock* block = GetUniverse()->NewBlock(method, GetUniverse()->GetInterpreter()->GetFrame(), @@ -142,7 +143,7 @@ void WriteBarrierTest::testWriteClass() { cl->SetSuperClass(load_ptr(integerClass)); TEST_WB_CALLED("VMClass failed to call writeBarrier on SetSuperClass", cl, load_ptr(integerClass)); - VMSymbol* newName = GetUniverse()->NewSymbol("andererName"); + VMSymbol* newName = NewSymbol("andererName"); cl->SetName(newName); TEST_WB_CALLED("VMClass failed to call writeBarrier on SetName", cl, newName); diff --git a/src/vm/Globals.cpp b/src/vm/Globals.cpp index 79b11a5a..ab57f9ce 100644 --- a/src/vm/Globals.cpp +++ b/src/vm/Globals.cpp @@ -22,6 +22,3 @@ GCClass* doubleClass; GCClass* trueClass; GCClass* falseClass; - -GCSymbol* symbolIfTrue; -GCSymbol* symbolIfFalse; diff --git a/src/vm/Globals.h b/src/vm/Globals.h index 1c62aed1..12fefc60 100644 --- a/src/vm/Globals.h +++ b/src/vm/Globals.h @@ -23,6 +23,3 @@ extern GCClass* doubleClass; extern GCClass* trueClass; extern GCClass* falseClass; - -extern GCSymbol* symbolIfTrue; -extern GCSymbol* symbolIfFalse; diff --git a/src/vm/LogAllocation.cpp b/src/vm/LogAllocation.cpp new file mode 100644 index 00000000..7ec01ee8 --- /dev/null +++ b/src/vm/LogAllocation.cpp @@ -0,0 +1,29 @@ +#ifdef GENERATE_ALLOCATION_STATISTICS +#include +#include + +#include "LogAllocation.h" + +std::map allocationStats; +#endif + +void InitializeAllocationLog() { +#ifdef GENERATE_ALLOCATION_STATISTICS + allocationStats["VMArray"] = {0,0}; +#endif +} + +void OutputAllocationLogFile() { +#ifdef GENERATE_ALLOCATION_STATISTICS + std::string file_name_allocation = std::string(bm_name); + file_name_allocation.append("_allocation_statistics.csv"); + + 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; + } +#endif +} + diff --git a/src/vm/LogAllocation.h b/src/vm/LogAllocation.h new file mode 100644 index 00000000..e0aa2d05 --- /dev/null +++ b/src/vm/LogAllocation.h @@ -0,0 +1,12 @@ +#pragma once + +#ifdef GENERATE_ALLOCATION_STATISTICS +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;} +#else +#define LOG_ALLOCATION(TYPE,SIZE) +#endif + +void InitializeAllocationLog(); +void OutputAllocationLogFile(); diff --git a/src/vm/Shell.cpp b/src/vm/Shell.cpp index 8a104a8d..0db3620c 100644 --- a/src/vm/Shell.cpp +++ b/src/vm/Shell.cpp @@ -36,6 +36,7 @@ #include "../vmobjects/VMMethod.h" #include "Globals.h" #include "Shell.h" +#include "Symbols.h" #include "Universe.h" // maximal length of an input line from the shell @@ -123,8 +124,7 @@ void Shell::Start(Interpreter* interp) { currentFrame->Push(it); // Lookup the run: method - VMInvokable* initialize = runClass->LookupInvokable( - GetUniverse()->SymbolFor("run:")); + VMInvokable* initialize = runClass->LookupInvokable(SymbolFor("run:")); // Invoke the run method initialize->Invoke(interp, currentFrame); diff --git a/src/vm/Symbols.cpp b/src/vm/Symbols.cpp new file mode 100644 index 00000000..c7cbaf23 --- /dev/null +++ b/src/vm/Symbols.cpp @@ -0,0 +1,53 @@ +#include +#include +#include + +#include "../memory/Heap.h" +#include "../misc/defs.h" +#include "../vmobjects/AbstractObject.h" +#include "../vmobjects/ObjectFormats.h" +#include "../vmobjects/VMSymbol.h" +#include "LogAllocation.h" +#include "Symbols.h" + +map symbolsMap; + +GCSymbol* symbolIfTrue; +GCSymbol* symbolIfFalse; + +VMSymbol* NewSymbol(const size_t length, const char* str) { + VMSymbol* result = new (GetHeap(), PADDED_SIZE(length)) VMSymbol(length, str); + symbolsMap[StdString(str, length)] = _store_ptr(result); + + LOG_ALLOCATION("VMSymbol", result->GetObjectSize()); + return result; +} + +VMSymbol* NewSymbol(const std::string& str) { + return NewSymbol(str.length(), str.c_str()); +} + +VMSymbol* SymbolFor(const std::string& str) { + map::iterator it = symbolsMap.find(str); + return (it == symbolsMap.end()) ? NewSymbol(str) : load_ptr(it->second); +} + +void InitializeSymbols() { + symbolIfTrue = _store_ptr(SymbolFor("ifTrue:")); + symbolIfFalse = _store_ptr(SymbolFor("ifFalse:")); +} + +void WalkSymbols(walk_heap_fn walk) { + // walk all entries in symbols map + map::iterator symbolIter; + for (symbolIter = symbolsMap.begin(); + symbolIter != symbolsMap.end(); + symbolIter++) { + //insert overwrites old entries inside the internal map + symbolIter->second = static_cast(walk(symbolIter->second)); + } + + //reassign ifTrue ifFalse Symbols + symbolIfTrue = symbolsMap["ifTrue:"]; + symbolIfFalse = symbolsMap["ifFalse:"]; +} diff --git a/src/vm/Symbols.h b/src/vm/Symbols.h new file mode 100644 index 00000000..d5657f9e --- /dev/null +++ b/src/vm/Symbols.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "../vmobjects/VMSymbol.h" + +VMSymbol* SymbolFor(const std::string& str); + +void InitializeSymbols(); + +void WalkSymbols(walk_heap_fn walk); + +#ifdef UNITTESTS +VMSymbol* NewSymbol(const std::string& str); +VMSymbol* NewSymbol(const size_t length, const char* str); +#endif + +extern GCSymbol* symbolIfTrue; +extern GCSymbol* symbolIfFalse; diff --git a/src/vm/Universe.cpp b/src/vm/Universe.cpp index 6671dc3c..50e5ff68 100644 --- a/src/vm/Universe.cpp +++ b/src/vm/Universe.cpp @@ -58,8 +58,10 @@ #include "../vmobjects/VMSymbol.h" #include "Globals.h" #include "IsValidObject.h" +#include "LogAllocation.h" #include "Print.h" #include "Shell.h" +#include "Symbols.h" #include "Universe.h" #if CACHE_INTEGER @@ -77,14 +79,6 @@ Universe* Universe::theUniverse = nullptr; std::string bm_name; -#ifdef GENERATE_ALLOCATION_STATISTICS -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;} -#else -#define LOG_ALLOCATION(TYPE,SIZE) -#endif - map integerHist; @@ -127,17 +121,8 @@ __attribute__((noreturn)) void Universe::Quit(long err) { ", " << it->second.noPrimitiveCalls << ", " << it->second.noCalls - it->second.noPrimitiveCalls << endl; #endif -#ifdef GENERATE_ALLOCATION_STATISTICS - std::string file_name_allocation = std::string(bm_name); - file_name_allocation.append("_allocation_statistics.csv"); - - 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; - } -#endif + OutputAllocationLogFile(); + if (theUniverse) delete (theUniverse); @@ -332,9 +317,7 @@ vm_oop_t Universe::interpretMethod(VMObject* receiver, VMInvokable* initialize, } void Universe::initialize(long _argc, char** _argv) { -#ifdef GENERATE_ALLOCATION_STATISTICS - allocationStats["VMArray"] = {0,0}; -#endif + InitializeAllocationLog(); heapSize = 1 * 1024 * 1024; @@ -465,9 +448,7 @@ VMObject* Universe::InitializeGlobals() { SetGlobal(SymbolFor("System"), load_ptr(systemClass)); SetGlobal(SymbolFor("Block"), load_ptr(blockClass)); - symbolIfTrue = _store_ptr(SymbolFor("ifTrue:")); - symbolIfFalse = _store_ptr(SymbolFor("ifFalse:")); - + InitializeSymbols(); return systemObject; } @@ -578,8 +559,7 @@ VMClass* Universe::LoadClassBasic(VMSymbol* name, VMClass* systemClass) { for (vector::iterator i = classPath.begin(); i != classPath.end(); ++i) { - SourcecodeCompiler compiler; - result = compiler.CompileClass(*i, name->GetStdString(), systemClass); + result = SourcecodeCompiler::CompileClass(*i, name->GetStdString(), systemClass); if (result) { if (dumpBytecodes) { Disassembler::Dump(result->GetClass()); @@ -592,8 +572,7 @@ VMClass* Universe::LoadClassBasic(VMSymbol* name, VMClass* systemClass) { } VMClass* Universe::LoadShellClass(StdString& stmt) { - SourcecodeCompiler compiler; - VMClass* result = compiler.CompileClassString(stmt, nullptr); + VMClass* result = SourcecodeCompiler::CompileClassString(stmt, nullptr); if(dumpBytecodes) Disassembler::Dump(result); return result; @@ -814,14 +793,8 @@ void Universe::WalkGlobals(walk_heap_fn walk) { globals[key] = val; } - // walk all entries in symbols map - map::iterator symbolIter; - for (symbolIter = symbolsMap.begin(); - symbolIter != symbolsMap.end(); - symbolIter++) { - //insert overwrites old entries inside the internal map - symbolIter->second = static_cast(walk(symbolIter->second)); - } + WalkSymbols(walk); + map::iterator bcIter; for (bcIter = blockClassesByNoOfArgs.begin(); @@ -829,10 +802,6 @@ void Universe::WalkGlobals(walk_heap_fn walk) { bcIter++) { bcIter->second = static_cast(walk(bcIter->second)); } - - //reassign ifTrue ifFalse Symbols - symbolIfTrue = symbolsMap["ifTrue:"]; - symbolIfFalse = symbolsMap["ifFalse:"]; interpreter->WalkGlobals(walk); } @@ -867,18 +836,6 @@ VMString* Universe::NewString(const size_t length, const char* str) const { return result; } -VMSymbol* Universe::NewSymbol(const StdString& str) { - return NewSymbol(str.length(), str.c_str()); -} - -VMSymbol* Universe::NewSymbol(const size_t length, const char* str) { - VMSymbol* result = new (GetHeap(), PADDED_SIZE(length)) VMSymbol(length, str); - symbolsMap[StdString(str, length)] = _store_ptr(result); - - LOG_ALLOCATION("VMSymbol", result->GetObjectSize()); - return result; -} - VMClass* Universe::NewSystemClass() const { VMClass* systemClass = new (GetHeap()) VMClass(); @@ -891,11 +848,6 @@ VMClass* Universe::NewSystemClass() const { return systemClass; } -VMSymbol* Universe::SymbolFor(const StdString& str) { - map::iterator it = symbolsMap.find(str); - return (it == symbolsMap.end()) ? NewSymbol(str) : load_ptr(it->second); -} - void Universe::SetGlobal(VMSymbol* name, vm_oop_t val) { globals[_store_ptr(name)] = _store_ptr(val); } diff --git a/src/vm/Universe.h b/src/vm/Universe.h index cf9a9530..cd2c78cf 100644 --- a/src/vm/Universe.h +++ b/src/vm/Universe.h @@ -64,8 +64,6 @@ class Universe { void Assert(bool) const; - VMSymbol* SymbolFor(const StdString&); - //VMObject instanciation methods. These should probably be refactored to a new class VMArray* NewArray(long) const; @@ -85,9 +83,7 @@ class Universe { VMDouble* NewDouble(double) const; VMClass* NewMetaclassClass(void) const; VMString* NewString(const StdString&) const; - VMSymbol* NewSymbol(const StdString&); VMString* NewString(const size_t, const char*) const; - VMSymbol* NewSymbol(const size_t, const char*); VMClass* NewSystemClass(void) const; void InitializeSystemClass(VMClass*, VMClass*, const char*); @@ -134,7 +130,7 @@ class Universe { long heapSize; map globals; - map symbolsMap; + map blockClassesByNoOfArgs; vector classPath; diff --git a/src/vmobjects/AbstractObject.cpp b/src/vmobjects/AbstractObject.cpp index c7f07535..04095079 100644 --- a/src/vmobjects/AbstractObject.cpp +++ b/src/vmobjects/AbstractObject.cpp @@ -8,7 +8,8 @@ #include #include -#include "../vm/Universe.h" +#include "../interpreter/Interpreter.h" +#include "../vm/Symbols.h" #include "../vmobjects/ObjectFormats.h" #include "AbstractObject.h" #include "VMClass.h" @@ -22,7 +23,7 @@ int64_t AbstractVMObject::GetHash() { void AbstractVMObject::Send(Interpreter* interp, std::string selectorString, vm_oop_t* arguments, long argc) { VMFrame* frame = interp->GetFrame(); - VMSymbol* selector = GetUniverse()->SymbolFor(selectorString); + VMSymbol* selector = SymbolFor(selectorString); frame->Push(this); for (long i = 0; i < argc; ++i) { diff --git a/src/vmobjects/IntegerBox.cpp b/src/vmobjects/IntegerBox.cpp index 8308abd5..675c2dce 100644 --- a/src/vmobjects/IntegerBox.cpp +++ b/src/vmobjects/IntegerBox.cpp @@ -5,7 +5,6 @@ GCInteger* GlobalBox::integerBox = nullptr; void GlobalBox::updateIntegerBox(VMInteger* newValue) { -# warning Is this acceptable use of _store_ptr?? integerBox = _store_ptr(newValue); } diff --git a/src/vmobjects/VMEvaluationPrimitive.cpp b/src/vmobjects/VMEvaluationPrimitive.cpp index 7608adda..e8423b52 100644 --- a/src/vmobjects/VMEvaluationPrimitive.cpp +++ b/src/vmobjects/VMEvaluationPrimitive.cpp @@ -30,7 +30,8 @@ #include "../memory/Heap.h" #include "../misc/defs.h" #include "../primitivesCore/Routine.h" -#include "../vm/Universe.h" +#include "../vm/Symbols.h" +#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" @@ -78,12 +79,12 @@ VMSymbol* VMEvaluationPrimitive::computeSignatureString(long argc) { } // Return the signature string - return GetUniverse()->SymbolFor(signatureString); + return SymbolFor(signatureString); } void EvaluationRoutine::Invoke(Interpreter* interp, VMFrame* frame) { VMEvaluationPrimitive* prim = load_ptr(evalPrim); - + // Get the block (the receiver) from the stack long numArgs = prim->GetNumberOfArguments(); VMBlock* block = static_cast(frame->GetStackElement(numArgs - 1));