This commit is contained in:
Rachael Alexanderson 2017-03-07 22:03:56 -05:00
commit 527a172fcd
10 changed files with 121 additions and 84 deletions

View File

@ -2,28 +2,31 @@ language: c++
dist: trusty
sudo: required
branches:
except:
- /^appveyor.*$/
git:
depth: 3
matrix:
include:
- os: osx
osx_image: xcode8.2
env:
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7"
- os: osx
osx_image: xcode8.2
env:
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 -DFORCE_INTERNAL_ZLIB=YES -DFORCE_INTERNAL_JPEG=YES -DFORCE_INTERNAL_BZIP2=YES -DFORCE_INTERNAL_GME=YES"
- FMOD_LIBRARY=libfmodex.dylib
- os: linux
compiler: gcc
env:
- GCC_VERSION=5
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release"
- FMOD_LIBRARY=libfmodex64.so
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- kubuntu-backports
packages:
- g++-5
- libsdl2-dev
@ -34,17 +37,37 @@ matrix:
- libfluidsynth-dev
- libgtk-3-dev
- os: linux
compiler: gcc
env:
- GCC_VERSION=6
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=RelWithDebInfo -DDYN_FLUIDSYNTH=NO"
- FMOD_LIBRARY=libfmodex64.so
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
- libsdl2-dev
- libgme-dev
- libopenal-dev
- libmpg123-dev
- libsndfile-dev
- libfluidsynth-dev
- libgtk-3-dev
- os: linux
compiler: clang
env:
- CLANG_VERSION=3.9
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=RelWithDebInfo -DDYN_OPENAL=NO -DDYN_FLUIDSYNTH=NO"
- CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Debug -DDYN_OPENAL=NO"
- FMOD_LIBRARY=libfmodex64.so
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-3.9
- kubuntu-backports
packages:
- clang-3.9
- libstdc++-5-dev
@ -62,11 +85,15 @@ before_install:
- if [ -n "$CLANG_VERSION" ]; then export CC="clang-${CLANG_VERSION}" CXX="clang++-${CLANG_VERSION}"; fi
- $CC --version
- $CXX --version
- export FMOD_FILENAME=fmod-4.44.64-${TRAVIS_OS_NAME}.tar.bz2
- curl -LO "https://github.com/coelckers/gzdoom/releases/download/ci_deps/${FMOD_FILENAME}"
- tar -xf "${FMOD_FILENAME}"
script:
- echo ${TRAVIS_BUILD_DIR}
- mkdir build
- cd build
- cmake ${CMAKE_OPTIONS} ..
- cmake ${CMAKE_OPTIONS} -DFMOD_INCLUDE_DIR="${TRAVIS_BUILD_DIR}/fmod/inc" -DFMOD_LIBRARY="${TRAVIS_BUILD_DIR}/fmod/lib/${FMOD_LIBRARY}" ..
- make -j2
notifications:

View File

