- fixed: WP_NOCHANGE had different values in native and script code, resulting in problems with weapon selection.

This now explicitly allocates a single object it can safely point to instead of trying to hack around it.
This commit is contained in:
Christoph Oelckers 2017-04-13 18:59:45 +02:00
parent 98dab9c4b9
commit 2d098e99fb
3 changed files with 17 additions and 9 deletions

View file

@ -235,7 +235,7 @@ enum
// The VM cannot deal with this as an invalid pointer because it performs a read barrier on every object pointer read. // The VM cannot deal with this as an invalid pointer because it performs a read barrier on every object pointer read.
// This doesn't have to point to a valid weapon, though, because WP_NOCHANGE is never dereferenced, but it must point to a valid object // This doesn't have to point to a valid weapon, though, because WP_NOCHANGE is never dereferenced, but it must point to a valid object
// and the class descriptor just works fine for that. // and the class descriptor just works fine for that.
#define WP_NOCHANGE ((AWeapon*)RUNTIME_CLASS_CASTLESS(AWeapon)) extern AWeapon *WP_NOCHANGE;
#define MAXPLAYERNAME 15 #define MAXPLAYERNAME 15

View file

@ -74,6 +74,12 @@ TArray<VMFunction**> PClass::FunctionPtrList;
bool PClass::bShutdown; bool PClass::bShutdown;
bool PClass::bVMOperational; bool PClass::bVMOperational;
// Originally this was just a bogus pointer, but with the VM performing a read barrier on every object pointer write
// that does not work anymore. WP_NOCHANGE needs to point to a vaild object to work as intended.
// This Object does not need to be garbage collected, though, but it needs to provide the proper structure so that the
// GC can process it.
AWeapon *WP_NOCHANGE;
DEFINE_GLOBAL(WP_NOCHANGE);
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -218,6 +224,10 @@ void PClass::StaticInit ()
// I'm not sure if this is really necessary to maintain any sort of sync. // I'm not sure if this is really necessary to maintain any sort of sync.
qsort(&AllClasses[0], AllClasses.Size(), sizeof(AllClasses[0]), cregcmp); qsort(&AllClasses[0], AllClasses.Size(), sizeof(AllClasses[0]), cregcmp);
// WP_NOCHANGE must point to a valid object, although it does not need to be a weapon.
// A simple DObject is enough to give the GC the ability to deal with it, if subjected to it.
WP_NOCHANGE = (AWeapon*)new DObject;
WP_NOCHANGE->Release();
} }
//========================================================================== //==========================================================================
@ -230,6 +240,12 @@ void PClass::StaticInit ()
void PClass::StaticShutdown () void PClass::StaticShutdown ()
{ {
if (WP_NOCHANGE != nullptr)
{
WP_NOCHANGE->ObjectFlags |= OF_YesReallyDelete;
delete WP_NOCHANGE;
}
// delete all variables containing pointers to script functions. // delete all variables containing pointers to script functions.
for (auto p : FunctionPtrList) for (auto p : FunctionPtrList)
{ {

View file

@ -70,14 +70,6 @@ static TArray<FieldDesc> FieldTable;
extern int BackbuttonTime; extern int BackbuttonTime;
extern float BackbuttonAlpha; extern float BackbuttonAlpha;
// Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but is used everywhere as a special flag.
// It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution'
// is to create a static variable from it that points to an otherwise unused object and reference that in the script. Yuck!!!
// This must point to a valid DObject derived object so that the garbage collector can deal with it.
// The global VM types are the most convenient options here because they get created before the compiler is started and they
// are not exposed in other ways to scripts - and they do not change unless the engine is shut down.
DEFINE_GLOBAL_NAMED(TypeSInt32, wp_nochange);
//========================================================================== //==========================================================================
// //
// List of all flags // List of all flags