From 8882e3180d1cb152b808a23d14568c3b7919ab2b Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Sun, 11 Aug 2024 11:22:03 +0100 Subject: [PATCH] Remove all of the old primitive code, and use now the same approach as for safe prims Signed-off-by: Stefan Marr --- SOM.xcodeproj/project.pbxproj | 2 - src/primitives/Method.cpp | 6 +-- src/primitives/Object.cpp | 25 ++++------ src/primitives/Primitive.cpp | 7 +-- src/primitives/System.cpp | 6 +-- src/primitivesCore/PrimitiveContainer.cpp | 28 ++++-------- src/primitivesCore/PrimitiveContainer.h | 15 ++---- src/primitivesCore/PrimitiveLoader.cpp | 28 ------------ src/primitivesCore/PrimitiveLoader.h | 6 --- src/primitivesCore/Primitives.h | 44 +++++++++++------- src/primitivesCore/Routine.h | 56 ----------------------- src/unitTests/CloneObjectsTest.cpp | 7 +-- src/vm/IsValidObject.cpp | 2 +- src/vmobjects/VMPrimitive.cpp | 31 +++++++------ src/vmobjects/VMPrimitive.h | 31 +++++-------- 15 files changed, 89 insertions(+), 205 deletions(-) delete mode 100644 src/primitivesCore/Routine.h diff --git a/SOM.xcodeproj/project.pbxproj b/SOM.xcodeproj/project.pbxproj index 498dbaf8..362003d2 100644 --- a/SOM.xcodeproj/project.pbxproj +++ b/SOM.xcodeproj/project.pbxproj @@ -299,7 +299,6 @@ 3F52032A0FA6624C00E75857 /* PrimitiveContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrimitiveContainer.h; sourceTree = ""; }; 3F52032B0FA6624C00E75857 /* PrimitiveLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrimitiveLoader.cpp; sourceTree = ""; }; 3F52032C0FA6624C00E75857 /* PrimitiveLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrimitiveLoader.h; sourceTree = ""; }; - 3F52032E0FA6624C00E75857 /* Routine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Routine.h; sourceTree = ""; }; 3F5203300FA6624C00E75857 /* Shell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shell.cpp; sourceTree = ""; }; 3F5203310FA6624C00E75857 /* Shell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shell.h; sourceTree = ""; }; 3F5203320FA6624C00E75857 /* Universe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Universe.cpp; sourceTree = ""; }; @@ -618,7 +617,6 @@ 3F52032A0FA6624C00E75857 /* PrimitiveContainer.h */, 3F52032B0FA6624C00E75857 /* PrimitiveLoader.cpp */, 3F52032C0FA6624C00E75857 /* PrimitiveLoader.h */, - 3F52032E0FA6624C00E75857 /* Routine.h */, 0A5A7E932C5DA9A90011C783 /* Primitives.h */, ); path = primitivesCore; diff --git a/src/primitives/Method.cpp b/src/primitives/Method.cpp index fbaad07d..2485f940 100644 --- a/src/primitives/Method.cpp +++ b/src/primitives/Method.cpp @@ -3,7 +3,6 @@ #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 @@ -21,7 +20,7 @@ static vm_oop_t mSignature(vm_oop_t rcvr) { return self->GetSignature(); } -void _Method::InvokeOn_With_(VMFrame* frame) { +void mInvokeOnWith(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()); @@ -40,6 +39,5 @@ void _Method::InvokeOn_With_(VMFrame* frame) { _Method::_Method() : PrimitiveContainer() { Add("signature", &mSignature, false); Add("holder", &mHolder, false); - SetPrimitive("invokeOn:with:", - new Routine<_Method>(this, &_Method::InvokeOn_With_, false)); + Add("invokeOn:with:", &mInvokeOnWith, false); } diff --git a/src/primitives/Object.cpp b/src/primitives/Object.cpp index 7c446b80..a0a3cc33 100644 --- a/src/primitives/Object.cpp +++ b/src/primitives/Object.cpp @@ -30,7 +30,6 @@ #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 "../vmobjects/ObjectFormats.h" @@ -66,7 +65,7 @@ vm_oop_t objHalt(vm_oop_t) { return load_ptr(falseObject); } -void _Object::Perform(VMFrame* frame) { +void objPerform(VMFrame* frame) { VMSymbol* selector = (VMSymbol*)frame->Pop(); vm_oop_t self = frame->GetStackElement(0); @@ -76,7 +75,7 @@ void _Object::Perform(VMFrame* frame) { invokable->Invoke(frame); } -void _Object::PerformInSuperclass(VMFrame* frame) { +void objPerformInSuperclass(VMFrame* frame) { VMClass* clazz = (VMClass*)frame->Pop(); VMSymbol* selector = (VMSymbol*)frame->Pop(); @@ -85,7 +84,7 @@ void _Object::PerformInSuperclass(VMFrame* frame) { invokable->Invoke(frame); } -void _Object::PerformWithArguments(VMFrame* frame) { +void objPerformWithArguments(VMFrame* frame) { VMArray* args = (VMArray*)frame->Pop(); VMSymbol* selector = (VMSymbol*)frame->Pop(); vm_oop_t self = frame->GetStackElement(0); @@ -102,7 +101,7 @@ void _Object::PerformWithArguments(VMFrame* frame) { invokable->Invoke(frame); } -void _Object::PerformWithArgumentsInSuperclass(VMFrame* frame) { +void objPerformWithArgumentsInSuperclass(VMFrame* frame) { VMClass* clazz = (VMClass*)frame->Pop(); VMArray* args = (VMArray*)frame->Pop(); VMSymbol* selector = (VMSymbol*)frame->Pop(); @@ -146,17 +145,11 @@ _Object::_Object() : PrimitiveContainer() { Add("inspect", &objInspect, false); Add("halt", &objHalt, 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)); + Add("perform:", &objPerform, false); + Add("perform:withArguments:", &objPerformWithArguments, false); + Add("perform:inSuperclass:", &objPerformInSuperclass, false); + Add("perform:withArguments:inSuperclass:", + &objPerformWithArgumentsInSuperclass, false); Add("instVarAt:", &objInstVarAt, false); Add("instVarAt:put:", &objInstVarAtPut, false); diff --git a/src/primitives/Primitive.cpp b/src/primitives/Primitive.cpp index c31f7110..f2c3c1f8 100644 --- a/src/primitives/Primitive.cpp +++ b/src/primitives/Primitive.cpp @@ -3,7 +3,6 @@ #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/VMFrame.h" @@ -19,7 +18,7 @@ static vm_oop_t pSignature(vm_oop_t rcvr) { return self->GetSignature(); } -void _Primitive::InvokeOn_With_(VMFrame* frame) { +void pInvokeOnWith(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()); @@ -38,7 +37,5 @@ void _Primitive::InvokeOn_With_(VMFrame* frame) { _Primitive::_Primitive() : PrimitiveContainer() { Add("signature", &pSignature, false); Add("holder", &pHolder, false); - SetPrimitive( - "invokeOn:with:", - new Routine<_Primitive>(this, &_Primitive::InvokeOn_With_, false)); + Add("invokeOn:with:", &pInvokeOnWith, false); } diff --git a/src/primitives/System.cpp b/src/primitives/System.cpp index 0674d136..090da5cb 100644 --- a/src/primitives/System.cpp +++ b/src/primitives/System.cpp @@ -34,7 +34,6 @@ #include "../memory/Heap.h" #include "../misc/defs.h" #include "../primitivesCore/PrimitiveContainer.h" -#include "../primitivesCore/Routine.h" #include "../vm/Globals.h" #include "../vm/Print.h" #include "../vm/Universe.h" @@ -167,7 +166,7 @@ static vm_oop_t sysLoadFile_(vm_oop_t, vm_oop_t rightObj) { } } -void _System::PrintStackTrace(VMFrame* frame) { +void printStackTrace(VMFrame* frame) { frame->PrintStackTrace(); } @@ -188,8 +187,7 @@ _System::_System(void) : PrimitiveContainer() { Add("fullGC", &sysFullGC, false); Add("loadFile:", &sysLoadFile_, false); - SetPrimitive("printStackTrace", - new Routine<_System>(this, &_System::PrintStackTrace, false)); + Add("printStackTrace", &printStackTrace, false); } _System::~_System() {} diff --git a/src/primitivesCore/PrimitiveContainer.cpp b/src/primitivesCore/PrimitiveContainer.cpp index 7f87451c..b434dd49 100644 --- a/src/primitivesCore/PrimitiveContainer.cpp +++ b/src/primitivesCore/PrimitiveContainer.cpp @@ -33,18 +33,18 @@ #include #include "../vm/Symbols.h" -#include "../vmobjects/PrimitiveRoutine.h" #include "../vmobjects/VMClass.h" #include "../vmobjects/VMPrimitive.h" #include "../vmobjects/VMSafePrimitive.h" #include "../vmobjects/VMSymbol.h" #include "Primitives.h" -void PrimitiveContainer::SetPrimitive(const char* name, - PrimitiveRoutine* routine) { - methods[std::string(name)] = routine; +void PrimitiveContainer::Add(const char* name, + FramePrimitiveRoutine routine, + bool classSide) { + assert(framePrims.find(name) == framePrims.end()); + framePrims[std::string(name)] = {routine, classSide}; } - void PrimitiveContainer::Add(const char* name, BinaryPrimitiveRoutine routine, bool classSide) { @@ -66,14 +66,6 @@ void PrimitiveContainer::Add(const char* name, ternaryPrims[std::string(name)] = {routine, classSide}; } -PrimitiveRoutine* PrimitiveContainer::GetPrimitive( - const std::string& routineName) { - if (methods.find(routineName) != methods.end()) { - return methods[routineName]; - } - return nullptr; -} - void PrimitiveContainer::InstallPrimitives(VMClass* clazz, bool classSide) { for (auto const& p : unaryPrims) { assert(p.second.IsValid()); @@ -120,15 +112,15 @@ void PrimitiveContainer::InstallPrimitives(VMClass* clazz, bool classSide) { } } - for (auto const& p : methods) { - if (classSide != p.second->isClassSide()) { + for (auto const& p : framePrims) { + assert(p.second.IsValid()); + if (classSide != p.second.isClassSide) { continue; } VMSymbol* sig = SymbolFor(p.first); - VMPrimitive* prim = VMPrimitive::GetEmptyPrimitive(sig, classSide); - prim->SetRoutine(p.second, false); - if (clazz->AddInstanceInvokable(prim)) { + if (clazz->AddInstanceInvokable( + VMPrimitive::GetFramePrim(sig, p.second))) { cout << "Warn: Primitive " << p.first << " is not in class definition for class " << clazz->GetName()->GetStdString() << endl; diff --git a/src/primitivesCore/PrimitiveContainer.h b/src/primitivesCore/PrimitiveContainer.h index bd29f41b..7a91d73d 100644 --- a/src/primitivesCore/PrimitiveContainer.h +++ b/src/primitivesCore/PrimitiveContainer.h @@ -33,7 +33,7 @@ #include "Primitives.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. class PrimitiveContainer { @@ -41,24 +41,15 @@ class PrimitiveContainer { 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*) - void SetPrimitive(const char* name, PrimitiveRoutine* routine); - - PrimitiveRoutine* GetPrimitive(const std::string& routineName); - void InstallPrimitives(VMClass* clazz, bool classSide); + void Add(const char* name, FramePrimitiveRoutine, bool classSide); void Add(const char* name, UnaryPrimitiveRoutine, bool classSide); void Add(const char* name, BinaryPrimitiveRoutine, bool classSide); void Add(const char* name, TernaryPrimitiveRoutine, bool classSide); private: - std::map methods{}; + std::map framePrims{}; std::map unaryPrims{}; std::map binaryPrims{}; std::map ternaryPrims{}; diff --git a/src/primitivesCore/PrimitiveLoader.cpp b/src/primitivesCore/PrimitiveLoader.cpp index 7795ee61..18d275fc 100644 --- a/src/primitivesCore/PrimitiveLoader.cpp +++ b/src/primitivesCore/PrimitiveLoader.cpp @@ -40,9 +40,7 @@ #include "../primitives/String.h" #include "../primitives/Symbol.h" #include "../primitives/System.h" -#include "../vm/Print.h" #include "../vmobjects/ObjectFormats.h" -#include "../vmobjects/PrimitiveRoutine.h" #include "PrimitiveContainer.h" PrimitiveLoader PrimitiveLoader::loader; @@ -80,12 +78,6 @@ bool PrimitiveLoader::SupportsClass(const std::string& name) { return loader.supportsClass(name); } -PrimitiveRoutine* PrimitiveLoader::GetPrimitiveRoutine(const std::string& cname, - const std::string& mname, - bool isPrimitive) { - return loader.getPrimitiveRoutine(cname, mname, isPrimitive); -} - void PrimitiveLoader::InstallPrimitives(const std::string& cname, VMClass* clazz, bool classSide) { @@ -101,23 +93,3 @@ void PrimitiveLoader::installPrimitives(const std::string& cname, primitiveObjects[cname]->InstallPrimitives(clazz, classSide); } - -PrimitiveRoutine* PrimitiveLoader::getPrimitiveRoutine(const std::string& cname, - const std::string& mname, - bool isPrimitive) { - if (primitiveObjects.find(cname) == primitiveObjects.end()) { - ErrorPrint("Primitive object not found for name: " + cname + "\n"); - return nullptr; - } - - PrimitiveContainer* primitive = primitiveObjects[cname]; - PrimitiveRoutine* result = primitive->GetPrimitive(mname); - if (!result) { - if (isPrimitive) { - 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 71899ee9..013d5201 100644 --- a/src/primitivesCore/PrimitiveLoader.h +++ b/src/primitivesCore/PrimitiveLoader.h @@ -50,9 +50,6 @@ class 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, - bool isPrimitive); static void InstallPrimitives(const std::string& cname, VMClass* clazz, @@ -64,9 +61,6 @@ class PrimitiveLoader { bool classSide); bool supportsClass(const std::string& name); - PrimitiveRoutine* getPrimitiveRoutine(const std::string& cname, - const std::string& mname, - bool isPrimitive); std::map primitiveObjects{}; diff --git a/src/primitivesCore/Primitives.h b/src/primitivesCore/Primitives.h index 64e19f73..d71e2e59 100644 --- a/src/primitivesCore/Primitives.h +++ b/src/primitivesCore/Primitives.h @@ -2,51 +2,63 @@ #include "../vmobjects/ObjectFormats.h" +using FramePrimitiveRoutine = void(VMFrame*); using UnaryPrimitiveRoutine = vm_oop_t(vm_oop_t); using BinaryPrimitiveRoutine = vm_oop_t(vm_oop_t, vm_oop_t); using TernaryPrimitiveRoutine = vm_oop_t(vm_oop_t, vm_oop_t, vm_oop_t); -class UnaryPrim { +class Prim { public: - UnaryPrim(UnaryPrimitiveRoutine ptr, bool classSide) - : pointer(ptr), isClassSide(classSide) {} - explicit UnaryPrim() : pointer(nullptr), isClassSide(false) {} + Prim(bool classSide) : isClassSide(classSide) {} + bool isClassSide; +}; + +class FramePrim : public Prim { +public: + FramePrim(FramePrimitiveRoutine ptr, bool classSide) + : Prim(classSide), pointer(ptr) {} + explicit FramePrim() : Prim(false), pointer(nullptr) {} bool IsValid() const { return pointer != nullptr; } + void MarkObjectAsInvalid() { pointer = nullptr; } + + void (*pointer)(VMFrame*); +}; + +class UnaryPrim : public Prim { +public: + UnaryPrim(UnaryPrimitiveRoutine ptr, bool classSide) + : Prim(classSide), pointer(ptr) {} + explicit UnaryPrim() : Prim(false), pointer(nullptr) {} + bool IsValid() const { return pointer != nullptr; } void MarkObjectAsInvalid() { pointer = nullptr; } vm_oop_t (*pointer)(vm_oop_t); - - bool isClassSide; }; -class BinaryPrim { +class BinaryPrim : public Prim { public: BinaryPrim(BinaryPrimitiveRoutine ptr, bool classSide) - : pointer(ptr), isClassSide(classSide) {} - explicit BinaryPrim() : pointer(nullptr), isClassSide(false) {} + : Prim(classSide), pointer(ptr) {} + explicit BinaryPrim() : Prim(false), pointer(nullptr) {} bool IsValid() const { return pointer != nullptr; } void MarkObjectAsInvalid() { pointer = nullptr; } vm_oop_t (*pointer)(vm_oop_t, vm_oop_t); - - bool isClassSide; }; -class TernaryPrim { +class TernaryPrim : public Prim { public: TernaryPrim(TernaryPrimitiveRoutine ptr, bool classSide) - : pointer(ptr), isClassSide(classSide) {} - explicit TernaryPrim() : pointer(nullptr), isClassSide(false) {} + : Prim(classSide), pointer(ptr) {} + explicit TernaryPrim() : Prim(false), pointer(nullptr) {} bool IsValid() const { return pointer != nullptr; } void MarkObjectAsInvalid() { pointer = nullptr; } vm_oop_t (*pointer)(vm_oop_t, vm_oop_t, vm_oop_t); - - bool isClassSide; }; diff --git a/src/primitivesCore/Routine.h b/src/primitivesCore/Routine.h deleted file mode 100644 index 3c970f1a..00000000 --- a/src/primitivesCore/Routine.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -/* - * - * - Copyright (c) 2007 Michael Haupt, Tobias Pape, Arne Bergmann - Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany - http://www.hpi.uni-potsdam.de/swa/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -#include "../vmobjects/PrimitiveRoutine.h" - -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 { -private: - void (TClass::*func)(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)(VMFrame*), - bool classSide) - : PrimitiveRoutine(), func(_fpt), primContainerObj(primContainerObj), - classSide(classSide) {}; - - void Invoke(VMFrame* frm) override { - (*primContainerObj.*func)(frm); // execute member function - } - - bool isClassSide() override { return classSide; } -}; diff --git a/src/unitTests/CloneObjectsTest.cpp b/src/unitTests/CloneObjectsTest.cpp index b7def32c..3b6c3400 100644 --- a/src/unitTests/CloneObjectsTest.cpp +++ b/src/unitTests/CloneObjectsTest.cpp @@ -175,9 +175,10 @@ void CloneObjectsTest::testClonePrimitive() { 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("routine differs!!", orig->prim.pointer, + clone->prim.pointer); + CPPUNIT_ASSERT_EQUAL_MESSAGE("routine differs!!", orig->prim.isClassSide, + clone->prim.isClassSide); CPPUNIT_ASSERT_EQUAL_MESSAGE("hash differs!!", orig->GetHash(), clone->GetHash()); } diff --git a/src/vm/IsValidObject.cpp b/src/vm/IsValidObject.cpp index 92934211..47e98d61 100644 --- a/src/vm/IsValidObject.cpp +++ b/src/vm/IsValidObject.cpp @@ -189,7 +189,7 @@ void obtain_vtables_of_known_classes(VMSymbol* someValidSymbol) { vt_object = get_vtable(load_ptr(nilObject)); VMPrimitive* prm = - new (GetHeap(), 0) VMPrimitive(someValidSymbol); + new (GetHeap(), 0) VMPrimitive(someValidSymbol, FramePrim()); vt_primitive = get_vtable(prm); VMSafeUnaryPrimitive* sbp1 = new (GetHeap(), 0) diff --git a/src/vmobjects/VMPrimitive.cpp b/src/vmobjects/VMPrimitive.cpp index f0cb03c8..11d8fc6c 100644 --- a/src/vmobjects/VMPrimitive.cpp +++ b/src/vmobjects/VMPrimitive.cpp @@ -31,7 +31,7 @@ #include "../compiler/LexicalScope.h" #include "../memory/Heap.h" #include "../misc/defs.h" -#include "../primitivesCore/Routine.h" +#include "../primitivesCore/Primitives.h" #include "../vm/Globals.h" // NOLINT (misc-include-cleaner) #include "../vm/Print.h" #include "ObjectFormats.h" @@ -39,17 +39,9 @@ #include "VMFrame.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); - return prim; -} - -VMPrimitive::VMPrimitive(VMSymbol* signature) - : VMInvokable(signature), routine(nullptr), empty(false) { - write_barrier(this, signature); +VMPrimitive* VMPrimitive::GetFramePrim(VMSymbol* sig, FramePrim prim) { + VMPrimitive* p = new (GetHeap(), 0) VMPrimitive(sig, prim); + return p; } VMPrimitive* VMPrimitive::CloneForMovingGC() const { @@ -58,9 +50,18 @@ VMPrimitive* VMPrimitive::CloneForMovingGC() const { return prim; } -void VMPrimitive::EmptyRoutine(VMFrame*) { - VMSymbol* sig = GetSignature(); - ErrorPrint("undefined primitive called: " + sig->GetStdString() + "\n"); +void emptyRoutine(VMFrame* frame) { + ErrorPrint("undefined primitive called\n"); + frame->PrintStackTrace(); + ErrorExit("undefined primitive called"); +} + +VMPrimitive* VMPrimitive::GetEmptyPrimitive(VMSymbol* sig, bool classSide) { + return GetFramePrim(sig, FramePrim(&emptyRoutine, classSide)); +} + +bool VMPrimitive::IsEmpty() const { + return prim.pointer == &emptyRoutine; } void VMPrimitive::InlineInto(MethodGenerationContext&, bool) { diff --git a/src/vmobjects/VMPrimitive.h b/src/vmobjects/VMPrimitive.h index 5ffdace5..4abd9dfe 100644 --- a/src/vmobjects/VMPrimitive.h +++ b/src/vmobjects/VMPrimitive.h @@ -26,6 +26,7 @@ THE SOFTWARE. */ +#include "../primitivesCore/Primitives.h" #include "PrimitiveRoutine.h" #include "Signature.h" #include "VMInvokable.h" @@ -36,25 +37,24 @@ class VMPrimitive : public VMInvokable { typedef GCPrimitive Stored; static VMPrimitive* GetEmptyPrimitive(VMSymbol* sig, bool classSide); + static VMPrimitive* GetFramePrim(VMSymbol* sig, FramePrim prim); - VMPrimitive(VMSymbol* sig); + VMPrimitive(VMSymbol* sig, FramePrim prim) : VMInvokable(sig), prim(prim) { + write_barrier(this, sig); + } VMClass* GetClass() const final { return load_ptr(primitiveClass); } inline size_t GetObjectSize() const override { return sizeof(VMPrimitive); } - inline bool IsEmpty() const { return empty; } + bool IsEmpty() const; - inline void SetRoutine(PrimitiveRoutine* rtn, bool empty) { - routine = rtn; - this->empty = empty; - } + inline void SetRoutine(FramePrim p) { prim = p; } - void SetEmpty(bool value) { empty = value; }; VMPrimitive* CloneForMovingGC() const override; VMFrame* Invoke(VMFrame* frm) override { - routine->Invoke(frm); + prim.pointer(frm); return nullptr; }; @@ -64,12 +64,11 @@ class VMPrimitive : public VMInvokable { bool IsPrimitive() const override { return true; }; void MarkObjectAsInvalid() override { - routine = (PrimitiveRoutine*)INVALID_GC_POINTER; + VMInvokable::MarkObjectAsInvalid(); + prim.MarkObjectAsInvalid(); } - bool IsMarkedInvalid() const override { - return routine == (PrimitiveRoutine*)INVALID_GC_POINTER; - } + bool IsMarkedInvalid() const override { return !prim.IsValid(); } StdString AsDebugString() const override; @@ -77,14 +76,8 @@ class VMPrimitive : public VMInvokable { return Signature::GetNumberOfArguments(load_ptr(signature)); } -private: - void EmptyRoutine(VMFrame*); - -public: - PrimitiveRoutine* routine; - private: make_testable(public); - bool empty; + FramePrim prim; };