@ -289,7 +289,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex
if (frontreflect > 0)
{
float backreflect = bs->GetReflect(sector_t::ceiling);
if (backreflect > 0 && bs->ceilingplane.fD() == fs->ceilingplane.fD())
if (backreflect > 0 && bs->ceilingplane.fD() == fs->ceilingplane.fD() && !bs->isClosed())
{
// Don't add intra-portal line to the portal.
return;
@ -368,7 +368,7 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver
if (frontreflect > 0)
{
float backreflect = bs->GetReflect(sector_t::floor);
if (backreflect > 0 && bs->floorplane.fD() == fs->floorplane.fD())
if (backreflect > 0 && bs->floorplane.fD() == fs->floorplane.fD() && !bs->isClosed())
{
// Don't add intra-portal line to the portal.
return;

View File

@ -954,6 +954,11 @@ public:
return LowestFloorAt(a->Pos(), resultsec);
}
bool isClosed() const
{
return floorplane.Normal() == -ceilingplane.Normal() && floorplane.D == -ceilingplane.D;
}
double NextHighestCeilingAt(double x, double y, double bottomz, double topz, int flags = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL);
double NextLowestFloorAt(double x, double y, double z, int flags = 0, double steph = 0, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL);

View File

@ -5105,7 +5105,18 @@ ExpEmit FxNew::Emit(VMFunctionBuilder *build)
ExpEmit from = val->Emit(build);
from.Free(build);
ExpEmit to(build, REGT_POINTER);
build->Emit(from.Konst ? OP_NEW_K : OP_NEW, to.RegNum, from.RegNum, build->GetConstantAddress(CallingFunction, ATAG_OBJECT));
if (!from.Konst)
{
int outerside = FScopeBarrier::SideFromFlags(CallingFunction->Variants[0].Flags);
if (outerside == FScopeBarrier::Side_Virtual)
outerside = FScopeBarrier::SideFromObjectFlags(CallingFunction->OwningClass->ObjectFlags);
build->Emit(OP_NEW, to.RegNum, from.RegNum, outerside+1); // +1 to ensure it's not 0
}
else
{
build->Emit(OP_NEW_K, to.RegNum, from.RegNum);
}
return to;
}
@ -8781,20 +8792,27 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
ExpEmit selfemit;
if (Function->Variants[0].Flags & VARF_Method)
{
#if 0
// [ZZ]
if (Function->Variants[0].Implementation && Function->Variants[0].Implementation->BarrierSide == FScopeBarrier::Side_Virtual)
{
// pass this even before Self, because otherwise we can't silently advance the arguments.
// this is not even implicit arguments.
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(Function, ATAG_OBJECT));
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(CallingFunction, ATAG_OBJECT));
count += 2;
}
#endif
assert(Self != nullptr);
selfemit = Self->Emit(build);
assert((selfemit.RegType == REGT_POINTER) || (selfemit.Fixed && selfemit.Target));
int innerside = FScopeBarrier::SideFromFlags(Function->Variants[0].Flags);
if (innerside == FScopeBarrier::Side_Virtual)
{
auto selfside = FScopeBarrier::SideFromObjectFlags(static_cast<PPointer*>(Self->ValueType)->PointedType->ObjectFlags);
int outerside = FScopeBarrier::SideFromFlags(CallingFunction->Variants[0].Flags);
if (outerside == FScopeBarrier::Side_Virtual)
outerside = FScopeBarrier::SideFromObjectFlags(CallingFunction->OwningClass->ObjectFlags);
if (selfside != outerside && (selfside == FScopeBarrier::Side_Play || selfside == FScopeBarrier::Side_UI)) // if the self pointer and the calling functions have the same scope the check here is not needed.
{
// 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));
}
}
if (selfemit.Fixed && selfemit.Target)
{
// Address of a local variable.
@ -8859,6 +8877,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
{
selfemit.Free(build);
ExpEmit funcreg(build, REGT_POINTER);
build->Emit(OP_VTBL, funcreg.RegNum, selfemit.RegNum, vmfunc->VirtualIndex);
if (EmitTail)
{ // Tail call

View File

@ -173,25 +173,16 @@ void FScopeBarrier::AddFlags(int flags1, int flags2, const char* name)
}
// these are for vmexec.h
void FScopeBarrier::ValidateNew(PClass* cls, PFunction* callingfunc)
void FScopeBarrier::ValidateNew(PClass* cls, int outerside)
{
int outerside = callingfunc->Variants.Size() ? FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags) : FScopeBarrier::Side_Virtual;
if (outerside == FScopeBarrier::Side_Virtual)
outerside = FScopeBarrier::SideFromObjectFlags(callingfunc->OwningClass->ObjectFlags);
int innerside = FScopeBarrier::SideFromObjectFlags(cls->ObjectFlags);
if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData)) // "cannot construct ui class ... from data context"
ThrowAbortException(X_OTHER, "Cannot construct %s class %s from %s context", FScopeBarrier::StringFromSide(innerside), cls->TypeName.GetChars(), FScopeBarrier::StringFromSide(outerside));
}
// this can be imported in vmexec.h
void FScopeBarrier::ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype)
void FScopeBarrier::ValidateCall(PClass* selftype, VMFunction *calledfunc, int outerside)
{
// [ZZ] anonymous blocks have 0 variants, so give them Side_Virtual.
int outerside = callingfunc->Variants.Size() ? FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags) : FScopeBarrier::Side_Virtual;
if (outerside == FScopeBarrier::Side_Virtual)
outerside = FScopeBarrier::SideFromObjectFlags(callingfunc->OwningClass->ObjectFlags);
int innerside = FScopeBarrier::SideFromFlags(calledfunc->Variants[0].Flags);
if (innerside == FScopeBarrier::Side_Virtual)
innerside = FScopeBarrier::SideFromObjectFlags(selftype->ObjectFlags);
int innerside = FScopeBarrier::SideFromObjectFlags(selftype->ObjectFlags);
if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData))
ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->SymbolName.GetChars(), FScopeBarrier::StringFromSide(outerside));
ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->PrintableName.GetChars(), FScopeBarrier::StringFromSide(outerside));
}

