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 " 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