diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 69b7c814a4..4115648514 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -671,7 +671,7 @@ static int CreateSpawnFunc(VMFunctionBuilder &buildit, int value1, int value2) I_Error("No class found for dehackednum %d!\n", value1+1); return 0; } - int typereg = buildit.GetConstantAddress(InfoNames[value1-1], ATAG_OBJECT); + int typereg = buildit.GetConstantAddress(InfoNames[value1-1]); int heightreg = buildit.GetConstantFloat(value2); buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, typereg); // itemtype @@ -724,7 +724,7 @@ static int CreatePlaySoundFunc(VMFunctionBuilder &buildit, int value1, int value // misc1 = state, misc2 = probability static int CreateRandomJumpFunc(VMFunctionBuilder &buildit, int value1, int value2) { // A_Jump - int statereg = buildit.GetConstantAddress(FindState(value1), ATAG_STATE); + int statereg = buildit.GetConstantAddress(FindState(value1)); buildit.EmitParamInt(value2); // maxchance buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, statereg); // jumpto @@ -813,7 +813,7 @@ void SetDehParams(FState *state, int codepointer) } // Emit code for action parameters. int argcount = MBFCodePointerFactories[codepointer](buildit, value1, value2); - buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation, ATAG_OBJECT), numargs + argcount, 0); + buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation), numargs + argcount, 0); // Attach it to the state. VMScriptFunction *sfunc = new VMScriptFunction; buildit.MakeFunction(sfunc); diff --git a/src/dobject.h b/src/dobject.h index f12bfc5014..18a6f14b5a 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -200,6 +200,14 @@ protected: enum { MetaClassNum = CLASSREG_PClass }; // Per-instance variables. There are four. +#ifdef _DEBUG +public: + enum + { + MAGIC_ID = 0x1337cafe + }; + uint32_t MagicID = MAGIC_ID; // only used by the VM for checking native function parameter types. +#endif private: PClass *Class; // This object's type public: diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index f681def3e9..b4fd9835d0 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -780,6 +780,15 @@ PFloat::PFloat(unsigned int size) mDescriptiveName.Format("Float%d", size); if (size == 8) { +#ifdef __i386__ + // According to System V i386 ABI alignment of double type is 4 + // GCC and Clang for 32-bit Intel targets follow this requirement + // However GCC has -malign-double option to enable 8-byte alignment + // So calculation of the actual alignment is needed + struct AlignmentCheck { uint8_t i; double d; }; + Align = static_cast(offsetof(AlignmentCheck, d)); +#endif // __i386__ + SetDoubleSymbols(); } else diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 2348448ac5..9e1d95ffde 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -363,7 +363,7 @@ static PClassActor * T_GetAmmo(const svalue_t &t) p=DefAmmo[ammonum]; } auto am = PClass::FindActor(p); - if (am == NULL || !am->IsKindOf(PClass::FindClass(NAME_Ammo))) + if (am == NULL || !am->IsDescendantOf(PClass::FindClass(NAME_Ammo))) { script_error("unknown ammo type : %s", p); return NULL; @@ -2436,7 +2436,7 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount) type = "BasicArmorPickup"; } auto info = PClass::FindActor (type); - if (info == NULL || !info->IsKindOf(RUNTIME_CLASS(AInventory))) + if (info == NULL || !info->IsDescendantOf(RUNTIME_CLASS(AInventory))) { Printf ("Unknown inventory item: %s\n", type); return; diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index df6679d41a..0a44e6d14f 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -484,43 +484,6 @@ bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return) return !!res; } -//=========================================================================== -// -// AInventory :: CanPickup -// -//=========================================================================== - -DEFINE_ACTION_FUNCTION(AInventory, CanPickup) -{ - PARAM_SELF_PROLOGUE(AInventory); - PARAM_OBJECT(toucher, AActor); - - if (!toucher) - ACTION_RETURN_BOOL(false); - - auto ai = self->GetClass(); - // Is the item restricted to certain player classes? - if (ai->RestrictedToPlayerClass.Size() != 0) - { - for (unsigned i = 0; i < ai->RestrictedToPlayerClass.Size(); ++i) - { - if (toucher->IsKindOf(ai->RestrictedToPlayerClass[i])) - ACTION_RETURN_BOOL(true); - } - ACTION_RETURN_BOOL(false); - } - // Or is it forbidden to certain other classes? - else - { - for (unsigned i = 0; i < ai->ForbiddenToPlayerClass.Size(); ++i) - { - if (toucher->IsKindOf(ai->ForbiddenToPlayerClass[i])) - ACTION_RETURN_BOOL(false); - } - } - ACTION_RETURN_BOOL(true); -} - //=========================================================================== // // CCMD printinv diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 9259561b09..36ffd800bd 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -635,7 +635,7 @@ void InitAllPowerupEffects(AInventory *item) { if (item->IsKindOf(ptype)) { - IFVIRTUALPTRNAME(item, NAME_Powerup, EndEffect) + IFVIRTUALPTRNAME(item, NAME_Powerup, InitEffect) { VMValue params[1] = { item }; VMFrameStack stack; diff --git a/src/gl/shaders/gl_ambientshader.cpp b/src/gl/shaders/gl_ambientshader.cpp index 02090cf61c..3d0af2dabd 100644 --- a/src/gl/shaders/gl_ambientshader.cpp +++ b/src/gl/shaders/gl_ambientshader.cpp @@ -38,7 +38,7 @@ void FLinearDepthShader::Bind() if (!mShader) { - mShader = std::make_unique(); + mShader.reset(new FShaderProgram()); mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/lineardepth.fp", multisample ? "#define MULTISAMPLE\n" : "", 330); mShader->SetFragDataLocation(0, "FragColor"); @@ -66,7 +66,7 @@ void FSSAOShader::Bind() if (!mShader) { - mShader = std::make_unique(); + mShader.reset(new FShaderProgram()); mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssao.fp", GetDefines(gl_ssao, multisample), 330); mShader->SetFragDataLocation(0, "FragColor"); @@ -142,7 +142,7 @@ void FSSAOCombineShader::Bind() if (!mShader) { - mShader = std::make_unique(); + mShader.reset(new FShaderProgram()); mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", multisample ? "#define MULTISAMPLE\n" : "", 330); mShader->SetFragDataLocation(0, "FragColor"); diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp index 29c38a4a68..4a97eb95be 100644 --- a/src/gl/system/gl_swframebuffer.cpp +++ b/src/gl/system/gl_swframebuffer.cpp @@ -316,7 +316,7 @@ OpenGLSWFrameBuffer::HWPixelShader::~HWPixelShader() bool OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int height, HWFrameBuffer **outFramebuffer) { - auto fb = std::make_unique(); + std::unique_ptr fb(new HWFrameBuffer()); GLint format = GL_RGBA16F; if (gl.es) format = GL_RGB; @@ -357,7 +357,7 @@ bool OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines, HWPixelShader **outShader) { - auto shader = std::make_unique(); + std::unique_ptr shader(new HWPixelShader()); shader->Program = glCreateProgram(); if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return false; } @@ -443,7 +443,7 @@ bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragments bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVertexBuffer) { - auto obj = std::make_unique(); + std::unique_ptr obj(new HWVertexBuffer()); obj->Size = size; @@ -474,7 +474,7 @@ bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVerte bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer) { - auto obj = std::make_unique(); + std::unique_ptr obj(new HWIndexBuffer()); obj->Size = size; @@ -494,7 +494,7 @@ bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBu bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int height, int levels, int format, HWTexture **outTexture) { - auto obj = std::make_unique(); + std::unique_ptr obj(new HWTexture()); obj->Format = format; @@ -532,7 +532,7 @@ bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int heig OpenGLSWFrameBuffer::HWTexture *OpenGLSWFrameBuffer::CopyCurrentScreen() { - auto obj = std::make_unique(); + std::unique_ptr obj(new HWTexture()); obj->Format = GL_RGBA16F; GLint oldBinding = 0; @@ -611,7 +611,7 @@ void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const FBVERTEX *vertices) if (!StreamVertexBuffer) { - StreamVertexBuffer = std::make_unique(); + StreamVertexBuffer.reset(new HWVertexBuffer()); glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray); glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer); glBindVertexArray(StreamVertexBuffer->VertexArray); @@ -648,7 +648,7 @@ void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const BURNVERTEX *vertices if (!StreamVertexBufferBurn) { - StreamVertexBufferBurn = std::make_unique(); + StreamVertexBufferBurn.reset(new HWVertexBuffer()); glGenVertexArrays(1, (GLuint*)&StreamVertexBufferBurn->VertexArray); glGenBuffers(1, (GLuint*)&StreamVertexBufferBurn->Buffer); glBindVertexArray(StreamVertexBufferBurn->VertexArray); @@ -679,7 +679,7 @@ void OpenGLSWFrameBuffer::DrawPoints(int count, const FBVERTEX *vertices) if (!StreamVertexBuffer) { - StreamVertexBuffer = std::make_unique(); + StreamVertexBuffer.reset(new HWVertexBuffer()); glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray); glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer); glBindVertexArray(StreamVertexBuffer->VertexArray); diff --git a/src/info.cpp b/src/info.cpp index fdda8633e2..b8f7db995d 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -76,7 +76,7 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, { ActionCycles.Clock(); - VMValue params[3] = { self, stateowner, VMValue(info, ATAG_GENERIC) }; + VMValue params[3] = { self, stateowner, VMValue(info) }; // If the function returns a state, store it at *stateret. // If it doesn't return a state but stateret is non-NULL, we need // to set *stateret to NULL. @@ -314,10 +314,6 @@ void PClassActor::DeriveData(PClass *newclass) *newa->PainChances = *PainChances; } - // Inventory stuff - newa->ForbiddenToPlayerClass = ForbiddenToPlayerClass; - newa->RestrictedToPlayerClass = RestrictedToPlayerClass; - newa->DisplayName = DisplayName; } @@ -589,49 +585,6 @@ void PClassActor::SetPainChance(FName type, int chance) } } -//========================================================================== -// -// PClassActor :: ReplaceClassRef -// -//========================================================================== - -size_t PClassActor::PointerSubstitution(DObject *oldclass, DObject *newclass) -{ - auto changed = Super::PointerSubstitution(oldclass, newclass); - for (unsigned i = 0; i < VisibleToPlayerClass.Size(); i++) - { - if (VisibleToPlayerClass[i] == oldclass) - { - VisibleToPlayerClass[i] = static_cast(newclass); - changed++; - } - } - - for (unsigned i = 0; i < ForbiddenToPlayerClass.Size(); i++) - { - if (ForbiddenToPlayerClass[i] == oldclass) - { - ForbiddenToPlayerClass[i] = static_cast(newclass); - changed++; - } - } - for (unsigned i = 0; i < RestrictedToPlayerClass.Size(); i++) - { - if (RestrictedToPlayerClass[i] == oldclass) - { - RestrictedToPlayerClass[i] = static_cast(newclass); - changed++; - } - } - AInventory *def = dyn_cast((AActor*)Defaults); - if (def != NULL) - { - if (def->PickupFlash == oldclass) def->PickupFlash = static_cast(newclass); - } - - return changed; -} - //========================================================================== // // DmgFactors :: CheckFactor diff --git a/src/info.h b/src/info.h index 697bd836f7..5af8ac5f5a 100644 --- a/src/info.h +++ b/src/info.h @@ -248,7 +248,6 @@ public: PClassActor(); ~PClassActor(); - virtual size_t PointerSubstitution(DObject *oldclass, DObject *newclass); void BuildDefaults(); void ApplyDefaults(uint8_t *defaults); void RegisterIDs(); @@ -292,10 +291,6 @@ public: FString SourceLumpName; FIntCVar *distancecheck; - // These are only valid for inventory items. - TArray RestrictedToPlayerClass; - TArray ForbiddenToPlayerClass; - // This is from PClassPlayerPawn FString DisplayName; diff --git a/src/m_png.cpp b/src/m_png.cpp index c51f37be80..28f015e7b0 100644 --- a/src/m_png.cpp +++ b/src/m_png.cpp @@ -576,7 +576,7 @@ bool M_ReadIDAT (FileReader *file, uint8_t *buffer, int width, int height, int p if (stream.avail_in == 0 && chunklen > 0) { stream.next_in = chunkbuffer; - stream.avail_in = (uInt)file->Read (chunkbuffer, MIN(chunklen,sizeof(chunkbuffer))); + stream.avail_in = (uInt)file->Read (chunkbuffer, MIN(chunklen,sizeof(chunkbuffer))); chunklen -= stream.avail_in; } diff --git a/src/namedef.h b/src/namedef.h index a193945de4..4346844fc9 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -902,3 +902,5 @@ xx(Player6) xx(Player7) xx(Player8) xx(PlayerChunk) +xx(RestrictedToPlayerClass) +xx(ForbiddenToPlayerClass) diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 055274d3df..97be1b1082 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -153,7 +153,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state) VMReturn *wantret; FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON }; - params[2] = VMValue(&stp, ATAG_GENERIC); + params[2] = VMValue(&stp); retval = true; // assume success wantret = NULL; // assume no return value wanted numret = 0; @@ -2723,7 +2723,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem) PARAM_BOOL_DEF (useammo) PARAM_BOOL_DEF (transfer_translation); - if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT); + if (numret > 1) ret[1].SetObject(nullptr); if (missile == NULL) { @@ -2760,7 +2760,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem) int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0); bool res = InitSpawnedItem(self, mo, flags); // for an inventory item's use state if (numret > 0) ret[0].SetInt(res); - if (numret > 1) ret[1].SetPointer(mo, ATAG_OBJECT); + if (numret > 1) ret[1].SetObject(mo); return MIN(numret, 2); } @@ -2787,7 +2787,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx) PARAM_INT_DEF (chance) PARAM_INT_DEF (tid) - if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT); + if (numret > 1) ret[1].SetObject(nullptr); if (missile == NULL) { @@ -2852,7 +2852,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx) mo->Angles.Yaw = angle; } if (numret > 0) ret[0].SetInt(res); - if (numret > 1) ret[1].SetPointer(mo, ATAG_OBJECT); + if (numret > 1) ret[1].SetObject(mo); return MIN(numret, 2); } @@ -2872,7 +2872,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade) PARAM_FLOAT_DEF (zvel) PARAM_BOOL_DEF (useammo) - if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT); + if (numret > 1) ret[1].SetObject(nullptr); if (missile == NULL) { @@ -2934,7 +2934,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade) if (!P_CheckMissileSpawn(bo, self->radius)) bo = nullptr; if (numret > 0) ret[0].SetInt(true); - if (numret > 1) ret[1].SetPointer(bo, ATAG_OBJECT); + if (numret > 1) ret[1].SetObject(bo); return MIN(numret, 2); } else @@ -4363,7 +4363,7 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CheckForReload) if (numret > 0) { - ret->SetPointer(NULL, ATAG_STATE); + ret->SetPointer(NULL); numret = 1; } @@ -4381,7 +4381,7 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CheckForReload) // Go back to the refire frames, instead of continuing on to the reload frames. if (numret != 0) { - ret->SetPointer(jump, ATAG_STATE); + ret->SetPointer(jump); } } else @@ -4903,7 +4903,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Teleport) } if (numret > 0) { - ret[0].SetPointer(NULL, ATAG_STATE); + ret[0].SetPointer(NULL); } if (!ref) @@ -5039,7 +5039,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Teleport) } if (numret > 0) { - ret[0].SetPointer(teleport_state, ATAG_STATE); + ret[0].SetPointer(teleport_state); } return numret; } @@ -5337,7 +5337,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Warp) } if (numret > 0) { - ret[0].SetPointer(NULL, ATAG_STATE); + ret[0].SetPointer(NULL); } if ((flags & WARPF_USETID)) @@ -5363,7 +5363,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Warp) // in this case, you have the statejump to help you handle all the success anyway. if (numret > 0) { - ret[0].SetPointer(success_state, ATAG_STATE); + ret[0].SetPointer(success_state); } } else if (numret > 1) diff --git a/src/p_map.cpp b/src/p_map.cpp index 6f3f01cf4f..d2d98d2377 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2054,7 +2054,7 @@ DEFINE_ACTION_FUNCTION(AActor, TestMobjZ) if (numret > 1) { numret = 2; - ret[1].SetPointer(on, ATAG_OBJECT); + ret[1].SetObject(on); } if (numret > 0) { @@ -4685,7 +4685,7 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack) int acdmg; if (puffType == nullptr) puffType = PClass::FindActor("BulletPuff"); // P_LineAttack does not work without a puff to take info from. auto puff = P_LineAttack(self, angle, distance, pitch, damage, damageType, puffType, flags, victim, &acdmg); - if (numret > 0) ret[0].SetPointer(puff, ATAG_OBJECT); + if (numret > 0) ret[0].SetObject(puff); if (numret > 1) ret[1].SetInt(acdmg), numret = 2; return numret; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index ff8c093c00..23b079426c 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -7247,8 +7247,8 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnPlayerMissile) AActor *missileactor; if (numparam == 2) angle = self->Angles.Yaw; AActor *misl = P_SpawnPlayerMissile(self, x, y, z, type, angle, lt, &missileactor, nofreeaim, noautoaim, aimflags); - if (numret > 0) ret[0].SetPointer(misl, ATAG_OBJECT); - if (numret > 1) ret[1].SetPointer(missileactor, ATAG_OBJECT), numret = 2; + if (numret > 0) ret[0].SetObject(misl); + if (numret > 1) ret[1].SetObject(missileactor), numret = 2; return numret; } @@ -7695,7 +7695,7 @@ FDropItem *AActor::GetDropItems() const DEFINE_ACTION_FUNCTION(AActor, GetDropItems) { PARAM_SELF_PROLOGUE(AActor); - ACTION_RETURN_OBJECT(self->GetDropItems()); + ACTION_RETURN_POINTER(self->GetDropItems()); } double AActor::GetGravity() const diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 7dac68e1ac..b64478c77e 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -112,7 +112,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestFloorSurrounding) vertex_t *v; double h = self->FindLowestFloorSurrounding(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestFloorSurrounding) vertex_t *v; double h = self->FindHighestFloorSurrounding(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -224,7 +224,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextHighestFloor) vertex_t *v; double h = self->FindNextHighestFloor(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -286,7 +286,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextLowestFloor) vertex_t *v; double h = self->FindNextLowestFloor(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -348,7 +348,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextLowestCeiling) vertex_t *v; double h = self->FindNextLowestCeiling(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -411,7 +411,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextHighestCeiling) vertex_t *v; double h = self->FindNextHighestCeiling(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -459,7 +459,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestCeilingSurrounding) vertex_t *v; double h = self->FindLowestCeilingSurrounding(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -508,7 +508,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestCeilingSurrounding) vertex_t *v; double h = self->FindHighestCeilingSurrounding(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -744,7 +744,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestFloorPoint) vertex_t *v; double h = self->FindHighestFloorPoint(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -793,7 +793,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestCeilingPoint) vertex_t *v; double h = self->FindLowestCeilingPoint(&v); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(v); return numret; } @@ -1207,7 +1207,7 @@ DEFINE_ACTION_FUNCTION(_Sector, HighestCeilingAt) sector_t *s; double h = self->HighestCeilingAt(DVector2(x, y), &s); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(s, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(s); return numret; } @@ -1242,7 +1242,7 @@ DEFINE_ACTION_FUNCTION(_Sector, LowestFloorAt) sector_t *s; double h = self->LowestFloorAt(DVector2(x, y), &s); if (numret > 0) ret[0].SetFloat(h); - if (numret > 1) ret[1].SetPointer(s, ATAG_GENERIC); + if (numret > 1) ret[1].SetPointer(s); return numret; } @@ -1309,12 +1309,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextHighestCeilingAt) if (numret > 2) { - ret[2].SetPointer(resultff, ATAG_GENERIC); + ret[2].SetPointer(resultff); numret = 3; } if (numret > 1) { - ret[1].SetPointer(resultsec, ATAG_GENERIC); + ret[1].SetPointer(resultsec); } if (numret > 0) { @@ -1387,12 +1387,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt) if (numret > 2) { - ret[2].SetPointer(resultff, ATAG_GENERIC); + ret[2].SetPointer(resultff); numret = 3; } if (numret > 1) { - ret[1].SetPointer(resultsec, ATAG_GENERIC); + ret[1].SetPointer(resultsec); } if (numret > 0) { diff --git a/src/polyrenderer/drawers/poly_drawer32_sse2.h b/src/polyrenderer/drawers/poly_drawer32_sse2.h index 4070543379..5125c93c73 100644 --- a/src/polyrenderer/drawers/poly_drawer32_sse2.h +++ b/src/polyrenderer/drawers/poly_drawer32_sse2.h @@ -505,12 +505,13 @@ private: { // Load bgcolor uint32_t desttmp[2]; - if (mask0 & (1 << 31)) desttmp[0] = dest[x * 2]; - if (mask0 & (1 << 30)) desttmp[1] = dest[x * 2 + 1]; - __m128i bgcolor; if (BlendT::Mode != (int)BlendModes::Opaque) + { + if (mask0 & (1 << 31)) desttmp[0] = dest[x * 2]; + if (mask0 & (1 << 30)) desttmp[1] = dest[x * 2 + 1]; bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128()); + } else bgcolor = _mm_setzero_si128(); @@ -593,12 +594,13 @@ private: { // Load bgcolor uint32_t desttmp[2]; - if (mask1 & (1 << 31)) desttmp[0] = dest[x * 2]; - if (mask1 & (1 << 30)) desttmp[1] = dest[x * 2 + 1]; - __m128i bgcolor; if (BlendT::Mode != (int)BlendModes::Opaque) + { + if (mask1 & (1 << 31)) desttmp[0] = dest[x * 2]; + if (mask1 & (1 << 30)) desttmp[1] = dest[x * 2 + 1]; bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128()); + } else bgcolor = _mm_setzero_si128(); diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index d4cd0fb024..88ae14e10e 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -249,7 +249,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane & } if (!polyportal) { - sectorPortals.push_back(std::make_unique(portal, ceiling)); + sectorPortals.push_back(std::unique_ptr(new PolyDrawSectorPortal(portal, ceiling))); polyportal = sectorPortals.back().get(); } diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index ae11577e42..5d2ad6cab5 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -44,7 +44,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan { if (PolyRenderer::Instance()->InsertSeenMirror(line->linedef)) { - linePortals.push_back(std::make_unique(line->linedef)); + linePortals.push_back(std::unique_ptr(new PolyDrawLinePortal(line->linedef))); polyportal = linePortals.back().get(); } } @@ -63,7 +63,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan } if (!polyportal) { - linePortals.push_back(std::make_unique(portal)); + linePortals.push_back(std::unique_ptr(new PolyDrawLinePortal(portal))); polyportal = linePortals.back().get(); } } diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 93fca44ed7..4327bde9df 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -385,7 +385,7 @@ void FxExpression::EmitCompare(VMFunctionBuilder *build, bool invert, TArrayEmit(OP_EQA_K, !invert, op.RegNum, build->GetConstantAddress(0, ATAG_GENERIC)); + build->Emit(OP_EQA_K, !invert, op.RegNum, build->GetConstantAddress(0)); break; case REGT_STRING: @@ -587,16 +587,7 @@ ExpEmit FxConstant::Emit(VMFunctionBuilder *build) } else if (regtype == REGT_POINTER) { - VM_ATAG tag = ATAG_GENERIC; - if (value.Type == TypeState) - { - tag = ATAG_STATE; - } - else if (value.Type->GetLoadOp() != OP_LP) - { - tag = ATAG_OBJECT; - } - out.RegNum = build->GetConstantAddress(value.pointer, tag); + out.RegNum = build->GetConstantAddress(value.pointer); } else if (regtype == REGT_STRING) { @@ -2998,7 +2989,7 @@ texcheck: auto * countptr = &ptr->Count; ExpEmit bndp(build, REGT_POINTER); ExpEmit bndc(build, REGT_INT); - build->Emit(OP_LKP, bndp.RegNum, build->GetConstantAddress(countptr, ATAG_GENERIC)); + build->Emit(OP_LKP, bndp.RegNum, build->GetConstantAddress(countptr)); build->Emit(OP_LW, bndc.RegNum, bndp.RegNum, build->GetConstantInt(0)); build->Emit(OP_BOUND_R, to.RegNum, bndc.RegNum); bndp.Free(build); @@ -4638,7 +4629,7 @@ void FxTypeCheck::EmitCompare(VMFunctionBuilder *build, bool invert, TArrayEmit(OP_EQA_K, !invert, ares.RegNum, build->GetConstantAddress(nullptr, ATAG_OBJECT)); + build->Emit(OP_EQA_K, !invert, ares.RegNum, build->GetConstantAddress(nullptr)); patchspots_no.Push(build->Emit(OP_JMP, 0)); } @@ -4706,7 +4697,7 @@ ExpEmit FxDynamicCast::Emit(VMFunctionBuilder *build) ExpEmit castee = expr->Emit(build); castee.Free(build); ExpEmit ares(build, REGT_POINTER); - build->Emit(OP_DYNCAST_K, ares.RegNum, castee.RegNum, build->GetConstantAddress(CastType, ATAG_OBJECT)); + build->Emit(OP_DYNCAST_K, ares.RegNum, castee.RegNum, build->GetConstantAddress(CastType)); return ares; } @@ -5536,16 +5527,16 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG)); + build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); if (min != nullptr && max != nullptr) { EmitParameter(build, min, ScriptPosition); EmitParameter(build, max, ScriptPosition); - build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1); + build->Emit(opcode, build->GetConstantAddress(callfunc), 3, 1); } else { - build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 1, 1); + build->Emit(opcode, build->GetConstantAddress(callfunc), 1, 1); } if (EmitTail) @@ -5657,10 +5648,10 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build) assert(((PSymbolVMFunction *)sym)->Function != nullptr); callfunc = ((PSymbolVMFunction *)sym)->Function; - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG)); + build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); build->EmitParamInt(0); build->EmitParamInt(choices.Size() - 1); - build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1); + build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 3, 1); ExpEmit resultreg(build, REGT_INT); build->Emit(OP_RESULT, 0, REGT_INT, resultreg.RegNum); @@ -5787,16 +5778,16 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG)); + build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); if (min != nullptr && max != nullptr) { EmitParameter(build, min, ScriptPosition); EmitParameter(build, max, ScriptPosition); - build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1); + build->Emit(opcode, build->GetConstantAddress(callfunc), 3, 1); } else { - build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 1, 1); + build->Emit(opcode, build->GetConstantAddress(callfunc), 1, 1); } if (EmitTail) @@ -5882,9 +5873,9 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG)); + build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); EmitParameter(build, mask, ScriptPosition); - build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1); + build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 1); if (EmitTail) { @@ -6661,7 +6652,7 @@ ExpEmit FxGlobalVariable::Emit(VMFunctionBuilder *build) { ExpEmit obj(build, REGT_POINTER); - build->Emit(OP_LKP, obj.RegNum, build->GetConstantAddress((void*)(intptr_t)membervar->Offset, ATAG_GENERIC)); + build->Emit(OP_LKP, obj.RegNum, build->GetConstantAddress((void*)(intptr_t)membervar->Offset)); if (AddressRequested) { return obj; @@ -6744,34 +6735,34 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build) switch (CVar->GetRealType()) { case CVAR_Int: - build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value, ATAG_GENERIC)); + build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value)); build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul); break; case CVAR_Color: - build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value, ATAG_GENERIC)); + build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value)); build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul); break; case CVAR_Float: - build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value, ATAG_GENERIC)); + build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value)); build->Emit(OP_LSP, dest.RegNum, addr.RegNum, nul); break; case CVAR_Bool: - build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value, ATAG_GENERIC)); + build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value)); build->Emit(OP_LBU, dest.RegNum, addr.RegNum, nul); break; case CVAR_String: - build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value, ATAG_GENERIC)); + build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast(CVar)->Value)); build->Emit(OP_LCS, dest.RegNum, addr.RegNum, nul); break; case CVAR_DummyBool: { auto cv = static_cast(CVar); - build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value, ATAG_GENERIC)); + build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value)); build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul); build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum); build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(1)); @@ -6781,7 +6772,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build) case CVAR_DummyInt: { auto cv = static_cast(CVar); - build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value, ATAG_GENERIC)); + build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value)); build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul); build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(cv->BitVal)); build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum); @@ -6923,13 +6914,13 @@ FxStructMember::~FxStructMember() bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable) { - // Cannot take the address of metadata variables. + AddressRequested = true; if (membervar->Flags & VARF_Meta) { - return false; + // Meta variables are read only. + *writable = false; } - AddressRequested = true; - if (writable != nullptr) + else if (writable != nullptr) { // [ZZ] original check. bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) && @@ -7323,11 +7314,13 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) if (SizeAddr != ~0u) { + bool ismeta = Array->ExprType == EFX_ClassMember && static_cast(Array)->membervar->Flags & VARF_Meta; + arrayvar.Free(build); start = ExpEmit(build, REGT_POINTER); build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0)); - auto f = new PField(NAME_None, TypeUInt32, 0, SizeAddr); + auto f = new PField(NAME_None, TypeUInt32, ismeta? VARF_Meta : 0, SizeAddr); static_cast(Array)->membervar = f; static_cast(Array)->AddressRequested = false; Array->ValueType = TypeUInt32; @@ -8544,14 +8537,14 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use if (EmitTail) { - build->Emit(OP_TAIL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2 + i, 0); + build->Emit(OP_TAIL_K, build->GetConstantAddress(callfunc), 2 + i, 0); ExpEmit call; call.Final = true; return call; } ExpEmit dest(build, REGT_INT); - build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2 + i, 1); + build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 2 + i, 1); build->Emit(OP_RESULT, 0, REGT_INT, dest.RegNum); return dest; } @@ -8941,7 +8934,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) if (selfside == FScopeBarrier::Side_PlainData) { // Check the self object against the calling function's flags at run time - build->Emit(OP_SCOPE, selfemit.RegNum, outerside + 1, build->GetConstantAddress(vmfunc, ATAG_OBJECT)); + build->Emit(OP_SCOPE, selfemit.RegNum, outerside + 1, build->GetConstantAddress(vmfunc)); } } @@ -8967,7 +8960,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) { // pass self as stateowner, otherwise all attempts of the subfunction to retrieve a state from a name would fail. build->Emit(OP_PARAM, 0, selfemit.RegType, selfemit.RegNum); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr, ATAG_GENERIC)); + build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr)); } count += 2; } @@ -8985,7 +8978,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) // Get a constant register for this function if (staticcall) { - int funcaddr = build->GetConstantAddress(vmfunc, ATAG_OBJECT); + int funcaddr = build->GetConstantAddress(vmfunc); // Emit the call if (EmitTail) { // Tail call @@ -10503,7 +10496,7 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build) ExpEmit reg(build, REGT_POINTER); build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(build->ConstructedStructs[i]->StackOffset)); build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum); - build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor, ATAG_OBJECT), 1, 0); + build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0); reg.Free(build); } @@ -10690,9 +10683,9 @@ int BuiltinNameToClass(VMValue *param, TArray &defaultparam, int numpar // Let the caller check this. Making this an error with a message is only taking away options from the user. cls = nullptr; } - ret->SetPointer(const_cast(cls), ATAG_OBJECT); + ret->SetObject(const_cast(cls)); } - else ret->SetPointer(nullptr, ATAG_OBJECT); + else ret->SetObject(nullptr); return 1; } @@ -10700,13 +10693,13 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build) { if (basex->ValueType != TypeName) { - return ExpEmit(build->GetConstantAddress(nullptr, ATAG_OBJECT), REGT_POINTER, true); + return ExpEmit(build->GetConstantAddress(nullptr), REGT_POINTER, true); } ExpEmit clsname = basex->Emit(build); assert(!clsname.Konst); ExpEmit dest(build, REGT_POINTER); build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast(desttype), ATAG_OBJECT)); + build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast(desttype))); // Call the BuiltinNameToClass function to convert from 'name' to class. VMFunction *callfunc; @@ -10716,7 +10709,7 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build) assert(((PSymbolVMFunction *)sym)->Function != nullptr); callfunc = ((PSymbolVMFunction *)sym)->Function; - build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1); + build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 2, 1); build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum); clsname.Free(build); return dest; @@ -10815,7 +10808,7 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) ExpEmit clsname = basex->Emit(build); build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype, ATAG_OBJECT)); + build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype)); VMFunction *callfunc; PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast); @@ -10825,7 +10818,7 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) callfunc = ((PSymbolVMFunction *)sym)->Function; clsname.Free(build); ExpEmit dest(build, REGT_POINTER); - build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1); + build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 2, 1); build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum); return dest; } @@ -11164,7 +11157,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build) case REGT_POINTER: { - build->Emit(OP_LKP, RegNum, build->GetConstantAddress(constval->GetValue().GetPointer(), ValueType->GetLoadOp() != OP_LP ? ATAG_OBJECT : ATAG_GENERIC)); + build->Emit(OP_LKP, RegNum, build->GetConstantAddress(constval->GetValue().GetPointer())); break; } case REGT_STRING: @@ -11196,7 +11189,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build) ExpEmit reg(build, REGT_POINTER); build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset)); build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum); - build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor, ATAG_OBJECT), 1, 0); + build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor), 1, 0); reg.Free(build); } if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this); @@ -11222,7 +11215,7 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build) ExpEmit reg(build, REGT_POINTER); build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset)); build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum); - build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor, ATAG_OBJECT), 1, 0); + build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0); reg.Free(build); } build->ConstructedStructs.Delete(build->ConstructedStructs.Find(this)); @@ -11304,7 +11297,7 @@ ExpEmit FxStaticArray::Emit(VMFunctionBuilder *build) { TArray cvalues; for (auto v : values) cvalues.Push(static_cast(v)->GetValue().GetPointer()); - StackOffset = build->AllocConstantsAddress(cvalues.Size(), &cvalues[0], ElementType->GetLoadOp() != OP_LP ? ATAG_OBJECT : ATAG_GENERIC); + StackOffset = build->AllocConstantsAddress(cvalues.Size(), &cvalues[0]); break; } } diff --git a/src/scripting/backend/vmbuilder.cpp b/src/scripting/backend/vmbuilder.cpp index 1543becd1b..d8af3204d4 100644 --- a/src/scripting/backend/vmbuilder.cpp +++ b/src/scripting/backend/vmbuilder.cpp @@ -126,7 +126,7 @@ void VMFunctionBuilder::MakeFunction(VMScriptFunction *func) } if (AddressConstantList.Size() > 0) { - FillAddressConstants(func->KonstA, func->KonstATags()); + FillAddressConstants(func->KonstA); } if (StringConstantList.Size() > 0) { @@ -175,10 +175,9 @@ void VMFunctionBuilder::FillFloatConstants(double *konst) // //========================================================================== -void VMFunctionBuilder::FillAddressConstants(FVoidObj *konst, VM_ATAG *tags) +void VMFunctionBuilder::FillAddressConstants(FVoidObj *konst) { memcpy(konst, &AddressConstantList[0], sizeof(void*) * AddressConstantList.Size()); - memcpy(tags, &AtagConstantList[0], sizeof(VM_ATAG) * AtagConstantList.Size()); } //========================================================================== @@ -258,7 +257,7 @@ unsigned VMFunctionBuilder::GetConstantString(FString val) } else { - int loc = StringConstantList.Push(val); + unsigned loc = StringConstantList.Push(val); StringConstantMap.Insert(val, loc); return loc; } @@ -273,27 +272,18 @@ unsigned VMFunctionBuilder::GetConstantString(FString val) // //========================================================================== -unsigned VMFunctionBuilder::GetConstantAddress(void *ptr, VM_ATAG tag) +unsigned VMFunctionBuilder::GetConstantAddress(void *ptr) { - if (ptr == NULL) - { // Make all NULL pointers generic. (Or should we allow typed NULLs?) - tag = ATAG_GENERIC; - } - AddrKonst *locp = AddressConstantMap.CheckKey(ptr); + unsigned *locp = AddressConstantMap.CheckKey(ptr); if (locp != NULL) { - // There should only be one tag associated with a memory location. Exceptions are made for null pointers that got allocated through constant arrays. - assert(ptr == nullptr || locp->Tag == tag); - return locp->KonstNum; + return *locp; } else { - unsigned locc = AddressConstantList.Push(ptr); - AtagConstantList.Push(tag); - - AddrKonst loc = { locc, tag }; + unsigned loc = AddressConstantList.Push(ptr); AddressConstantMap.Insert(ptr, loc); - return loc.KonstNum; + return loc; } } @@ -327,16 +317,13 @@ unsigned VMFunctionBuilder::AllocConstantsFloat(unsigned count, double *values) return addr; } -unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs, VM_ATAG tag) +unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs) { unsigned addr = AddressConstantList.Reserve(count); - AtagConstantList.Reserve(count); memcpy(&AddressConstantList[addr], ptrs, count * sizeof(void *)); for (unsigned i = 0; i < count; i++) { - AtagConstantList[addr + i] = tag; - AddrKonst loc = { addr+i, tag }; - AddressConstantMap.Insert(ptrs[i], loc); + AddressConstantMap.Insert(ptrs[i], addr+i); } return addr; } diff --git a/src/scripting/backend/vmbuilder.h b/src/scripting/backend/vmbuilder.h index a5274794a7..ea5213b66c 100644 --- a/src/scripting/backend/vmbuilder.h +++ b/src/scripting/backend/vmbuilder.h @@ -51,12 +51,12 @@ public: // Returns the constant register holding the value. unsigned GetConstantInt(int val); unsigned GetConstantFloat(double val); - unsigned GetConstantAddress(void *ptr, VM_ATAG tag); + unsigned GetConstantAddress(void *ptr); unsigned GetConstantString(FString str); unsigned AllocConstantsInt(unsigned int count, int *values); unsigned AllocConstantsFloat(unsigned int count, double *values); - unsigned AllocConstantsAddress(unsigned int count, void **ptrs, VM_ATAG tag); + unsigned AllocConstantsAddress(unsigned int count, void **ptrs); unsigned AllocConstantsString(unsigned int count, FString *ptrs); @@ -79,7 +79,7 @@ public: // Write out complete constant tables. void FillIntConstants(int *konst); void FillFloatConstants(double *konst); - void FillAddressConstants(FVoidObj *konst, VM_ATAG *tags); + void FillAddressConstants(FVoidObj *konst); void FillStringConstants(FString *strings); // PARAM increases ActiveParam; CALL decreases it. @@ -96,24 +96,17 @@ public: TArray ConstructedStructs; private: - struct AddrKonst - { - unsigned KonstNum; - VM_ATAG Tag; - }; - TArray LineNumbers; TArray StatementStack; TArray IntConstantList; TArray FloatConstantList; TArray AddressConstantList; - TArray AtagConstantList; TArray StringConstantList; // These map from the constant value to its position in the constant table. TMap IntConstantMap; TMap FloatConstantMap; - TMap AddressConstantMap; + TMap AddressConstantMap; TMap StringConstantMap; int MaxParam; diff --git a/src/scripting/backend/vmdisasm.cpp b/src/scripting/backend/vmdisasm.cpp index 276533e2d1..3a37da8e3b 100644 --- a/src/scripting/backend/vmdisasm.cpp +++ b/src/scripting/backend/vmdisasm.cpp @@ -243,7 +243,7 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func) { for (j = 0, k = i; j < 4 && k < func->NumKonstA; j++, k += kk) { - mysnprintf(tmp, countof(tmp), "%3d. %p:%d", k, func->KonstA[k].v, func->KonstATags()[k]); + mysnprintf(tmp, countof(tmp), "%3d. %p", k, func->KonstA[k].v); printf_wrapper(out, "%-22s", tmp); } printf_wrapper(out, "\n"); @@ -320,7 +320,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction switch (code[i].op) { case OP_JMP: - case OP_TRY: + //case OP_TRY: col = printf_wrapper(out, "%08x", (i + 1 + code[i].i24) << 2); break; @@ -498,7 +498,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction col = 30; } printf_wrapper(out, "%*c", 30 - col, ';'); - if (!cmp && (code[i].op == OP_JMP || code[i].op == OP_TRY || code[i].op == OP_PARAMI)) + if (!cmp && (code[i].op == OP_JMP || /*code[i].op == OP_TRY ||*/ code[i].op == OP_PARAMI)) { printf_wrapper(out, "%d\n", code[i].i24); } diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 03fe4128a6..50994f1e76 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -1090,12 +1090,14 @@ DEFINE_PROPERTY(distancecheck, S, Actor) //========================================================================== DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory) { - static_cast(info)->RestrictedToPlayerClass.Clear(); + auto restrictarray = (TArray*)defaults->ScriptVar(NAME_RestrictedToPlayerClass, nullptr); + + restrictarray->Clear(); for(int i = 0;i < PROP_PARM_COUNT;++i) { PROP_STRING_PARM(n, i); if (*n != 0) - static_cast(info)->RestrictedToPlayerClass.Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); + restrictarray->Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); } } @@ -1104,12 +1106,14 @@ DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory) //========================================================================== DEFINE_CLASS_PROPERTY(forbiddento, Ssssssssssssssssssss, Inventory) { - static_cast(info)->ForbiddenToPlayerClass.Clear(); + auto forbidarray = (TArray*)defaults->ScriptVar(NAME_ForbiddenToPlayerClass, nullptr); + + forbidarray->Clear(); for(int i = 0;i < PROP_PARM_COUNT;++i) { PROP_STRING_PARM(n, i); if (*n != 0) - static_cast(info)->ForbiddenToPlayerClass.Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); + forbidarray->Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn))); } } diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index b95be74e30..a0103c83dd 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -23,7 +23,6 @@ typedef unsigned short VM_UHALF; typedef signed short VM_SHALF; typedef unsigned int VM_UWORD; typedef signed int VM_SWORD; -typedef VM_UBYTE VM_ATAG; #define VM_EPSILON (1/65536.0) @@ -176,27 +175,6 @@ enum #define RET_FINAL (0x80) // Used with RET and RETI in the destination slot: this is the final return value -// Tags for address registers -enum -{ - ATAG_GENERIC, // pointer to something; we don't care what - ATAG_OBJECT, // pointer to an object; will be followed by GC - - // The following are all for documentation during debugging and are - // functionally no different than ATAG_GENERIC (meaning they are useless because they trigger asserts all over the place.) - - /* - ATAG_FRAMEPOINTER, // pointer to extra stack frame space for this function - ATAG_DREGISTER, // pointer to a data register - ATAG_FREGISTER, // pointer to a float register - ATAG_SREGISTER, // pointer to a string register - ATAG_AREGISTER, // pointer to an address register - */ - - ATAG_RNG, // pointer to FRandom - ATAG_STATE = ATAG_GENERIC, // pointer to FState (cannot have its own type because there's no means to track inside the VM.) -}; - enum EVMAbortException { X_OTHER, @@ -322,7 +300,6 @@ extern const VMOpInfo OpInfo[NUM_OPS]; struct VMReturn { void *Location; - VM_SHALF TagOfs; // for pointers: Offset from Location to ATag; set to 0 if the caller is native code and doesn't care VM_UBYTE RegType; // Same as VMParam RegType, except REGT_KONST is invalid; only used by asserts void SetInt(int val) @@ -366,38 +343,37 @@ struct VMReturn assert(RegType == REGT_STRING); *(FString *)Location = val; } - void SetPointer(void *val, int tag) + + void SetPointer(void *val) + { + assert(RegType == REGT_POINTER); + *(void **)Location = val; + } + + void SetObject(DObject *val) { assert(RegType == REGT_POINTER); *(void **)Location = val; - if (TagOfs != 0) - { - *((VM_ATAG *)Location + TagOfs) = tag; - } } void IntAt(int *loc) { Location = loc; - TagOfs = 0; RegType = REGT_INT; } void FloatAt(double *loc) { Location = loc; - TagOfs = 0; RegType = REGT_FLOAT; } void StringAt(FString *loc) { Location = loc; - TagOfs = 0; RegType = REGT_STRING; } void PointerAt(void **loc) { Location = loc; - TagOfs = 0; RegType = REGT_POINTER; } VMReturn() { } @@ -415,7 +391,7 @@ struct VMValue union { int i; - struct { void *a; int atag; }; + void *a; double f; struct { int pad[3]; VM_UBYTE Type; }; struct { int foo[4]; } biggest; @@ -456,19 +432,11 @@ struct VMValue VMValue(DObject *v) { a = v; - atag = ATAG_OBJECT; Type = REGT_POINTER; } VMValue(void *v) { a = v; - atag = ATAG_GENERIC; - Type = REGT_POINTER; - } - VMValue(void *v, int tag) - { - a = v; - atag = tag; Type = REGT_POINTER; } VMValue &operator=(const VMValue &o) @@ -499,7 +467,6 @@ struct VMValue VMValue &operator=(DObject *v) { a = v; - atag = ATAG_OBJECT; Type = REGT_POINTER; return *this; } @@ -602,7 +569,7 @@ struct VMFrame int size = (sizeof(VMFrame) + 15) & ~15; size += numparam * sizeof(VMValue); size += numregf * sizeof(double); - size += numrega * (sizeof(void *) + sizeof(VM_UBYTE)); + size += numrega * sizeof(void *); size += numregs * sizeof(FString); size += numregd * sizeof(int); if (numextra != 0) @@ -613,9 +580,10 @@ struct VMFrame return size; } - int *GetRegD() const + VMValue *GetParam() const { - return (int *)(GetRegA() + NumRegA); + assert(((size_t)this & 15) == 0 && "VM frame is unaligned"); + return (VMValue *)(((size_t)(this + 1) + 15) & ~15); } double *GetRegF() const @@ -633,25 +601,19 @@ struct VMFrame return (void **)(GetRegS() + NumRegS); } - VM_ATAG *GetRegATag() const + int *GetRegD() const { - return (VM_ATAG *)(GetRegD() + NumRegD); - } - - VMValue *GetParam() const - { - assert(((size_t)this & 15) == 0 && "VM frame is unaligned"); - return (VMValue *)(((size_t)(this + 1) + 15) & ~15); + return (int *)(GetRegA() + NumRegA); } void *GetExtra() const { - VM_ATAG *ptag = GetRegATag(); - ptrdiff_t ofs = ptag - (VM_ATAG *)this; - return (VM_UBYTE *)this + ((ofs + NumRegA + 15) & ~15); + uint8_t *pbeg = (uint8_t*)(GetRegD() + NumRegD); + ptrdiff_t ofs = pbeg - (uint8_t *)this; + return (VM_UBYTE *)this + ((ofs + 15) & ~15); } - void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VM_ATAG *&atag, VMValue *¶m) const + void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VMValue *¶m) const { // Calling the individual functions produces suboptimal code. :( param = GetParam(); @@ -659,7 +621,6 @@ struct VMFrame s = (FString *)(f + NumRegF); a = (void **)(s + NumRegS); d = (int *)(a + NumRegA); - atag = (VM_ATAG *)(d + NumRegD); } void InitRegS(); @@ -669,18 +630,17 @@ struct VMRegisters { VMRegisters(const VMFrame *frame) { - frame->GetAllRegs(d, f, s, a, atag, param); + frame->GetAllRegs(d, f, s, a, param); } VMRegisters(const VMRegisters &o) - : d(o.d), f(o.f), s(o.s), a(o.a), atag(o.atag), param(o.param) + : d(o.d), f(o.f), s(o.s), a(o.a), param(o.param) { } int *d; double *f; FString *s; void **a; - VM_ATAG *atag; VMValue *param; }; @@ -703,9 +663,6 @@ public: ~VMScriptFunction(); void Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta, int numlinenumbers); - VM_ATAG *KonstATags() { return (VM_UBYTE *)(KonstA + NumKonstA); } - const VM_ATAG *KonstATags() const { return (VM_UBYTE *)(KonstA + NumKonstA); } - VMOP *Code; FStatementInfo *LineInfo; FString SourceFileName; @@ -810,14 +767,12 @@ public: void ParamObject(DObject *obj) { Reg.a[RegA] = obj; - Reg.atag[RegA] = ATAG_OBJECT; RegA++; } - void ParamPointer(void *ptr, VM_ATAG atag) + void ParamPointer(void *ptr) { Reg.a[RegA] = ptr; - Reg.atag[RegA] = atag; RegA++; } @@ -852,8 +807,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction // variable name at position

