3333#include < string>
3434#include < utility>
3535
36+ #include " ../vm/Print.h"
3637#include " ../vm/Symbols.h"
38+ #include " ../vm/Universe.h"
3739#include " ../vmobjects/VMClass.h"
3840#include " ../vmobjects/VMInvokable.h"
3941#include " ../vmobjects/VMPrimitive.h"
@@ -133,10 +135,12 @@ void PrimitiveContainer::Add(const char* name, bool classSide,
133135}
134136
135137template <class PrimT >
136- void PrimitiveContainer::installPrimitives (
138+ bool PrimitiveContainer::installPrimitives (
137139 bool classSide, bool showWarning, VMClass* clazz,
138140 std::map<std::string, std::pair<PrimT, PrimT>>& prims,
139141 VMInvokable* (*makePrimFn)(VMSymbol* sig, PrimT)) {
142+ bool hasHashMismatch = false ;
143+
140144 for (auto const & p : prims) {
141145 PrimT prim1 = std::get<0 >(p.second );
142146 PrimT prim2 = std::get<1 >(p.second );
@@ -150,27 +154,55 @@ void PrimitiveContainer::installPrimitives(
150154
151155 PrimInstallResult const result = clazz->InstallPrimitive (
152156 makePrimFn (sig, prim1), prim1.bytecodeHash , !prim2.IsValid ());
157+ if (!prim2.IsValid ()) {
158+ hasHashMismatch =
159+ hasHashMismatch || result == PrimInstallResult::HASH_MISMATCH;
160+ }
161+
153162 if (result == PrimInstallResult::INSTALLED_ADDED && showWarning) {
154163 cout << " Warn: Primitive " << p.first
155164 << " is not in class definition for class "
156165 << clazz->GetName ()->GetStdString () << ' \n ' ;
157166 } else if (result == PrimInstallResult::HASH_MISMATCH &&
158167 prim2.IsValid ()) {
159168 assert (prim1.isClassSide == prim2.isClassSide );
160- clazz->InstallPrimitive (makePrimFn (sig, prim2), prim2.bytecodeHash ,
161- true );
169+ PrimInstallResult const result2 = clazz->InstallPrimitive (
170+ makePrimFn (sig, prim2), prim2.bytecodeHash , true );
171+ hasHashMismatch =
172+ hasHashMismatch || result2 == PrimInstallResult::HASH_MISMATCH;
162173 }
163174 }
175+
176+ return hasHashMismatch;
164177}
165178
166179void PrimitiveContainer::InstallPrimitives (VMClass* clazz, bool classSide,
167180 bool showWarning) {
168- installPrimitives (classSide, showWarning, clazz, unaryPrims,
169- VMSafePrimitive::GetSafeUnary);
170- installPrimitives (classSide, showWarning, clazz, binaryPrims,
171- VMSafePrimitive::GetSafeBinary);
172- installPrimitives (classSide, showWarning, clazz, ternaryPrims,
173- VMSafePrimitive::GetSafeTernary);
174- installPrimitives (classSide, showWarning, clazz, framePrims,
175- VMPrimitive::GetFramePrim);
181+ bool hasHashMismatch = false ;
182+ hasHashMismatch =
183+ hasHashMismatch ||
184+ installPrimitives (classSide, showWarning, clazz, unaryPrims,
185+ VMSafePrimitive::GetSafeUnary);
186+ hasHashMismatch =
187+ hasHashMismatch ||
188+ installPrimitives (classSide, showWarning, clazz, binaryPrims,
189+ VMSafePrimitive::GetSafeBinary);
190+ hasHashMismatch =
191+ hasHashMismatch ||
192+ installPrimitives (classSide, showWarning, clazz, ternaryPrims,
193+ VMSafePrimitive::GetSafeTernary);
194+ hasHashMismatch = hasHashMismatch ||
195+ installPrimitives (classSide, showWarning, clazz,
196+ framePrims, VMPrimitive::GetFramePrim);
197+
198+ if (abortOnCoreLibHashMismatch && hasHashMismatch) {
199+ ErrorPrint (" The implementation of methods in " +
200+ clazz->GetName ()->GetStdString () +
201+ " seem to have changed.\n " );
202+ ErrorPrint (
203+ " The primitive implementation in the matching VM class may need to "
204+ " be changed. See for instance _Vector::_Vector() in "
205+ " primitives/Vector.cpp\n " );
206+ Quit (1 );
207+ }
176208}
0 commit comments