mirror of
https://github.com/polserver/polserver
synced 2026-08-13 08:23:08 -04:00
* test for sending a function to the same program * store executor pid inside funcrefs and classes * docs
1124 lines
38 KiB
C++
1124 lines
38 KiB
C++
/** @file
|
|
*
|
|
* @par History
|
|
* - 2006/10/28 Shinigami: GCC 4.1.1 fix - invalid use of constructor as a template
|
|
* - 2009/09/05 Turley: Added struct .? and .- as shortcut for .exists() and .erase()
|
|
* - 2009/12/21 Turley: ._method() call fix
|
|
*/
|
|
|
|
#ifndef BSCRIPT_BOBJECT_H
|
|
#define BSCRIPT_BOBJECT_H
|
|
|
|
#ifdef NDEBUG
|
|
#define BOBJECTIMP_DEBUG 0
|
|
#else
|
|
#define BOBJECTIMP_DEBUG 1
|
|
#endif
|
|
|
|
#if BOBJECTIMP_DEBUG
|
|
#define INLINE_BOBJECTIMP_CTOR 0
|
|
#else
|
|
#define INLINE_BOBJECTIMP_CTOR 1
|
|
#endif
|
|
|
|
#include <fmt/ostream.h>
|
|
|
|
#include "eprog.h"
|
|
|
|
#include "../clib/fixalloc.h"
|
|
#include "../clib/passert.h"
|
|
#include "../clib/rawtypes.h"
|
|
#include "../clib/refptr.h"
|
|
#include "../clib/spinlock.h"
|
|
|
|
#if INLINE_BOBJECTIMP_CTOR
|
|
#include "escriptv.h"
|
|
#endif
|
|
|
|
#include <iosfwd>
|
|
#include <stack>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
|
|
/**
|
|
* Bscript namespace is for escript stuff, like compiler and basic modules
|
|
*/
|
|
namespace Pol::Bscript
|
|
{
|
|
class BObjectImp;
|
|
class BObject;
|
|
class BObjectRef;
|
|
class ContIterator;
|
|
class Executor;
|
|
class Instruction;
|
|
|
|
class BLong;
|
|
class Double;
|
|
class String;
|
|
class ObjArray;
|
|
class UninitObject;
|
|
class BError;
|
|
class BStruct;
|
|
class BDictionary;
|
|
class BBoolean;
|
|
class BFunctionRef;
|
|
class BClassInstance;
|
|
class BClassInstanceRef;
|
|
class BContinuation;
|
|
class BSpread;
|
|
class BRegExp;
|
|
class BSpecialUserFuncJump;
|
|
class BApplicObjBase;
|
|
|
|
using ValueStackCont = std::vector<BObjectRef>;
|
|
|
|
class BObjectImp : public ref_counted
|
|
{
|
|
public:
|
|
/**
|
|
* Specify the object type for the child classes
|
|
*
|
|
* @warning This is directly returned by TypeOfInt(), so don't forget to
|
|
* keep constants inside basic.em in sync! It is better to always
|
|
* add new values at the end and use explicit int conversion to
|
|
* avoid breaking backward compatibility.
|
|
*/
|
|
enum BObjectType : u8
|
|
{
|
|
OTUnknown = 0,
|
|
OTUninit = 1,
|
|
OTString = 2,
|
|
OTLong = 3,
|
|
OTDouble = 4,
|
|
OTArray = 5,
|
|
// unused
|
|
OTApplicObj = 7,
|
|
OTError = 8,
|
|
OTDictionary = 9,
|
|
OTStruct = 10,
|
|
OTPacket = 11,
|
|
OTBinaryFile = 12,
|
|
OTXMLFile = 13,
|
|
OTXMLNode = 14,
|
|
OTXMLAttributes = 15,
|
|
OTPolCoreRef = 16,
|
|
|
|
// non direct used constants (for TypeOfInt) start
|
|
OTAccountRef = 17,
|
|
OTConfigFileRef = 18,
|
|
OTConfigElemRef = 19,
|
|
OTDataFileRef = 20,
|
|
OTDataElemRef = 21,
|
|
OTGuildRef = 22,
|
|
OTPartyRef = 23,
|
|
OTBoundingBox = 24,
|
|
OTDebugContext = 25,
|
|
OTScriptExRef = 26,
|
|
OTPackage = 27,
|
|
OTMenuRef = 28,
|
|
OTMobileRef = 29,
|
|
OTOfflineMobileRef = 30,
|
|
OTItemRef = 31,
|
|
OTBoatRef = 32,
|
|
OTMultiRef = 33,
|
|
OTClientRef = 34,
|
|
// non direct used Constants (for TypeOfInt) end
|
|
|
|
OTSQLConnection = 35,
|
|
OTSQLResultSet = 36,
|
|
OTSQLRow = 37,
|
|
OTBoolean = 38,
|
|
OTFuncRef = 39,
|
|
OTExportScript = 40,
|
|
OTStorageArea = 41,
|
|
OTClassInstanceRef = 42,
|
|
OTRegExp = 43,
|
|
|
|
// Used internally only during executor runtime. Can be modified without
|
|
// breaking compatibility.
|
|
OTContinuation = 100,
|
|
OTSpread = 101,
|
|
OTClassInstance = 102,
|
|
OTSpecialUserFuncJump = 103,
|
|
};
|
|
|
|
#if INLINE_BOBJECTIMP_CTOR
|
|
explicit BObjectImp( BObjectType type ) : type_( type )
|
|
{
|
|
++eobject_imp_count;
|
|
++eobject_imp_constructions;
|
|
}
|
|
~BObjectImp() override { --eobject_imp_count; }
|
|
#else
|
|
explicit BObjectImp( BObjectType type );
|
|
virtual ~BObjectImp();
|
|
#endif
|
|
|
|
|
|
// Class Machinery:
|
|
static BObjectImp* unpack( const char* pstr );
|
|
static BObjectImp* unpack( std::istream& is );
|
|
bool isa( BObjectType type ) const;
|
|
BObjectType type() const;
|
|
#if BOBJECTIMP_DEBUG
|
|
unsigned int instance() const { return instance_; }
|
|
#endif
|
|
static const char* typestr( BObjectType typ );
|
|
|
|
virtual BObjectImp* copy() const = 0;
|
|
virtual std::string getStringRep() const = 0;
|
|
virtual std::string getFormattedStringRep() const;
|
|
|
|
virtual size_t sizeEstimate() const = 0;
|
|
virtual const char* typeOf() const;
|
|
virtual u8 typeOfInt() const;
|
|
|
|
|
|
virtual std::string pack() const;
|
|
virtual void packonto( std::string& os ) const;
|
|
virtual void printOn( std::ostream& ) const;
|
|
|
|
virtual bool operator==( const BObjectImp& objimp ) const;
|
|
virtual bool operator<( const BObjectImp& objimp ) const;
|
|
virtual bool operator<=( const BObjectImp& objimp ) const;
|
|
virtual bool operator>( const BObjectImp& objimp ) const;
|
|
virtual bool operator>=( const BObjectImp& objimp ) const;
|
|
virtual bool operator!=( const BObjectImp& objimp ) const;
|
|
|
|
virtual BObjectImp* selfIsObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfIsObj( const BObjectImp& objimp ) const;
|
|
|
|
virtual BObjectImp* selfPlusObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfPlusObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfPlusObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfPlusObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfPlusObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfPlusObj( const ObjArray& objimp ) const;
|
|
virtual void selfPlusObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfPlusObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfPlusObj( BLong& objimp, BObject& obj );
|
|
virtual void selfPlusObj( Double& objimp, BObject& obj );
|
|
virtual void selfPlusObj( String& objimp, BObject& obj );
|
|
virtual void selfPlusObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfMinusObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfMinusObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfMinusObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfMinusObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfMinusObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfMinusObj( const ObjArray& objimp ) const;
|
|
virtual void selfMinusObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfMinusObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfMinusObj( BLong& objimp, BObject& obj );
|
|
virtual void selfMinusObj( Double& objimp, BObject& obj );
|
|
virtual void selfMinusObj( String& objimp, BObject& obj );
|
|
virtual void selfMinusObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfTimesObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfTimesObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfTimesObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfTimesObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfTimesObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfTimesObj( const ObjArray& objimp ) const;
|
|
virtual void selfTimesObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfTimesObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfTimesObj( BLong& objimp, BObject& obj );
|
|
virtual void selfTimesObj( Double& objimp, BObject& obj );
|
|
virtual void selfTimesObj( String& objimp, BObject& obj );
|
|
virtual void selfTimesObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfDividedByObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfDividedByObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfDividedByObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfDividedByObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfDividedByObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfDividedByObj( const ObjArray& objimp ) const;
|
|
virtual void selfDividedByObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfDividedByObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfDividedByObj( BLong& objimp, BObject& obj );
|
|
virtual void selfDividedByObj( Double& objimp, BObject& obj );
|
|
virtual void selfDividedByObj( String& objimp, BObject& obj );
|
|
virtual void selfDividedByObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfModulusObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfModulusObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfModulusObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfModulusObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfModulusObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfModulusObj( const ObjArray& objimp ) const;
|
|
virtual void selfModulusObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfModulusObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfModulusObj( BLong& objimp, BObject& obj );
|
|
virtual void selfModulusObj( Double& objimp, BObject& obj );
|
|
virtual void selfModulusObj( String& objimp, BObject& obj );
|
|
virtual void selfModulusObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfBitShiftRightObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftRightObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftRightObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftRightObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftRightObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftRightObj( const ObjArray& objimp ) const;
|
|
virtual void selfBitShiftRightObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitShiftRightObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitShiftRightObj( BLong& objimp, BObject& obj );
|
|
virtual void selfBitShiftRightObj( Double& objimp, BObject& obj );
|
|
virtual void selfBitShiftRightObj( String& objimp, BObject& obj );
|
|
virtual void selfBitShiftRightObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfBitShiftLeftObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftLeftObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftLeftObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftLeftObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftLeftObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfBitShiftLeftObj( const ObjArray& objimp ) const;
|
|
virtual void selfBitShiftLeftObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitShiftLeftObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitShiftLeftObj( BLong& objimp, BObject& obj );
|
|
virtual void selfBitShiftLeftObj( Double& objimp, BObject& obj );
|
|
virtual void selfBitShiftLeftObj( String& objimp, BObject& obj );
|
|
virtual void selfBitShiftLeftObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfBitAndObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitAndObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitAndObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfBitAndObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfBitAndObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfBitAndObj( const ObjArray& objimp ) const;
|
|
virtual void selfBitAndObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitAndObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitAndObj( BLong& objimp, BObject& obj );
|
|
virtual void selfBitAndObj( Double& objimp, BObject& obj );
|
|
virtual void selfBitAndObj( String& objimp, BObject& obj );
|
|
virtual void selfBitAndObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfBitXorObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitXorObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitXorObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfBitXorObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfBitXorObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfBitXorObj( const ObjArray& objimp ) const;
|
|
virtual void selfBitXorObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitXorObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitXorObj( BLong& objimp, BObject& obj );
|
|
virtual void selfBitXorObj( Double& objimp, BObject& obj );
|
|
virtual void selfBitXorObj( String& objimp, BObject& obj );
|
|
virtual void selfBitXorObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* selfBitOrObjImp( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitOrObj( const BObjectImp& objimp ) const;
|
|
virtual BObjectImp* selfBitOrObj( const BLong& objimp ) const;
|
|
virtual BObjectImp* selfBitOrObj( const Double& objimp ) const;
|
|
virtual BObjectImp* selfBitOrObj( const String& objimp ) const;
|
|
virtual BObjectImp* selfBitOrObj( const ObjArray& objimp ) const;
|
|
virtual void selfBitOrObjImp( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitOrObj( BObjectImp& objimp, BObject& obj );
|
|
virtual void selfBitOrObj( BLong& objimp, BObject& obj );
|
|
virtual void selfBitOrObj( Double& objimp, BObject& obj );
|
|
virtual void selfBitOrObj( String& objimp, BObject& obj );
|
|
virtual void selfBitOrObj( ObjArray& objimp, BObject& obj );
|
|
|
|
virtual BObjectImp* bitnot() const;
|
|
|
|
virtual BObjectRef operDotPlus( const char* name );
|
|
virtual BObjectRef operDotMinus( const char* name );
|
|
virtual BObjectRef operDotQMark( const char* name );
|
|
|
|
virtual void operInsertInto( BObject& obj, const BObjectImp& objimp );
|
|
|
|
virtual void operPlusEqual( BObject& obj, BObjectImp& objimp );
|
|
virtual void operMinusEqual( BObject& obj, BObjectImp& objimp );
|
|
virtual void operTimesEqual( BObject& obj, BObjectImp& objimp );
|
|
virtual void operDivideEqual( BObject& obj, BObjectImp& objimp );
|
|
virtual void operModulusEqual( BObject& obj, BObjectImp& objimp );
|
|
|
|
virtual BObject operator-() const;
|
|
|
|
virtual char /*BObjectRef */ member( const BObject& obj ) const;
|
|
virtual char /*BObjectImp* */ str_member( const std::string& membername ) const;
|
|
|
|
virtual BObjectImp* call_method( const char* methodname, Executor& ex );
|
|
virtual BObjectImp* call_method_id( const int id, Executor& ex, bool forcebuiltin = false );
|
|
virtual BObjectRef set_member( const char* membername, BObjectImp* valueimp, bool copy );
|
|
virtual BObjectRef get_member( const char* membername );
|
|
virtual BObjectRef get_member_id( const int id ); // test id
|
|
virtual BObjectRef set_member_id( const int id, BObjectImp* valueimp, bool copy ); // test id
|
|
|
|
virtual BObjectRef OperSubscript( const BObject& obj );
|
|
virtual BObjectRef OperMultiSubscript( std::stack<BObjectRef>& indices );
|
|
virtual BObjectRef OperMultiSubscriptAssign( std::stack<BObjectRef>& indices,
|
|
BObjectImp* target );
|
|
|
|
virtual bool isTrue() const;
|
|
virtual long contains( const BObjectImp& objimp ) const;
|
|
|
|
virtual BObjectImp* array_assign( BObjectImp* idx, BObjectImp* target, bool copy );
|
|
|
|
virtual BObjectImp* inverse() const;
|
|
|
|
virtual void selfPlusPlus();
|
|
virtual void selfMinusMinus();
|
|
|
|
virtual ContIterator* createIterator( BObject* pIterVal );
|
|
|
|
friend std::ostream& operator<<( std::ostream&, const BObjectImp& );
|
|
|
|
private:
|
|
BObjectType type_;
|
|
#if BOBJECTIMP_DEBUG
|
|
unsigned int instance_;
|
|
static unsigned int instances_;
|
|
static Clib::SpinLock bobjectimp_lock;
|
|
#endif
|
|
};
|
|
|
|
inline char /*BObjectRef */ BObjectImp::member( const BObject& ) const
|
|
{
|
|
return 0;
|
|
}
|
|
inline char /*BObjectImp* */ BObjectImp::str_member( const std::string& ) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
inline bool BObjectImp::isa( BObjectType type ) const
|
|
{
|
|
return ( type == type_ );
|
|
}
|
|
|
|
inline BObjectImp::BObjectType BObjectImp::type() const
|
|
{
|
|
return type_;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
template <typename T> // static_assert(false) is not valid, need a typedependent false
|
|
struct always_false : std::false_type
|
|
{
|
|
};
|
|
} // namespace
|
|
// accepts const/non-const BObjectImp pointers
|
|
template <typename T, typename I>
|
|
requires std::is_base_of_v<BObjectImp, std::remove_cv_t<std::remove_pointer_t<I>>>
|
|
T* impptrIf( I* objimp )
|
|
{
|
|
if ( !objimp )
|
|
return nullptr;
|
|
#define impif_test( type ) std::is_same_v<std::remove_const_t<T>, type>
|
|
#define impif_return( ot ) return objimp->isa( ot ) ? static_cast<T*>( objimp ) : nullptr
|
|
#define impif_i( ot, type ) \
|
|
if constexpr ( impif_test( type ) ) \
|
|
impif_return( ot )
|
|
#define impif_e( ot, type ) else if constexpr ( impif_test( type ) ) impif_return( ot )
|
|
|
|
impif_i( BObjectImp::OTUninit, UninitObject );
|
|
impif_e( BObjectImp::OTString, String );
|
|
impif_e( BObjectImp::OTLong, BLong );
|
|
impif_e( BObjectImp::OTDouble, Double );
|
|
impif_e( BObjectImp::OTArray, ObjArray );
|
|
impif_e( BObjectImp::OTError, BError );
|
|
impif_e( BObjectImp::OTDictionary, BDictionary );
|
|
impif_e( BObjectImp::OTStruct, BStruct );
|
|
impif_e( BObjectImp::OTBoolean, BBoolean );
|
|
impif_e( BObjectImp::OTFuncRef, BFunctionRef );
|
|
// BClassInstance objects are never given to scripts directly, so no need for
|
|
// inclusion here (so far...)
|
|
impif_e( BObjectImp::OTClassInstanceRef, BClassInstanceRef );
|
|
impif_e( BObjectImp::OTContinuation, BContinuation );
|
|
impif_e( BObjectImp::OTSpread, BSpread );
|
|
impif_e( BObjectImp::OTRegExp, BRegExp );
|
|
impif_e( BObjectImp::OTSpecialUserFuncJump, BSpecialUserFuncJump );
|
|
impif_e( BObjectImp::OTApplicObj, BApplicObjBase );
|
|
else static_assert( always_false<T>::value, "unsupported type" );
|
|
#undef impif_i
|
|
#undef impif_e
|
|
#undef impif_return
|
|
#undef impif_test
|
|
}
|
|
|
|
class BObject : public ref_counted
|
|
{
|
|
public:
|
|
explicit BObject( BObjectImp* objimp ) : ref_counted(), objimp( objimp ) { passert( objimp ); }
|
|
BObject( const BObject& obj ) : ref_counted(), objimp( obj.objimp ) {}
|
|
~BObject() override = default;
|
|
BObject& operator=( const BObject& ) = delete;
|
|
size_t sizeEstimate() const;
|
|
|
|
void* operator new( std::size_t len );
|
|
void operator delete( void* );
|
|
|
|
bool operator!=( const BObject& obj ) const;
|
|
bool operator==( const BObject& obj ) const;
|
|
bool operator<( const BObject& obj ) const;
|
|
bool operator<=( const BObject& obj ) const;
|
|
bool operator>( const BObject& obj ) const;
|
|
bool operator>=( const BObject& obj ) const;
|
|
|
|
BObjectImp* operator->() const { return objimp.get(); }
|
|
bool isTrue() const { return objimp->isTrue(); }
|
|
|
|
BObject* clone() const;
|
|
|
|
bool isa( BObjectImp::BObjectType type ) const;
|
|
|
|
friend std::ostream& operator<<( std::ostream&, const BObject& );
|
|
void printOn( std::ostream& ) const;
|
|
|
|
template <typename T = BObjectImp>
|
|
T* impptr();
|
|
template <typename T = BObjectImp>
|
|
const T* impptr() const;
|
|
template <typename T>
|
|
T* impptr_if(); // also als freestanding function available
|
|
template <typename T>
|
|
T* impptr_if() const; // also als freestanding function available
|
|
|
|
template <typename T = BObjectImp>
|
|
T& impref();
|
|
template <typename T = BObjectImp>
|
|
const T& impref() const;
|
|
|
|
virtual void setimp( BObjectImp* imp );
|
|
|
|
private:
|
|
ref_ptr<BObjectImp> objimp;
|
|
};
|
|
|
|
class BConstObject : public BObject
|
|
{
|
|
public:
|
|
explicit BConstObject( BObjectImp* objimp ) : BObject( objimp ) {}
|
|
~BConstObject() override = default;
|
|
void setimp( BObjectImp* ) override { /* do nothing */ };
|
|
// This class does not use a specific fixed allocator, sharing the BObject
|
|
// one. Do not add new members to this class.
|
|
};
|
|
|
|
using BObjectImpRefVec = std::vector<ref_ptr<BObjectImp>>;
|
|
|
|
extern Clib::fixed_allocator<sizeof( BObject ), 256> bobject_alloc;
|
|
|
|
inline void* BObject::operator new( std::size_t /*len*/ )
|
|
{
|
|
return bobject_alloc.allocate();
|
|
}
|
|
|
|
inline void BObject::operator delete( void* p )
|
|
{
|
|
bobject_alloc.deallocate( p );
|
|
}
|
|
|
|
inline bool BObject::isa( BObjectImp::BObjectType type ) const
|
|
{
|
|
return objimp->isa( type );
|
|
}
|
|
|
|
template <typename T>
|
|
inline T* BObject::impptr()
|
|
{
|
|
return static_cast<T*>( objimp.get() );
|
|
}
|
|
|
|
template <typename T>
|
|
inline const T* BObject::impptr() const
|
|
{
|
|
return static_cast<T*>( objimp.get() );
|
|
}
|
|
|
|
template <typename T>
|
|
T* BObject::impptr_if()
|
|
{
|
|
return impptrIf<T>( objimp.get() );
|
|
}
|
|
|
|
template <typename T>
|
|
T* BObject::impptr_if() const
|
|
{
|
|
return impptrIf<T>( objimp.get() );
|
|
}
|
|
|
|
template <typename T>
|
|
inline T& BObject::impref()
|
|
{
|
|
return static_cast<T&>( *objimp );
|
|
}
|
|
template <typename T>
|
|
inline const T& BObject::impref() const
|
|
{
|
|
return static_cast<T&>( *objimp );
|
|
}
|
|
inline void BObject::setimp( BObjectImp* imp )
|
|
{
|
|
objimp.set( imp );
|
|
}
|
|
|
|
class BObjectRef : public ref_ptr<BObject>
|
|
{
|
|
public:
|
|
explicit BObjectRef( BObject* pobj = nullptr ) : ref_ptr<BObject>( pobj ) {}
|
|
explicit BObjectRef( BObjectImp* pimp ) : ref_ptr<BObject>( new BObject( pimp ) ) {}
|
|
void set( BObject* obj ) { ref_ptr<BObject>::set( obj ); }
|
|
void set( BObjectImp* imp ) { ref_ptr<BObject>::set( new BObject( imp ) ); }
|
|
size_t sizeEstimate() const;
|
|
};
|
|
|
|
|
|
class UninitObject final : public BObjectImp
|
|
{
|
|
public:
|
|
UninitObject();
|
|
UninitObject( const UninitObject& i );
|
|
|
|
static UninitObject* SharedInstance;
|
|
static ref_ptr<BObjectImp> SharedInstanceOwner;
|
|
static BObjectRef SharedInstanceRef;
|
|
|
|
BObjectImp* copy() const override;
|
|
size_t sizeEstimate() const override;
|
|
std::string getStringRep() const override { return "<uninitialized object>"; }
|
|
void printOn( std::ostream& os ) const override;
|
|
|
|
bool isTrue() const override;
|
|
bool operator==( const BObjectImp& objimp ) const override;
|
|
bool operator<( const BObjectImp& objimp ) const override;
|
|
|
|
void* operator new( std::size_t len );
|
|
void operator delete( void* );
|
|
|
|
static UninitObject* create() { return SharedInstance; }
|
|
static void ReleaseSharedInstance()
|
|
{
|
|
SharedInstanceOwner.clear();
|
|
SharedInstance = nullptr;
|
|
}
|
|
};
|
|
extern Clib::fixed_allocator<sizeof( UninitObject ), 256> uninit_alloc;
|
|
|
|
inline void* UninitObject::operator new( std::size_t /*len*/ )
|
|
{
|
|
return uninit_alloc.allocate();
|
|
}
|
|
|
|
inline void UninitObject::operator delete( void* p )
|
|
{
|
|
uninit_alloc.deallocate( p );
|
|
}
|
|
class ObjArray final : public BObjectImp
|
|
{
|
|
public:
|
|
using NameCont = std::vector<std::string>;
|
|
using name_iterator = NameCont::iterator;
|
|
using const_name_iterator = NameCont::const_iterator;
|
|
|
|
using Cont = std::vector<BObjectRef>;
|
|
using iterator = Cont::iterator;
|
|
using const_iterator = Cont::const_iterator;
|
|
|
|
NameCont name_arr;
|
|
Cont ref_arr;
|
|
|
|
ObjArray();
|
|
ObjArray( const ObjArray& i ); // copy constructor
|
|
|
|
void packonto( std::string& str ) const override;
|
|
static BObjectImp* unpack( std::istream& is );
|
|
size_t sizeEstimate() const override;
|
|
BObjectImp* copy() const override;
|
|
|
|
BObjectRef operDotPlus( const char* name ) override;
|
|
long contains( const BObjectImp& imp ) const override;
|
|
void operInsertInto( BObject& obj, const BObjectImp& objimp ) override;
|
|
BObjectImp* selfPlusObjImp( const BObjectImp& other ) const override;
|
|
BObjectImp* selfPlusObj( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const Double& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const String& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const ObjArray& objimp ) const override;
|
|
void selfPlusObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfPlusObj( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfPlusObj( BLong& objimp, BObject& obj ) override;
|
|
void selfPlusObj( Double& objimp, BObject& obj ) override;
|
|
void selfPlusObj( String& objimp, BObject& obj ) override;
|
|
void selfPlusObj( ObjArray& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* call_method( const char* methodname, Executor& ex ) override;
|
|
BObjectImp* call_method_id( const int id, Executor& ex, bool forcebuiltin = false ) override;
|
|
BObjectRef set_member( const char* membername, BObjectImp* value, bool copy ) override;
|
|
BObjectRef get_member( const char* membername ) override;
|
|
|
|
void addElement( BObjectImp* imp );
|
|
|
|
const BObjectImp* imp_at( unsigned index ) const; // 1-based
|
|
|
|
std::string getStringRep() const override;
|
|
void printOn( std::ostream& os ) const override;
|
|
|
|
BObjectImp* array_assign( BObjectImp* idx, BObjectImp* target, bool copy ) override;
|
|
BObjectRef OperSubscript( const BObject& obj ) override;
|
|
BObjectRef OperMultiSubscript( std::stack<BObjectRef>& indices ) override;
|
|
|
|
bool operator==( const BObjectImp& objimp ) const override;
|
|
|
|
ContIterator* createIterator( BObject* pIterVal ) override;
|
|
|
|
protected:
|
|
explicit ObjArray( BObjectType type );
|
|
void deepcopy();
|
|
};
|
|
|
|
class BLong final : public BObjectImp
|
|
{
|
|
using base = BObjectImp;
|
|
|
|
public:
|
|
#if BOBJECTIMP_DEBUG
|
|
explicit BLong( int lval = 0L );
|
|
BLong( const BLong& L );
|
|
#else
|
|
explicit BLong( int lval = 0L ) : BObjectImp( OTLong ), lval_( static_cast<int>( lval ) ) {}
|
|
BLong( const BLong& L ) : BObjectImp( OTLong ), lval_( L.lval_ ) {}
|
|
#endif
|
|
private:
|
|
~BLong() override = default;
|
|
|
|
public:
|
|
void* operator new( std::size_t len );
|
|
void operator delete( void* );
|
|
void operator delete( void*, size_t );
|
|
|
|
static BObjectImp* unpack( std::istream& is );
|
|
static std::string pack( int val );
|
|
void packonto( std::string& os ) const override;
|
|
size_t sizeEstimate() const override;
|
|
|
|
int value() const { return lval_; }
|
|
int increment() { return ++lval_; }
|
|
|
|
public: // Class Machinery
|
|
BObjectImp* copy() const override;
|
|
BObjectImp* inverse() const override { return new BLong( -lval_ ); }
|
|
void copyvalue( const BLong& ni ) { lval_ = ni.lval_; }
|
|
bool isTrue() const override;
|
|
bool operator==( const BObjectImp& objimp ) const override;
|
|
bool operator<( const BObjectImp& objimp ) const override;
|
|
|
|
BObjectImp* selfPlusObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const Double& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const String& objimp ) const override;
|
|
void selfPlusObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfPlusObj( BLong& objimp, BObject& obj ) override;
|
|
void selfPlusObj( Double& objimp, BObject& obj ) override;
|
|
void selfPlusObj( String& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfMinusObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfMinusObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfMinusObj( const Double& objimp ) const override;
|
|
BObjectImp* selfMinusObj( const String& objimp ) const override;
|
|
void selfMinusObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfMinusObj( BLong& objimp, BObject& obj ) override;
|
|
void selfMinusObj( Double& objimp, BObject& obj ) override;
|
|
void selfMinusObj( String& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfTimesObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfTimesObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfTimesObj( const Double& objimp ) const override;
|
|
void selfTimesObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfTimesObj( BLong& objimp, BObject& obj ) override;
|
|
void selfTimesObj( Double& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfDividedByObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfDividedByObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfDividedByObj( const Double& objimp ) const override;
|
|
void selfDividedByObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfDividedByObj( BLong& objimp, BObject& obj ) override;
|
|
void selfDividedByObj( Double& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfModulusObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfModulusObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfModulusObj( const Double& objimp ) const override;
|
|
void selfModulusObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfModulusObj( BLong& objimp, BObject& obj ) override;
|
|
void selfModulusObj( Double& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfBitShiftRightObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfBitShiftRightObj( const BLong& objimp ) const override;
|
|
void selfBitShiftRightObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfBitShiftRightObj( BLong& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfBitShiftLeftObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfBitShiftLeftObj( const BLong& objimp ) const override;
|
|
void selfBitShiftLeftObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfBitShiftLeftObj( BLong& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfBitAndObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfBitAndObj( const BLong& objimp ) const override;
|
|
void selfBitAndObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfBitAndObj( BLong& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfBitXorObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfBitXorObj( const BLong& objimp ) const override;
|
|
void selfBitXorObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfBitXorObj( BLong& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfBitOrObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfBitOrObj( const BLong& objimp ) const override;
|
|
void selfBitOrObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfBitOrObj( BLong& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* bitnot() const override;
|
|
|
|
void selfPlusPlus() override { ++lval_; }
|
|
void selfMinusMinus() override { --lval_; }
|
|
|
|
std::string getStringRep() const override;
|
|
void printOn( std::ostream& ) const override;
|
|
|
|
protected:
|
|
int lval_;
|
|
};
|
|
|
|
extern Clib::fixed_allocator<sizeof( BLong ), 256> blong_alloc;
|
|
inline void* BLong::operator new( std::size_t len )
|
|
{
|
|
(void)len;
|
|
passert_paranoid( len == sizeof( BLong ) );
|
|
return blong_alloc.allocate();
|
|
}
|
|
inline void BLong::operator delete( void* p )
|
|
{
|
|
blong_alloc.deallocate( p );
|
|
}
|
|
inline void BLong::operator delete( void* p, size_t /*len*/ )
|
|
{
|
|
blong_alloc.deallocate( p );
|
|
}
|
|
|
|
class Double final : public BObjectImp
|
|
{
|
|
using base = BObjectImp;
|
|
|
|
public:
|
|
explicit Double( double dval = 0.0 ) : BObjectImp( OTDouble ), dval_( dval ) {}
|
|
Double( const Double& dbl ) : BObjectImp( OTDouble ), dval_( dbl.dval_ ) {}
|
|
|
|
static std::string double_to_string( double val );
|
|
|
|
protected:
|
|
~Double() override = default;
|
|
|
|
public:
|
|
void* operator new( std::size_t len );
|
|
void operator delete( void* );
|
|
|
|
static BObjectImp* unpack( std::istream& is );
|
|
void packonto( std::string& str ) const override;
|
|
size_t sizeEstimate() const override;
|
|
|
|
double value() const { return dval_; }
|
|
void copyvalue( const Double& dbl ) { dval_ = dbl.dval_; }
|
|
double increment() { return ++dval_; }
|
|
|
|
public: // Class Machinery
|
|
bool isTrue() const override { return ( dval_ != 0.0 ); }
|
|
BObjectImp* copy() const override { return new Double( *this ); }
|
|
bool operator==( const BObjectImp& objimp ) const override;
|
|
bool operator<( const BObjectImp& objimp ) const override;
|
|
|
|
BObjectImp* selfPlusObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const Double& objimp ) const override;
|
|
BObjectImp* selfPlusObj( const String& objimp ) const override;
|
|
void selfPlusObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfPlusObj( BLong& objimp, BObject& obj ) override;
|
|
void selfPlusObj( Double& objimp, BObject& obj ) override;
|
|
void selfPlusObj( String& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfMinusObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfMinusObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfMinusObj( const Double& objimp ) const override;
|
|
BObjectImp* selfMinusObj( const String& objimp ) const override;
|
|
void selfMinusObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfMinusObj( BLong& objimp, BObject& obj ) override;
|
|
void selfMinusObj( Double& objimp, BObject& obj ) override;
|
|
void selfMinusObj( String& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfTimesObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfTimesObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfTimesObj( const Double& objimp ) const override;
|
|
void selfTimesObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfTimesObj( BLong& objimp, BObject& obj ) override;
|
|
void selfTimesObj( Double& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* selfDividedByObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfDividedByObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfDividedByObj( const Double& objimp ) const override;
|
|
void selfDividedByObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfDividedByObj( BLong& objimp, BObject& obj ) override;
|
|
void selfDividedByObj( Double& objimp, BObject& obj ) override;
|
|
void selfPlusPlus() override { ++dval_; }
|
|
void selfMinusMinus() override { --dval_; }
|
|
|
|
BObjectImp* selfModulusObjImp( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfModulusObj( const BLong& objimp ) const override;
|
|
BObjectImp* selfModulusObj( const Double& objimp ) const override;
|
|
void selfModulusObjImp( BObjectImp& objimp, BObject& obj ) override;
|
|
void selfModulusObj( BLong& objimp, BObject& obj ) override;
|
|
void selfModulusObj( Double& objimp, BObject& obj ) override;
|
|
|
|
BObjectImp* inverse() const override { return new Double( -dval_ ); }
|
|
std::string getStringRep() const override;
|
|
void printOn( std::ostream& ) const override;
|
|
|
|
private:
|
|
double dval_;
|
|
};
|
|
|
|
extern Clib::fixed_allocator<sizeof( Double ), 256> double_alloc;
|
|
inline void* Double::operator new( std::size_t len )
|
|
{
|
|
(void)len;
|
|
passert_paranoid( len == sizeof( Double ) );
|
|
return double_alloc.allocate();
|
|
}
|
|
inline void Double::operator delete( void* p )
|
|
{
|
|
double_alloc.deallocate( p );
|
|
}
|
|
|
|
class BBoolean final : public BObjectImp
|
|
{
|
|
using base = BObjectImp;
|
|
|
|
public:
|
|
#if BOBJECTIMP_DEBUG
|
|
explicit BBoolean( bool bval = false );
|
|
BBoolean( const BBoolean& B );
|
|
#else
|
|
explicit BBoolean( bool bval = false ) : BObjectImp( OTBoolean ), bval_( bval ) {}
|
|
BBoolean( const BBoolean& B ) : BBoolean( B.bval_ ) {}
|
|
#endif
|
|
private:
|
|
~BBoolean() override = default;
|
|
|
|
public:
|
|
static BObjectImp* unpack( std::istream& is );
|
|
void packonto( std::string& os ) const override;
|
|
size_t sizeEstimate() const override;
|
|
|
|
bool value() const { return bval_; }
|
|
|
|
public: // Class Machinery
|
|
BObjectImp* copy() const override;
|
|
bool isTrue() const override;
|
|
bool operator==( const BObjectImp& objimp ) const override;
|
|
|
|
std::string getStringRep() const override;
|
|
void printOn( std::ostream& ) const override;
|
|
|
|
private:
|
|
bool bval_;
|
|
};
|
|
|
|
class BFunctionRef final : public BObjectImp
|
|
{
|
|
using base = BObjectImp;
|
|
|
|
public:
|
|
BFunctionRef( ref_ptr<EScriptProgram> program, unsigned int pid,
|
|
unsigned function_reference_index, std::weak_ptr<ValueStackCont> globals,
|
|
ValueStackCont&& captures );
|
|
BFunctionRef( const BFunctionRef& B );
|
|
|
|
private:
|
|
~BFunctionRef() override = default;
|
|
|
|
public:
|
|
size_t sizeEstimate() const override;
|
|
bool validCall( const int id, Executor& ex, Instruction* inst ) const;
|
|
bool validCall( const char* methodname, Executor& ex, Instruction* inst ) const;
|
|
int numParams() const;
|
|
unsigned pc() const;
|
|
bool variadic() const;
|
|
ref_ptr<EScriptProgram> prog() const;
|
|
unsigned int pid() const;
|
|
unsigned class_index() const;
|
|
bool constructor() const;
|
|
bool class_method() const;
|
|
const std::vector<unsigned>& default_parameter_addresses() const;
|
|
int default_parameter_count() const;
|
|
|
|
// Does not consider variadic functions. Caller must handle variadic()
|
|
// explicitly!
|
|
std::pair<int /*min count*/, int /*max count*/> expected_args() const;
|
|
|
|
public: // Class Machinery
|
|
BObjectImp* copy() const override;
|
|
bool isTrue() const override;
|
|
bool operator==( const BObjectImp& objimp ) const override;
|
|
BObjectImp* selfIsObjImp( const BObjectImp& ) const override;
|
|
std::string getStringRep() const override;
|
|
|
|
BObjectImp* call_method( const char* methodname, Executor& ex ) override;
|
|
BObjectImp* call_method_id( const int id, Executor& ex, bool forcebuiltin = false ) override;
|
|
|
|
private:
|
|
// Need to reference the program, not the Executor, as the exec that created
|
|
// this funcref could be destroyed by the time the funcref gets called
|
|
ref_ptr<EScriptProgram> prog_;
|
|
unsigned int original_pid_;
|
|
unsigned function_reference_index_;
|
|
|
|
public:
|
|
std::weak_ptr<ValueStackCont> globals;
|
|
ValueStackCont captures;
|
|
};
|
|
|
|
class BSpread final : public BObjectImp
|
|
{
|
|
public:
|
|
BSpread( BObjectRef obj );
|
|
BSpread( const BSpread& B );
|
|
|
|
private:
|
|
~BSpread() override = default;
|
|
|
|
public:
|
|
size_t sizeEstimate() const override;
|
|
|
|
public: // Class Machinery
|
|
BObjectImp* copy() const override;
|
|
bool isTrue() const override;
|
|
std::string getStringRep() const override;
|
|
|
|
BObjectRef object;
|
|
};
|
|
|
|
// very very special Imp, should never be actually used
|
|
// we need to tell the executor that in certain cases
|
|
// call_method and call_method_id do not return a BObjectImp
|
|
// and the ValueStack should not be modified
|
|
// should not be handled like a "imp" and never be passed to
|
|
// a BObject since its a singleton
|
|
class BSpecialUserFuncJump final : public BObjectImp
|
|
{
|
|
public:
|
|
static BSpecialUserFuncJump* get();
|
|
static void ReleaseSharedInstance();
|
|
|
|
public: // needed minimal imp
|
|
size_t sizeEstimate() const override;
|
|
BObjectImp* copy() const override;
|
|
std::string getStringRep() const override;
|
|
|
|
private:
|
|
BSpecialUserFuncJump();
|
|
~BSpecialUserFuncJump() override = default;
|
|
static std::unique_ptr<BSpecialUserFuncJump> imp_special_userjmp;
|
|
friend std::unique_ptr<BSpecialUserFuncJump> std::make_unique<BSpecialUserFuncJump>();
|
|
friend std::unique_ptr<BSpecialUserFuncJump>::deleter_type;
|
|
};
|
|
|
|
class BApplicObjType
|
|
{
|
|
};
|
|
|
|
class BApplicObjBase : public BObjectImp
|
|
{
|
|
public:
|
|
explicit BApplicObjBase( const BApplicObjType* object_type );
|
|
|
|
const BApplicObjType* object_type() const;
|
|
|
|
public: // Class Machinery
|
|
BObjectImp* copy() const override = 0;
|
|
|
|
std::string getStringRep() const override;
|
|
void printOn( std::ostream& ) const override;
|
|
size_t sizeEstimate() const override = 0;
|
|
|
|
private:
|
|
const BApplicObjType* object_type_;
|
|
};
|
|
|
|
inline BApplicObjBase::BApplicObjBase( const BApplicObjType* object_type )
|
|
: BObjectImp( OTApplicObj ), object_type_( object_type )
|
|
{
|
|
}
|
|
|
|
inline const BApplicObjType* BApplicObjBase::object_type() const
|
|
{
|
|
return object_type_;
|
|
}
|
|
|
|
|
|
template <class T>
|
|
class BApplicObj : public BApplicObjBase
|
|
{
|
|
public:
|
|
explicit BApplicObj( const BApplicObjType* object_type );
|
|
BApplicObj( const BApplicObjType*, T );
|
|
|
|
T& value();
|
|
const T& value() const;
|
|
T* operator->();
|
|
|
|
const char* typeOf() const override = 0;
|
|
u8 typeOfInt() const override = 0;
|
|
BObjectImp* copy() const override = 0;
|
|
size_t sizeEstimate() const override;
|
|
|
|
protected:
|
|
T obj_;
|
|
};
|
|
|
|
template <class T>
|
|
BApplicObj<T>::BApplicObj( const BApplicObjType* object_type ) : BApplicObjBase( object_type )
|
|
{
|
|
}
|
|
|
|
template <class T>
|
|
BApplicObj<T>::BApplicObj( const BApplicObjType* object_type, T obj )
|
|
: BApplicObjBase( object_type ), obj_( std::move( obj ) )
|
|
{
|
|
}
|
|
|
|
template <class T>
|
|
inline size_t BApplicObj<T>::sizeEstimate() const
|
|
{
|
|
return sizeof( BApplicObj<T> );
|
|
}
|
|
|
|
template <class T>
|
|
T& BApplicObj<T>::value()
|
|
{
|
|
return obj_;
|
|
}
|
|
|
|
template <class T>
|
|
const T& BApplicObj<T>::value() const
|
|
{
|
|
return obj_;
|
|
}
|
|
|
|
template <class T>
|
|
T* BApplicObj<T>::operator->()
|
|
{
|
|
return &obj_;
|
|
}
|
|
} // namespace Pol::Bscript
|
|
|
|
template <>
|
|
struct fmt::formatter<Pol::Bscript::BObjectImp> : fmt::ostream_formatter
|
|
{
|
|
};
|
|
template <>
|
|
struct fmt::formatter<Pol::Bscript::BObject> : fmt::ostream_formatter
|
|
{
|
|
};
|
|
#endif
|