void NullParam(const char *varname); +#ifdef _DEBUG +bool AssertObject(void * ob); +#endif + #define PARAM_NULLCHECK(ptr, var) (ptr == nullptr? NullParam(#var), ptr : ptr) +#define ASSERTINT(p) assert((p).Type == REGT_INT) +#define ASSERTFLOAT(p) assert((p).Type == REGT_FLOAT) +#define ASSERTSTRING(p) assert((p).Type == REGT_STRING) +#define ASSERTOBJECT(p) assert((p).Type == REGT_POINTER && AssertObject(p.a)) +#define ASSERTPOINTER(p) assert((p).Type == REGT_POINTER) + // For required parameters. #define PARAM_INT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); int x = param[p].i; #define PARAM_UINT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); unsigned x = param[p].i; @@ -868,19 +833,13 @@ void NullParam(const char *varname); #define PARAM_STATE_ACTION_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, stateowner->GetClass()); #define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a; #define PARAM_POINTERTYPE_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type x = (type )param[p].a; -#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); -#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); +#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && AssertObject(param[p].a)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); +#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && AssertObject(param[p].a)); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); #define PARAM_POINTER_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); -#define PARAM_OBJECT_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); -#define PARAM_CLASS_NOT_NULL_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); +#define PARAM_OBJECT_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (AssertObject(param[p].a))); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); +#define PARAM_CLASS_NOT_NULL_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (AssertObject(param[p].a))); base::MetaClass *x = (base::MetaClass *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); #define PARAM_EXISTS(p) ((p) < numparam) -#define ASSERTINT(p) assert((p).Type == REGT_INT) -#define ASSERTFLOAT(p) assert((p).Type == REGT_FLOAT) -#define ASSERTSTRING(p) assert((p).Type == REGT_STRING) -#define ASSERTOBJECT(p) assert((p).Type == REGT_POINTER && ((p).atag == ATAG_OBJECT || (p).a == nullptr)) -#define ASSERTPOINTER(p) assert((p).Type == REGT_POINTER && (p).atag == ATAG_GENERIC) -#define ASSERTSTATE(p) assert((p).Type == REGT_POINTER && ((p).atag == ATAG_GENERIC || (p).atag == ATAG_STATE)) #define PARAM_INT_DEF_AT(p,x) int x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = param[p].i; } else { ASSERTINT(defaultparam[p]); x = defaultparam[p].i; } #define PARAM_BOOL_DEF_AT(p,x) bool x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = !!param[p].i; } else { ASSERTINT(defaultparam[p]); x = !!defaultparam[p].i; } @@ -1030,9 +989,9 @@ struct AFuncDesc class AActor; -#define ACTION_RETURN_STATE(v) do { FState *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_STATE); return 1; } return 0; } while(0) -#define ACTION_RETURN_POINTER(v) do { void *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_GENERIC); return 1; } return 0; } while(0) -#define ACTION_RETURN_OBJECT(v) do { auto state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_OBJECT); return 1; } return 0; } while(0) +#define ACTION_RETURN_STATE(v) do { FState *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state); return 1; } return 0; } while(0) +#define ACTION_RETURN_POINTER(v) do { void *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state); return 1; } return 0; } while(0) +#define ACTION_RETURN_OBJECT(v) do { auto state = v; if (numret > 0) { assert(ret != NULL); ret->SetObject(state); return 1; } return 0; } while(0) #define ACTION_RETURN_FLOAT(v) do { double u = v; if (numret > 0) { assert(ret != nullptr); ret->SetFloat(u); return 1; } return 0; } while(0) #define ACTION_RETURN_VEC2(v) do { DVector2 u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetVector2(u); return 1; } return 0; } while(0) #define ACTION_RETURN_VEC3(v) do { DVector3 u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetVector(u); return 1; } return 0; } while(0) @@ -1062,7 +1021,7 @@ class AActor; PARAM_PROLOGUE; \ PARAM_OBJECT(self, type); -// for structs we need to check for ATAG_GENERIC instead of ATAG_OBJECT +// for structs we cannot do a class validation #define PARAM_SELF_STRUCT_PROLOGUE(type) \ PARAM_PROLOGUE; \ PARAM_POINTER(self, type); diff --git a/src/scripting/vm/vmexec.cpp b/src/scripting/vm/vmexec.cpp index f8fb4bfd26..1e3afd709e 100644 --- a/src/scripting/vm/vmexec.cpp +++ b/src/scripting/vm/vmexec.cpp @@ -82,7 +82,6 @@ void ThrowVMException(VMException *x); #define ASSERTF(x) assert((unsigned)(x) < f->NumRegF) #define ASSERTA(x) assert((unsigned)(x) < f->NumRegA) #define ASSERTS(x) assert((unsigned)(x) < f->NumRegS) -#define ASSERTO(x) assert((unsigned)(x) < f->NumRegA && reg.atag[x] == ATAG_OBJECT) #define ASSERTKD(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstD) #define ASSERTKF(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstF) @@ -228,10 +227,29 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam) else { assert(p.Type == REGT_POINTER); - calleereg.a[rega] = p.a; - calleereg.atag[rega++] = p.atag; + calleereg.a[rega++] = p.a; } } } +#ifdef _DEBUG +bool AssertObject(void * ob) +{ + auto obj = (DObject*)ob; + if (obj == nullptr) return true; +#ifdef _MSC_VER + __try + { + return obj->MagicID == DObject::MAGIC_ID; + } + __except (1) + { + return false; + } +#else + // No SEH on non-Microsoft compilers. :( + return obj->MagicID == DObject::MAGIC_ID; +#endif +} +#endif diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 672dfe8ca9..adb0480dec 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -11,8 +11,8 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) #include "vmops.h" }; #endif - const VMOP *exception_frames[MAX_TRY_DEPTH]; - int try_depth = 0; + //const VMOP *exception_frames[MAX_TRY_DEPTH]; + //int try_depth = 0; VMFrame *f = stack->TopFrame(); VMScriptFunction *sfunc; const VMRegisters reg(f); @@ -20,7 +20,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) const double *konstf; const FString *konsts; const FVoidObj *konsta; - const VM_ATAG *konstatag; if (f->Func != NULL && !(f->Func->VarFlags & VARF_Native)) { @@ -29,7 +28,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) konstf = sfunc->KonstF; konsts = sfunc->KonstS; konsta = sfunc->KonstA; - konstatag = sfunc->KonstATags(); } else { @@ -38,7 +36,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) konstf = NULL; konsts = NULL; konsta = NULL; - konstatag = NULL; } void *ptr; @@ -46,7 +43,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) const double *fbp, *fcp; int a, b, c; -begin: +//begin: try { #if !COMPGOTO @@ -81,7 +78,6 @@ begin: OP(LKP): ASSERTA(a); ASSERTKA(BC); reg.a[a] = konsta[BC].v; - reg.atag[a] = konstatag[BC]; NEXTOP; OP(LK_R) : @@ -100,25 +96,21 @@ begin: ASSERTA(a); ASSERTD(B); b = reg.d[B] + C; reg.a[a] = konsta[b].v; - reg.atag[a] = konstatag[b]; NEXTOP; OP(LFP): ASSERTA(a); assert(sfunc != NULL); assert(sfunc->ExtraSpace > 0); reg.a[a] = f->GetExtra(); - reg.atag[a] = ATAG_GENERIC; // using ATAG_FRAMEPOINTER will cause endless asserts. NEXTOP; OP(CLSS): - ASSERTA(a); ASSERTO(B); + ASSERTA(a); ASSERTA(B); reg.a[a] = ((DObject*)reg.a[B])->GetClass(); // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer... - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(META): - ASSERTA(a); ASSERTO(B); + ASSERTA(a); ASSERTA(B); reg.a[a] = ((DObject*)reg.a[B])->GetClass()->Meta; // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer... - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(LB): @@ -217,37 +209,31 @@ begin: ASSERTA(a); ASSERTA(B); ASSERTKD(C); GETADDR(PB,KC,X_READ_NIL); reg.a[a] = GC::ReadBarrier(*(DObject **)ptr); - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(LO_R): ASSERTA(a); ASSERTA(B); ASSERTD(C); GETADDR(PB,RC,X_READ_NIL); reg.a[a] = GC::ReadBarrier(*(DObject **)ptr); - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(LOS): ASSERTA(a); ASSERTA(B); ASSERTKD(C); GETADDR(PB,KC,X_READ_NIL); reg.a[a] = *(DObject **)ptr; - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(LOS_R): ASSERTA(a); ASSERTA(B); ASSERTD(C); GETADDR(PB,RC,X_READ_NIL); reg.a[a] = *(DObject **)ptr; - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(LP): ASSERTA(a); ASSERTA(B); ASSERTKD(C); GETADDR(PB,KC,X_READ_NIL); reg.a[a] = *(void **)ptr; - reg.atag[a] = ATAG_GENERIC; NEXTOP; OP(LP_R): ASSERTA(a); ASSERTA(B); ASSERTD(C); GETADDR(PB,RC,X_READ_NIL); reg.a[a] = *(void **)ptr; - reg.atag[a] = ATAG_GENERIC; NEXTOP; OP(LV2): ASSERTF(a+1); ASSERTA(B); ASSERTKD(C); @@ -442,7 +428,6 @@ begin: ASSERTA(a); ASSERTA(B); b = B; reg.a[a] = reg.a[b]; - reg.atag[a] = reg.atag[b]; NEXTOP; } OP(MOVEV2): @@ -466,25 +451,21 @@ begin: ASSERTA(a); ASSERTA(B); ASSERTA(C); b = B; reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr; - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(DYNCAST_K) : ASSERTA(a); ASSERTA(B); ASSERTKA(C); b = B; reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr; - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(DYNCASTC_R) : ASSERTA(a); ASSERTA(B); ASSERTA(C); b = B; reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr; - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(DYNCASTC_K) : ASSERTA(a); ASSERTA(B); ASSERTKA(C); b = B; reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr; - reg.atag[a] = ATAG_OBJECT; NEXTOP; OP(CAST): if (C == CAST_I2F) @@ -575,7 +556,7 @@ begin: break; case REGT_INT | REGT_ADDROF: assert(C < f->NumRegD); - ::new(param) VMValue(®.d[C], ATAG_GENERIC); + ::new(param) VMValue(®.d[C]); break; case REGT_INT | REGT_KONST: assert(C < sfunc->NumKonstD); @@ -587,7 +568,7 @@ begin: break; case REGT_STRING | REGT_ADDROF: assert(C < f->NumRegS); - ::new(param) VMValue(®.s[C], ATAG_GENERIC); + ::new(param) VMValue((void*)®.s[C]); // Note that this may not use the FString* version of the constructor! break; case REGT_STRING | REGT_KONST: assert(C < sfunc->NumKonstS); @@ -595,15 +576,15 @@ begin: break; case REGT_POINTER: assert(C < f->NumRegA); - ::new(param) VMValue(reg.a[C], reg.atag[C]); + ::new(param) VMValue(reg.a[C]); break; case REGT_POINTER | REGT_ADDROF: assert(C < f->NumRegA); - ::new(param) VMValue(®.a[C], ATAG_GENERIC); + ::new(param) VMValue(®.a[C]); break; case REGT_POINTER | REGT_KONST: assert(C < sfunc->NumKonstA); - ::new(param) VMValue(konsta[C].v, konstatag[C]); + ::new(param) VMValue(konsta[C].v); break; case REGT_FLOAT: assert(C < f->NumRegF); @@ -626,7 +607,7 @@ begin: break; case REGT_FLOAT | REGT_ADDROF: assert(C < f->NumRegF); - ::new(param) VMValue(®.f[C], ATAG_GENERIC); + ::new(param) VMValue(®.f[C]); break; case REGT_FLOAT | REGT_KONST: assert(C < sfunc->NumKonstF); @@ -657,7 +638,6 @@ begin: OP(CALL_K): ASSERTKA(a); - assert(konstatag[a] == ATAG_OBJECT); ptr = konsta[a].o; goto Do_CALL; OP(CALL): @@ -713,7 +693,6 @@ begin: NEXTOP; OP(TAIL_K): ASSERTKA(a); - assert(konstatag[a] == ATAG_OBJECT); ptr = konsta[a].o; goto Do_TAILCALL; OP(TAIL): @@ -825,10 +804,10 @@ begin: c = C; if (c) FScopeBarrier::ValidateNew(cls, c - 1); reg.a[a] = cls->CreateNew(); - reg.atag[a] = ATAG_OBJECT; NEXTOP; } +#if 0 OP(TRY): assert(try_depth < MAX_TRY_DEPTH); if (try_depth >= MAX_TRY_DEPTH) @@ -842,7 +821,9 @@ begin: assert(a <= try_depth); try_depth -= a; NEXTOP; +#endif OP(THROW): +#if 0 if (a == 0) { ASSERTA(B); @@ -851,19 +832,22 @@ begin: else if (a == 1) { ASSERTKA(B); - assert(konstatag[B] == ATAG_OBJECT); + assert(AssertObject(konsta[B].o)); ThrowVMException((VMException *)konsta[B].o); } else +#endif { ThrowAbortException(EVMAbortException(BC), nullptr); } NEXTOP; +#if 0 OP(CATCH): // This instruction is handled by our own catch handler and should // not be executed by the normal VM code. assert(0); NEXTOP; +#endif OP(BOUND): if (reg.d[a] >= BC) @@ -1658,7 +1642,6 @@ begin: c = 0; } reg.a[a] = (VM_UBYTE *)reg.a[B] + c; - reg.atag[a] = c == 0 ? reg.atag[B] : (int)ATAG_GENERIC; NEXTOP; OP(ADDA_RK): ASSERTA(a); ASSERTA(B); ASSERTKD(C); @@ -1683,6 +1666,7 @@ begin: NEXTOP; } } +#if 0 catch(VMException *exception) { // Try to find a handler for the exception. @@ -1709,7 +1693,6 @@ begin: { assert(pc->a == 3); ASSERTKA(b); - assert(konstatag[b] == ATAG_OBJECT); type = (PClass *)konsta[b].o; } ASSERTA(pc->c); @@ -1718,7 +1701,6 @@ begin: // Found a handler. Store the exception in pC, skip the JMP, // and begin executing its code. reg.a[pc->c] = exception; - reg.atag[pc->c] = ATAG_OBJECT; pc += 2; goto begin; } @@ -1731,7 +1713,6 @@ begin: // Catch any type of VMException. This terminates the chain. ASSERTA(pc->c); reg.a[pc->c] = exception; - reg.atag[pc->c] = ATAG_OBJECT; pc += 1; goto begin; } @@ -1740,6 +1721,7 @@ begin: // Nothing caught it. Rethrow and let somebody else deal with it. throw; } +#endif catch (CVMAbortException &err) { err.MaybePrintMessage(); @@ -1831,16 +1813,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c { ASSERTS(a); ASSERTA(b); if (reg.a[b] == nullptr) reg.s[a] = "null"; - else if (reg.atag[b] == ATAG_OBJECT) - { - auto op = static_cast(reg.a[b]); - if (op->IsKindOf(RUNTIME_CLASS(PClass))) reg.s[a].Format("Class<%s>", static_cast(op)->TypeName.GetChars()); - else reg.s[a].Format("Object<%p>", ((DObject*)reg.a[b])->GetClass()->TypeName.GetChars()); - } - else - { - reg.s[a].Format("%s<%p>", "Pointer", reg.a[b]); - } + else reg.s[a].Format("%p", reg.a[b]); break; } @@ -1922,7 +1895,6 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return for (i = 0, ret = returns; i < numret; ++i, ++ret, ++retval) { assert(retval->op == OP_RESULT); // opcode - ret->TagOfs = 0; ret->RegType = type = retval->b; regnum = retval->c; assert(!(type & REGT_KONST)); @@ -1950,7 +1922,6 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return assert(type == REGT_POINTER); assert(regnum < frame->NumRegA); ret->Location = ®.a[regnum]; - ret->TagOfs = (VM_SHALF)(&frame->GetRegATag()[regnum] - (VM_ATAG *)ret->Location); } } } @@ -2033,12 +2004,12 @@ static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_ if (regtype & REGT_KONST) { assert(regnum < func->NumKonstA); - ret->SetPointer(func->KonstA[regnum].v, func->KonstATags()[regnum]); + ret->SetPointer(func->KonstA[regnum].v); } else { assert(regnum < frame->NumRegA); - ret->SetPointer(reg.a[regnum], reg.atag[regnum]); + ret->SetPointer(reg.a[regnum]); } break; } diff --git a/src/scripting/vm/vmframe.cpp b/src/scripting/vm/vmframe.cpp index 9cbf2adae0..c631dea748 100644 --- a/src/scripting/vm/vmframe.cpp +++ b/src/scripting/vm/vmframe.cpp @@ -97,7 +97,7 @@ void VMScriptFunction::Alloc(int numops, int numkonstd, int numkonstf, int numko numkonstd * sizeof(int) + numkonstf * sizeof(double) + numkonsts * sizeof(FString) + - numkonsta * (sizeof(FVoidObj) + 1) + + numkonsta * sizeof(FVoidObj) + numlinenumbers * sizeof(FStatementInfo)); Code = (VMOP *)mem; mem = (void *)((VMOP *)mem + numops); diff --git a/src/scripting/vm/vmops.h b/src/scripting/vm/vmops.h index 18a444677b..50f6568cb4 100644 --- a/src/scripting/vm/vmops.h +++ b/src/scripting/vm/vmops.h @@ -114,12 +114,12 @@ xx(RET, ret, I8BCP, NOP, 0, 0), // Copy value from register encoded in BC to xx(RETI, reti, I8I16, NOP, 0, 0), // Copy immediate from BC to return value A, possibly returning xx(NEW, new, RPRPI8, NOP, 0, 0), xx(NEW_K, new, RPKP, NOP, 0, 0), -xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC -xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack +//xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC +//xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack xx(THROW, throw, THROW, NOP, 0, 0), // A == 0: Throw exception object pB // A == 1: Throw exception object pkB // A >= 2: Throw VM exception of type BC -xx(CATCH, catch, CATCH, NOP, 0, 0), // A == 0: continue search on next try +//xx(CATCH, catch, CATCH, NOP, 0, 0), // A == 0: continue search on next try // A == 1: continue execution at instruction immediately following CATCH (catches any exception) // A == 2: (pB == ) then pc++ ; next instruction must JMP to another CATCH // A == 3: (pkB == ) then pc++ ; next instruction must JMP to another CATCH diff --git a/src/swrenderer/r_memory.cpp b/src/swrenderer/r_memory.cpp index 07c85723d7..4cbfb91ef7 100644 --- a/src/swrenderer/r_memory.cpp +++ b/src/swrenderer/r_memory.cpp @@ -46,7 +46,7 @@ void *RenderMemory::AllocBytes(int size) } else { - UsedBlocks.push_back(std::make_unique()); + UsedBlocks.push_back(std::unique_ptr(new MemoryBlock())); } } diff --git a/src/swrenderer/r_renderthread.cpp b/src/swrenderer/r_renderthread.cpp index 09a4e70091..fa20da4566 100644 --- a/src/swrenderer/r_renderthread.cpp +++ b/src/swrenderer/r_renderthread.cpp @@ -60,21 +60,21 @@ namespace swrenderer { Scene = scene; MainThread = mainThread; - FrameMemory = std::make_unique(); - Viewport = std::make_unique(); - Light = std::make_unique(); - DrawQueue = std::make_shared(FrameMemory.get()); - OpaquePass = std::make_unique(this); - TranslucentPass = std::make_unique(this); - SpriteList = std::make_unique(); - Portal = std::make_unique(this); - Clip3D = std::make_unique(this); - PlayerSprites = std::make_unique(this); - PlaneList = std::make_unique(this); - DrawSegments = std::make_unique(this); - ClipSegments = std::make_unique(); - tc_drawers = std::make_unique(DrawQueue); - pal_drawers = std::make_unique(DrawQueue); + FrameMemory.reset(new RenderMemory()); + Viewport.reset(new RenderViewport()); + Light.reset(new LightVisibility()); + DrawQueue.reset(new DrawerCommandQueue(FrameMemory.get())); + OpaquePass.reset(new RenderOpaquePass(this)); + TranslucentPass.reset(new RenderTranslucentPass(this)); + SpriteList.reset(new VisibleSpriteList()); + Portal.reset(new RenderPortal(this)); + Clip3D.reset(new Clip3DFloors(this)); + PlayerSprites.reset(new RenderPlayerSprites(this)); + PlaneList.reset(new VisiblePlaneList(this)); + DrawSegments.reset(new DrawSegmentList(this)); + ClipSegments.reset(new RenderClipSegment()); + tc_drawers.reset(new SWTruecolorDrawers(DrawQueue)); + pal_drawers.reset(new SWPalDrawers(DrawQueue)); } RenderThread::~RenderThread() diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index 609f2f7533..401517cf6c 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -61,7 +61,7 @@ namespace swrenderer RenderScene::RenderScene() { - Threads.push_back(std::make_unique(this)); + Threads.push_back(std::unique_ptr(new RenderThread(this))); } RenderScene::~RenderScene() @@ -289,7 +289,7 @@ namespace swrenderer { while (Threads.size() < (size_t)numThreads) { - auto thread = std::make_unique(this, false); + std::unique_ptr thread(new RenderThread(this, false)); auto renderthread = thread.get(); int start_run_id = run_id; thread->thread = std::thread([=]() diff --git a/wadsrc/static/zscript/inventory/inventory.txt b/wadsrc/static/zscript/inventory/inventory.txt index fe371ebea9..43de6b527a 100644 --- a/wadsrc/static/zscript/inventory/inventory.txt +++ b/wadsrc/static/zscript/inventory/inventory.txt @@ -25,6 +25,8 @@ class Inventory : Actor native native bool bInitEffectFailed; meta String PickupMsg; meta int GiveQuest; + meta array > ForbiddenToPlayerClass; + meta array > RestrictedToPlayerClass; property PickupMessage: PickupMsg; property GiveQuest: GiveQuest; @@ -46,7 +48,6 @@ class Inventory : Actor native Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG"; } - native bool CanPickup(Actor toucher); native bool DoRespawn(); native void BecomeItem(); native void BecomePickup(); @@ -330,6 +331,36 @@ class Inventory : Actor native } } + //=========================================================================== + // + // AInventory :: CanPickup + // + //=========================================================================== + + virtual bool CanPickup(Actor toucher) + { + if (toucher == null) return false; + + int rsize = RestrictedToPlayerClass.Size(); + if (rsize > 0) + { + for (int i=0; i < rsize; i++) + { + if (toucher is RestrictedToPlayerClass[i]) return true; + } + return false; + } + rsize = ForbiddenToPlayerClass.Size(); + if (rsize > 0) + { + for (int i=0; i < rsize; i++) + { + if (toucher is ForbiddenToPlayerClass[i]) return false; + } + } + return true; + } + //=========================================================================== // // AInventory :: CallTryPickup