View File

@ -53,7 +53,8 @@ struct FScopeBarrier
void AddFlags(int flags1, int flags2, const char* name);
// this is called from vmexec.h
static void ValidateNew(PClass* cls, PFunction* callingfunc);
static void ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype);
static void ValidateNew(PClass* cls, int scope);
static void ValidateCall(PClass* selftype, VMFunction *calledfunc, int outerside);
};

View File

@ -648,6 +648,13 @@ begin:
reg.a[a] = p->Virtuals[C];
}
NEXTOP;
OP(SCOPE) :
{
ASSERTA(a); ASSERTA(C);
FScopeBarrier::ValidateCall(((DObject*)a)->GetClass(), (VMFunction*)C, B - 1);
}
NEXTOP;
OP(CALL_K):
ASSERTKA(a);
assert(konstatag[a] == ATAG_OBJECT);
@ -665,19 +672,6 @@ begin:
int numret;
b = B;
#if 0
// [ZZ] hax!
if (call->BarrierSide == 3) // :( - this is Side_Virtual. Side_Virtual should receive special arguments.
{
PFunction* calledfunc = (PFunction*)(reg.param + f->NumParam - b)[0].a;
PFunction* callingfunc = (PFunction*)(reg.param + f->NumParam - b)[1].a;
DObject* dobj = (DObject*)(reg.param + f->NumParam - b)[2].a; // this is the self pointer. it should be in, since Side_Virtual functions are always non-static methods.
PClass* selftype = dobj->GetClass();
FScopeBarrier::ValidateCall(calledfunc, callingfunc, selftype);
b -= 2;
}
#endif
FillReturns(reg, f, returns, pc+1, C);
if (call->VarFlags & VARF_Native)
{
@ -817,11 +811,10 @@ begin:
{
b = B;
PClass *cls = (PClass*)(pc->op == OP_NEW ? reg.a[b] : konsta[b].v);
PFunction *callingfunc = (PFunction*)konsta[C].o; // [ZZ] due to how this is set, it's always const
if (cls->ObjectFlags & OF_Abstract) ThrowAbortException(X_OTHER, "Cannot instantiate abstract class %s", cls->TypeName.GetChars());
// [ZZ] validate readonly and between scope construction
if (callingfunc)
FScopeBarrier::ValidateNew(cls, callingfunc);
c = C;
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
reg.a[a] = cls->CreateNew();
reg.atag[a] = ATAG_OBJECT;
NEXTOP;

View File

@ -106,12 +106,13 @@ xx(PARAMI, parami, I24, NOP, 0, 0), // push immediate, signed integer for func
xx(CALL, call, RPI8I8, NOP, 0, 0), // Call function pkA with parameter count B and expected result count C
xx(CALL_K, call, KPI8I8, CALL, 1, REGT_POINTER),
xx(VTBL, vtbl, RPRPI8, NOP, 0, 0), // dereferences a virtual method table.
xx(SCOPE, scope, RPI8, NOP, 0, 0), // Scope check at runtime.
xx(TAIL, tail, RPI8, NOP, 0, 0), // Call+Ret in a single instruction
xx(TAIL_K, tail, KPI8, TAIL, 1, REGT_POINTER),
xx(RESULT, result, __BCP, NOP, 0, 0), // Result should go in register encoded in BC (in caller, after CALL)
xx(RET, ret, I8BCP, NOP, 0, 0), // Copy value from register encoded in BC to return value A, possibly returning
xx(RETI, reti, I8I16, NOP, 0, 0), // Copy immediate from BC to return value A, possibly returning
xx(NEW, new, RPRP, NOP, 0, 0),
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

View File

@ -450,13 +450,13 @@ class Actor : Thinker native
native static int FindUniqueTid(int start = 0, int limit = 0);
native void SetShade(color col);
native string GetTag(string defstr = "") const;
native clearscope string GetTag(string defstr = "") const;
native void SetTag(string defstr = "");
native double GetBobOffset(double frac = 0);
native void ClearCounters();
native bool GiveBody (int num, int max=0);
native bool HitFloor();
native bool isTeammate(Actor other) const;
native clearscope bool isTeammate(Actor other) const;
native int PlayerNumber();
native void SetFriendPlayer(PlayerInfo player);
native void SoundAlert(Actor target, bool splash = false, double maxdist = 0);
@ -468,15 +468,15 @@ class Actor : Thinker native
native bool UpdateWaterLevel (bool splash = true);
native bool IsZeroDamage();
native void ClearInterpolation();
native Vector3 PosRelative(sector sec) const;
native clearscope Vector3 PosRelative(sector sec) const;
native void HandleSpawnFlags();
native void ExplodeMissile(line lin = null, Actor target = null, bool onsky = false);
native void RestoreDamage();
native int SpawnHealth() const;
native clearscope int SpawnHealth() const;
native void SetDamage(int dmg);
native double Distance2D(Actor other) const;
native double Distance3D(Actor other) const;
native clearscope double Distance2D(Actor other) const;
native clearscope double Distance3D(Actor other) const;
native void SetOrigin(vector3 newpos, bool moving);
native void SetXYZ(vector3 newpos);
native Actor GetPointer(int aaptr);
@ -511,7 +511,7 @@ class Actor : Thinker native
native void BloodSplatter (Vector3 pos, double hitangle, bool axe = false);
native bool HitWater (sector sec, Vector3 pos, bool checkabove = false, bool alert = true, bool force = false);
native void PlaySpawnSound(Actor missile);
native bool CountsAsKill() const;
native clearscope bool CountsAsKill() const;
native bool Teleport(Vector3 pos, double angle, int flags);
native void TraceBleed(int damage, Actor missile);
@ -559,21 +559,21 @@ class Actor : Thinker native
native void LinkToWorld(LinkContext ctx = null);
native void UnlinkFromWorld(out LinkContext ctx = null);
native bool CanSeek(Actor target);
native double AngleTo(Actor target, bool absolute = false) const;
native clearscope double AngleTo(Actor target, bool absolute = false) const;
native void AddZ(double zadd, bool moving = true);
native void SetZ(double z);
native vector2 Vec2To(Actor other) const;
native vector3 Vec3To(Actor other) const;
native vector3 Vec3Offset(double x, double y, double z, bool absolute = false) const;
native vector3 Vec3Angle(double length, double angle, double z = 0, bool absolute = false) const;
native vector2 Vec2Angle(double length, double angle, bool absolute = false) const;
native vector2 Vec2Offset(double x, double y, bool absolute = false) const;
native vector3 Vec2OffsetZ(double x, double y, double atz, bool absolute = false) const;
native void VelFromAngle(double speed = 0, double angle = 0) const;
native void Vel3DFromAngle(double speed, double angle, double pitch) const;
native clearscope vector2 Vec2To(Actor other) const;
native clearscope vector3 Vec3To(Actor other) const;
native clearscope vector3 Vec3Offset(double x, double y, double z, bool absolute = false) const;
native clearscope vector3 Vec3Angle(double length, double angle, double z = 0, bool absolute = false) const;
native clearscope vector2 Vec2Angle(double length, double angle, bool absolute = false) const;
native clearscope vector2 Vec2Offset(double x, double y, bool absolute = false) const;
native clearscope vector3 Vec2OffsetZ(double x, double y, double atz, bool absolute = false) const;
native void VelFromAngle(double speed = 0, double angle = 0);
native void Vel3DFromAngle(double speed, double angle, double pitch);
native void Thrust(double speed = 0, double angle = 0);
native bool isFriend(Actor other) const;
native bool isHostile(Actor other) const;
native clearscope bool isFriend(Actor other) const;
native clearscope bool isHostile(Actor other) const;
native void AdjustFloorClip();
native DropItem GetDropItems();
native void CopyFriendliness (Actor other, bool changeTarget, bool resetHealth = true);
@ -588,8 +588,8 @@ class Actor : Thinker native
native void Howl();
native void DrawSplash (int count, double angle, int kind);
native void GiveSecret(bool printmsg = true, bool playsound = true);
native double GetCameraHeight() const;
native double GetGravity() const;
native clearscope double GetCameraHeight() const;
native clearscope double GetGravity() const;
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
native void AddInventory(Inventory inv);
@ -597,7 +597,7 @@ class Actor : Thinker native
native void ClearInventory();
native bool GiveInventory(class<Inventory> type, int amount, bool givecheat = false);
native bool TakeInventory(class<Inventory> itemclass, int amount, bool fromdecorate = false, bool notakeinfinite = false);
native Inventory FindInventory(class<Inventory> itemtype, bool subclass = false) const;
native clearscope Inventory FindInventory(class<Inventory> itemtype, bool subclass = false) const;
native Inventory GiveInventoryType(class<Inventory> itemtype);
native Inventory DropInventory (Inventory item, int amt = -1);
native bool UseInventory(Inventory item);
@ -609,11 +609,11 @@ class Actor : Thinker native
action native void SetCamera(Actor cam, bool revert = false);
// DECORATE compatible functions
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
native double GetDistance(bool checkz, int ptr = AAPTR_TARGET);
native double GetAngle(int flags, int ptr = AAPTR_TARGET);
native clearscope int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT) const;
native double GetDistance(bool checkz, int ptr = AAPTR_TARGET) const;
native double GetAngle(int flags, int ptr = AAPTR_TARGET) const;
native double GetZAt(double px = 0, double py = 0, double angle = 0, int flags = 0, int pick_pointer = AAPTR_DEFAULT);
native int GetSpawnHealth() const;
native clearscope int GetSpawnHealth() const;
native double GetCrouchFactor(int ptr = AAPTR_PLAYER1);
native double GetCVar(string cvar);
native int GetPlayerInput(int inputnum, int ptr = AAPTR_DEFAULT);

View File

@ -150,7 +150,7 @@ class PlayerPawn : Actor native
}
// This is for SBARINFO.
int, int GetEffectTicsForItem(class<Inventory> item) const
clearscope int, int GetEffectTicsForItem(class<Inventory> item) const
{
let pg = (class<PowerupGiver>)(item);
if (pg != null)
@ -167,7 +167,7 @@ class PlayerPawn : Actor native
return -1, -1;
}
native int GetMaxHealth(bool withupgrades = false) const;
native clearscope int GetMaxHealth(bool withupgrades = false) const;
native bool ResetAirSupply (bool playgasp = false);
native void CheckWeaponSwitch(class<Inventory> item);
native clearscope static String GetPrintableDisplayName(Class<Actor> cls);