Common: reformat (#4720)

* common: format AlignedMalloc.cpp

* common: format AppTrait.h

* common: format Assertions.h

* common: format CheckedStaticBox

* common: format Console

* common: format Dependencies.h

* common: format EmbeddedImage

* common: format EventSource

* common: format Exceptions

* common: format FastFormatString.cpp

* common: format General.h

* common: format InitInterface

* common: format MathUtils.h

* common: format MemsetFast/MemcpyFast

* common: format Mutex.cpp

* common: format PageFaultSource.h

* common: format Path.h

* common: format PathUtils.cpp

* common: format Pcsx2Types.h

* common: format Perf

* common: format PersistentThread.h

* common: format RwMutex

* common: format SafeArray

* common: format ScopedAlloc.h

* common: format ScopedPtrMT.h

* common: format Semaphore.cpp

* common: format StringHelpers

* common: format ThreadTools.cpp

* common: format Threading.h

* common: format ThreadingDialogs

* common: format ThreadingInternal.h

* common: format TraceLog.h

* common: format VirtualMemory.cpp

* common: format pxCheckBox

* common: format pxEvents.h

* common: format pxForwardDefs.h

* common: format pxRadioPanel

* common: format pxStaticText

* common: format pxStreams

* common: format pxTranslate.cpp

* common: format pxWindowTextWriter.cpp

* common: format wxAppWithHelpers

* common: format wxBaseTools.h

* common: format wxGuiTools

* common: format wxHelpers.cpp

* common: format Darwin directory

* common: format Linux directory

* common: format Windows directory

* common: format LnxCpuDetect.cpp

* common: format WinCpuDetect.cpp

* common: format bmi.cpp

* common: format cpudetect.cpp

* common: format cpu_detect_internal.h

* common: format fpu.cpp

* common: format groups.cpp

* common: format instructions.h

* common: format internal.h

* common: format jmp.cpp

* common: format legacy.cpp

* common: format legacy_instructions.h

* common: format legacy_internal.h

* common: format movs.cpp

* common: format simd.cpp

* common: format tools.h

* common: format x86emitter.cpp

* common: format x86types.h

* common: format bmi.h

* common: format dwshift.h

* common: format group1.h group2.h group3.h

* common: format incdec.h

* common: format jmpcall.h

* common: format movs.h

* common: format simd_arithmetic.h

* common: format simd_comparisons.h

* common: format simd_helpers.h

* common: format simd_moremovs.h

* common: format simd_shufflepack.h

* common: format simd_templated_helpers.h

* common: format test.h
This commit is contained in:
Kojin 2021-09-06 14:28:26 -04:00 committed by GitHub
parent f9bf87f50d
commit 13dfceff48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
102 changed files with 13189 additions and 12692 deletions

View File

@ -21,32 +21,33 @@
#include "common/Assertions.h" #include "common/Assertions.h"
#include "common/ScopedAlloc.h" #include "common/ScopedAlloc.h"
void *__fastcall _aligned_malloc(size_t size, size_t align) void* __fastcall _aligned_malloc(size_t size, size_t align)
{ {
pxAssert(align < 0x10000); pxAssert(align < 0x10000);
#if defined(__USE_ISOC11) && !defined(ASAN_WORKAROUND) // not supported yet on gcc 4.9 #if defined(__USE_ISOC11) && !defined(ASAN_WORKAROUND) // not supported yet on gcc 4.9
return aligned_alloc(align, size); return aligned_alloc(align, size);
#else #else
void *result = 0; void* result = 0;
posix_memalign(&result, align, size); posix_memalign(&result, align, size);
return result; return result;
#endif #endif
} }
void *__fastcall pcsx2_aligned_realloc(void *handle, size_t new_size, size_t align, size_t old_size) void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size)
{ {
pxAssert(align < 0x10000); pxAssert(align < 0x10000);
void *newbuf = _aligned_malloc(new_size, align); void* newbuf = _aligned_malloc(new_size, align);
if (newbuf != NULL && handle != NULL) { if (newbuf != NULL && handle != NULL)
{
memcpy(newbuf, handle, std::min(old_size, new_size)); memcpy(newbuf, handle, std::min(old_size, new_size));
_aligned_free(handle); _aligned_free(handle);
} }
return newbuf; return newbuf;
} }
__fi void _aligned_free(void *pmem) __fi void _aligned_free(void* pmem)
{ {
free(pmem); free(pmem);
} }

View File

@ -31,9 +31,9 @@ class Pcsx2AppTraits : public wxGUIAppTraits
public: public:
virtual ~Pcsx2AppTraits() {} virtual ~Pcsx2AppTraits() {}
wxMessageOutput *CreateMessageOutput(); wxMessageOutput* CreateMessageOutput();
#ifdef wxUSE_STDPATHS #ifdef wxUSE_STDPATHS
wxStandardPaths &GetStandardPaths(); wxStandardPaths& GetStandardPaths();
#endif #endif
}; };

View File

@ -27,7 +27,7 @@
#endif #endif
#ifndef wxNullChar #ifndef wxNullChar
#define wxNullChar ((wxChar *)NULL) #define wxNullChar ((wxChar*)NULL)
#endif #endif
// FnChar_t - function name char type; typedef'd in case it ever changes between compilers // FnChar_t - function name char type; typedef'd in case it ever changes between compilers
@ -39,12 +39,12 @@ typedef char FnChar_t;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct DiagnosticOrigin struct DiagnosticOrigin
{ {
const wxChar *srcfile; const wxChar* srcfile;
const FnChar_t *function; const FnChar_t* function;
const wxChar *condition; const wxChar* condition;
int line; int line;
DiagnosticOrigin(const wxChar *_file, int _line, const FnChar_t *_func, const wxChar *_cond = NULL) DiagnosticOrigin(const wxChar* _file, int _line, const FnChar_t* _func, const wxChar* _cond = NULL)
: srcfile(_file) : srcfile(_file)
, function(_func) , function(_func)
, condition(_cond) , condition(_cond)
@ -52,16 +52,16 @@ struct DiagnosticOrigin
{ {
} }
wxString ToString(const wxChar *msg = NULL) const; wxString ToString(const wxChar* msg = NULL) const;
}; };
// Returns ture if the assertion is to trap into the debugger, or false if execution // Returns ture if the assertion is to trap into the debugger, or false if execution
// of the program should continue unimpeded. // of the program should continue unimpeded.
typedef bool pxDoAssertFnType(const DiagnosticOrigin &origin, const wxChar *msg); typedef bool pxDoAssertFnType(const DiagnosticOrigin& origin, const wxChar* msg);
extern pxDoAssertFnType pxAssertImpl_LogIt; extern pxDoAssertFnType pxAssertImpl_LogIt;
extern pxDoAssertFnType *pxDoAssert; extern pxDoAssertFnType* pxDoAssert;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// pxAssert / pxAssertDev // pxAssert / pxAssertDev
@ -159,10 +159,13 @@ extern pxDoAssertFnType *pxDoAssert;
#define pxAssumeDev(cond, msg) (__assume(cond)) #define pxAssumeDev(cond, msg) (__assume(cond))
#define pxFail(msg) \ #define pxFail(msg) \
do { \ do \
{ \
} while (0) } while (0)
#define pxFailDev(msg) \ #define pxFailDev(msg) \
do { \ do \
{ \
} while (0) } while (0)
#endif #endif
@ -188,7 +191,7 @@ extern pxDoAssertFnType *pxDoAssert;
#define IndexBoundsAssumeDev(objname, idx, sze) pxAssumeDev((uint)(idx) < (uint)(sze), \ #define IndexBoundsAssumeDev(objname, idx, sze) pxAssumeDev((uint)(idx) < (uint)(sze), \
pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze))) pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
extern void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg); extern void pxOnAssert(const DiagnosticOrigin& origin, const wxString& msg);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization // jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization
@ -202,7 +205,8 @@ extern void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg);
// //
#ifndef jNO_DEFAULT #ifndef jNO_DEFAULT
#define jNO_DEFAULT \ #define jNO_DEFAULT \
default: { \ default: \
{ \
pxAssumeDev(0, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)"); \ pxAssumeDev(0, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)"); \
break; \ break; \
} }

View File

@ -15,7 +15,7 @@
#include "common/CheckedStaticBox.h" #include "common/CheckedStaticBox.h"
CheckedStaticBox::CheckedStaticBox(wxWindow *parent, int orientation, const wxString &title) CheckedStaticBox::CheckedStaticBox(wxWindow* parent, int orientation, const wxString& title)
: wxPanelWithHelpers(parent, wxVERTICAL) : wxPanelWithHelpers(parent, wxVERTICAL)
, ThisSizer(*new wxStaticBoxSizer(orientation, this)) , ThisSizer(*new wxStaticBoxSizer(orientation, this))
, ThisToggle(*new wxCheckBox(this, wxID_ANY, title, wxPoint(8, 0))) , ThisToggle(*new wxCheckBox(this, wxID_ANY, title, wxPoint(8, 0)))
@ -31,7 +31,7 @@ CheckedStaticBox::CheckedStaticBox(wxWindow *parent, int orientation, const wxSt
// Event handler for click events for the main checkbox (default behavior: enables/disables all child controls) // Event handler for click events for the main checkbox (default behavior: enables/disables all child controls)
// This function can be overridden to implement custom handling of check enable/disable behavior. // This function can be overridden to implement custom handling of check enable/disable behavior.
void CheckedStaticBox::MainToggle_Click(wxCommandEvent &evt) void CheckedStaticBox::MainToggle_Click(wxCommandEvent& evt)
{ {
SetValue(evt.IsChecked()); SetValue(evt.IsChecked());
evt.Skip(); evt.Skip();
@ -41,10 +41,11 @@ void CheckedStaticBox::MainToggle_Click(wxCommandEvent &evt)
// bound to the StaticBox accordingly. // bound to the StaticBox accordingly.
void CheckedStaticBox::SetValue(bool val) void CheckedStaticBox::SetValue(bool val)
{ {
wxWindowList &list = GetChildren(); wxWindowList& list = GetChildren();
for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) { for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter)
wxWindow *current = *iter; {
wxWindow* current = *iter;
if (current != &ThisToggle) if (current != &ThisToggle)
current->Enable(IsEnabled() && val); current->Enable(IsEnabled() && val);
} }
@ -64,10 +65,11 @@ bool CheckedStaticBox::Enable(bool enable)
return false; return false;
bool val = enable && ThisToggle.GetValue(); bool val = enable && ThisToggle.GetValue();
wxWindowList &list = GetChildren(); wxWindowList& list = GetChildren();
for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) { for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter)
wxWindow *current = *iter; {
wxWindow* current = *iter;
if (current != &ThisToggle) if (current != &ThisToggle)
current->Enable(val); current->Enable(val);
} }

View File

@ -22,16 +22,16 @@ class CheckedStaticBox : public wxPanelWithHelpers
typedef wxPanelWithHelpers _parent; typedef wxPanelWithHelpers _parent;
public: public:
wxBoxSizer &ThisSizer; // Boxsizer which holds all child items. wxBoxSizer& ThisSizer; // Boxsizer which holds all child items.
wxCheckBox &ThisToggle; // toggle which can enable/disable all child controls wxCheckBox& ThisToggle; // toggle which can enable/disable all child controls
public: public:
CheckedStaticBox(wxWindow *parent, int orientation, const wxString &title = wxEmptyString); CheckedStaticBox(wxWindow* parent, int orientation, const wxString& title = wxEmptyString);
void SetValue(bool val); void SetValue(bool val);
bool GetValue() const; bool GetValue() const;
bool Enable(bool enable = true); bool Enable(bool enable = true);
public: public:
virtual void MainToggle_Click(wxCommandEvent &evt); virtual void MainToggle_Click(wxCommandEvent& evt);
}; };

View File

@ -26,9 +26,9 @@ static DeclareTls(int) conlog_Indent(0);
static DeclareTls(ConsoleColors) conlog_Color(DefaultConsoleColor); static DeclareTls(ConsoleColors) conlog_Color(DefaultConsoleColor);
#ifdef __POSIX__ #ifdef __POSIX__
static FILE *stdout_fp = stdout; static FILE* stdout_fp = stdout;
void Console_SetStdout(FILE *fp) void Console_SetStdout(FILE* fp)
{ {
stdout_fp = fp; stdout_fp = fp;
} }
@ -41,7 +41,7 @@ void Console_SetStdout(FILE *fp)
// Important! Only Assert and Null console loggers are allowed during C++ startup init (when // Important! Only Assert and Null console loggers are allowed during C++ startup init (when
// the program or DLL first loads). Other log targets rely on the static buffer and a // the program or DLL first loads). Other log targets rely on the static buffer and a
// threaded mutex lock, which are only valid after C++ initialization has finished. // threaded mutex lock, which are only valid after C++ initialization has finished.
void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp) void Console_SetActiveHandler(const IConsoleWriter& writer, FILE* flushfp)
{ {
pxAssertDev( pxAssertDev(
(writer.WriteRaw != NULL) && (writer.DoWriteLn != NULL) && (writer.WriteRaw != NULL) && (writer.DoWriteLn != NULL) &&
@ -59,7 +59,7 @@ void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp)
// Writes text to the Visual Studio Output window (Microsoft Windows only). // Writes text to the Visual Studio Output window (Microsoft Windows only).
// On all other platforms this pipes to Stdout instead. // On all other platforms this pipes to Stdout instead.
void MSW_OutputDebugString(const wxString &text) void MSW_OutputDebugString(const wxString& text)
{ {
#if defined(__WXMSW__) && !defined(__WXMICROWIN__) #if defined(__WXMSW__) && !defined(__WXMICROWIN__)
static bool hasDebugger = wxIsDebuggerRunning(); static bool hasDebugger = wxIsDebuggerRunning();
@ -76,11 +76,11 @@ void MSW_OutputDebugString(const wxString &text)
// ConsoleNull // ConsoleNull
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
static void __concall ConsoleNull_SetTitle(const wxString &title) {} static void __concall ConsoleNull_SetTitle(const wxString& title) {}
static void __concall ConsoleNull_DoSetColor(ConsoleColors color) {} static void __concall ConsoleNull_DoSetColor(ConsoleColors color) {}
static void __concall ConsoleNull_Newline() {} static void __concall ConsoleNull_Newline() {}
static void __concall ConsoleNull_DoWrite(const wxString &fmt) {} static void __concall ConsoleNull_DoWrite(const wxString& fmt) {}
static void __concall ConsoleNull_DoWriteLn(const wxString &fmt) {} static void __concall ConsoleNull_DoWriteLn(const wxString& fmt) {}
const IConsoleWriter ConsoleWriter_Null = const IConsoleWriter ConsoleWriter_Null =
{ {
@ -100,9 +100,10 @@ const IConsoleWriter ConsoleWriter_Null =
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#if defined(__unix__) #if defined(__unix__)
static __fi const char *GetLinuxConsoleColor(ConsoleColors color) static __fi const char* GetLinuxConsoleColor(ConsoleColors color)
{ {
switch (color) { switch (color)
{
case Color_Black: case Color_Black:
case Color_StrongBlack: case Color_StrongBlack:
return "\033[30m\033[1m"; return "\033[30m\033[1m";
@ -157,13 +158,13 @@ static __fi const char *GetLinuxConsoleColor(ConsoleColors color)
#endif #endif
// One possible default write action at startup and shutdown is to use the stdout. // One possible default write action at startup and shutdown is to use the stdout.
static void __concall ConsoleStdout_DoWrite(const wxString &fmt) static void __concall ConsoleStdout_DoWrite(const wxString& fmt)
{ {
MSW_OutputDebugString(fmt); MSW_OutputDebugString(fmt);
} }
// Default write action at startup and shutdown is to use the stdout. // Default write action at startup and shutdown is to use the stdout.
static void __concall ConsoleStdout_DoWriteLn(const wxString &fmt) static void __concall ConsoleStdout_DoWriteLn(const wxString& fmt)
{ {
MSW_OutputDebugString(fmt + L"\n"); MSW_OutputDebugString(fmt + L"\n");
} }
@ -181,7 +182,7 @@ static void __concall ConsoleStdout_DoSetColor(ConsoleColors color)
#endif #endif
} }
static void __concall ConsoleStdout_SetTitle(const wxString &title) static void __concall ConsoleStdout_SetTitle(const wxString& title)
{ {
#if defined(__unix__) #if defined(__unix__)
fputs("\033]0;", stdout_fp); fputs("\033]0;", stdout_fp);
@ -206,12 +207,12 @@ const IConsoleWriter ConsoleWriter_Stdout =
// ConsoleAssert // ConsoleAssert
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
static void __concall ConsoleAssert_DoWrite(const wxString &fmt) static void __concall ConsoleAssert_DoWrite(const wxString& fmt)
{ {
pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt); pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt);
} }
static void __concall ConsoleAssert_DoWriteLn(const wxString &fmt) static void __concall ConsoleAssert_DoWriteLn(const wxString& fmt)
{ {
pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt); pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt);
} }
@ -239,7 +240,7 @@ const IConsoleWriter ConsoleWriter_Assert =
// glob_indent - this parameter is used to specify a global indentation setting. It is used by // glob_indent - this parameter is used to specify a global indentation setting. It is used by
// WriteLn function, but defaults to 0 for Warning and Error calls. Local indentation always // WriteLn function, but defaults to 0 for Warning and Error calls. Local indentation always
// applies to all writes. // applies to all writes.
wxString IConsoleWriter::_addIndentation(const wxString &src, int glob_indent = 0) const wxString IConsoleWriter::_addIndentation(const wxString& src, int glob_indent = 0) const
{ {
const int indent = glob_indent + _imm_indentation; const int indent = glob_indent + _imm_indentation;
if (indent == 0) if (indent == 0)
@ -254,7 +255,7 @@ wxString IConsoleWriter::_addIndentation(const wxString &src, int glob_indent =
// Sets the indentation to be applied to all WriteLn's. The indentation is added to the // Sets the indentation to be applied to all WriteLn's. The indentation is added to the
// primary write, and to any newlines specified within the write. Note that this applies // primary write, and to any newlines specified within the write. Note that this applies
// to calls to WriteLn *only* -- calls to Write bypass the indentation parser. // to calls to WriteLn *only* -- calls to Write bypass the indentation parser.
const IConsoleWriter &IConsoleWriter::SetIndent(int tabcount) const const IConsoleWriter& IConsoleWriter::SetIndent(int tabcount) const
{ {
conlog_Indent += tabcount; conlog_Indent += tabcount;
pxAssert(conlog_Indent >= 0); pxAssert(conlog_Indent >= 0);
@ -271,7 +272,7 @@ IConsoleWriter IConsoleWriter::Indent(int tabcount) const
// Changes the active console color. // Changes the active console color.
// This color will be unset by calls to colored text methods // This color will be unset by calls to colored text methods
// such as ErrorMsg and Notice. // such as ErrorMsg and Notice.
const IConsoleWriter &IConsoleWriter::SetColor(ConsoleColors color) const const IConsoleWriter& IConsoleWriter::SetColor(ConsoleColors color) const
{ {
// Ignore current color requests since, well, the current color is already set. ;) // Ignore current color requests since, well, the current color is already set. ;)
if (color == Color_Current) if (color == Color_Current)
@ -291,7 +292,7 @@ ConsoleColors IConsoleWriter::GetColor() const
} }
// Restores the console color to default (usually black, or low-intensity white if the console uses a black background) // Restores the console color to default (usually black, or low-intensity white if the console uses a black background)
const IConsoleWriter &IConsoleWriter::ClearColor() const const IConsoleWriter& IConsoleWriter::ClearColor() const
{ {
if (conlog_Color != DefaultConsoleColor) if (conlog_Color != DefaultConsoleColor)
DoSetColor(conlog_Color = DefaultConsoleColor); DoSetColor(conlog_Color = DefaultConsoleColor);
@ -303,13 +304,13 @@ const IConsoleWriter &IConsoleWriter::ClearColor() const
// ASCII/UTF8 (char*) // ASCII/UTF8 (char*)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
bool IConsoleWriter::FormatV(const char *fmt, va_list args) const bool IConsoleWriter::FormatV(const char* fmt, va_list args) const
{ {
DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent)); DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent));
return false; return false;
} }
bool IConsoleWriter::WriteLn(const char *fmt, ...) const bool IConsoleWriter::WriteLn(const char* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -319,7 +320,7 @@ bool IConsoleWriter::WriteLn(const char *fmt, ...) const
return false; return false;
} }
bool IConsoleWriter::WriteLn(ConsoleColors color, const char *fmt, ...) const bool IConsoleWriter::WriteLn(ConsoleColors color, const char* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -330,7 +331,7 @@ bool IConsoleWriter::WriteLn(ConsoleColors color, const char *fmt, ...) const
return false; return false;
} }
bool IConsoleWriter::Error(const char *fmt, ...) const bool IConsoleWriter::Error(const char* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -341,7 +342,7 @@ bool IConsoleWriter::Error(const char *fmt, ...) const
return false; return false;
} }
bool IConsoleWriter::Warning(const char *fmt, ...) const bool IConsoleWriter::Warning(const char* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -356,13 +357,13 @@ bool IConsoleWriter::Warning(const char *fmt, ...) const
// Write Variants - Unicode/UTF16 style // Write Variants - Unicode/UTF16 style
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
bool IConsoleWriter::FormatV(const wxChar *fmt, va_list args) const bool IConsoleWriter::FormatV(const wxChar* fmt, va_list args) const
{ {
DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent)); DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent));
return false; return false;
} }
bool IConsoleWriter::WriteLn(const wxChar *fmt, ...) const bool IConsoleWriter::WriteLn(const wxChar* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -372,7 +373,7 @@ bool IConsoleWriter::WriteLn(const wxChar *fmt, ...) const
return false; return false;
} }
bool IConsoleWriter::WriteLn(ConsoleColors color, const wxChar *fmt, ...) const bool IConsoleWriter::WriteLn(ConsoleColors color, const wxChar* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -383,7 +384,7 @@ bool IConsoleWriter::WriteLn(ConsoleColors color, const wxChar *fmt, ...) const
return false; return false;
} }
bool IConsoleWriter::Error(const wxChar *fmt, ...) const bool IConsoleWriter::Error(const wxChar* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -394,7 +395,7 @@ bool IConsoleWriter::Error(const wxChar *fmt, ...) const
return false; return false;
} }
bool IConsoleWriter::Warning(const wxChar *fmt, ...) const bool IConsoleWriter::Warning(const wxChar* fmt, ...) const
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -470,7 +471,8 @@ ConsoleColorScope::~ConsoleColorScope()
void ConsoleColorScope::EnterScope() void ConsoleColorScope::EnterScope()
{ {
if (!m_IsScoped) { if (!m_IsScoped)
{
m_old_color = Console.GetColor(); m_old_color = Console.GetColor();
Console.SetColor(m_newcolor); Console.SetColor(m_newcolor);
m_IsScoped = true; m_IsScoped = true;
@ -491,7 +493,8 @@ ConsoleIndentScope::ConsoleIndentScope(int tabs)
ConsoleIndentScope::~ConsoleIndentScope() ConsoleIndentScope::~ConsoleIndentScope()
{ {
try { try
{
LeaveScope(); LeaveScope();
} }
DESTRUCTOR_CATCHALL DESTRUCTOR_CATCHALL
@ -517,7 +520,8 @@ ConsoleAttrScope::ConsoleAttrScope(ConsoleColors newcolor, int indent)
ConsoleAttrScope::~ConsoleAttrScope() ConsoleAttrScope::~ConsoleAttrScope()
{ {
try { try
{
Console.SetColor(m_old_color); Console.SetColor(m_old_color);
Console.SetIndent(-m_tabsize); Console.SetIndent(-m_tabsize);
} }
@ -552,14 +556,14 @@ NullConsoleWriter NullCon = {};
// Writes to the console using the specified color. This overrides the default color setting // Writes to the console using the specified color. This overrides the default color setting
// for this log. // for this log.
bool ConsoleLogSource::WriteV(ConsoleColors color, const char *fmt, va_list list) const bool ConsoleLogSource::WriteV(ConsoleColors color, const char* fmt, va_list list) const
{ {
ConsoleColorScope cs(color); ConsoleColorScope cs(color);
DoWrite(pxsFmtV(fmt, list).c_str()); DoWrite(pxsFmtV(fmt, list).c_str());
return false; return false;
} }
bool ConsoleLogSource::WriteV(ConsoleColors color, const wxChar *fmt, va_list list) const bool ConsoleLogSource::WriteV(ConsoleColors color, const wxChar* fmt, va_list list) const
{ {
ConsoleColorScope cs(color); ConsoleColorScope cs(color);
DoWrite(pxsFmtV(fmt, list).c_str()); DoWrite(pxsFmtV(fmt, list).c_str());
@ -569,13 +573,13 @@ bool ConsoleLogSource::WriteV(ConsoleColors color, const wxChar *fmt, va_list li
// Writes to the console using the source's default color. Note that the source's default // Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the // color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default. // console's default color is Color_Default.
bool ConsoleLogSource::WriteV(const char *fmt, va_list list) const bool ConsoleLogSource::WriteV(const char* fmt, va_list list) const
{ {
WriteV(DefaultColor, fmt, list); WriteV(DefaultColor, fmt, list);
return false; return false;
} }
bool ConsoleLogSource::WriteV(const wxChar *fmt, va_list list) const bool ConsoleLogSource::WriteV(const wxChar* fmt, va_list list) const
{ {
WriteV(DefaultColor, fmt, list); WriteV(DefaultColor, fmt, list);
return false; return false;

View File

@ -15,9 +15,10 @@
#pragma once #pragma once
#include "StringHelpers.h" #include "common/StringHelpers.h"
enum ConsoleColors { enum ConsoleColors
{
Color_Current = -1, Color_Current = -1,
Color_Default = 0, Color_Default = 0,
@ -72,28 +73,28 @@ struct IConsoleWriter
{ {
// A direct console write, without tabbing or newlines. Useful to devs who want to do quick // A direct console write, without tabbing or newlines. Useful to devs who want to do quick
// logging of various junk; but should *not* be used in production code due. // logging of various junk; but should *not* be used in production code due.
void(__concall *WriteRaw)(const wxString &fmt); void(__concall* WriteRaw)(const wxString& fmt);
// WriteLn implementation for internal use only. Bypasses tabbing, prefixing, and other // WriteLn implementation for internal use only. Bypasses tabbing, prefixing, and other
// formatting. // formatting.
void(__concall *DoWriteLn)(const wxString &fmt); void(__concall* DoWriteLn)(const wxString& fmt);
// SetColor implementation for internal use only. // SetColor implementation for internal use only.
void(__concall *DoSetColor)(ConsoleColors color); void(__concall* DoSetColor)(ConsoleColors color);
// Special implementation of DoWrite that's pretty much for MSVC use only. // Special implementation of DoWrite that's pretty much for MSVC use only.
// All implementations should map to DoWrite, except Stdio which should map to Null. // All implementations should map to DoWrite, except Stdio which should map to Null.
// (This avoids circular/recursive stdio output) // (This avoids circular/recursive stdio output)
void(__concall *DoWriteFromStdout)(const wxString &fmt); void(__concall* DoWriteFromStdout)(const wxString& fmt);
void(__concall *Newline)(); void(__concall* Newline)();
void(__concall *SetTitle)(const wxString &title); void(__concall* SetTitle)(const wxString& title);
// internal value for indentation of individual lines. Use the Indent() member to invoke. // internal value for indentation of individual lines. Use the Indent() member to invoke.
int _imm_indentation; int _imm_indentation;
// For internal use only. // For internal use only.
wxString _addIndentation(const wxString &src, int glob_indent) const; wxString _addIndentation(const wxString& src, int glob_indent) const;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Public members; call these to print stuff to console! // Public members; call these to print stuff to console!
@ -102,23 +103,23 @@ struct IConsoleWriter
// disable logs at compile time using the "0&&action" macro trick. // disable logs at compile time using the "0&&action" macro trick.
ConsoleColors GetColor() const; ConsoleColors GetColor() const;
const IConsoleWriter &SetColor(ConsoleColors color) const; const IConsoleWriter& SetColor(ConsoleColors color) const;
const IConsoleWriter &ClearColor() const; const IConsoleWriter& ClearColor() const;
const IConsoleWriter &SetIndent(int tabcount = 1) const; const IConsoleWriter& SetIndent(int tabcount = 1) const;
IConsoleWriter Indent(int tabcount = 1) const; IConsoleWriter Indent(int tabcount = 1) const;
bool FormatV(const char *fmt, va_list args) const; bool FormatV(const char* fmt, va_list args) const;
bool WriteLn(ConsoleColors color, const char *fmt, ...) const; bool WriteLn(ConsoleColors color, const char* fmt, ...) const;
bool WriteLn(const char *fmt, ...) const; bool WriteLn(const char* fmt, ...) const;
bool Error(const char *fmt, ...) const; bool Error(const char* fmt, ...) const;
bool Warning(const char *fmt, ...) const; bool Warning(const char* fmt, ...) const;
bool FormatV(const wxChar *fmt, va_list args) const; bool FormatV(const wxChar* fmt, va_list args) const;
bool WriteLn(ConsoleColors color, const wxChar *fmt, ...) const; bool WriteLn(ConsoleColors color, const wxChar* fmt, ...) const;
bool WriteLn(const wxChar *fmt, ...) const; bool WriteLn(const wxChar* fmt, ...) const;
bool Error(const wxChar *fmt, ...) const; bool Error(const wxChar* fmt, ...) const;
bool Warning(const wxChar *fmt, ...) const; bool Warning(const wxChar* fmt, ...) const;
bool WriteLn(ConsoleColors color, const wxString fmt, ...) const; bool WriteLn(ConsoleColors color, const wxString fmt, ...) const;
bool WriteLn(const wxString fmt, ...) const; bool WriteLn(const wxString fmt, ...) const;
@ -133,32 +134,32 @@ struct IConsoleWriter
// //
struct NullConsoleWriter struct NullConsoleWriter
{ {
void WriteRaw(const wxString &fmt) {} void WriteRaw(const wxString& fmt) {}
void DoWriteLn(const wxString &fmt) {} void DoWriteLn(const wxString& fmt) {}
void DoSetColor(ConsoleColors color) {} void DoSetColor(ConsoleColors color) {}
void DoWriteFromStdout(const wxString &fmt) {} void DoWriteFromStdout(const wxString& fmt) {}
void Newline() {} void Newline() {}
void SetTitle(const wxString &title) {} void SetTitle(const wxString& title) {}
ConsoleColors GetColor() const { return Color_Current; } ConsoleColors GetColor() const { return Color_Current; }
const NullConsoleWriter &SetColor(ConsoleColors color) const { return *this; } const NullConsoleWriter& SetColor(ConsoleColors color) const { return *this; }
const NullConsoleWriter &ClearColor() const { return *this; } const NullConsoleWriter& ClearColor() const { return *this; }
const NullConsoleWriter &SetIndent(int tabcount = 1) const { return *this; } const NullConsoleWriter& SetIndent(int tabcount = 1) const { return *this; }
NullConsoleWriter Indent(int tabcount = 1) const { return NullConsoleWriter(); } NullConsoleWriter Indent(int tabcount = 1) const { return NullConsoleWriter(); }
bool FormatV(const char *fmt, va_list args) const { return false; } bool FormatV(const char* fmt, va_list args) const { return false; }
bool WriteLn(ConsoleColors color, const char *fmt, ...) const { return false; } bool WriteLn(ConsoleColors color, const char* fmt, ...) const { return false; }
bool WriteLn(const char *fmt, ...) const { return false; } bool WriteLn(const char* fmt, ...) const { return false; }
bool Error(const char *fmt, ...) const { return false; } bool Error(const char* fmt, ...) const { return false; }
bool Warning(const char *fmt, ...) const { return false; } bool Warning(const char* fmt, ...) const { return false; }
bool FormatV(const wxChar *fmt, va_list args) const { return false; } bool FormatV(const wxChar* fmt, va_list args) const { return false; }
bool WriteLn(ConsoleColors color, const wxChar *fmt, ...) const { return false; } bool WriteLn(ConsoleColors color, const wxChar* fmt, ...) const { return false; }
bool WriteLn(const wxChar *fmt, ...) const { return false; } bool WriteLn(const wxChar* fmt, ...) const { return false; }
bool Error(const wxChar *fmt, ...) const { return false; } bool Error(const wxChar* fmt, ...) const { return false; }
bool Warning(const wxChar *fmt, ...) const { return false; } bool Warning(const wxChar* fmt, ...) const { return false; }
bool WriteLn(ConsoleColors color, const wxString fmt, ...) const { return false; } bool WriteLn(ConsoleColors color, const wxString fmt, ...) const { return false; }
bool WriteLn(const wxString fmt, ...) const { return false; } bool WriteLn(const wxString fmt, ...) const { return false; }
@ -234,9 +235,9 @@ public:
extern IConsoleWriter Console; extern IConsoleWriter Console;
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
extern void Console_SetStdout(FILE *fp); extern void Console_SetStdout(FILE* fp);
#endif #endif
extern void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp = NULL); extern void Console_SetActiveHandler(const IConsoleWriter& writer, FILE* flushfp = NULL);
extern const IConsoleWriter ConsoleWriter_Null; extern const IConsoleWriter ConsoleWriter_Null;
extern const IConsoleWriter ConsoleWriter_Stdout; extern const IConsoleWriter ConsoleWriter_Stdout;
@ -250,7 +251,7 @@ extern bool DevConWriterEnabled;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
#define DevCon DevConWriter #define DevCon DevConWriter
#else #else
#define DevCon DevConWriterEnabled &&DevConWriter #define DevCon DevConWriterEnabled&& DevConWriter
#endif #endif
#ifdef PCSX2_DEBUG #ifdef PCSX2_DEBUG

View File

@ -45,11 +45,13 @@ u64 GetPhysicalMemory()
// doesn't change during the course of the program. Thread-safety is // doesn't change during the course of the program. Thread-safety is
// ensured by atomic operations with full-barriers (usually compiled // ensured by atomic operations with full-barriers (usually compiled
// down to XCHG on x86). // down to XCHG on x86).
if (__atomic_load_n(&mem, __ATOMIC_SEQ_CST) == 0) { if (__atomic_load_n(&mem, __ATOMIC_SEQ_CST) == 0)
{
u64 getmem = 0; u64 getmem = 0;
size_t len = sizeof(getmem); size_t len = sizeof(getmem);
int mib[] = {CTL_HW, HW_MEMSIZE}; int mib[] = {CTL_HW, HW_MEMSIZE};
if (sysctl(mib, NELEM(mib), &getmem, &len, NULL, 0) < 0) { if (sysctl(mib, NELEM(mib), &getmem, &len, NULL, 0) < 0)
{
perror("sysctl:"); perror("sysctl:");
} }
__atomic_store_n(&mem, getmem, __ATOMIC_SEQ_CST); __atomic_store_n(&mem, getmem, __ATOMIC_SEQ_CST);
@ -76,14 +78,16 @@ u64 GetTickFrequency()
// by the time denom is not 0, the structure will have been fully // by the time denom is not 0, the structure will have been fully
// updated and no more atomic accesses are necessary. // updated and no more atomic accesses are necessary.
if (__atomic_load_n(&freq, __ATOMIC_SEQ_CST) == 0) { if (__atomic_load_n(&freq, __ATOMIC_SEQ_CST) == 0)
{
mach_timebase_info_data_t info; mach_timebase_info_data_t info;
// mach_timebase_info() is a syscall, very slow, that's why we take // mach_timebase_info() is a syscall, very slow, that's why we take
// pains to only do it once. On x86(-64), the result is guaranteed // pains to only do it once. On x86(-64), the result is guaranteed
// to be info.denom == info.numer == 1 (i.e.: the frequency is 1e9, // to be info.denom == info.numer == 1 (i.e.: the frequency is 1e9,
// which means GetCPUTicks is just nanoseconds). // which means GetCPUTicks is just nanoseconds).
if (mach_timebase_info(&info) != KERN_SUCCESS) { if (mach_timebase_info(&info) != KERN_SUCCESS)
{
abort(); abort();
} }
@ -109,13 +113,15 @@ wxString GetOSVersionString()
static int initialized = 0; static int initialized = 0;
// fetch the OS description only once (thread-safely) // fetch the OS description only once (thread-safely)
if (__atomic_load_n(&initialized, __ATOMIC_SEQ_CST) == 0) { if (__atomic_load_n(&initialized, __ATOMIC_SEQ_CST) == 0)
{
char type[32] = {0}; char type[32] = {0};
char release[32] = {0}; char release[32] = {0};
char arch[32] = {0}; char arch[32] = {0};
#define SYSCTL_GET(var, base, name) \ #define SYSCTL_GET(var, base, name) \
do { \ do \
{ \
int mib[] = {base, name}; \ int mib[] = {base, name}; \
size_t len = sizeof(var); \ size_t len = sizeof(var); \
sysctl(mib, NELEM(mib), NULL, &len, NULL, 0); \ sysctl(mib, NELEM(mib), NULL, &len, NULL, 0); \

View File

@ -45,8 +45,10 @@
static void MACH_CHECK(kern_return_t mach_retval) static void MACH_CHECK(kern_return_t mach_retval)
{ {
switch (mach_retval) { switch (mach_retval)
case KERN_SUCCESS: break; {
case KERN_SUCCESS:
break;
case KERN_ABORTED: // Awoken due reason unrelated to semaphore (e.g. pthread_cancel) case KERN_ABORTED: // Awoken due reason unrelated to semaphore (e.g. pthread_cancel)
pthread_testcancel(); // Unlike sem_wait, mach semaphore ops aren't cancellation points pthread_testcancel(); // Unlike sem_wait, mach semaphore ops aren't cancellation points
// fallthrough // fallthrough
@ -60,7 +62,7 @@ Threading::Semaphore::Semaphore()
{ {
// other platforms explicitly make a thread-private (unshared) semaphore // other platforms explicitly make a thread-private (unshared) semaphore
// here. But it seems Mach doesn't support that. // here. But it seems Mach doesn't support that.
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0)); MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t*)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST); __atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
} }
@ -73,7 +75,7 @@ Threading::Semaphore::~Semaphore()
void Threading::Semaphore::Reset() void Threading::Semaphore::Reset()
{ {
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t)m_sema)); MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t)m_sema));
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0)); MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t*)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST); __atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
} }
@ -85,7 +87,8 @@ void Threading::Semaphore::Post()
void Threading::Semaphore::Post(int multiple) void Threading::Semaphore::Post(int multiple)
{ {
for (int i = 0; i < multiple; ++i) { for (int i = 0; i < multiple; ++i)
{
MACH_CHECK(semaphore_signal(m_sema)); MACH_CHECK(semaphore_signal(m_sema));
} }
__atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST); __atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST);
@ -98,7 +101,7 @@ void Threading::Semaphore::WaitWithoutYield()
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST); __atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
} }
bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout) bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout)
{ {
// This method is the reason why there has to be a special Darwin // This method is the reason why there has to be a special Darwin
// implementation of Semaphore. Note that semaphore_timedwait() is prone // implementation of Semaphore. Note that semaphore_timedwait() is prone
@ -115,8 +118,10 @@ bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout)
mach_timespec_t ts; mach_timespec_t ts;
kern_return_t kr = KERN_ABORTED; kern_return_t kr = KERN_ABORTED;
for (u64 now = mach_absolute_time(), deadline = now + delta; for (u64 now = mach_absolute_time(), deadline = now + delta;
kr == KERN_ABORTED; now = mach_absolute_time()) { kr == KERN_ABORTED; now = mach_absolute_time())
if (now > deadline) { {
if (now > deadline)
{
// timed out by definition // timed out by definition
return false; return false;
} }
@ -135,7 +140,8 @@ bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout)
kr = semaphore_timedwait(m_sema, ts); kr = semaphore_timedwait(m_sema, ts);
} }
if (kr == KERN_OPERATION_TIMED_OUT) { if (kr == KERN_OPERATION_TIMED_OUT)
{
return false; return false;
} }
@ -155,13 +161,19 @@ bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout)
void Threading::Semaphore::Wait() void Threading::Semaphore::Wait()
{ {
#if wxUSE_GUI #if wxUSE_GUI
if (!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL))
{
WaitWithoutYield(); WaitWithoutYield();
} else if (_WaitGui_RecursionGuard(L"Semaphore::Wait")) { }
else if (_WaitGui_RecursionGuard(L"Semaphore::Wait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy); ScopedBusyCursor hourglass(Cursor_ReallyBusy);
WaitWithoutYield(); WaitWithoutYield();
} else { }
while (!WaitWithoutYield(def_yieldgui_interval)) { else
{
while (!WaitWithoutYield(def_yieldgui_interval))
{
YieldToMain(); YieldToMain();
} }
} }
@ -179,19 +191,25 @@ void Threading::Semaphore::Wait()
// false if the wait timed out before the semaphore was signaled, or true if the signal was // false if the wait timed out before the semaphore was signaled, or true if the signal was
// reached prior to timeout. // reached prior to timeout.
// //
bool Threading::Semaphore::Wait(const wxTimeSpan &timeout) bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
{ {
#if wxUSE_GUI #if wxUSE_GUI
if (!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL))
{
return WaitWithoutYield(timeout); return WaitWithoutYield(timeout);
} else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait")) { }
else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy); ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return WaitWithoutYield(timeout); return WaitWithoutYield(timeout);
} else { }
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy ); //ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout)); wxTimeSpan countdown((timeout));
do { do
{
if (WaitWithoutYield(def_yieldgui_interval)) if (WaitWithoutYield(def_yieldgui_interval))
break; break;
YieldToMain(); YieldToMain();
@ -226,7 +244,7 @@ void Threading::Semaphore::WaitNoCancel()
pthread_setcancelstate(oldstate, NULL); pthread_setcancelstate(oldstate, NULL);
} }
void Threading::Semaphore::WaitNoCancel(const wxTimeSpan &timeout) void Threading::Semaphore::WaitNoCancel(const wxTimeSpan& timeout)
{ {
int oldstate; int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);

View File

@ -70,7 +70,8 @@ static u64 getthreadtime(thread_port_t thread)
kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO, kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO,
(thread_info_t)&info, &count); (thread_info_t)&info, &count);
if (kr != KERN_SUCCESS) { if (kr != KERN_SUCCESS)
{
return 0; return 0;
} }
@ -103,7 +104,8 @@ u64 Threading::pxThread::GetCpuTime() const
// m_native_handle to implement it. Return value should be a measure of total time the // m_native_handle to implement it. Return value should be a measure of total time the
// thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(), // thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(),
// which typically would be an OS-provided scalar or some sort). // which typically would be an OS-provided scalar or some sort).
if (!m_native_id) { if (!m_native_id)
{
return 0; return 0;
} }
@ -123,7 +125,7 @@ void Threading::pxThread::_platform_specific_OnCleanupInThread()
} }
// name can be up to 16 bytes // name can be up to 16 bytes
void Threading::SetNameOfCurrentThread(const char *name) void Threading::SetNameOfCurrentThread(const char* name)
{ {
pthread_setname_np(name); pthread_setname_np(name);
} }

View File

@ -62,43 +62,47 @@
// EnumToString(value); // EnumToString(value);
// //
#define ImplementEnumOperators(enumName) \ #define ImplementEnumOperators(enumName) \
static __fi enumName &operator++(enumName &src) \ static __fi enumName& operator++(enumName& src) \
{ \ { \
src = (enumName)((int)src + 1); \ src = (enumName)((int)src + 1); \
return src; \ return src; \
} \ } \
static __fi enumName &operator--(enumName &src) \ \
static __fi enumName& operator--(enumName& src) \
{ \ { \
src = (enumName)((int)src - 1); \ src = (enumName)((int)src - 1); \
return src; \ return src; \
} \ } \
static __fi enumName operator++(enumName &src, int) \ \
static __fi enumName operator++(enumName& src, int) \
{ \ { \
enumName orig = src; \ enumName orig = src; \
src = (enumName)((int)src + 1); \ src = (enumName)((int)src + 1); \
return orig; \ return orig; \
} \ } \
static __fi enumName operator--(enumName &src, int) \ \
static __fi enumName operator--(enumName& src, int) \
{ \ { \
enumName orig = src; \ enumName orig = src; \
src = (enumName)((int)src - 1); \ src = (enumName)((int)src - 1); \
return orig; \ return orig; \
} \ } \
\ \
static __fi bool operator<(const enumName &left, const pxEnumEnd_t &) { return (int)left < enumName##_COUNT; } \ static __fi bool operator<(const enumName& left, const pxEnumEnd_t&) { return (int)left < enumName##_COUNT; } \
static __fi bool operator!=(const enumName &left, const pxEnumEnd_t &) { return (int)left != enumName##_COUNT; } \ static __fi bool operator!=(const enumName& left, const pxEnumEnd_t&) { return (int)left != enumName##_COUNT; } \
static __fi bool operator==(const enumName &left, const pxEnumEnd_t &) { return (int)left == enumName##_COUNT; } \ static __fi bool operator==(const enumName& left, const pxEnumEnd_t&) { return (int)left == enumName##_COUNT; } \
\ \
static __fi bool EnumIsValid(enumName id) \ static __fi bool EnumIsValid(enumName id) \
{ \ { \
return ((int)id >= enumName##_FIRST) && ((int)id < enumName##_COUNT); \ return ((int)id >= enumName##_FIRST) && ((int)id < enumName##_COUNT); \
} \ } \
\
static __fi void EnumAssert(enumName id) \ static __fi void EnumAssert(enumName id) \
{ \ { \
pxAssert(EnumIsValid(id)); \ pxAssert(EnumIsValid(id)); \
} \ } \
\ \
extern const wxChar *EnumToString(enumName id) extern const wxChar* EnumToString(enumName id)
class pxEnumEnd_t class pxEnumEnd_t
{ {
@ -131,8 +135,8 @@ static const pxEnumEnd_t pxEnumEnd = {};
#ifndef DeclareNoncopyableObject #ifndef DeclareNoncopyableObject
#define DeclareNoncopyableObject(classname) \ #define DeclareNoncopyableObject(classname) \
private: \ private: \
explicit classname(const classname &); \ explicit classname(const classname&); \
classname &operator=(const classname &) classname& operator=(const classname&)
#endif #endif
@ -144,10 +148,10 @@ private: \
class ScopedBool class ScopedBool
{ {
protected: protected:
bool *m_boolme; bool* m_boolme;
public: public:
ScopedBool(bool &boolme) ScopedBool(bool& boolme)
{ {
boolme = true; boolme = true;
m_boolme = &boolme; m_boolme = &boolme;
@ -262,12 +266,12 @@ static const s64 _4gb = _1gb * 4;
#define pxE_dev(english) pxExpandMsg((english)) #define pxE_dev(english) pxExpandMsg((english))
extern const wxChar *__fastcall pxExpandMsg(const wxChar *message); extern const wxChar* __fastcall pxExpandMsg(const wxChar* message);
extern const wxChar *__fastcall pxGetTranslation(const wxChar *message); extern const wxChar* __fastcall pxGetTranslation(const wxChar* message);
extern bool pxIsEnglish(int id); extern bool pxIsEnglish(int id);
extern wxString fromUTF8(const char *src); extern wxString fromUTF8(const char* src);
extern wxString fromAscii(const char *src); extern wxString fromAscii(const char* src);
#include "common/Assertions.h" #include "common/Assertions.h"

View File

@ -25,7 +25,7 @@
class IEmbeddedImage class IEmbeddedImage
{ {
public: public:
virtual const wxImage &Get() = 0; virtual const wxImage& Get() = 0;
virtual wxImage Scale(int width, int height) = 0; virtual wxImage Scale(int width, int height) = 0;
}; };
@ -52,7 +52,8 @@ protected:
// //
void _loadImage() void _loadImage()
{ {
if (!m_Image.Ok()) { if (!m_Image.Ok())
{
wxMemoryInputStream joe(ImageType::Data, ImageType::Length); wxMemoryInputStream joe(ImageType::Data, ImageType::Length);
m_Image.LoadFile(joe, ImageType::GetFormat()); m_Image.LoadFile(joe, ImageType::GetFormat());
@ -90,7 +91,7 @@ public:
// and only happens when the image is actually fetched. Simply creating an instance // and only happens when the image is actually fetched. Simply creating an instance
// of an EmbeddedImage object uses no excess memory nor cpu overhead. :) // of an EmbeddedImage object uses no excess memory nor cpu overhead. :)
// //
const wxImage &Get() const wxImage& Get()
{ {
_loadImage(); _loadImage();
return m_Image; return m_Image;

View File

@ -27,7 +27,7 @@ class EventSource
{ {
public: public:
typedef typename ListenerType::EvtParams EvtParams; typedef typename ListenerType::EvtParams EvtParams;
typedef typename std::list<ListenerType *> ListenerList; typedef typename std::list<ListenerType*> ListenerList;
typedef typename ListenerList::iterator ListenerIterator; typedef typename ListenerList::iterator ListenerIterator;
protected: protected:
@ -51,29 +51,29 @@ public:
virtual ~EventSource() = default; virtual ~EventSource() = default;
virtual ListenerIterator Add(ListenerType &listener); virtual ListenerIterator Add(ListenerType& listener);
virtual void Remove(ListenerType &listener); virtual void Remove(ListenerType& listener);
virtual void Remove(const ListenerIterator &listenerHandle); virtual void Remove(const ListenerIterator& listenerHandle);
void Add(ListenerType *listener) void Add(ListenerType* listener)
{ {
if (listener == NULL) if (listener == NULL)
return; return;
Add(*listener); Add(*listener);
} }
void Remove(ListenerType *listener) void Remove(ListenerType* listener)
{ {
if (listener == NULL) if (listener == NULL)
return; return;
Remove(*listener); Remove(*listener);
} }
void Dispatch(const EvtParams &params); void Dispatch(const EvtParams& params);
protected: protected:
virtual ListenerIterator _AddFast_without_lock(ListenerType &listener); virtual ListenerIterator _AddFast_without_lock(ListenerType& listener);
virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams &params); virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator& iend, const EvtParams& params);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -90,5 +90,5 @@ protected:
public: public:
virtual ~IEventDispatcher() = default; virtual ~IEventDispatcher() = default;
virtual void DispatchEvent(const EvtParams &params) = 0; virtual void DispatchEvent(const EvtParams& params) = 0;
}; };

View File

@ -20,14 +20,16 @@
using Threading::ScopedLock; using Threading::ScopedLock;
template <typename ListenerType> template <typename ListenerType>
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::Add(ListenerType &listener) typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::Add(ListenerType& listener)
{ {
ScopedLock locker(m_listeners_lock); ScopedLock locker(m_listeners_lock);
// Check for duplicates before adding the event. // Check for duplicates before adding the event.
if (IsDebugBuild) { if (IsDebugBuild)
{
ListenerIterator iter = m_listeners.begin(); ListenerIterator iter = m_listeners.begin();
while (iter != m_listeners.end()) { while (iter != m_listeners.end())
{
if ((*iter) == &listener) if ((*iter) == &listener)
return iter; return iter;
++iter; ++iter;
@ -37,7 +39,7 @@ typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::
} }
template <typename ListenerType> template <typename ListenerType>
void EventSource<ListenerType>::Remove(ListenerType &listener) void EventSource<ListenerType>::Remove(ListenerType& listener)
{ {
ScopedLock locker(m_listeners_lock); ScopedLock locker(m_listeners_lock);
m_cache_valid = false; m_cache_valid = false;
@ -45,7 +47,7 @@ void EventSource<ListenerType>::Remove(ListenerType &listener)
} }
template <typename ListenerType> template <typename ListenerType>
void EventSource<ListenerType>::Remove(const ListenerIterator &listenerHandle) void EventSource<ListenerType>::Remove(const ListenerIterator& listenerHandle)
{ {
ScopedLock locker(m_listeners_lock); ScopedLock locker(m_listeners_lock);
m_cache_valid = false; m_cache_valid = false;
@ -53,7 +55,7 @@ void EventSource<ListenerType>::Remove(const ListenerIterator &listenerHandle)
} }
template <typename ListenerType> template <typename ListenerType>
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::_AddFast_without_lock(ListenerType &listener) typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::_AddFast_without_lock(ListenerType& listener)
{ {
m_cache_valid = false; m_cache_valid = false;
m_listeners.push_front(&listener); m_listeners.push_front(&listener);
@ -62,19 +64,29 @@ typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::
template <typename ListenerType> template <typename ListenerType>
__fi void EventSource<ListenerType>::_DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams &evtparams) __fi void EventSource<ListenerType>::_DispatchRaw(ListenerIterator iter, const ListenerIterator& iend, const EvtParams& evtparams)
{ {
while (iter != iend) { while (iter != iend)
try { {
try
{
(*iter)->DispatchEvent(evtparams); (*iter)->DispatchEvent(evtparams);
} catch (Exception::RuntimeError &ex) { }
if (IsDevBuild) { catch (Exception::RuntimeError& ex)
{
if (IsDevBuild)
{
pxFailDev(L"Ignoring runtime error thrown from event listener (event listeners should not throw exceptions!): " + ex.FormatDiagnosticMessage()); pxFailDev(L"Ignoring runtime error thrown from event listener (event listeners should not throw exceptions!): " + ex.FormatDiagnosticMessage());
} else { }
else
{
Console.Error(L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage()); Console.Error(L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage());
} }
} catch (BaseException &ex) { }
if (IsDevBuild) { catch (BaseException& ex)
{
if (IsDevBuild)
{
ex.DiagMsg() = L"Non-runtime BaseException thrown from event listener .. " + ex.DiagMsg(); ex.DiagMsg() = L"Non-runtime BaseException thrown from event listener .. " + ex.DiagMsg();
throw; throw;
} }
@ -85,9 +97,10 @@ __fi void EventSource<ListenerType>::_DispatchRaw(ListenerIterator iter, const L
} }
template <typename ListenerType> template <typename ListenerType>
void EventSource<ListenerType>::Dispatch(const EvtParams &evtparams) void EventSource<ListenerType>::Dispatch(const EvtParams& evtparams)
{ {
if (!m_cache_valid) { if (!m_cache_valid)
{
m_cache_copy = m_listeners; m_cache_copy = m_listeners;
m_cache_valid = true; m_cache_valid = true;
} }

View File

@ -42,11 +42,11 @@ Fnptr_OutOfMemory pxDoOutOfMemory = NULL;
// That's ok. What we don't want is the *same* thread recurse-asserting. // That's ok. What we don't want is the *same* thread recurse-asserting.
static DeclareTls(int) s_assert_guard(0); static DeclareTls(int) s_assert_guard(0);
pxDoAssertFnType *pxDoAssert = pxAssertImpl_LogIt; pxDoAssertFnType* pxDoAssert = pxAssertImpl_LogIt;
// make life easier for people using VC++ IDE by using this format, which allows double-click // make life easier for people using VC++ IDE by using this format, which allows double-click
// response times from the Output window... // response times from the Output window...
wxString DiagnosticOrigin::ToString(const wxChar *msg) const wxString DiagnosticOrigin::ToString(const wxChar* msg) const
{ {
FastFormatUnicode message; FastFormatUnicode message;
@ -88,7 +88,7 @@ void pxTrap()
} }
bool pxAssertImpl_LogIt(const DiagnosticOrigin &origin, const wxChar *msg) bool pxAssertImpl_LogIt(const DiagnosticOrigin& origin, const wxChar* msg)
{ {
//wxLogError( L"%s", origin.ToString( msg ).c_str() ); //wxLogError( L"%s", origin.ToString( msg ).c_str() );
wxMessageOutputDebug().Printf(L"%s", origin.ToString(msg).c_str()); wxMessageOutputDebug().Printf(L"%s", origin.ToString(msg).c_str());
@ -97,13 +97,14 @@ bool pxAssertImpl_LogIt(const DiagnosticOrigin &origin, const wxChar *msg)
} }
DEVASSERT_INLINE void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg) DEVASSERT_INLINE void pxOnAssert(const DiagnosticOrigin& origin, const wxString& msg)
{ {
// Recursion guard: Allow at least one recursive call. This is useful because sometimes // Recursion guard: Allow at least one recursive call. This is useful because sometimes
// we get meaningless assertions while unwinding stack traces after exceptions have occurred. // we get meaningless assertions while unwinding stack traces after exceptions have occurred.
RecursionGuard guard(s_assert_guard); RecursionGuard guard(s_assert_guard);
if (guard.Counter > 2) { if (guard.Counter > 2)
{
return pxTrap(); return pxTrap();
} }
@ -114,14 +115,18 @@ DEVASSERT_INLINE void pxOnAssert(const DiagnosticOrigin &origin, const wxString
bool trapit; bool trapit;
if (pxDoAssert == NULL) { if (pxDoAssert == NULL)
{
// Note: Format uses MSVC's syntax for output window hotlinking. // Note: Format uses MSVC's syntax for output window hotlinking.
trapit = pxAssertImpl_LogIt(origin, msg.wc_str()); trapit = pxAssertImpl_LogIt(origin, msg.wc_str());
} else { }
else
{
trapit = pxDoAssert(origin, msg.wc_str()); trapit = pxDoAssert(origin, msg.wc_str());
} }
if (trapit) { if (trapit)
{
pxTrap(); pxTrap();
} }
} }
@ -130,19 +135,19 @@ DEVASSERT_INLINE void pxOnAssert(const DiagnosticOrigin &origin, const wxString
// BaseException (implementations) // BaseException (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
BaseException &BaseException::SetBothMsgs(const wxChar *msg_diag) BaseException& BaseException::SetBothMsgs(const wxChar* msg_diag)
{ {
m_message_user = msg_diag ? wxString(wxGetTranslation(msg_diag)) : wxString(""); m_message_user = msg_diag ? wxString(wxGetTranslation(msg_diag)) : wxString("");
return SetDiagMsg(msg_diag); return SetDiagMsg(msg_diag);
} }
BaseException &BaseException::SetDiagMsg(const wxString &msg_diag) BaseException& BaseException::SetDiagMsg(const wxString& msg_diag)
{ {
m_message_diag = msg_diag; m_message_diag = msg_diag;
return *this; return *this;
} }
BaseException &BaseException::SetUserMsg(const wxString &msg_user) BaseException& BaseException::SetUserMsg(const wxString& msg_user)
{ {
m_message_user = msg_user; m_message_user = msg_user;
return *this; return *this;
@ -161,7 +166,7 @@ wxString BaseException::FormatDisplayMessage() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::RuntimeError (implementations) // Exception::RuntimeError (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
Exception::RuntimeError::RuntimeError(const std::runtime_error &ex, const wxString &prefix) Exception::RuntimeError::RuntimeError(const std::runtime_error& ex, const wxString& prefix)
{ {
IsSilent = false; IsSilent = false;
@ -170,7 +175,7 @@ Exception::RuntimeError::RuntimeError(const std::runtime_error &ex, const wxStri
WX_STR(fromUTF8(ex.what())))); WX_STR(fromUTF8(ex.what()))));
} }
Exception::RuntimeError::RuntimeError(const std::exception &ex, const wxString &prefix) Exception::RuntimeError::RuntimeError(const std::exception& ex, const wxString& prefix)
{ {
IsSilent = false; IsSilent = false;
@ -182,7 +187,7 @@ Exception::RuntimeError::RuntimeError(const std::exception &ex, const wxString &
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::OutOfMemory (implementations) // Exception::OutOfMemory (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
Exception::OutOfMemory::OutOfMemory(const wxString &allocdesc) Exception::OutOfMemory::OutOfMemory(const wxString& allocdesc)
{ {
AllocDescription = allocdesc; AllocDescription = allocdesc;
} }
@ -215,7 +220,7 @@ wxString Exception::OutOfMemory::FormatDisplayMessage() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::VirtualMemoryMapConflict (implementations) // Exception::VirtualMemoryMapConflict (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
Exception::VirtualMemoryMapConflict::VirtualMemoryMapConflict(const wxString &allocdesc) Exception::VirtualMemoryMapConflict::VirtualMemoryMapConflict(const wxString& allocdesc)
{ {
AllocDescription = allocdesc; AllocDescription = allocdesc;
m_message_user = _("Virtual memory mapping failure! Your system may have conflicting device drivers, services, or may simply have insufficient memory or resources to meet PCSX2's lofty needs."); m_message_user = _("Virtual memory mapping failure! Your system may have conflicting device drivers, services, or may simply have insufficient memory or resources to meet PCSX2's lofty needs.");
@ -275,7 +280,7 @@ wxString Exception::BadStream::FormatDisplayMessage() const
return retval; return retval;
} }
void Exception::BadStream::_formatDiagMsg(FastFormatUnicode &dest) const void Exception::BadStream::_formatDiagMsg(FastFormatUnicode& dest) const
{ {
dest.Write(L"Path: "); dest.Write(L"Path: ");
if (!StreamName.IsEmpty()) if (!StreamName.IsEmpty())
@ -287,7 +292,7 @@ void Exception::BadStream::_formatDiagMsg(FastFormatUnicode &dest) const
dest.Write(L"\n%s", WX_STR(m_message_diag)); dest.Write(L"\n%s", WX_STR(m_message_diag));
} }
void Exception::BadStream::_formatUserMsg(FastFormatUnicode &dest) const void Exception::BadStream::_formatUserMsg(FastFormatUnicode& dest) const
{ {
dest.Write(_("Path: ")); dest.Write(_("Path: "));
if (!StreamName.IsEmpty()) if (!StreamName.IsEmpty())
@ -385,11 +390,12 @@ wxString Exception::EndOfStream::FormatDisplayMessage() const
// Translates an Errno code into an exception. // Translates an Errno code into an exception.
// Throws an exception based on the given error code (usually taken from ANSI C's errno) // Throws an exception based on the given error code (usually taken from ANSI C's errno)
BaseException *Exception::FromErrno(const wxString &streamname, int errcode) BaseException* Exception::FromErrno(const wxString& streamname, int errcode)
{ {
pxAssumeDev(errcode != 0, "Invalid NULL error code? (errno)"); pxAssumeDev(errcode != 0, "Invalid NULL error code? (errno)");
switch (errcode) { switch (errcode)
{
case EINVAL: case EINVAL:
pxFailDev(L"Invalid argument"); pxFailDev(L"Invalid argument");
return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)"); return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)");

View File

@ -35,19 +35,25 @@ void pxTrap();
#define __DESTRUCTOR_CATCHALL(funcname) \ #define __DESTRUCTOR_CATCHALL(funcname) \
catch (BaseException & ex) \ catch (BaseException & ex) \
{ \ { \
try { \ try \
{ \
Console.Error("Unhandled BaseException in %s (ignored!):", funcname); \ Console.Error("Unhandled BaseException in %s (ignored!):", funcname); \
Console.Error(ex.FormatDiagnosticMessage()); \ Console.Error(ex.FormatDiagnosticMessage()); \
} catch (...) { \ } \
catch (...) \
{ \
fprintf(stderr, "ERROR: (out of memory?)\n"); \ fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \ } \
} \ } \
catch (std::exception & ex) \ catch (std::exception & ex) \
{ \ { \
try { \ try \
{ \
Console.Error("Unhandled std::exception in %s (ignored!):", funcname); \ Console.Error("Unhandled std::exception in %s (ignored!):", funcname); \
Console.Error(ex.what()); \ Console.Error(ex.what()); \
} catch (...) { \ } \
catch (...) \
{ \
fprintf(stderr, "ERROR: (out of memory?)\n"); \ fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \ } \
} \ } \
@ -60,46 +66,46 @@ void pxTrap();
namespace Exception namespace Exception
{ {
class BaseException; class BaseException;
int MakeNewType(); int MakeNewType();
BaseException *FromErrno(const wxString &streamname, int errcode); BaseException* FromErrno(const wxString& streamname, int errcode);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// BaseException // BaseException
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// std::exception sucks, and isn't entirely cross-platform reliable in its implementation, // std::exception sucks, and isn't entirely cross-platform reliable in its implementation,
// so I made a replacement. The internal messages are non-const, which means that a // so I made a replacement. The internal messages are non-const, which means that a
// catch clause can optionally modify them and then re-throw to a top-level handler. // catch clause can optionally modify them and then re-throw to a top-level handler.
// //
// Note, this class is "abstract" which means you shouldn't use it directly like, ever. // Note, this class is "abstract" which means you shouldn't use it directly like, ever.
// Use Exception::RuntimeError instead for generic exceptions. // Use Exception::RuntimeError instead for generic exceptions.
// //
// Because exceptions are the (only!) really useful example of multiple inheritance, // Because exceptions are the (only!) really useful example of multiple inheritance,
// this class has only a trivial constructor, and must be manually initialized using // this class has only a trivial constructor, and must be manually initialized using
// InitBaseEx() or by individual member assignments. This is because C++ multiple inheritence // InitBaseEx() or by individual member assignments. This is because C++ multiple inheritence
// is, by design, a lot of fail, especially when class initializers are mixed in. // is, by design, a lot of fail, especially when class initializers are mixed in.
// //
// [TODO] : Add an InnerException component, and Clone() facility. // [TODO] : Add an InnerException component, and Clone() facility.
// //
class BaseException class BaseException
{ {
protected: protected:
wxString m_message_diag; // (untranslated) a "detailed" message of what disastrous thing has occurred! wxString m_message_diag; // (untranslated) a "detailed" message of what disastrous thing has occurred!
wxString m_message_user; // (translated) a "detailed" message of what disastrous thing has occurred! wxString m_message_user; // (translated) a "detailed" message of what disastrous thing has occurred!
public: public:
virtual ~BaseException() = default; virtual ~BaseException() = default;
const wxString &DiagMsg() const { return m_message_diag; } const wxString& DiagMsg() const { return m_message_diag; }
const wxString &UserMsg() const { return m_message_user; } const wxString& UserMsg() const { return m_message_user; }
wxString &DiagMsg() { return m_message_diag; } wxString& DiagMsg() { return m_message_diag; }
wxString &UserMsg() { return m_message_user; } wxString& UserMsg() { return m_message_user; }
BaseException &SetBothMsgs(const wxChar *msg_diag); BaseException& SetBothMsgs(const wxChar* msg_diag);
BaseException &SetDiagMsg(const wxString &msg_diag); BaseException& SetDiagMsg(const wxString& msg_diag);
BaseException &SetUserMsg(const wxString &msg_user); BaseException& SetUserMsg(const wxString& msg_user);
// Returns a message suitable for diagnostic / logging purposes. // Returns a message suitable for diagnostic / logging purposes.
// This message is always in English, and includes a full stack trace. // This message is always in English, and includes a full stack trace.
@ -110,37 +116,37 @@ public:
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
virtual void Rethrow() const = 0; virtual void Rethrow() const = 0;
virtual BaseException *Clone() const = 0; virtual BaseException* Clone() const = 0;
}; };
typedef std::unique_ptr<BaseException> ScopedExcept; typedef std::unique_ptr<BaseException> ScopedExcept;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Ps2Generic Exception // Ps2Generic Exception
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc). // This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc).
// //
// Implementation note: does not derive from BaseException, so that we can use different // Implementation note: does not derive from BaseException, so that we can use different
// catch block hierarchies to handle them (if needed). // catch block hierarchies to handle them (if needed).
// //
// Translation Note: Currently these exceptions are never translated. English/diagnostic // Translation Note: Currently these exceptions are never translated. English/diagnostic
// format only. :) // format only. :)
// //
class Ps2Generic class Ps2Generic
{ {
protected: protected:
wxString m_message; // a "detailed" message of what disastrous thing has occurred! wxString m_message; // a "detailed" message of what disastrous thing has occurred!
public: public:
virtual ~Ps2Generic() = default; virtual ~Ps2Generic() = default;
virtual u32 GetPc() const = 0; virtual u32 GetPc() const = 0;
virtual bool IsDelaySlot() const = 0; virtual bool IsDelaySlot() const = 0;
virtual wxString &Message() { return m_message; } virtual wxString& Message() { return m_message; }
virtual void Rethrow() const = 0; virtual void Rethrow() const = 0;
virtual Ps2Generic *Clone() const = 0; virtual Ps2Generic* Clone() const = 0;
}; };
// Some helper macros for defining the standard constructors of internationalized constructors // Some helper macros for defining the standard constructors of internationalized constructors
// Parameters: // Parameters:
@ -159,25 +165,35 @@ public:
#define DEFINE_EXCEPTION_COPYTORS(classname, parent) \ #define DEFINE_EXCEPTION_COPYTORS(classname, parent) \
private: \ private: \
typedef parent _parent; \ typedef parent _parent; \
\ \
public: \ public: \
virtual ~classname() = default; \ virtual ~classname() = default; \
virtual void Rethrow() const { throw * this; } \ \
virtual classname *Clone() const { return new classname(*this); } virtual void Rethrow() const \
{ \
throw *this; \
} \
\
virtual classname* Clone() const \
{ \
return new classname(*this); \
}
#define DEFINE_EXCEPTION_MESSAGES(classname) \ #define DEFINE_EXCEPTION_MESSAGES(classname) \
public: \ public: \
classname &SetBothMsgs(const wxChar *msg_diag) \ classname& SetBothMsgs(const wxChar* msg_diag) \
{ \ { \
BaseException::SetBothMsgs(msg_diag); \ BaseException::SetBothMsgs(msg_diag); \
return *this; \ return *this; \
} \ } \
classname &SetDiagMsg(const wxString &msg_diag) \ \
classname& SetDiagMsg(const wxString& msg_diag) \
{ \ { \
m_message_diag = msg_diag; \ m_message_diag = msg_diag; \
return *this; \ return *this; \
} \ } \
classname &SetUserMsg(const wxString &msg_user) \ \
classname& SetUserMsg(const wxString& msg_user) \
{ \ { \
m_message_user = msg_user; \ m_message_user = msg_user; \
return *this; \ return *this; \
@ -185,42 +201,45 @@ public: \
#define DEFINE_RUNTIME_EXCEPTION(classname, parent, message) \ #define DEFINE_RUNTIME_EXCEPTION(classname, parent, message) \
DEFINE_EXCEPTION_COPYTORS(classname, parent) \ DEFINE_EXCEPTION_COPYTORS(classname, parent) \
classname() { SetDiagMsg(message); } \ classname() \
{ \
SetDiagMsg(message); \
} \
DEFINE_EXCEPTION_MESSAGES(classname) DEFINE_EXCEPTION_MESSAGES(classname)
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// RuntimeError - Generalized Exceptions with Recoverable Traits! // RuntimeError - Generalized Exceptions with Recoverable Traits!
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
class RuntimeError : public BaseException class RuntimeError : public BaseException
{ {
DEFINE_EXCEPTION_COPYTORS(RuntimeError, BaseException) DEFINE_EXCEPTION_COPYTORS(RuntimeError, BaseException)
DEFINE_EXCEPTION_MESSAGES(RuntimeError) DEFINE_EXCEPTION_MESSAGES(RuntimeError)
public: public:
bool IsSilent; bool IsSilent;
RuntimeError() { IsSilent = false; } RuntimeError() { IsSilent = false; }
RuntimeError(const std::runtime_error &ex, const wxString &prefix = wxEmptyString); RuntimeError(const std::runtime_error& ex, const wxString& prefix = wxEmptyString);
RuntimeError(const std::exception &ex, const wxString &prefix = wxEmptyString); RuntimeError(const std::exception& ex, const wxString& prefix = wxEmptyString);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// CancelAppEvent - Exception for canceling an event in a non-verbose fashion // CancelAppEvent - Exception for canceling an event in a non-verbose fashion
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Typically the PCSX2 interface issues popup dialogs for runtime errors. This exception // Typically the PCSX2 interface issues popup dialogs for runtime errors. This exception
// instead issues a "silent" cancelation that is handled by the app gracefully (generates // instead issues a "silent" cancelation that is handled by the app gracefully (generates
// log, and resumes messages queue processing). // log, and resumes messages queue processing).
// //
// I chose to have this exception derive from RuntimeError, since if one is thrown from outside // I chose to have this exception derive from RuntimeError, since if one is thrown from outside
// an App message loop we'll still want it to be handled in a reasonably graceful manner. // an App message loop we'll still want it to be handled in a reasonably graceful manner.
class CancelEvent : public RuntimeError class CancelEvent : public RuntimeError
{ {
DEFINE_RUNTIME_EXCEPTION(CancelEvent, RuntimeError, pxLt("No reason given.")) DEFINE_RUNTIME_EXCEPTION(CancelEvent, RuntimeError, pxLt("No reason given."))
public: public:
explicit CancelEvent(const wxString &logmsg) explicit CancelEvent(const wxString& logmsg)
{ {
m_message_diag = logmsg; m_message_diag = logmsg;
// overridden message formatters only use the diagnostic version... // overridden message formatters only use the diagnostic version...
@ -228,73 +247,74 @@ public:
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
}; };
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// OutOfMemory // OutOfMemory
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// This exception has a custom-formatted Diagnostic string. The parameter give when constructing // This exception has a custom-formatted Diagnostic string. The parameter give when constructing
// the exception is a block/alloc name, which is used as a formatting parameter in the diagnostic // the exception is a block/alloc name, which is used as a formatting parameter in the diagnostic
// output. The default diagnostic message is "Out of memory exception, while allocating the %s." // output. The default diagnostic message is "Out of memory exception, while allocating the %s."
// where %s is filled in with the block name. // where %s is filled in with the block name.
// //
// The user string is not custom-formatted, and should contain *NO* %s tags. // The user string is not custom-formatted, and should contain *NO* %s tags.
// //
class OutOfMemory : public RuntimeError class OutOfMemory : public RuntimeError
{ {
DEFINE_RUNTIME_EXCEPTION(OutOfMemory, RuntimeError, wxEmptyString) DEFINE_RUNTIME_EXCEPTION(OutOfMemory, RuntimeError, wxEmptyString)
public: public:
wxString AllocDescription; wxString AllocDescription;
public: public:
OutOfMemory(const wxString &allocdesc); OutOfMemory(const wxString& allocdesc);
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
}; };
class ParseError : public RuntimeError class ParseError : public RuntimeError
{ {
DEFINE_RUNTIME_EXCEPTION(ParseError, RuntimeError, pxL("Parse error")); DEFINE_RUNTIME_EXCEPTION(ParseError, RuntimeError, pxL("Parse error"));
}; };
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Hardware/OS Exceptions: // Hardware/OS Exceptions:
// HardwareDeficiency / VirtualMemoryMapConflict // HardwareDeficiency / VirtualMemoryMapConflict
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// This exception is a specific type of OutOfMemory error that isn't "really" an out of // This exception is a specific type of OutOfMemory error that isn't "really" an out of
// memory error. More likely it's caused by a plugin or driver reserving a range of memory // memory error. More likely it's caused by a plugin or driver reserving a range of memory
// we'd really like to have access to. // we'd really like to have access to.
class VirtualMemoryMapConflict : public OutOfMemory class VirtualMemoryMapConflict : public OutOfMemory
{ {
DEFINE_RUNTIME_EXCEPTION(VirtualMemoryMapConflict, OutOfMemory, wxEmptyString) DEFINE_RUNTIME_EXCEPTION(VirtualMemoryMapConflict, OutOfMemory, wxEmptyString)
VirtualMemoryMapConflict(const wxString &allocdesc); VirtualMemoryMapConflict(const wxString& allocdesc);
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
}; };
class HardwareDeficiency : public RuntimeError class HardwareDeficiency : public RuntimeError
{ {
public: public:
DEFINE_RUNTIME_EXCEPTION(HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood.")); DEFINE_RUNTIME_EXCEPTION(HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood."));
}; };
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Streaming (file) Exceptions: // Streaming (file) Exceptions:
// Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream // Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
#define DEFINE_STREAM_EXCEPTION_ACCESSORS(classname) \ #define DEFINE_STREAM_EXCEPTION_ACCESSORS(classname) \
virtual classname &SetStreamName(const wxString &name) \ virtual classname& SetStreamName(const wxString& name) \
{ \ { \
StreamName = name; \ StreamName = name; \
return *this; \ return *this; \
} \ } \
virtual classname &SetStreamName(const char *name) \ \
virtual classname& SetStreamName(const char* name) \
{ \ { \
StreamName = fromUTF8(name); \ StreamName = fromUTF8(name); \
return *this; \ return *this; \
@ -302,95 +322,95 @@ public:
#define DEFINE_STREAM_EXCEPTION(classname, parent) \ #define DEFINE_STREAM_EXCEPTION(classname, parent) \
DEFINE_RUNTIME_EXCEPTION(classname, parent, wxEmptyString) \ DEFINE_RUNTIME_EXCEPTION(classname, parent, wxEmptyString) \
classname(const wxString &filename) \ classname(const wxString& filename) \
{ \ { \
StreamName = filename; \ StreamName = filename; \
} \ } \
DEFINE_STREAM_EXCEPTION_ACCESSORS(classname) DEFINE_STREAM_EXCEPTION_ACCESSORS(classname)
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of // A generic base error class for bad streams -- corrupted data, sudden closures, loss of
// connection, or anything else that would indicate a failure to open a stream or read the // connection, or anything else that would indicate a failure to open a stream or read the
// data after the stream was successfully opened. // data after the stream was successfully opened.
// //
class BadStream : public RuntimeError class BadStream : public RuntimeError
{ {
DEFINE_STREAM_EXCEPTION(BadStream, RuntimeError) DEFINE_STREAM_EXCEPTION(BadStream, RuntimeError)
public: public:
wxString StreamName; // name of the stream (if applicable) wxString StreamName; // name of the stream (if applicable)
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
protected: protected:
void _formatDiagMsg(FastFormatUnicode &dest) const; void _formatDiagMsg(FastFormatUnicode& dest) const;
void _formatUserMsg(FastFormatUnicode &dest) const; void _formatUserMsg(FastFormatUnicode& dest) const;
}; };
// A generic exception for odd-ball stream creation errors. // A generic exception for odd-ball stream creation errors.
// //
class CannotCreateStream : public BadStream class CannotCreateStream : public BadStream
{ {
DEFINE_STREAM_EXCEPTION(CannotCreateStream, BadStream) DEFINE_STREAM_EXCEPTION(CannotCreateStream, BadStream)
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
}; };
// Exception thrown when an attempt to open a non-existent file is made. // Exception thrown when an attempt to open a non-existent file is made.
// (this exception can also mean file permissions are invalid) // (this exception can also mean file permissions are invalid)
// //
class FileNotFound : public CannotCreateStream class FileNotFound : public CannotCreateStream
{ {
public: public:
DEFINE_STREAM_EXCEPTION(FileNotFound, CannotCreateStream) DEFINE_STREAM_EXCEPTION(FileNotFound, CannotCreateStream)
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
}; };
class AccessDenied : public CannotCreateStream class AccessDenied : public CannotCreateStream
{ {
public: public:
DEFINE_STREAM_EXCEPTION(AccessDenied, CannotCreateStream) DEFINE_STREAM_EXCEPTION(AccessDenied, CannotCreateStream)
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
}; };
// EndOfStream can be used either as an error, or used just as a shortcut for manual // EndOfStream can be used either as an error, or used just as a shortcut for manual
// feof checks. // feof checks.
// //
class EndOfStream : public BadStream class EndOfStream : public BadStream
{ {
public: public:
DEFINE_STREAM_EXCEPTION(EndOfStream, BadStream) DEFINE_STREAM_EXCEPTION(EndOfStream, BadStream)
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
}; };
#ifdef __WXMSW__ #ifdef __WXMSW__
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::WinApiError // Exception::WinApiError
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class WinApiError : public RuntimeError class WinApiError : public RuntimeError
{ {
DEFINE_EXCEPTION_COPYTORS(WinApiError, RuntimeError) DEFINE_EXCEPTION_COPYTORS(WinApiError, RuntimeError)
DEFINE_EXCEPTION_MESSAGES(WinApiError) DEFINE_EXCEPTION_MESSAGES(WinApiError)
public: public:
int ErrorId; int ErrorId;
public: public:
WinApiError(); WinApiError();
wxString GetMsgFromWindows() const; wxString GetMsgFromWindows() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
}; };
#endif #endif
} } // namespace Exception
using Exception::BaseException; using Exception::BaseException;
using Exception::ScopedExcept; using Exception::ScopedExcept;

View File

@ -33,15 +33,15 @@ template class SafeAlignedArray<u8, 16>;
// system deadlock. // system deadlock.
static const int MaxFormattedStringLength = 0x80000; static const int MaxFormattedStringLength = 0x80000;
static
#ifndef __linux__ #ifndef __linux__
__ri static __ri void format_that_ascii_mess(CharBufferType& buffer, uint writepos, const char* fmt, va_list argptr)
#else
static void format_that_ascii_mess(CharBufferType& buffer, uint writepos, const char* fmt, va_list argptr)
#endif #endif
void
format_that_ascii_mess(CharBufferType &buffer, uint writepos, const char *fmt, va_list argptr)
{ {
va_list args; va_list args;
while (true) { while (true)
{
int size = buffer.GetLength(); int size = buffer.GetLength();
va_copy(args, argptr); va_copy(args, argptr);
@ -74,25 +74,25 @@ static
} }
// returns the length of the formatted string, in characters (wxChars). // returns the length of the formatted string, in characters (wxChars).
static
#ifndef __linux__ #ifndef __linux__
__ri static __ri uint format_that_unicode_mess(CharBufferType& buffer, uint writepos, const wxChar* fmt, va_list argptr)
#else
static uint format_that_unicode_mess(CharBufferType& buffer, uint writepos, const wxChar* fmt, va_list argptr)
#endif #endif
uint
format_that_unicode_mess(CharBufferType &buffer, uint writepos, const wxChar *fmt, va_list argptr)
{ {
va_list args; va_list args;
while (true) { while (true)
{
int size = buffer.GetLength() / sizeof(wxChar); int size = buffer.GetLength() / sizeof(wxChar);
va_copy(args, argptr); va_copy(args, argptr);
int len = wxVsnprintf((wxChar *)buffer.GetPtr(writepos * sizeof(wxChar)), size - writepos, fmt, args); int len = wxVsnprintf((wxChar*)buffer.GetPtr(writepos * sizeof(wxChar)), size - writepos, fmt, args);
va_end(args); va_end(args);
// some implementations of vsnprintf() don't NUL terminate // some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so // the string if there is not enough space for it so
// always do it manually // always do it manually
((wxChar *)buffer.GetPtr())[size - 1] = L'\0'; ((wxChar*)buffer.GetPtr())[size - 1] = L'\0';
if (size >= MaxFormattedStringLength) if (size >= MaxFormattedStringLength)
return size - 1; return size - 1;
@ -135,29 +135,29 @@ FastFormatUnicode::FastFormatUnicode()
void FastFormatUnicode::Clear() void FastFormatUnicode::Clear()
{ {
m_Length = 0; m_Length = 0;
((wxChar *)m_dest.GetPtr())[0] = 0; ((wxChar*)m_dest.GetPtr())[0] = 0;
} }
FastFormatUnicode &FastFormatUnicode::WriteV(const char *fmt, va_list argptr) FastFormatUnicode& FastFormatUnicode::WriteV(const char* fmt, va_list argptr)
{ {
wxString converted(fromUTF8(FastFormatAscii().WriteV(fmt, argptr))); wxString converted(fromUTF8(FastFormatAscii().WriteV(fmt, argptr)));
const uint inspos = m_Length; const uint inspos = m_Length;
const uint convLen = converted.Length(); const uint convLen = converted.Length();
m_dest.MakeRoomFor((inspos + convLen + 64) * sizeof(wxChar)); m_dest.MakeRoomFor((inspos + convLen + 64) * sizeof(wxChar));
memcpy(&((wxChar *)m_dest.GetPtr())[inspos], converted.wc_str(), (convLen + 1) * sizeof(wxChar)); memcpy(&((wxChar*)m_dest.GetPtr())[inspos], converted.wc_str(), (convLen + 1) * sizeof(wxChar));
m_Length += convLen; m_Length += convLen;
return *this; return *this;
} }
FastFormatUnicode &FastFormatUnicode::WriteV(const wxChar *fmt, va_list argptr) FastFormatUnicode& FastFormatUnicode::WriteV(const wxChar* fmt, va_list argptr)
{ {
m_Length = format_that_unicode_mess(m_dest, m_Length, fmt, argptr); m_Length = format_that_unicode_mess(m_dest, m_Length, fmt, argptr);
return *this; return *this;
} }
FastFormatUnicode &FastFormatUnicode::Write(const char *fmt, ...) FastFormatUnicode& FastFormatUnicode::Write(const char* fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -166,7 +166,7 @@ FastFormatUnicode &FastFormatUnicode::Write(const char *fmt, ...)
return *this; return *this;
} }
FastFormatUnicode &FastFormatUnicode::Write(const wxChar *fmt, ...) FastFormatUnicode& FastFormatUnicode::Write(const wxChar* fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -175,7 +175,7 @@ FastFormatUnicode &FastFormatUnicode::Write(const wxChar *fmt, ...)
return *this; return *this;
} }
FastFormatUnicode &FastFormatUnicode::Write(const wxString fmt, ...) FastFormatUnicode& FastFormatUnicode::Write(const wxString fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -186,61 +186,61 @@ FastFormatUnicode &FastFormatUnicode::Write(const wxString fmt, ...)
bool FastFormatUnicode::IsEmpty() const bool FastFormatUnicode::IsEmpty() const
{ {
return ((wxChar &)m_dest[0]) == 0; return ((wxChar&)m_dest[0]) == 0;
} }
FastFormatUnicode &FastFormatUnicode::ToUpper() FastFormatUnicode& FastFormatUnicode::ToUpper()
{ {
wxChar *ch = (wxChar *)m_dest.GetPtr(); wxChar* ch = (wxChar*)m_dest.GetPtr();
for (uint i = 0; i < m_Length; ++i, ++ch) for (uint i = 0; i < m_Length; ++i, ++ch)
*ch = (wxChar)wxToupper(*ch); *ch = (wxChar)wxToupper(*ch);
return *this; return *this;
} }
FastFormatUnicode &FastFormatUnicode::ToLower() FastFormatUnicode& FastFormatUnicode::ToLower()
{ {
wxChar *ch = (wxChar *)m_dest.GetPtr(); wxChar* ch = (wxChar*)m_dest.GetPtr();
for (uint i = 0; i < m_Length; ++i, ++ch) for (uint i = 0; i < m_Length; ++i, ++ch)
*ch = (wxChar)wxTolower(*ch); *ch = (wxChar)wxTolower(*ch);
return *this; return *this;
} }
FastFormatUnicode &FastFormatUnicode::operator+=(const char *psz) FastFormatUnicode& FastFormatUnicode::operator+=(const char* psz)
{ {
Write(L"%s", WX_STR(fromUTF8(psz))); Write(L"%s", WX_STR(fromUTF8(psz)));
return *this; return *this;
} }
wxString &operator+=(wxString &str1, const FastFormatUnicode &str2) wxString& operator+=(wxString& str1, const FastFormatUnicode& str2)
{ {
str1.Append(str2.c_str(), str2.Length()); str1.Append(str2.c_str(), str2.Length());
return str1; return str1;
} }
wxString operator+(const wxString &str1, const FastFormatUnicode &str2) wxString operator+(const wxString& str1, const FastFormatUnicode& str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
return s; return s;
} }
wxString operator+(const wxChar *str1, const FastFormatUnicode &str2) wxString operator+(const wxChar* str1, const FastFormatUnicode& str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
return s; return s;
} }
wxString operator+(const FastFormatUnicode &str1, const wxString &str2) wxString operator+(const FastFormatUnicode& str1, const wxString& str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
return s; return s;
} }
wxString operator+(const FastFormatUnicode &str1, const wxChar *str2) wxString operator+(const FastFormatUnicode& str1, const wxChar* str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
@ -267,13 +267,13 @@ const wxString FastFormatAscii::GetString() const
return fromAscii(m_dest.GetPtr()); return fromAscii(m_dest.GetPtr());
} }
FastFormatAscii &FastFormatAscii::WriteV(const char *fmt, va_list argptr) FastFormatAscii& FastFormatAscii::WriteV(const char* fmt, va_list argptr)
{ {
format_that_ascii_mess(m_dest, strlen(m_dest.GetPtr()), fmt, argptr); format_that_ascii_mess(m_dest, strlen(m_dest.GetPtr()), fmt, argptr);
return *this; return *this;
} }
FastFormatAscii &FastFormatAscii::Write(const char *fmt, ...) FastFormatAscii& FastFormatAscii::Write(const char* fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);

View File

@ -33,10 +33,8 @@
{ {
#define BITFIELD_END \ #define BITFIELD_END \
} \ }; \
; \ };
} \
;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -52,9 +50,9 @@
class RecursionGuard class RecursionGuard
{ {
public: public:
int &Counter; int& Counter;
RecursionGuard(int &counter) RecursionGuard(int& counter)
: Counter(counter) : Counter(counter)
{ {
++Counter; ++Counter;
@ -81,7 +79,7 @@ public:
class ICloneable class ICloneable
{ {
public: public:
virtual ICloneable *Clone() const = 0; virtual ICloneable* Clone() const = 0;
}; };
class IDeletableObject class IDeletableObject
@ -164,25 +162,25 @@ public:
All(false); All(false);
} }
PageProtectionMode &Read(bool allow = true) PageProtectionMode& Read(bool allow = true)
{ {
m_read = allow; m_read = allow;
return *this; return *this;
} }
PageProtectionMode &Write(bool allow = true) PageProtectionMode& Write(bool allow = true)
{ {
m_write = allow; m_write = allow;
return *this; return *this;
} }
PageProtectionMode &Execute(bool allow = true) PageProtectionMode& Execute(bool allow = true)
{ {
m_exec = allow; m_exec = allow;
return *this; return *this;
} }
PageProtectionMode &All(bool allow = true) PageProtectionMode& All(bool allow = true)
{ {
m_read = m_write = m_exec = allow; m_read = m_write = m_exec = allow;
return *this; return *this;
@ -233,31 +231,31 @@ static __fi PageProtectionMode PageAccess_Any()
// platform prior to wxWidgets .. it should prolly be removed -- air) // platform prior to wxWidgets .. it should prolly be removed -- air)
namespace HostSys namespace HostSys
{ {
void *MmapReserve(uptr base, size_t size); void* MmapReserve(uptr base, size_t size);
bool MmapCommit(uptr base, size_t size, const PageProtectionMode &mode); bool MmapCommit(uptr base, size_t size, const PageProtectionMode& mode);
void MmapReset(uptr base, size_t size); void MmapReset(uptr base, size_t size);
void *MmapReservePtr(void *base, size_t size); void* MmapReservePtr(void* base, size_t size);
bool MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode); bool MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode);
void MmapResetPtr(void *base, size_t size); void MmapResetPtr(void* base, size_t size);
// Maps a block of memory for use as a recompiled code buffer. // Maps a block of memory for use as a recompiled code buffer.
// Returns NULL on allocation failure. // Returns NULL on allocation failure.
extern void *Mmap(uptr base, size_t size); extern void* Mmap(uptr base, size_t size);
// Unmaps a block allocated by SysMmap // Unmaps a block allocated by SysMmap
extern void Munmap(uptr base, size_t size); extern void Munmap(uptr base, size_t size);
extern void MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode); extern void MemProtect(void* baseaddr, size_t size, const PageProtectionMode& mode);
extern void Munmap(void *base, size_t size); extern void Munmap(void* base, size_t size);
template <uint size> template <uint size>
void MemProtectStatic(u8 (&arr)[size], const PageProtectionMode &mode) void MemProtectStatic(u8 (&arr)[size], const PageProtectionMode& mode)
{ {
MemProtect(arr, size, mode); MemProtect(arr, size, mode);
} }
} } // namespace HostSys
// Safe version of Munmap -- NULLs the pointer variable immediately after free'ing it. // Safe version of Munmap -- NULLs the pointer variable immediately after free'ing it.
#define SafeSysMunmap(ptr, size) \ #define SafeSysMunmap(ptr, size) \

View File

@ -26,10 +26,11 @@ void SetFullBaseDir(wxDirName appRoot)
g_fullBaseDirName = appRoot; g_fullBaseDirName = appRoot;
} }
static int _calcEnumLength(const wxChar *const *enumArray) static int _calcEnumLength(const wxChar* const* enumArray)
{ {
int cnt = 0; int cnt = 0;
while (*enumArray != NULL) { while (*enumArray != NULL)
{
enumArray++; enumArray++;
cnt++; cnt++;
} }
@ -37,7 +38,7 @@ static int _calcEnumLength(const wxChar *const *enumArray)
return cnt; return cnt;
} }
ScopedIniGroup::ScopedIniGroup(IniInterface &mommy, const wxString &group) ScopedIniGroup::ScopedIniGroup(IniInterface& mommy, const wxString& group)
: m_mom(mommy) : m_mom(mommy)
{ {
pxAssertDev(wxStringTokenize(group, L"/").Count() <= 1, L"Cannot nest more than one group deep per instance of ScopedIniGroup."); pxAssertDev(wxStringTokenize(group, L"/").Count() <= 1, L"Cannot nest more than one group deep per instance of ScopedIniGroup.");
@ -52,12 +53,12 @@ ScopedIniGroup::~ScopedIniGroup()
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// IniInterface (implementations) // IniInterface (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
IniInterface::IniInterface(wxConfigBase &config) IniInterface::IniInterface(wxConfigBase& config)
{ {
m_Config = &config; m_Config = &config;
} }
IniInterface::IniInterface(wxConfigBase *config) IniInterface::IniInterface(wxConfigBase* config)
{ {
m_Config = config; m_Config = config;
} }
@ -72,7 +73,7 @@ IniInterface::~IniInterface()
Flush(); Flush();
} }
void IniInterface::SetPath(const wxString &path) void IniInterface::SetPath(const wxString& path)
{ {
if (m_Config) if (m_Config)
m_Config->SetPath(path); m_Config->SetPath(path);
@ -88,12 +89,12 @@ void IniInterface::Flush()
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// IniLoader (implementations) // IniLoader (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
IniLoader::IniLoader(wxConfigBase &config) IniLoader::IniLoader(wxConfigBase& config)
: IniInterface(config) : IniInterface(config)
{ {
} }
IniLoader::IniLoader(wxConfigBase *config) IniLoader::IniLoader(wxConfigBase* config)
: IniInterface(config) : IniInterface(config)
{ {
} }
@ -103,7 +104,7 @@ IniLoader::IniLoader()
{ {
} }
void IniLoader::Entry(const wxString &var, wxString &value, const wxString defvalue) void IniLoader::Entry(const wxString& var, wxString& value, const wxString defvalue)
{ {
if (m_Config) if (m_Config)
m_Config->Read(var, &value, defvalue); m_Config->Read(var, &value, defvalue);
@ -111,7 +112,7 @@ void IniLoader::Entry(const wxString &var, wxString &value, const wxString defva
value = defvalue; value = defvalue;
} }
void IniLoader::Entry(const wxString &var, wxDirName &value, const wxDirName defvalue, bool isAllowRelative) void IniLoader::Entry(const wxString& var, wxDirName& value, const wxDirName defvalue, bool isAllowRelative)
{ {
wxString dest; wxString dest;
if (m_Config) if (m_Config)
@ -119,7 +120,8 @@ void IniLoader::Entry(const wxString &var, wxDirName &value, const wxDirName def
if (dest.IsEmpty()) if (dest.IsEmpty())
value = defvalue; value = defvalue;
else { else
{
value = dest; value = dest;
if (isAllowRelative) if (isAllowRelative)
value = g_fullBaseDirName + value; value = g_fullBaseDirName + value;
@ -129,7 +131,7 @@ void IniLoader::Entry(const wxString &var, wxDirName &value, const wxDirName def
} }
} }
void IniLoader::Entry(const wxString &var, wxFileName &value, const wxFileName defvalue, bool isAllowRelative) void IniLoader::Entry(const wxString& var, wxFileName& value, const wxFileName defvalue, bool isAllowRelative)
{ {
wxString dest(defvalue.GetFullPath()); wxString dest(defvalue.GetFullPath());
if (m_Config) if (m_Config)
@ -145,7 +147,7 @@ void IniLoader::Entry(const wxString &var, wxFileName &value, const wxFileName d
value.SetVolume(value.GetVolume().Upper()); value.SetVolume(value.GetVolume().Upper());
} }
void IniLoader::Entry(const wxString &var, int &value, const int defvalue) void IniLoader::Entry(const wxString& var, int& value, const int defvalue)
{ {
if (m_Config) if (m_Config)
m_Config->Read(var, &value, defvalue); m_Config->Read(var, &value, defvalue);
@ -153,19 +155,19 @@ void IniLoader::Entry(const wxString &var, int &value, const int defvalue)
value = defvalue; value = defvalue;
} }
void IniLoader::Entry(const wxString &var, uint &value, const uint defvalue) void IniLoader::Entry(const wxString& var, uint& value, const uint defvalue)
{ {
if (m_Config) if (m_Config)
m_Config->Read(var, (int *)&value, (int)defvalue); m_Config->Read(var, (int*)&value, (int)defvalue);
else else
value = defvalue; value = defvalue;
} }
void IniLoader::Entry(const wxString &var, bool &value, const bool defvalue) void IniLoader::Entry(const wxString& var, bool& value, const bool defvalue)
{ {
// TODO : Stricter value checking on enabled/disabled? // TODO : Stricter value checking on enabled/disabled?
wxString dest; wxString dest;
if(defvalue) if (defvalue)
dest = wxString("enabled"); dest = wxString("enabled");
else else
dest = wxString("disabled"); dest = wxString("disabled");
@ -175,7 +177,7 @@ void IniLoader::Entry(const wxString &var, bool &value, const bool defvalue)
value = (dest == L"enabled") || (dest == L"1"); value = (dest == L"enabled") || (dest == L"1");
} }
bool IniLoader::EntryBitBool(const wxString &var, bool value, const bool defvalue) bool IniLoader::EntryBitBool(const wxString& var, bool value, const bool defvalue)
{ {
// Note: 'value' param is used by inisaver only. // Note: 'value' param is used by inisaver only.
bool result; bool result;
@ -183,14 +185,14 @@ bool IniLoader::EntryBitBool(const wxString &var, bool value, const bool defvalu
return result; return result;
} }
int IniLoader::EntryBitfield(const wxString &var, int value, const int defvalue) int IniLoader::EntryBitfield(const wxString& var, int value, const int defvalue)
{ {
int result; int result;
Entry(var, result, defvalue); Entry(var, result, defvalue);
return result; return result;
} }
void IniLoader::Entry(const wxString &var, double& value, const double defvalue) void IniLoader::Entry(const wxString& var, double& value, const double defvalue)
{ {
auto readval = wxString::FromDouble(value); auto readval = wxString::FromDouble(value);
@ -201,46 +203,51 @@ void IniLoader::Entry(const wxString &var, double& value, const double defvalue)
value = 0.0; value = 0.0;
} }
void IniLoader::Entry(const wxString &var, wxPoint &value, const wxPoint defvalue) void IniLoader::Entry(const wxString& var, wxPoint& value, const wxPoint defvalue)
{ {
if (!m_Config) { if (!m_Config)
{
value = defvalue; value = defvalue;
return; return;
} }
TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue); TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
} }
void IniLoader::Entry(const wxString &var, wxSize &value, const wxSize defvalue) void IniLoader::Entry(const wxString& var, wxSize& value, const wxSize defvalue)
{ {
if (!m_Config) { if (!m_Config)
{
value = defvalue; value = defvalue;
return; return;
} }
TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue); TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
} }
void IniLoader::Entry(const wxString &var, wxRect &value, const wxRect defvalue) void IniLoader::Entry(const wxString& var, wxRect& value, const wxRect defvalue)
{ {
if (!m_Config) { if (!m_Config)
{
value = defvalue; value = defvalue;
return; return;
} }
TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue); TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
} }
void IniLoader::_EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue) void IniLoader::_EnumEntry(const wxString& var, int& value, const wxChar* const* enumArray, int defvalue)
{ {
// Confirm default value sanity... // Confirm default value sanity...
const int cnt = _calcEnumLength(enumArray); const int cnt = _calcEnumLength(enumArray);
if (!IndexBoundsCheck(L"IniLoader EnumDefaultValue", defvalue, cnt)) { if (!IndexBoundsCheck(L"IniLoader EnumDefaultValue", defvalue, cnt))
{
Console.Error("(LoadSettings) Default enumeration index is out of bounds. Truncating."); Console.Error("(LoadSettings) Default enumeration index is out of bounds. Truncating.");
defvalue = cnt - 1; defvalue = cnt - 1;
} }
// Sanity confirmed, proceed with craziness! // Sanity confirmed, proceed with craziness!
if (!m_Config) { if (!m_Config)
{
value = defvalue; value = defvalue;
return; return;
} }
@ -252,11 +259,13 @@ void IniLoader::_EnumEntry(const wxString &var, int &value, const wxChar *const
while (enumArray[i] != NULL && (retval != enumArray[i])) while (enumArray[i] != NULL && (retval != enumArray[i]))
i++; i++;
if (enumArray[i] == NULL) { if (enumArray[i] == NULL)
{
Console.Warning(L"(LoadSettings) Warning: Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.", Console.Warning(L"(LoadSettings) Warning: Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.",
WX_STR(retval), WX_STR(var), enumArray[defvalue]); WX_STR(retval), WX_STR(var), enumArray[defvalue]);
value = defvalue; value = defvalue;
} else }
else
value = i; value = i;
} }
@ -264,12 +273,12 @@ void IniLoader::_EnumEntry(const wxString &var, int &value, const wxChar *const
// IniSaver (implementations) // IniSaver (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
IniSaver::IniSaver(wxConfigBase &config) IniSaver::IniSaver(wxConfigBase& config)
: IniInterface(config) : IniInterface(config)
{ {
} }
IniSaver::IniSaver(wxConfigBase *config) IniSaver::IniSaver(wxConfigBase* config)
: IniInterface(config) : IniInterface(config)
{ {
} }
@ -279,14 +288,14 @@ IniSaver::IniSaver()
{ {
} }
void IniSaver::Entry(const wxString &var, wxString &value, const wxString defvalue) void IniSaver::Entry(const wxString& var, wxString& value, const wxString defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
m_Config->Write(var, value); m_Config->Write(var, value);
} }
void IniSaver::Entry(const wxString &var, wxDirName &value, const wxDirName defvalue, bool isAllowRelative) void IniSaver::Entry(const wxString& var, wxDirName& value, const wxDirName defvalue, bool isAllowRelative)
{ {
if (!m_Config) if (!m_Config)
return; return;
@ -305,7 +314,7 @@ void IniSaver::Entry(const wxString &var, wxDirName &value, const wxDirName defv
m_Config->Write(var, res.ToString()); m_Config->Write(var, res.ToString());
} }
void IniSaver::Entry(const wxString &var, wxFileName &value, const wxFileName defvalue, bool isAllowRelative) void IniSaver::Entry(const wxString& var, wxFileName& value, const wxFileName defvalue, bool isAllowRelative)
{ {
if (!m_Config) if (!m_Config)
return; return;
@ -320,42 +329,42 @@ void IniSaver::Entry(const wxString &var, wxFileName &value, const wxFileName de
m_Config->Write(var, res.GetFullPath()); m_Config->Write(var, res.GetFullPath());
} }
void IniSaver::Entry(const wxString &var, int &value, const int defvalue) void IniSaver::Entry(const wxString& var, int& value, const int defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
m_Config->Write(var, value); m_Config->Write(var, value);
} }
void IniSaver::Entry(const wxString &var, uint &value, const uint defvalue) void IniSaver::Entry(const wxString& var, uint& value, const uint defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
m_Config->Write(var, (int)value); m_Config->Write(var, (int)value);
} }
void IniSaver::Entry(const wxString &var, bool &value, const bool defvalue) void IniSaver::Entry(const wxString& var, bool& value, const bool defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
m_Config->Write(var, value ? L"enabled" : L"disabled"); m_Config->Write(var, value ? L"enabled" : L"disabled");
} }
bool IniSaver::EntryBitBool(const wxString &var, bool value, const bool defvalue) bool IniSaver::EntryBitBool(const wxString& var, bool value, const bool defvalue)
{ {
if (m_Config) if (m_Config)
m_Config->Write(var, value ? L"enabled" : L"disabled"); m_Config->Write(var, value ? L"enabled" : L"disabled");
return value; return value;
} }
int IniSaver::EntryBitfield(const wxString &var, int value, const int defvalue) int IniSaver::EntryBitfield(const wxString& var, int value, const int defvalue)
{ {
if (m_Config) if (m_Config)
m_Config->Write(var, value); m_Config->Write(var, value);
return value; return value;
} }
void IniSaver::Entry(const wxString &var, double &value, const double defvalue) void IniSaver::Entry(const wxString& var, double& value, const double defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
@ -363,34 +372,35 @@ void IniSaver::Entry(const wxString &var, double &value, const double defvalue)
m_Config->Write(var, wxString::FromDouble(value)); m_Config->Write(var, wxString::FromDouble(value));
} }
void IniSaver::Entry(const wxString &var, wxPoint &value, const wxPoint defvalue) void IniSaver::Entry(const wxString& var, wxPoint& value, const wxPoint defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
m_Config->Write(var, ToString(value)); m_Config->Write(var, ToString(value));
} }
void IniSaver::Entry(const wxString &var, wxSize &value, const wxSize defvalue) void IniSaver::Entry(const wxString& var, wxSize& value, const wxSize defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
m_Config->Write(var, ToString(value)); m_Config->Write(var, ToString(value));
} }
void IniSaver::Entry(const wxString &var, wxRect &value, const wxRect defvalue) void IniSaver::Entry(const wxString& var, wxRect& value, const wxRect defvalue)
{ {
if (!m_Config) if (!m_Config)
return; return;
m_Config->Write(var, ToString(value)); m_Config->Write(var, ToString(value));
} }
void IniSaver::_EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue) void IniSaver::_EnumEntry(const wxString& var, int& value, const wxChar* const* enumArray, int defvalue)
{ {
const int cnt = _calcEnumLength(enumArray); const int cnt = _calcEnumLength(enumArray);
// Confirm default value sanity... // Confirm default value sanity...
if (!IndexBoundsCheck(L"IniSaver EnumDefaultValue", defvalue, cnt)) { if (!IndexBoundsCheck(L"IniSaver EnumDefaultValue", defvalue, cnt))
{
Console.Error("(SaveSettings) Default enumeration index is out of bounds. Truncating."); Console.Error("(SaveSettings) Default enumeration index is out of bounds. Truncating.");
defvalue = cnt - 1; defvalue = cnt - 1;
} }
@ -398,7 +408,8 @@ void IniSaver::_EnumEntry(const wxString &var, int &value, const wxChar *const *
if (!m_Config) if (!m_Config)
return; return;
if (value >= cnt) { if (value >= cnt)
{
Console.Warning(L"(SaveSettings) An illegal enumerated index was detected when saving '%s'", WX_STR(var)); Console.Warning(L"(SaveSettings) An illegal enumerated index was detected when saving '%s'", WX_STR(var));
Console.Indent().Warning( Console.Indent().Warning(
L"Illegal Value: %d\n" L"Illegal Value: %d\n"

View File

@ -31,18 +31,18 @@
class IniInterface class IniInterface
{ {
protected: protected:
wxConfigBase *m_Config; wxConfigBase* m_Config;
public: public:
virtual ~IniInterface(); virtual ~IniInterface();
explicit IniInterface(); explicit IniInterface();
explicit IniInterface(wxConfigBase &config); explicit IniInterface(wxConfigBase& config);
explicit IniInterface(wxConfigBase *config); explicit IniInterface(wxConfigBase* config);
void SetPath(const wxString &path); void SetPath(const wxString& path);
void Flush(); void Flush();
wxConfigBase &GetConfig() wxConfigBase& GetConfig()
{ {
pxAssert(m_Config); pxAssert(m_Config);
return *m_Config; return *m_Config;
@ -52,25 +52,25 @@ public:
virtual bool IsLoading() const = 0; virtual bool IsLoading() const = 0;
bool IsSaving() const { return !IsLoading(); } bool IsSaving() const { return !IsLoading(); }
virtual void Entry(const wxString &var, wxString &value, const wxString defvalue = wxString()) = 0; virtual void Entry(const wxString& var, wxString& value, const wxString defvalue = wxString()) = 0;
virtual void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false) = 0; virtual void Entry(const wxString& var, wxDirName& value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false) = 0;
virtual void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false) = 0; virtual void Entry(const wxString& var, wxFileName& value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false) = 0;
virtual void Entry(const wxString &var, int &value, const int defvalue = 0) = 0; virtual void Entry(const wxString& var, int& value, const int defvalue = 0) = 0;
virtual void Entry(const wxString &var, uint &value, const uint defvalue = 0) = 0; virtual void Entry(const wxString& var, uint& value, const uint defvalue = 0) = 0;
virtual void Entry(const wxString &var, bool &value, const bool defvalue = false) = 0; virtual void Entry(const wxString& var, bool& value, const bool defvalue = false) = 0;
// This special form of Entry is provided for bitfields, which cannot be passed by reference. // This special form of Entry is provided for bitfields, which cannot be passed by reference.
virtual bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false) = 0; virtual bool EntryBitBool(const wxString& var, bool value, const bool defvalue = false) = 0;
virtual int EntryBitfield(const wxString &var, int value, const int defvalue = 0) = 0; virtual int EntryBitfield(const wxString& var, int value, const int defvalue = 0) = 0;
virtual void Entry(const wxString &var, double& value, const double defvalue = 0.0) = 0; virtual void Entry(const wxString& var, double& value, const double defvalue = 0.0) = 0;
virtual void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition) = 0; virtual void Entry(const wxString& var, wxPoint& value, const wxPoint defvalue = wxDefaultPosition) = 0;
virtual void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize) = 0; virtual void Entry(const wxString& var, wxSize& value, const wxSize defvalue = wxDefaultSize) = 0;
virtual void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect) = 0; virtual void Entry(const wxString& var, wxRect& value, const wxRect defvalue = wxDefaultRect) = 0;
template <typename T> template <typename T>
void EnumEntry(const wxString &var, T &value, const wxChar *const *enumArray = NULL, const T defvalue = (T)0) void EnumEntry(const wxString& var, T& value, const wxChar* const* enumArray = NULL, const T defvalue = (T)0)
{ {
int tstore = (int)value; int tstore = (int)value;
auto defaultvalue = enum_cast(defvalue); auto defaultvalue = enum_cast(defvalue);
@ -82,7 +82,7 @@ public:
} }
protected: protected:
virtual void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue) = 0; virtual void _EnumEntry(const wxString& var, int& value, const wxChar* const* enumArray, int defvalue) = 0;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -91,10 +91,10 @@ protected:
class ScopedIniGroup class ScopedIniGroup
{ {
protected: protected:
IniInterface &m_mom; IniInterface& m_mom;
public: public:
ScopedIniGroup(IniInterface &mommy, const wxString &group); ScopedIniGroup(IniInterface& mommy, const wxString& group);
virtual ~ScopedIniGroup(); virtual ~ScopedIniGroup();
}; };
@ -111,29 +111,29 @@ class IniLoader : public IniInterface
public: public:
virtual ~IniLoader() = default; virtual ~IniLoader() = default;
explicit IniLoader(); explicit IniLoader();
explicit IniLoader(wxConfigBase &config); explicit IniLoader(wxConfigBase& config);
explicit IniLoader(wxConfigBase *config); explicit IniLoader(wxConfigBase* config);
bool IsLoading() const { return true; } bool IsLoading() const { return true; }
void Entry(const wxString &var, wxString &value, const wxString defvalue = wxEmptyString); void Entry(const wxString& var, wxString& value, const wxString defvalue = wxEmptyString);
void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false); void Entry(const wxString& var, wxDirName& value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false);
void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false); void Entry(const wxString& var, wxFileName& value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false);
void Entry(const wxString &var, int &value, const int defvalue = 0); void Entry(const wxString& var, int& value, const int defvalue = 0);
void Entry(const wxString &var, uint &value, const uint defvalue = 0); void Entry(const wxString& var, uint& value, const uint defvalue = 0);
void Entry(const wxString &var, bool &value, const bool defvalue = false); void Entry(const wxString& var, bool& value, const bool defvalue = false);
bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false); bool EntryBitBool(const wxString& var, bool value, const bool defvalue = false);
int EntryBitfield(const wxString &var, int value, const int defvalue = 0); int EntryBitfield(const wxString& var, int value, const int defvalue = 0);
void Entry(const wxString &var, double& value, const double defvalue = 0.0) override; void Entry(const wxString& var, double& value, const double defvalue = 0.0) override;
void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition); void Entry(const wxString& var, wxPoint& value, const wxPoint defvalue = wxDefaultPosition);
void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize); void Entry(const wxString& var, wxSize& value, const wxSize defvalue = wxDefaultSize);
void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect); void Entry(const wxString& var, wxRect& value, const wxRect defvalue = wxDefaultRect);
protected: protected:
void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue); void _EnumEntry(const wxString& var, int& value, const wxChar* const* enumArray, int defvalue);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -149,29 +149,29 @@ class IniSaver : public IniInterface
public: public:
virtual ~IniSaver() = default; virtual ~IniSaver() = default;
explicit IniSaver(); explicit IniSaver();
explicit IniSaver(wxConfigBase &config); explicit IniSaver(wxConfigBase& config);
explicit IniSaver(wxConfigBase *config); explicit IniSaver(wxConfigBase* config);
bool IsLoading() const { return false; } bool IsLoading() const { return false; }
void Entry(const wxString &var, wxString &value, const wxString defvalue = wxString()); void Entry(const wxString& var, wxString& value, const wxString defvalue = wxString());
void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false); void Entry(const wxString& var, wxDirName& value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false);
void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false); void Entry(const wxString& var, wxFileName& value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false);
void Entry(const wxString &var, int &value, const int defvalue = 0); void Entry(const wxString& var, int& value, const int defvalue = 0);
void Entry(const wxString &var, uint &value, const uint defvalue = 0); void Entry(const wxString& var, uint& value, const uint defvalue = 0);
void Entry(const wxString &var, bool &value, const bool defvalue = false); void Entry(const wxString& var, bool& value, const bool defvalue = false);
bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false); bool EntryBitBool(const wxString& var, bool value, const bool defvalue = false);
int EntryBitfield(const wxString &var, int value, const int defvalue = 0); int EntryBitfield(const wxString& var, int value, const int defvalue = 0);
void Entry(const wxString &var, double &value, const double defvalue = 0.0) override; void Entry(const wxString& var, double& value, const double defvalue = 0.0) override;
void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition); void Entry(const wxString& var, wxPoint& value, const wxPoint defvalue = wxDefaultPosition);
void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize); void Entry(const wxString& var, wxSize& value, const wxSize defvalue = wxDefaultSize);
void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect); void Entry(const wxString& var, wxRect& value, const wxRect defvalue = wxDefaultRect);
protected: protected:
void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue); void _EnumEntry(const wxString& var, int& value, const wxChar* const* enumArray, int defvalue);
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -33,7 +33,7 @@ extern void SignalExit(int sig);
static const uptr m_pagemask = getpagesize() - 1; static const uptr m_pagemask = getpagesize() - 1;
// Linux implementation of SIGSEGV handler. Bind it using sigaction(). // Linux implementation of SIGSEGV handler. Bind it using sigaction().
static void SysPageFaultSignalFilter(int signal, siginfo_t *siginfo, void *) static void SysPageFaultSignalFilter(int signal, siginfo_t* siginfo, void*)
{ {
// [TODO] : Add a thread ID filter to the Linux Signal handler here. // [TODO] : Add a thread ID filter to the Linux Signal handler here.
// Rationale: On windows, the __try/__except model allows per-thread specific behavior // Rationale: On windows, the __try/__except model allows per-thread specific behavior
@ -64,7 +64,8 @@ static void SysPageFaultSignalFilter(int signal, siginfo_t *siginfo, void *)
if (Source_PageFault->WasHandled()) if (Source_PageFault->WasHandled())
return; return;
if (!wxThread::IsMain()) { if (!wxThread::IsMain())
{
pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr)); pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr));
} }
@ -108,7 +109,7 @@ static __ri void PageSizeAssertionTest(size_t size)
// returns FALSE if the mprotect call fails with an ENOMEM. // returns FALSE if the mprotect call fails with an ENOMEM.
// Raises assertions on other types of POSIX errors (since those typically reflect invalid object // Raises assertions on other types of POSIX errors (since those typically reflect invalid object
// or memory states). // or memory states).
static bool _memprotect(void *baseaddr, size_t size, const PageProtectionMode &mode) static bool _memprotect(void* baseaddr, size_t size, const PageProtectionMode& mode)
{ {
PageSizeAssertionTest(size); PageSizeAssertionTest(size);
@ -126,7 +127,8 @@ static bool _memprotect(void *baseaddr, size_t size, const PageProtectionMode &m
if (result == 0) if (result == 0)
return true; return true;
switch (errno) { switch (errno)
{
case EINVAL: case EINVAL:
pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X (mode=%s)", pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString()))); baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));
@ -144,7 +146,7 @@ static bool _memprotect(void *baseaddr, size_t size, const PageProtectionMode &m
return false; return false;
} }
void *HostSys::MmapReservePtr(void *base, size_t size) void* HostSys::MmapReservePtr(void* base, size_t size)
{ {
PageSizeAssertionTest(size); PageSizeAssertionTest(size);
@ -155,7 +157,7 @@ void *HostSys::MmapReservePtr(void *base, size_t size)
return mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
} }
bool HostSys::MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode) bool HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode)
{ {
// In linux, reserved memory is automatically committed when its permissions are // In linux, reserved memory is automatically committed when its permissions are
// changed to something other than PROT_NONE. If the user is committing memory // changed to something other than PROT_NONE. If the user is committing memory
@ -174,51 +176,52 @@ bool HostSys::MmapCommitPtr(void *base, size_t size, const PageProtectionMode &m
return _memprotect(base, size, mode); return _memprotect(base, size, mode);
} }
void HostSys::MmapResetPtr(void *base, size_t size) void HostSys::MmapResetPtr(void* base, size_t size)
{ {
PageSizeAssertionTest(size); PageSizeAssertionTest(size);
void *result = mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); void* result = mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
pxAssertRel((uptr)result == (uptr)base, pxsFmt( pxAssertRel((uptr)result == (uptr)base, pxsFmt(
"Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped.", "Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped.",
base, (uptr)base + size)); base, (uptr)base + size));
} }
void *HostSys::MmapReserve(uptr base, size_t size) void* HostSys::MmapReserve(uptr base, size_t size)
{ {
return MmapReservePtr((void *)base, size); return MmapReservePtr((void*)base, size);
} }
bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode &mode) bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode& mode)
{ {
return MmapCommitPtr((void *)base, size, mode); return MmapCommitPtr((void*)base, size, mode);
} }
void HostSys::MmapReset(uptr base, size_t size) void HostSys::MmapReset(uptr base, size_t size)
{ {
MmapResetPtr((void *)base, size); MmapResetPtr((void*)base, size);
} }
void *HostSys::Mmap(uptr base, size_t size) void* HostSys::Mmap(uptr base, size_t size)
{ {
PageSizeAssertionTest(size); PageSizeAssertionTest(size);
// MAP_ANONYMOUS - means we have no associated file handle (or device). // MAP_ANONYMOUS - means we have no associated file handle (or device).
return mmap((void *)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return mmap((void*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
} }
void HostSys::Munmap(uptr base, size_t size) void HostSys::Munmap(uptr base, size_t size)
{ {
if (!base) if (!base)
return; return;
munmap((void *)base, size); munmap((void*)base, size);
} }
void HostSys::MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode) void HostSys::MemProtect(void* baseaddr, size_t size, const PageProtectionMode& mode)
{ {
if (!_memprotect(baseaddr, size, mode)) { if (!_memprotect(baseaddr, size, mode))
{
throw Exception::OutOfMemory(L"MemProtect") throw Exception::OutOfMemory(L"MemProtect")
.SetDiagMsg(pxsFmt(L"mprotect failed @ 0x%08X -> 0x%08X (mode=%s)", .SetDiagMsg(pxsFmt(L"mprotect failed @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString()))); baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));

View File

@ -71,11 +71,14 @@ u64 Threading::GetThreadTicksPerSecond()
static u64 get_thread_time(uptr id = 0) static u64 get_thread_time(uptr id = 0)
{ {
clockid_t cid; clockid_t cid;
if (id) { if (id)
{
int err = pthread_getcpuclockid((pthread_t)id, &cid); int err = pthread_getcpuclockid((pthread_t)id, &cid);
if (err) if (err)
return 0; return 0;
} else { }
else
{
cid = CLOCK_THREAD_CPUTIME_ID; cid = CLOCK_THREAD_CPUTIME_ID;
} }
@ -118,7 +121,7 @@ void Threading::pxThread::_platform_specific_OnCleanupInThread()
// Cleanup handles here, which were opened above. // Cleanup handles here, which were opened above.
} }
void Threading::SetNameOfCurrentThread(const char *name) void Threading::SetNameOfCurrentThread(const char* name)
{ {
#if defined(__linux__) #if defined(__linux__)
// Extract of manpage: "The name can be up to 16 bytes long, and should be // Extract of manpage: "The name can be up to 16 bytes long, and should be

View File

@ -22,7 +22,7 @@
// For 32-bit MSVC compiles, memcmp performs much worse than memcmp_mmx and // For 32-bit MSVC compiles, memcmp performs much worse than memcmp_mmx and
// other implementations. So for this combination only, prefer memcmp_mmx // other implementations. So for this combination only, prefer memcmp_mmx
#if defined(_MSC_VER) && !defined(_M_X86_64) #if defined(_MSC_VER) && !defined(_M_X86_64)
extern u8 memcmp_mmx(const void *src1, const void *src2, int cmpsize); extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
#else #else
#define memcmp_mmx memcmp #define memcmp_mmx memcmp
#endif #endif
@ -31,14 +31,14 @@ extern u8 memcmp_mmx(const void *src1, const void *src2, int cmpsize);
// Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically // Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically
// for you! // for you!
template <typename T> template <typename T>
static __fi void memzero(T &object) static __fi void memzero(T& object)
{ {
memset(&object, 0, sizeof(T)); memset(&object, 0, sizeof(T));
} }
// This method clears an object with the given 8 bit value. // This method clears an object with the given 8 bit value.
template <u8 data, typename T> template <u8 data, typename T>
static __fi void memset8(T &object) static __fi void memset8(T& object)
{ {
memset(&object, data, sizeof(T)); memset(&object, data, sizeof(T));
} }

View File

@ -18,7 +18,7 @@
#include <xmmintrin.h> #include <xmmintrin.h>
template <u8 data> template <u8 data>
__noinline void memset_sse_a(void *dest, const size_t size) __noinline void memset_sse_a(void* dest, const size_t size)
{ {
const uint MZFqwc = size / 16; const uint MZFqwc = size / 16;
@ -26,15 +26,18 @@ __noinline void memset_sse_a(void *dest, const size_t size)
__m128 srcreg; __m128 srcreg;
if (data != 0) { if (data != 0)
{
static __aligned16 const u8 loadval[8] = {data, data, data, data, data, data, data, data}; static __aligned16 const u8 loadval[8] = {data, data, data, data, data, data, data, data};
srcreg = _mm_loadh_pi(_mm_load_ps((float *)loadval), (__m64 *)loadval); srcreg = _mm_loadh_pi(_mm_load_ps((float*)loadval), (__m64*)loadval);
} else }
else
srcreg = _mm_setzero_ps(); srcreg = _mm_setzero_ps();
float(*destxmm)[4] = (float(*)[4])dest; float(*destxmm)[4] = (float(*)[4])dest;
switch (MZFqwc & 0x07) { switch (MZFqwc & 0x07)
{
case 0x07: case 0x07:
_mm_store_ps(&destxmm[0x07 - 1][0], srcreg); _mm_store_ps(&destxmm[0x07 - 1][0], srcreg);
// Fall through // Fall through
@ -59,7 +62,8 @@ __noinline void memset_sse_a(void *dest, const size_t size)
} }
destxmm += (MZFqwc & 0x07); destxmm += (MZFqwc & 0x07);
for (uint i = 0; i < MZFqwc / 8; ++i, destxmm += 8) { for (uint i = 0; i < MZFqwc / 8; ++i, destxmm += 8)
{
_mm_store_ps(&destxmm[0][0], srcreg); _mm_store_ps(&destxmm[0][0], srcreg);
_mm_store_ps(&destxmm[1][0], srcreg); _mm_store_ps(&destxmm[1][0], srcreg);
_mm_store_ps(&destxmm[2][0], srcreg); _mm_store_ps(&destxmm[2][0], srcreg);
@ -71,20 +75,20 @@ __noinline void memset_sse_a(void *dest, const size_t size)
} }
}; };
static __fi void memzero_sse_a(void *dest, const size_t size) static __fi void memzero_sse_a(void* dest, const size_t size)
{ {
memset_sse_a<0>(dest, size); memset_sse_a<0>(dest, size);
} }
template <u8 data, typename T> template <u8 data, typename T>
__noinline void memset_sse_a(T &dest) __noinline void memset_sse_a(T& dest)
{ {
static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset"); static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<data>(&dest, sizeof(dest)); memset_sse_a<data>(&dest, sizeof(dest));
} }
template <typename T> template <typename T>
void memzero_sse_a(T &dest) void memzero_sse_a(T& dest)
{ {
static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset"); static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<0>(&dest, sizeof(dest)); memset_sse_a<0>(&dest, sizeof(dest));

View File

@ -20,9 +20,9 @@
namespace Threading namespace Threading
{ {
static std::atomic<int> _attr_refcount(0); static std::atomic<int> _attr_refcount(0);
static pthread_mutexattr_t _attr_recursive; static pthread_mutexattr_t _attr_recursive;
} } // namespace Threading
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Mutex Implementations // Mutex Implementations
@ -52,19 +52,19 @@ static pthread_mutexattr_t _attr_recursive;
// This is an implementation that emulates pthread_mutex_timedlock() via // This is an implementation that emulates pthread_mutex_timedlock() via
// pthread_mutex_trylock(). // pthread_mutex_trylock().
static int xpthread_mutex_timedlock( static int xpthread_mutex_timedlock(
pthread_mutex_t *mutex, pthread_mutex_t* mutex,
const struct timespec *abs_timeout) const struct timespec* abs_timeout)
{ {
int err = 0; int err = 0;
while ((err = pthread_mutex_trylock(mutex)) == EBUSY) { while ((err = pthread_mutex_trylock(mutex)) == EBUSY)
{
// check if the timeout has expired, gettimeofday() is implemented // check if the timeout has expired, gettimeofday() is implemented
// efficiently (in userspace) on OSX // efficiently (in userspace) on OSX
struct timeval now; struct timeval now;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
if (now.tv_sec > abs_timeout->tv_sec if (now.tv_sec > abs_timeout->tv_sec || (now.tv_sec == abs_timeout->tv_sec && (u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec))
|| (now.tv_sec == abs_timeout->tv_sec {
&& (u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec)) {
return ETIMEDOUT; return ETIMEDOUT;
} }
@ -72,7 +72,8 @@ static int xpthread_mutex_timedlock(
struct timespec ts; struct timespec ts;
ts.tv_sec = 0; ts.tv_sec = 0;
ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS; ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS;
while (nanosleep(&ts, &ts) == -1); while (nanosleep(&ts, &ts) == -1)
;
} }
return err; return err;
@ -91,7 +92,8 @@ void Threading::Mutex::Detach()
if (EBUSY != pthread_mutex_destroy(&m_mutex)) if (EBUSY != pthread_mutex_destroy(&m_mutex))
return; return;
if (IsRecursive()) { if (IsRecursive())
{
// Sanity check: Recursive locks could be held by our own thread, which would // Sanity check: Recursive locks could be held by our own thread, which would
// be considered an assertion failure, but can also be handled gracefully. // be considered an assertion failure, but can also be handled gracefully.
// (note: if the mutex is locked recursively more than twice then this assert won't // (note: if the mutex is locked recursively more than twice then this assert won't
@ -112,7 +114,8 @@ void Threading::Mutex::Detach()
Threading::Mutex::~Mutex() Threading::Mutex::~Mutex()
{ {
try { try
{
Mutex::Detach(); Mutex::Detach();
} }
DESTRUCTOR_CATCHALL; DESTRUCTOR_CATCHALL;
@ -121,7 +124,8 @@ Threading::Mutex::~Mutex()
Threading::MutexRecursive::MutexRecursive() Threading::MutexRecursive::MutexRecursive()
: Mutex(false) : Mutex(false)
{ {
if (++_attr_refcount == 1) { if (++_attr_refcount == 1)
{
if (0 != pthread_mutexattr_init(&_attr_recursive)) if (0 != pthread_mutexattr_init(&_attr_recursive))
throw Exception::OutOfMemory(L"Recursive mutexing attributes"); throw Exception::OutOfMemory(L"Recursive mutexing attributes");
@ -153,7 +157,8 @@ void Threading::Mutex::Recreate()
// unlocked. // unlocked.
bool Threading::Mutex::RecreateIfLocked() bool Threading::Mutex::RecreateIfLocked()
{ {
if (!Wait(def_detach_timeout)) { if (!Wait(def_detach_timeout))
{
Recreate(); Recreate();
return true; return true;
} }
@ -171,7 +176,7 @@ void Threading::Mutex::AcquireWithoutYield()
pthread_mutex_lock(&m_mutex); pthread_mutex_lock(&m_mutex);
} }
bool Threading::Mutex::AcquireWithoutYield(const wxTimeSpan &timeout) bool Threading::Mutex::AcquireWithoutYield(const wxTimeSpan& timeout)
{ {
wxDateTime megafail(wxDateTime::UNow() + timeout); wxDateTime megafail(wxDateTime::UNow() + timeout);
const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000}; const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000};
@ -194,12 +199,17 @@ bool Threading::Mutex::TryAcquire()
void Threading::Mutex::Acquire() void Threading::Mutex::Acquire()
{ {
#if wxUSE_GUI #if wxUSE_GUI
if (!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL))
{
pthread_mutex_lock(&m_mutex); pthread_mutex_lock(&m_mutex);
} else if (_WaitGui_RecursionGuard(L"Mutex::Acquire")) { }
else if (_WaitGui_RecursionGuard(L"Mutex::Acquire"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy); ScopedBusyCursor hourglass(Cursor_ReallyBusy);
pthread_mutex_lock(&m_mutex); pthread_mutex_lock(&m_mutex);
} else { }
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy ); //ScopedBusyCursor hourglass( Cursor_KindaBusy );
while (!AcquireWithoutYield(def_yieldgui_interval)) while (!AcquireWithoutYield(def_yieldgui_interval))
YieldToMain(); YieldToMain();
@ -209,19 +219,25 @@ void Threading::Mutex::Acquire()
#endif #endif
} }
bool Threading::Mutex::Acquire(const wxTimeSpan &timeout) bool Threading::Mutex::Acquire(const wxTimeSpan& timeout)
{ {
#if wxUSE_GUI #if wxUSE_GUI
if (!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL))
{
return AcquireWithoutYield(timeout); return AcquireWithoutYield(timeout);
} else if (_WaitGui_RecursionGuard(L"Mutex::TimedAcquire")) { }
else if (_WaitGui_RecursionGuard(L"Mutex::TimedAcquire"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy); ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return AcquireWithoutYield(timeout); return AcquireWithoutYield(timeout);
} else { }
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy ); //ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout)); wxTimeSpan countdown((timeout));
do { do
{
if (AcquireWithoutYield(def_yieldgui_interval)) if (AcquireWithoutYield(def_yieldgui_interval))
break; break;
YieldToMain(); YieldToMain();
@ -262,18 +278,20 @@ void Threading::Mutex::WaitWithoutYield()
// true if the mutex was freed and is in an unlocked state; or false if the wait timed out // true if the mutex was freed and is in an unlocked state; or false if the wait timed out
// and the mutex is still locked by another thread. // and the mutex is still locked by another thread.
// //
bool Threading::Mutex::Wait(const wxTimeSpan &timeout) bool Threading::Mutex::Wait(const wxTimeSpan& timeout)
{ {
if (Acquire(timeout)) { if (Acquire(timeout))
{
Release(); Release();
return true; return true;
} }
return false; return false;
} }
bool Threading::Mutex::WaitWithoutYield(const wxTimeSpan &timeout) bool Threading::Mutex::WaitWithoutYield(const wxTimeSpan& timeout)
{ {
if (AcquireWithoutYield(timeout)) { if (AcquireWithoutYield(timeout))
{
Release(); Release();
return true; return true;
} }
@ -290,28 +308,28 @@ Threading::ScopedLock::~ScopedLock()
m_lock->Release(); m_lock->Release();
} }
Threading::ScopedLock::ScopedLock(const Mutex *locker) Threading::ScopedLock::ScopedLock(const Mutex* locker)
{ {
m_IsLocked = false; m_IsLocked = false;
AssignAndLock(locker); AssignAndLock(locker);
} }
Threading::ScopedLock::ScopedLock(const Mutex &locker) Threading::ScopedLock::ScopedLock(const Mutex& locker)
{ {
m_IsLocked = false; m_IsLocked = false;
AssignAndLock(locker); AssignAndLock(locker);
} }
void Threading::ScopedLock::AssignAndLock(const Mutex &locker) void Threading::ScopedLock::AssignAndLock(const Mutex& locker)
{ {
AssignAndLock(&locker); AssignAndLock(&locker);
} }
void Threading::ScopedLock::AssignAndLock(const Mutex *locker) void Threading::ScopedLock::AssignAndLock(const Mutex* locker)
{ {
pxAssert(!m_IsLocked); // if we're already locked, changing the lock is bad mojo. pxAssert(!m_IsLocked); // if we're already locked, changing the lock is bad mojo.
m_lock = const_cast<Mutex *>(locker); m_lock = const_cast<Mutex*>(locker);
if (!m_lock) if (!m_lock)
return; return;
@ -319,14 +337,14 @@ void Threading::ScopedLock::AssignAndLock(const Mutex *locker)
m_lock->Acquire(); m_lock->Acquire();
} }
void Threading::ScopedLock::Assign(const Mutex &locker) void Threading::ScopedLock::Assign(const Mutex& locker)
{ {
m_lock = const_cast<Mutex *>(&locker); m_lock = const_cast<Mutex*>(&locker);
} }
void Threading::ScopedLock::Assign(const Mutex *locker) void Threading::ScopedLock::Assign(const Mutex* locker)
{ {
m_lock = const_cast<Mutex *>(locker); m_lock = const_cast<Mutex*>(locker);
} }
// Provides manual unlocking of a scoped lock prior to object destruction. // Provides manual unlocking of a scoped lock prior to object destruction.
@ -348,9 +366,9 @@ void Threading::ScopedLock::Acquire()
m_IsLocked = true; m_IsLocked = true;
} }
Threading::ScopedLock::ScopedLock(const Mutex &locker, bool isTryLock) Threading::ScopedLock::ScopedLock(const Mutex& locker, bool isTryLock)
{ {
m_lock = const_cast<Mutex *>(&locker); m_lock = const_cast<Mutex*>(&locker);
if (!m_lock) if (!m_lock)
return; return;
m_IsLocked = isTryLock ? m_lock->TryAcquire() : false; m_IsLocked = isTryLock ? m_lock->TryAcquire() : false;

View File

@ -49,17 +49,17 @@ public:
public: public:
virtual ~IEventListener_PageFault() = default; virtual ~IEventListener_PageFault() = default;
virtual void DispatchEvent(const PageFaultInfo &evtinfo, bool &handled) virtual void DispatchEvent(const PageFaultInfo& evtinfo, bool& handled)
{ {
OnPageFaultEvent(evtinfo, handled); OnPageFaultEvent(evtinfo, handled);
} }
virtual void DispatchEvent(const PageFaultInfo &evtinfo) virtual void DispatchEvent(const PageFaultInfo& evtinfo)
{ {
pxFailRel("Don't call me, damnit. Use DispatchException instead."); pxFailRel("Don't call me, damnit. Use DispatchException instead.");
} }
virtual void OnPageFaultEvent(const PageFaultInfo &evtinfo, bool &handled) {} virtual void OnPageFaultEvent(const PageFaultInfo& evtinfo, bool& handled) {}
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -76,15 +76,15 @@ template <typename TypeToDispatchTo>
class EventListenerHelper_PageFault : public EventListener_PageFault class EventListenerHelper_PageFault : public EventListener_PageFault
{ {
public: public:
TypeToDispatchTo *Owner; TypeToDispatchTo* Owner;
public: public:
EventListenerHelper_PageFault(TypeToDispatchTo &dispatchTo) EventListenerHelper_PageFault(TypeToDispatchTo& dispatchTo)
{ {
Owner = &dispatchTo; Owner = &dispatchTo;
} }
EventListenerHelper_PageFault(TypeToDispatchTo *dispatchTo) EventListenerHelper_PageFault(TypeToDispatchTo* dispatchTo)
{ {
Owner = dispatchTo; Owner = dispatchTo;
} }
@ -92,7 +92,7 @@ public:
virtual ~EventListenerHelper_PageFault() = default; virtual ~EventListenerHelper_PageFault() = default;
protected: protected:
virtual void OnPageFaultEvent(const PageFaultInfo &info, bool &handled) virtual void OnPageFaultEvent(const PageFaultInfo& info, bool& handled)
{ {
Owner->OnPageFaultEvent(info, handled); Owner->OnPageFaultEvent(info, handled);
} }
@ -117,10 +117,10 @@ public:
virtual ~SrcType_PageFault() = default; virtual ~SrcType_PageFault() = default;
bool WasHandled() const { return m_handled; } bool WasHandled() const { return m_handled; }
virtual void Dispatch(const PageFaultInfo &params); virtual void Dispatch(const PageFaultInfo& params);
protected: protected:
virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const PageFaultInfo &evt); virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator& iend, const PageFaultInfo& evt);
}; };
@ -137,7 +137,7 @@ class VirtualMemoryManager
uptr m_baseptr; uptr m_baseptr;
// An array to track page usage (to trigger asserts if things try to overlap) // An array to track page usage (to trigger asserts if things try to overlap)
std::atomic<bool> *m_pageuse; std::atomic<bool>* m_pageuse;
// reserved memory (in pages) // reserved memory (in pages)
u32 m_pages_reserved; u32 m_pages_reserved;
@ -146,20 +146,21 @@ public:
// If upper_bounds is nonzero and the OS fails to allocate memory that is below it, // If upper_bounds is nonzero and the OS fails to allocate memory that is below it,
// calls to IsOk() will return false and Alloc() will always return null pointers // calls to IsOk() will return false and Alloc() will always return null pointers
// strict indicates that the allocation should quietly fail if the memory can't be mapped at `base` // strict indicates that the allocation should quietly fail if the memory can't be mapped at `base`
VirtualMemoryManager(const wxString &name, uptr base, size_t size, uptr upper_bounds = 0, bool strict = false); VirtualMemoryManager(const wxString& name, uptr base, size_t size, uptr upper_bounds = 0, bool strict = false);
~VirtualMemoryManager(); ~VirtualMemoryManager();
void *GetBase() const { return (void *)m_baseptr; } void* GetBase() const { return (void*)m_baseptr; }
// Request the use of the memory at offsetLocation bytes from the start of the reserved memory area // Request the use of the memory at offsetLocation bytes from the start of the reserved memory area
// offsetLocation must be page-aligned // offsetLocation must be page-aligned
void *Alloc(uptr offsetLocation, size_t size) const; void* Alloc(uptr offsetLocation, size_t size) const;
void *AllocAtAddress(void *address, size_t size) const { void* AllocAtAddress(void* address, size_t size) const
{
return Alloc(size, (uptr)address - m_baseptr); return Alloc(size, (uptr)address - m_baseptr);
} }
void Free(void *address, size_t size) const; void Free(void* address, size_t size) const;
// Was this VirtualMemoryManager successfully able to get its memory mapping? // Was this VirtualMemoryManager successfully able to get its memory mapping?
// (If not, calls to Alloc will return null pointers) // (If not, calls to Alloc will return null pointers)
@ -176,9 +177,10 @@ class VirtualMemoryBumpAllocator
const VirtualMemoryManagerPtr m_allocator; const VirtualMemoryManagerPtr m_allocator;
std::atomic<uptr> m_baseptr{0}; std::atomic<uptr> m_baseptr{0};
const uptr m_endptr = 0; const uptr m_endptr = 0;
public: public:
VirtualMemoryBumpAllocator(VirtualMemoryManagerPtr allocator, size_t size, uptr offsetLocation); VirtualMemoryBumpAllocator(VirtualMemoryManagerPtr allocator, size_t size, uptr offsetLocation);
void *Alloc(size_t size); void* Alloc(size_t size);
const VirtualMemoryManagerPtr& GetAllocator() { return m_allocator; } const VirtualMemoryManagerPtr& GetAllocator() { return m_allocator; }
}; };
@ -200,7 +202,7 @@ protected:
// in the Reserve parameters. // in the Reserve parameters.
size_t m_defsize; size_t m_defsize;
void *m_baseptr; void* m_baseptr;
// reserved memory (in pages). // reserved memory (in pages).
uptr m_pages_reserved; uptr m_pages_reserved;
@ -223,7 +225,7 @@ protected:
virtual size_t GetSize(size_t requestedSize); virtual size_t GetSize(size_t requestedSize);
public: public:
VirtualMemoryReserve(const wxString &name, size_t size = 0); VirtualMemoryReserve(const wxString& name, size_t size = 0);
virtual ~VirtualMemoryReserve() virtual ~VirtualMemoryReserve()
{ {
Release(); Release();
@ -232,15 +234,15 @@ public:
// Initialize with the given piece of memory // Initialize with the given piece of memory
// Note: The memory is already allocated, the allocator is for future use to free the region // Note: The memory is already allocated, the allocator is for future use to free the region
// It may be null in which case there is no way to free the memory in a way it will be usable again // It may be null in which case there is no way to free the memory in a way it will be usable again
virtual void *Assign(VirtualMemoryManagerPtr allocator, void *baseptr, size_t size); virtual void* Assign(VirtualMemoryManagerPtr allocator, void* baseptr, size_t size);
void *Reserve(VirtualMemoryManagerPtr allocator, uptr baseOffset, size_t size = 0) void* Reserve(VirtualMemoryManagerPtr allocator, uptr baseOffset, size_t size = 0)
{ {
size = GetSize(size); size = GetSize(size);
void *allocation = allocator->Alloc(baseOffset, size); void* allocation = allocator->Alloc(baseOffset, size);
return Assign(std::move(allocator), allocation, size); return Assign(std::move(allocator), allocation, size);
} }
void *Reserve(VirtualMemoryBumpAllocator& allocator, size_t size = 0) void* Reserve(VirtualMemoryBumpAllocator& allocator, size_t size = 0)
{ {
size = GetSize(size); size = GetSize(size);
return Assign(allocator.GetAllocator(), allocator.Alloc(size), size); return Assign(allocator.GetAllocator(), allocator.Alloc(size), size);
@ -262,33 +264,33 @@ public:
uint GetCommittedPageCount() const { return m_pages_commited; } uint GetCommittedPageCount() const { return m_pages_commited; }
uint GetCommittedBytes() const { return m_pages_commited * __pagesize; } uint GetCommittedBytes() const { return m_pages_commited * __pagesize; }
u8 *GetPtr() { return (u8 *)m_baseptr; } u8* GetPtr() { return (u8*)m_baseptr; }
const u8 *GetPtr() const { return (u8 *)m_baseptr; } const u8* GetPtr() const { return (u8*)m_baseptr; }
u8 *GetPtrEnd() { return (u8 *)m_baseptr + (m_pages_reserved * __pagesize); } u8* GetPtrEnd() { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); }
const u8 *GetPtrEnd() const { return (u8 *)m_baseptr + (m_pages_reserved * __pagesize); } const u8* GetPtrEnd() const { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); }
VirtualMemoryReserve &SetPageAccessOnCommit(const PageProtectionMode &mode); VirtualMemoryReserve& SetPageAccessOnCommit(const PageProtectionMode& mode);
operator void *() { return m_baseptr; } operator void*() { return m_baseptr; }
operator const void *() const { return m_baseptr; } operator const void*() const { return m_baseptr; }
operator u8 *() { return (u8 *)m_baseptr; } operator u8*() { return (u8*)m_baseptr; }
operator const u8 *() const { return (u8 *)m_baseptr; } operator const u8*() const { return (u8*)m_baseptr; }
u8 &operator[](uint idx) u8& operator[](uint idx)
{ {
pxAssert(idx < (m_pages_reserved * __pagesize)); pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8 *)m_baseptr + idx); return *((u8*)m_baseptr + idx);
} }
const u8 &operator[](uint idx) const const u8& operator[](uint idx) const
{ {
pxAssert(idx < (m_pages_reserved * __pagesize)); pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8 *)m_baseptr + idx); return *((u8*)m_baseptr + idx);
} }
protected: protected:
virtual void ReprotectCommittedBlocks(const PageProtectionMode &newmode); virtual void ReprotectCommittedBlocks(const PageProtectionMode& newmode);
}; };
#ifdef __POSIX__ #ifdef __POSIX__
@ -299,7 +301,7 @@ protected:
#elif defined(_WIN32) #elif defined(_WIN32)
struct _EXCEPTION_POINTERS; struct _EXCEPTION_POINTERS;
extern long __stdcall SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS *eps); extern long __stdcall SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps);
#define PCSX2_PAGEFAULT_PROTECT __try #define PCSX2_PAGEFAULT_PROTECT __try
#define PCSX2_PAGEFAULT_EXCEPT \ #define PCSX2_PAGEFAULT_EXCEPT \
@ -313,5 +315,5 @@ extern void pxInstallSignalHandler();
extern void _platform_InstallSignalHandler(); extern void _platform_InstallSignalHandler();
#include "Threading.h" #include "Threading.h"
extern SrcType_PageFault *Source_PageFault; extern SrcType_PageFault* Source_PageFault;
extern Threading::Mutex PageFault_Mutex; extern Threading::Mutex PageFault_Mutex;

View File

@ -26,7 +26,7 @@
class wxDirName : protected wxFileName class wxDirName : protected wxFileName
{ {
public: public:
explicit wxDirName(const wxFileName &src) explicit wxDirName(const wxFileName& src)
{ {
Assign(src.GetPath(), wxEmptyString); Assign(src.GetPath(), wxEmptyString);
} }
@ -35,25 +35,25 @@ public:
: wxFileName() : wxFileName()
{ {
} }
wxDirName(const wxDirName &src) wxDirName(const wxDirName& src)
: wxFileName(src) : wxFileName(src)
{ {
} }
explicit wxDirName(const char *src) { Assign(fromUTF8(src)); } explicit wxDirName(const char* src) { Assign(fromUTF8(src)); }
explicit wxDirName(const wxString &src) { Assign(src); } explicit wxDirName(const wxString& src) { Assign(src); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void Assign(const wxString &volume, const wxString &path) void Assign(const wxString& volume, const wxString& path)
{ {
wxFileName::Assign(volume, path, wxEmptyString); wxFileName::Assign(volume, path, wxEmptyString);
} }
void Assign(const wxString &path) void Assign(const wxString& path)
{ {
wxFileName::Assign(path, wxEmptyString); wxFileName::Assign(path, wxEmptyString);
} }
void Assign(const wxDirName &path) void Assign(const wxDirName& path)
{ {
wxFileName::Assign(path); wxFileName::Assign(path);
} }
@ -73,20 +73,21 @@ public:
bool IsRelative() const { return wxFileName::IsRelative(); } bool IsRelative() const { return wxFileName::IsRelative(); }
bool IsAbsolute() const { return wxFileName::IsAbsolute(); } bool IsAbsolute() const { return wxFileName::IsAbsolute(); }
bool SameAs(const wxDirName &filepath) const bool SameAs(const wxDirName& filepath) const
{ {
return wxFileName::SameAs(filepath); return wxFileName::SameAs(filepath);
} }
//Returns true if the file is somewhere inside this directory (and both file and directory are not relative). //Returns true if the file is somewhere inside this directory (and both file and directory are not relative).
bool IsContains(const wxFileName &file) const bool IsContains(const wxFileName& file) const
{ {
if (this->IsRelative() || file.IsRelative()) if (this->IsRelative() || file.IsRelative())
return false; return false;
wxFileName f(file); wxFileName f(file);
while (1) { while (1)
{
if (this->SameAs(wxDirName(f.GetPath()))) if (this->SameAs(wxDirName(f.GetPath())))
return true; return true;
@ -99,7 +100,7 @@ public:
return false; return false;
} }
bool IsContains(const wxDirName &dir) const bool IsContains(const wxDirName& dir) const
{ {
return IsContains((wxFileName)dir); return IsContains((wxFileName)dir);
} }
@ -112,7 +113,7 @@ public:
// 4. else, result is absolute path of subject. // 4. else, result is absolute path of subject.
// //
// returns ok if both this and base are absolute paths. // returns ok if both this and base are absolute paths.
static wxString MakeAutoRelativeTo(const wxFileName _subject, const wxString &pathbase) static wxString MakeAutoRelativeTo(const wxFileName _subject, const wxString& pathbase)
{ {
wxFileName subject(_subject); wxFileName subject(_subject);
wxDirName base(pathbase); wxDirName base(pathbase);
@ -124,9 +125,12 @@ public:
wxString sv(subject.GetVolume()); wxString sv(subject.GetVolume());
sv.MakeUpper(); sv.MakeUpper();
if (base.IsContains(subject)) { if (base.IsContains(subject))
{
subject.MakeRelativeTo(base.GetFullPath()); subject.MakeRelativeTo(base.GetFullPath());
} else if (base.HasVolume() && subject.HasVolume() && bv == sv) { }
else if (base.HasVolume() && subject.HasVolume() && bv == sv)
{
wxString unusedVolume; wxString unusedVolume;
wxString pathSansVolume; wxString pathSansVolume;
subject.SplitVolume(subject.GetFullPath(), &unusedVolume, &pathSansVolume); subject.SplitVolume(subject.GetFullPath(), &unusedVolume, &pathSansVolume);
@ -137,7 +141,7 @@ public:
return subject.GetFullPath(); return subject.GetFullPath();
} }
static wxString MakeAutoRelativeTo(const wxDirName subject, const wxString &pathbase) static wxString MakeAutoRelativeTo(const wxDirName subject, const wxString& pathbase)
{ {
return MakeAutoRelativeTo(wxFileName(subject), pathbase); return MakeAutoRelativeTo(wxFileName(subject), pathbase);
} }
@ -146,19 +150,19 @@ public:
size_t GetCount() const { return GetDirCount(); } size_t GetCount() const { return GetDirCount(); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
wxFileName Combine(const wxFileName &right) const; wxFileName Combine(const wxFileName& right) const;
wxDirName Combine(const wxDirName &right) const; wxDirName Combine(const wxDirName& right) const;
// removes the lastmost directory from the path // removes the lastmost directory from the path
void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); } void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); }
wxDirName &Normalize(int flags = wxPATH_NORM_ALL, const wxString &cwd = wxEmptyString); wxDirName& Normalize(int flags = wxPATH_NORM_ALL, const wxString& cwd = wxEmptyString);
wxDirName &MakeRelativeTo(const wxString &pathBase = wxEmptyString); wxDirName& MakeRelativeTo(const wxString& pathBase = wxEmptyString);
wxDirName &MakeAbsolute(const wxString &cwd = wxEmptyString); wxDirName& MakeAbsolute(const wxString& cwd = wxEmptyString);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void AssignCwd(const wxString &volume = wxEmptyString) { wxFileName::AssignCwd(volume); } void AssignCwd(const wxString& volume = wxEmptyString) { wxFileName::AssignCwd(volume); }
bool SetCwd() { return wxFileName::SetCwd(); } bool SetCwd() { return wxFileName::SetCwd(); }
// wxWidgets is missing the const qualifier for this one! Shame! // wxWidgets is missing the const qualifier for this one! Shame!
@ -167,39 +171,39 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
wxDirName &operator=(const wxDirName &dirname) wxDirName& operator=(const wxDirName& dirname)
{ {
Assign(dirname); Assign(dirname);
return *this; return *this;
} }
wxDirName &operator=(const wxString &dirname) wxDirName& operator=(const wxString& dirname)
{ {
Assign(dirname); Assign(dirname);
return *this; return *this;
} }
wxDirName &operator=(const char *dirname) wxDirName& operator=(const char* dirname)
{ {
Assign(fromUTF8(dirname)); Assign(fromUTF8(dirname));
return *this; return *this;
} }
wxFileName operator+(const wxFileName &right) const { return Combine(right); } wxFileName operator+(const wxFileName& right) const { return Combine(right); }
wxDirName operator+(const wxDirName &right) const { return Combine(right); } wxDirName operator+(const wxDirName& right) const { return Combine(right); }
wxFileName operator+(const wxString &right) const { return Combine(wxFileName(right)); } wxFileName operator+(const wxString& right) const { return Combine(wxFileName(right)); }
wxFileName operator+(const char *right) const { return Combine(wxFileName(fromUTF8(right))); } wxFileName operator+(const char* right) const { return Combine(wxFileName(fromUTF8(right))); }
bool operator==(const wxDirName &filename) const { return SameAs(filename); } bool operator==(const wxDirName& filename) const { return SameAs(filename); }
bool operator!=(const wxDirName &filename) const { return !SameAs(filename); } bool operator!=(const wxDirName& filename) const { return !SameAs(filename); }
bool operator==(const wxFileName &filename) const { return SameAs(wxDirName(filename)); } bool operator==(const wxFileName& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxFileName &filename) const { return !SameAs(wxDirName(filename)); } bool operator!=(const wxFileName& filename) const { return !SameAs(wxDirName(filename)); }
// compare with a filename string interpreted as a native file name // compare with a filename string interpreted as a native file name
bool operator==(const wxString &filename) const { return SameAs(wxDirName(filename)); } bool operator==(const wxString& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxString &filename) const { return !SameAs(wxDirName(filename)); } bool operator!=(const wxString& filename) const { return !SameAs(wxDirName(filename)); }
const wxFileName &GetFilename() const { return *this; } const wxFileName& GetFilename() const { return *this; }
wxFileName &GetFilename() { return *this; } wxFileName& GetFilename() { return *this; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -211,20 +215,20 @@ public:
// //
namespace Path namespace Path
{ {
extern bool IsRelative(const wxString &path); extern bool IsRelative(const wxString& path);
extern s64 GetFileSize(const wxString &path); extern s64 GetFileSize(const wxString& path);
extern wxString Normalize(const wxString &srcpath); extern wxString Normalize(const wxString& srcpath);
extern wxString Normalize(const wxDirName &srcpath); extern wxString Normalize(const wxDirName& srcpath);
extern wxString MakeAbsolute(const wxString &srcpath); extern wxString MakeAbsolute(const wxString& srcpath);
extern wxString Combine(const wxString &srcPath, const wxString &srcFile); extern wxString Combine(const wxString& srcPath, const wxString& srcFile);
extern wxString Combine(const wxDirName &srcPath, const wxFileName &srcFile); extern wxString Combine(const wxDirName& srcPath, const wxFileName& srcFile);
extern wxString Combine(const wxString &srcPath, const wxDirName &srcFile); extern wxString Combine(const wxString& srcPath, const wxDirName& srcFile);
extern wxString ReplaceExtension(const wxString &src, const wxString &ext); extern wxString ReplaceExtension(const wxString& src, const wxString& ext);
extern wxString ReplaceFilename(const wxString &src, const wxString &newfilename); extern wxString ReplaceFilename(const wxString& src, const wxString& newfilename);
extern wxString GetFilename(const wxString &src); extern wxString GetFilename(const wxString& src);
extern wxString GetDirectory(const wxString &src); extern wxString GetDirectory(const wxString& src);
extern wxString GetFilenameWithoutExt(const wxString &src); extern wxString GetFilenameWithoutExt(const wxString& src);
extern wxString GetRootDirectory(const wxString &src); extern wxString GetRootDirectory(const wxString& src);
} } // namespace Path

View File

@ -22,7 +22,7 @@
// wxDirName (implementations) // wxDirName (implementations)
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
wxFileName wxDirName::Combine(const wxFileName &right) const wxFileName wxDirName::Combine(const wxFileName& right) const
{ {
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wxDirName concatenation."); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wxDirName concatenation.");
if (right.IsAbsolute()) if (right.IsAbsolute())
@ -37,7 +37,7 @@ wxFileName wxDirName::Combine(const wxFileName &right) const
return result; return result;
} }
wxDirName wxDirName::Combine(const wxDirName &right) const wxDirName wxDirName::Combine(const wxDirName& right) const
{ {
pxAssertMsg(IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation."); pxAssertMsg(IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation.");
@ -46,7 +46,7 @@ wxDirName wxDirName::Combine(const wxDirName &right) const
return result; return result;
} }
wxDirName &wxDirName::Normalize(int flags, const wxString &cwd) wxDirName& wxDirName::Normalize(int flags, const wxString& cwd)
{ {
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization."); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if (!wxFileName::Normalize(flags, cwd)) if (!wxFileName::Normalize(flags, cwd))
@ -54,7 +54,7 @@ wxDirName &wxDirName::Normalize(int flags, const wxString &cwd)
return *this; return *this;
} }
wxDirName &wxDirName::MakeRelativeTo(const wxString &pathBase) wxDirName& wxDirName::MakeRelativeTo(const wxString& pathBase)
{ {
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization."); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if (!wxFileName::MakeRelativeTo(pathBase)) if (!wxFileName::MakeRelativeTo(pathBase))
@ -62,7 +62,7 @@ wxDirName &wxDirName::MakeRelativeTo(const wxString &pathBase)
return *this; return *this;
} }
wxDirName &wxDirName::MakeAbsolute(const wxString &cwd) wxDirName& wxDirName::MakeAbsolute(const wxString& cwd)
{ {
pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization."); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if (!wxFileName::MakeAbsolute(cwd)) if (!wxFileName::MakeAbsolute(cwd))
@ -98,13 +98,13 @@ bool wxDirName::Mkdir()
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
bool Path::IsRelative(const wxString &path) bool Path::IsRelative(const wxString& path)
{ {
return wxDirName(path).IsRelative(); return wxDirName(path).IsRelative();
} }
// Returns -1 if the file does not exist. // Returns -1 if the file does not exist.
s64 Path::GetFileSize(const wxString &path) s64 Path::GetFileSize(const wxString& path)
{ {
if (!wxFile::Exists(path.c_str())) if (!wxFile::Exists(path.c_str()))
return -1; return -1;
@ -112,19 +112,19 @@ s64 Path::GetFileSize(const wxString &path)
} }
wxString Path::Normalize(const wxString &src) wxString Path::Normalize(const wxString& src)
{ {
wxFileName normalize(src); wxFileName normalize(src);
normalize.Normalize(); normalize.Normalize();
return normalize.GetFullPath(); return normalize.GetFullPath();
} }
wxString Path::Normalize(const wxDirName &src) wxString Path::Normalize(const wxDirName& src)
{ {
return wxDirName(src).Normalize().ToString(); return wxDirName(src).Normalize().ToString();
} }
wxString Path::MakeAbsolute(const wxString &src) wxString Path::MakeAbsolute(const wxString& src)
{ {
wxFileName absolute(src); wxFileName absolute(src);
absolute.MakeAbsolute(); absolute.MakeAbsolute();
@ -134,48 +134,48 @@ wxString Path::MakeAbsolute(const wxString &src)
// Concatenates two pathnames together, inserting delimiters (backslash on win32) // Concatenates two pathnames together, inserting delimiters (backslash on win32)
// as needed! Assumes the 'dest' is allocated to at least g_MaxPath length. // as needed! Assumes the 'dest' is allocated to at least g_MaxPath length.
// //
wxString Path::Combine(const wxString &srcPath, const wxString &srcFile) wxString Path::Combine(const wxString& srcPath, const wxString& srcFile)
{ {
return (wxDirName(srcPath) + srcFile).GetFullPath(); return (wxDirName(srcPath) + srcFile).GetFullPath();
} }
wxString Path::Combine(const wxDirName &srcPath, const wxFileName &srcFile) wxString Path::Combine(const wxDirName& srcPath, const wxFileName& srcFile)
{ {
return (srcPath + srcFile).GetFullPath(); return (srcPath + srcFile).GetFullPath();
} }
wxString Path::Combine(const wxString &srcPath, const wxDirName &srcFile) wxString Path::Combine(const wxString& srcPath, const wxDirName& srcFile)
{ {
return (wxDirName(srcPath) + srcFile).ToString(); return (wxDirName(srcPath) + srcFile).ToString();
} }
// Replaces the extension of the file with the one given. // Replaces the extension of the file with the one given.
// This function works for path names as well as file names. // This function works for path names as well as file names.
wxString Path::ReplaceExtension(const wxString &src, const wxString &ext) wxString Path::ReplaceExtension(const wxString& src, const wxString& ext)
{ {
wxFileName jojo(src); wxFileName jojo(src);
jojo.SetExt(ext); jojo.SetExt(ext);
return jojo.GetFullPath(); return jojo.GetFullPath();
} }
wxString Path::ReplaceFilename(const wxString &src, const wxString &newfilename) wxString Path::ReplaceFilename(const wxString& src, const wxString& newfilename)
{ {
wxFileName jojo(src); wxFileName jojo(src);
jojo.SetFullName(newfilename); jojo.SetFullName(newfilename);
return jojo.GetFullPath(); return jojo.GetFullPath();
} }
wxString Path::GetFilename(const wxString &src) wxString Path::GetFilename(const wxString& src)
{ {
return wxFileName(src).GetFullName(); return wxFileName(src).GetFullName();
} }
wxString Path::GetFilenameWithoutExt(const wxString &src) wxString Path::GetFilenameWithoutExt(const wxString& src)
{ {
return wxFileName(src).GetName(); return wxFileName(src).GetName();
} }
wxString Path::GetDirectory(const wxString &src) wxString Path::GetDirectory(const wxString& src)
{ {
return wxFileName(src).GetPath(); return wxFileName(src).GetPath();
} }
@ -183,7 +183,7 @@ wxString Path::GetDirectory(const wxString &src)
// returns the base/root directory of the given path. // returns the base/root directory of the given path.
// Example /this/that/something.txt -> dest == "/" // Example /this/that/something.txt -> dest == "/"
wxString Path::GetRootDirectory(const wxString &src) wxString Path::GetRootDirectory(const wxString& src)
{ {
size_t pos = src.find_first_of(wxFileName::GetPathSeparators()); size_t pos = src.find_first_of(wxFileName::GetPathSeparators());
if (pos == wxString::npos) if (pos == wxString::npos)
@ -195,12 +195,12 @@ wxString Path::GetRootDirectory(const wxString &src)
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Launches the specified file according to its mime type // Launches the specified file according to its mime type
// //
void pxLaunch(const wxString &filename) void pxLaunch(const wxString& filename)
{ {
wxLaunchDefaultBrowser(filename); wxLaunchDefaultBrowser(filename);
} }
void pxLaunch(const char *filename) void pxLaunch(const char* filename)
{ {
pxLaunch(fromUTF8(filename)); pxLaunch(fromUTF8(filename));
} }
@ -211,12 +211,12 @@ void pxLaunch(const char *filename)
// bypasses wxWidgets internal filename checking, which can end up launching things // bypasses wxWidgets internal filename checking, which can end up launching things
// through browser more often than desired. // through browser more often than desired.
// //
void pxExplore(const wxString &path) void pxExplore(const wxString& path)
{ {
wxLaunchDefaultBrowser(!path.Contains(L"://") ? L"file://" + path : path); wxLaunchDefaultBrowser(!path.Contains(L"://") ? L"file://" + path : path);
} }
void pxExplore(const char *path) void pxExplore(const char* path)
{ {
pxExplore(fromUTF8(path)); pxExplore(fromUTF8(path));
} }

View File

@ -94,12 +94,12 @@ union u128
operator u16() const { return _u16[0]; } operator u16() const { return _u16[0]; }
operator u8() const { return _u8[0]; } operator u8() const { return _u8[0]; }
bool operator==(const u128 &right) const bool operator==(const u128& right) const
{ {
return (lo == right.lo) && (hi == right.hi); return (lo == right.lo) && (hi == right.hi);
} }
bool operator!=(const u128 &right) const bool operator!=(const u128& right) const
{ {
return (lo != right.lo) || (hi != right.hi); return (lo != right.lo) || (hi != right.hi);
} }
@ -111,9 +111,9 @@ union u128
wxString ToString64() const; wxString ToString64() const;
wxString ToString8() const; wxString ToString8() const;
void WriteTo(FastFormatAscii &dest) const; void WriteTo(FastFormatAscii& dest) const;
void WriteTo8(FastFormatAscii &dest) const; void WriteTo8(FastFormatAscii& dest) const;
void WriteTo64(FastFormatAscii &dest) const; void WriteTo64(FastFormatAscii& dest) const;
}; };
struct s128 struct s128
@ -139,12 +139,12 @@ struct s128
operator u16() const { return (s16)lo; } operator u16() const { return (s16)lo; }
operator u8() const { return (s8)lo; } operator u8() const { return (s8)lo; }
bool operator==(const s128 &right) const bool operator==(const s128& right) const
{ {
return (lo == right.lo) && (hi == right.hi); return (lo == right.lo) && (hi == right.hi);
} }
bool operator!=(const s128 &right) const bool operator!=(const s128& right) const
{ {
return (lo != right.lo) || (hi != right.hi); return (lo != right.lo) || (hi != right.hi);
} }

View File

@ -33,63 +33,63 @@
namespace Perf namespace Perf
{ {
// Warning object aren't thread safe // Warning object aren't thread safe
InfoVector any(""); InfoVector any("");
InfoVector ee("EE"); InfoVector ee("EE");
InfoVector iop("IOP"); InfoVector iop("IOP");
InfoVector vu("VU"); InfoVector vu("VU");
InfoVector vif("VIF"); InfoVector vif("VIF");
// Perf is only supported on linux // Perf is only supported on linux
#if defined(__linux__) && (defined(ProfileWithPerf) || defined(ENABLE_VTUNE)) #if defined(__linux__) && (defined(ProfileWithPerf) || defined(ENABLE_VTUNE))
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Implementation of the Info object // Implementation of the Info object
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Info::Info(uptr x86, u32 size, const char *symbol) Info::Info(uptr x86, u32 size, const char* symbol)
: m_x86(x86) : m_x86(x86)
, m_size(size) , m_size(size)
, m_dynamic(false) , m_dynamic(false)
{ {
strncpy(m_symbol, symbol, sizeof(m_symbol)); strncpy(m_symbol, symbol, sizeof(m_symbol));
} }
Info::Info(uptr x86, u32 size, const char *symbol, u32 pc) Info::Info(uptr x86, u32 size, const char* symbol, u32 pc)
: m_x86(x86) : m_x86(x86)
, m_size(size) , m_size(size)
, m_dynamic(true) , m_dynamic(true)
{ {
snprintf(m_symbol, sizeof(m_symbol), "%s_0x%08x", symbol, pc); snprintf(m_symbol, sizeof(m_symbol), "%s_0x%08x", symbol, pc);
} }
void Info::Print(FILE *fp) void Info::Print(FILE* fp)
{ {
fprintf(fp, "%x %x %s\n", m_x86, m_size, m_symbol); fprintf(fp, "%x %x %s\n", m_x86, m_size, m_symbol);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Implementation of the InfoVector object // Implementation of the InfoVector object
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char *prefix) InfoVector::InfoVector(const char* prefix)
{ {
strncpy(m_prefix, prefix, sizeof(m_prefix)); strncpy(m_prefix, prefix, sizeof(m_prefix));
#ifdef ENABLE_VTUNE #ifdef ENABLE_VTUNE
m_vtune_id = iJIT_GetNewMethodID(); m_vtune_id = iJIT_GetNewMethodID();
#else #else
m_vtune_id = 0; m_vtune_id = 0;
#endif #endif
} }
void InfoVector::print(FILE *fp) void InfoVector::print(FILE* fp)
{ {
for (auto &&it : m_v) for (auto&& it : m_v)
it.Print(fp); it.Print(fp);
} }
void InfoVector::map(uptr x86, u32 size, const char *symbol) void InfoVector::map(uptr x86, u32 size, const char* symbol)
{ {
// This function is typically used for dispatcher and recompiler. // This function is typically used for dispatcher and recompiler.
// Dispatchers are on a page and must always be kept. // Dispatchers are on a page and must always be kept.
// Recompilers are much bigger (TODO check VIF) and are only // Recompilers are much bigger (TODO check VIF) and are only
@ -100,7 +100,8 @@ void InfoVector::map(uptr x86, u32 size, const char *symbol)
u32 max_code_size = _1gb; u32 max_code_size = _1gb;
#endif #endif
if (size < max_code_size) { if (size < max_code_size)
{
m_v.emplace_back(x86, size, symbol); m_v.emplace_back(x86, size, symbol);
#ifdef ENABLE_VTUNE #ifdef ENABLE_VTUNE
@ -111,8 +112,8 @@ void InfoVector::map(uptr x86, u32 size, const char *symbol)
memset(&ml, 0, sizeof(ml)); memset(&ml, 0, sizeof(ml));
ml.method_id = iJIT_GetNewMethodID(); ml.method_id = iJIT_GetNewMethodID();
ml.method_name = (char *)name.c_str(); ml.method_name = (char*)name.c_str();
ml.method_load_address = (void *)x86; ml.method_load_address = (void*)x86;
ml.method_size = size; ml.method_size = size;
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &ml); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &ml);
@ -120,10 +121,10 @@ void InfoVector::map(uptr x86, u32 size, const char *symbol)
//fprintf(stderr, "mapF %s: %p size %dKB\n", ml.method_name, ml.method_load_address, ml.method_size / 1024u); //fprintf(stderr, "mapF %s: %p size %dKB\n", ml.method_name, ml.method_load_address, ml.method_size / 1024u);
#endif #endif
} }
} }
void InfoVector::map(uptr x86, u32 size, u32 pc) void InfoVector::map(uptr x86, u32 size, u32 pc)
{ {
#ifndef MERGE_BLOCK_RESULT #ifndef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, m_prefix, pc); m_v.emplace_back(x86, size, m_prefix, pc);
#endif #endif
@ -139,32 +140,32 @@ void InfoVector::map(uptr x86, u32 size, u32 pc)
#else #else
std::string name = std::string(m_prefix) + "_" + std::to_string(pc); std::string name = std::string(m_prefix) + "_" + std::to_string(pc);
ml.method_id = iJIT_GetNewMethodID(); ml.method_id = iJIT_GetNewMethodID();
ml.method_name = (char *)name.c_str(); ml.method_name = (char*)name.c_str();
#endif #endif
ml.method_load_address = (void *)x86; ml.method_load_address = (void*)x86;
ml.method_size = size; ml.method_size = size;
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, &ml); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, &ml);
//fprintf(stderr, "mapB %s: %p size %d\n", ml.method_name, ml.method_load_address, ml.method_size); //fprintf(stderr, "mapB %s: %p size %d\n", ml.method_name, ml.method_load_address, ml.method_size);
#endif #endif
} }
void InfoVector::reset() void InfoVector::reset()
{ {
auto dynamic = std::remove_if(m_v.begin(), m_v.end(), [](Info i) { return i.m_dynamic; }); auto dynamic = std::remove_if(m_v.begin(), m_v.end(), [](Info i) { return i.m_dynamic; });
m_v.erase(dynamic, m_v.end()); m_v.erase(dynamic, m_v.end());
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Global function // Global function
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void dump() void dump()
{ {
char file[256]; char file[256];
snprintf(file, 250, "/tmp/perf-%d.map", getpid()); snprintf(file, 250, "/tmp/perf-%d.map", getpid());
FILE *fp = fopen(file, "w"); FILE* fp = fopen(file, "w");
any.print(fp); any.print(fp);
ee.print(fp); ee.print(fp);
@ -173,34 +174,34 @@ void dump()
if (fp) if (fp)
fclose(fp); fclose(fp);
} }
void dump_and_reset() void dump_and_reset()
{ {
dump(); dump();
any.reset(); any.reset();
ee.reset(); ee.reset();
iop.reset(); iop.reset();
vu.reset(); vu.reset();
} }
#else #else
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Dummy implementation // Dummy implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char *prefix) InfoVector::InfoVector(const char* prefix)
: m_vtune_id(0) : m_vtune_id(0)
{ {
} }
void InfoVector::map(uptr x86, u32 size, const char *symbol) {} void InfoVector::map(uptr x86, u32 size, const char* symbol) {}
void InfoVector::map(uptr x86, u32 size, u32 pc) {} void InfoVector::map(uptr x86, u32 size, u32 pc) {}
void InfoVector::reset() {} void InfoVector::reset() {}
void dump() {} void dump() {}
void dump_and_reset() {} void dump_and_reset() {}
#endif #endif
} } // namespace Perf

View File

@ -22,8 +22,8 @@
namespace Perf namespace Perf
{ {
struct Info struct Info
{ {
uptr m_x86; uptr m_x86;
u32 m_size; u32 m_size;
char m_symbol[20]; char m_symbol[20];
@ -31,32 +31,32 @@ struct Info
// once. // once.
bool m_dynamic; bool m_dynamic;
Info(uptr x86, u32 size, const char *symbol); Info(uptr x86, u32 size, const char* symbol);
Info(uptr x86, u32 size, const char *symbol, u32 pc); Info(uptr x86, u32 size, const char* symbol, u32 pc);
void Print(FILE *fp); void Print(FILE* fp);
}; };
class InfoVector class InfoVector
{ {
std::vector<Info> m_v; std::vector<Info> m_v;
char m_prefix[20]; char m_prefix[20];
unsigned int m_vtune_id; unsigned int m_vtune_id;
public: public:
InfoVector(const char *prefix); InfoVector(const char* prefix);
void print(FILE *fp); void print(FILE* fp);
void map(uptr x86, u32 size, const char *symbol); void map(uptr x86, u32 size, const char* symbol);
void map(uptr x86, u32 size, u32 pc); void map(uptr x86, u32 size, u32 pc);
void reset(); void reset();
}; };
void dump(); void dump();
void dump_and_reset(); void dump_and_reset();
extern InfoVector any; extern InfoVector any;
extern InfoVector ee; extern InfoVector ee;
extern InfoVector iop; extern InfoVector iop;
extern InfoVector vu; extern InfoVector vu;
extern InfoVector vif; extern InfoVector vif;
} } // namespace Perf

View File

@ -22,18 +22,18 @@
namespace Threading namespace Threading
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ThreadDeleteEvent // ThreadDeleteEvent
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class EventListener_Thread : public IEventDispatcher<int> class EventListener_Thread : public IEventDispatcher<int>
{ {
public: public:
typedef int EvtParams; typedef int EvtParams;
protected: protected:
pxThread *m_thread; pxThread* m_thread;
public: public:
EventListener_Thread() EventListener_Thread()
{ {
m_thread = NULL; m_thread = NULL;
@ -41,60 +41,60 @@ public:
virtual ~EventListener_Thread() = default; virtual ~EventListener_Thread() = default;
void SetThread(pxThread &thr) { m_thread = &thr; } void SetThread(pxThread& thr) { m_thread = &thr; }
void SetThread(pxThread *thr) { m_thread = thr; } void SetThread(pxThread* thr) { m_thread = thr; }
void DispatchEvent(const int &params) void DispatchEvent(const int& params)
{ {
OnThreadCleanup(); OnThreadCleanup();
} }
protected: protected:
// Invoked by the pxThread when the thread execution is ending. This is // Invoked by the pxThread when the thread execution is ending. This is
// typically more useful than a delete listener since the extended thread information // typically more useful than a delete listener since the extended thread information
// provided by virtualized functions/methods will be available. // provided by virtualized functions/methods will be available.
// Important! This event is executed *by the thread*, so care must be taken to ensure // Important! This event is executed *by the thread*, so care must be taken to ensure
// thread sync when necessary (posting messages to the main thread, etc). // thread sync when necessary (posting messages to the main thread, etc).
virtual void OnThreadCleanup() = 0; virtual void OnThreadCleanup() = 0;
}; };
/// Set the name of the current thread /// Set the name of the current thread
void SetNameOfCurrentThread(const char* name); void SetNameOfCurrentThread(const char* name);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxThread - Helper class for the basics of starting/managing persistent threads. // pxThread - Helper class for the basics of starting/managing persistent threads.
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This class is meant to be a helper for the typical threading model of "start once and // This class is meant to be a helper for the typical threading model of "start once and
// reuse many times." This class incorporates a lot of extra overhead in stopping and // reuse many times." This class incorporates a lot of extra overhead in stopping and
// starting threads, but in turn provides most of the basic thread-safety and event-handling // starting threads, but in turn provides most of the basic thread-safety and event-handling
// functionality needed for a threaded operation. In practice this model is usually an // functionality needed for a threaded operation. In practice this model is usually an
// ideal one for efficiency since Operating Systems themselves typically subscribe to a // ideal one for efficiency since Operating Systems themselves typically subscribe to a
// design where sleeping, suspending, and resuming threads is very efficient, but starting // design where sleeping, suspending, and resuming threads is very efficient, but starting
// new threads has quite a bit of overhead. // new threads has quite a bit of overhead.
// //
// To use this as a base class for your threaded procedure, overload the following virtual // To use this as a base class for your threaded procedure, overload the following virtual
// methods: // methods:
// void OnStart(); // void OnStart();
// void ExecuteTaskInThread(); // void ExecuteTaskInThread();
// void OnCleanupInThread(); // void OnCleanupInThread();
// //
// Use the public methods Start() and Cancel() to start and shutdown the thread, and use // Use the public methods Start() and Cancel() to start and shutdown the thread, and use
// m_sem_event internally to post/receive events for the thread (make a public accessor for // m_sem_event internally to post/receive events for the thread (make a public accessor for
// it in your derived class if your thread utilizes the post). // it in your derived class if your thread utilizes the post).
// //
// Notes: // Notes:
// * Constructing threads as static global vars isn't recommended since it can potentially // * Constructing threads as static global vars isn't recommended since it can potentially
// confuse w32pthreads, if the static initializers are executed out-of-order (C++ offers // confuse w32pthreads, if the static initializers are executed out-of-order (C++ offers
// no dependency options for ensuring correct static var initializations). Use heap // no dependency options for ensuring correct static var initializations). Use heap
// allocation to create thread objects instead. // allocation to create thread objects instead.
// //
class pxThread class pxThread
{ {
DeclareNoncopyableObject(pxThread); DeclareNoncopyableObject(pxThread);
friend void pxYield(int ms); friend void pxYield(int ms);
protected: protected:
wxString m_name; // diagnostic name for our thread. wxString m_name; // diagnostic name for our thread.
pthread_t m_thread; pthread_t m_thread;
uptr m_native_id; // typically an id, but implementing platforms can do whatever. uptr m_native_id; // typically an id, but implementing platforms can do whatever.
@ -116,42 +116,42 @@ protected:
EventSource<EventListener_Thread> m_evtsrc_OnDelete; EventSource<EventListener_Thread> m_evtsrc_OnDelete;
public: public:
virtual ~pxThread(); virtual ~pxThread();
pxThread(const wxString &name = L"pxThread"); pxThread(const wxString& name = L"pxThread");
pthread_t GetId() const { return m_thread; } pthread_t GetId() const { return m_thread; }
u64 GetCpuTime() const; u64 GetCpuTime() const;
virtual void Start(); virtual void Start();
virtual void Cancel(bool isBlocking = true); virtual void Cancel(bool isBlocking = true);
virtual bool Cancel(const wxTimeSpan &timeout); virtual bool Cancel(const wxTimeSpan& timeout);
virtual bool Detach(); virtual bool Detach();
virtual void Block(); virtual void Block();
virtual bool Block(const wxTimeSpan &timeout); virtual bool Block(const wxTimeSpan& timeout);
virtual void RethrowException() const; virtual void RethrowException() const;
void AddListener(EventListener_Thread &evt); void AddListener(EventListener_Thread& evt);
void AddListener(EventListener_Thread *evt) void AddListener(EventListener_Thread* evt)
{ {
if (evt == NULL) if (evt == NULL)
return; return;
AddListener(*evt); AddListener(*evt);
} }
void WaitOnSelf(Semaphore &mutex) const; void WaitOnSelf(Semaphore& mutex) const;
void WaitOnSelf(Mutex &mutex) const; void WaitOnSelf(Mutex& mutex) const;
bool WaitOnSelf(Semaphore &mutex, const wxTimeSpan &timeout) const; bool WaitOnSelf(Semaphore& mutex, const wxTimeSpan& timeout) const;
bool WaitOnSelf(Mutex &mutex, const wxTimeSpan &timeout) const; bool WaitOnSelf(Mutex& mutex, const wxTimeSpan& timeout) const;
bool IsRunning() const; bool IsRunning() const;
bool IsSelf() const; bool IsSelf() const;
bool HasPendingException() const { return !!m_except; } bool HasPendingException() const { return !!m_except; }
wxString GetName() const; wxString GetName() const;
void SetName(const wxString &newname); void SetName(const wxString& newname);
protected: protected:
// Extending classes should always implement your own OnStart(), which is called by // Extending classes should always implement your own OnStart(), which is called by
// Start() once necessary locks have been obtained. Do not override Start() directly // Start() once necessary locks have been obtained. Do not override Start() directly
// unless you're really sure that's what you need to do. ;) // unless you're really sure that's what you need to do. ;)
@ -184,10 +184,10 @@ protected:
TestCancel(); TestCancel();
} }
void FrankenMutex(Mutex &mutex); void FrankenMutex(Mutex& mutex);
bool AffinityAssert_AllowFromSelf(const DiagnosticOrigin &origin) const; bool AffinityAssert_AllowFromSelf(const DiagnosticOrigin& origin) const;
bool AffinityAssert_DisallowFromSelf(const DiagnosticOrigin &origin) const; bool AffinityAssert_DisallowFromSelf(const DiagnosticOrigin& origin) const;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Section of methods for internal use only. // Section of methods for internal use only.
@ -195,15 +195,15 @@ protected:
void _platform_specific_OnStartInThread(); void _platform_specific_OnStartInThread();
void _platform_specific_OnCleanupInThread(); void _platform_specific_OnCleanupInThread();
bool _basecancel(); bool _basecancel();
void _selfRunningTest(const wxChar *name) const; void _selfRunningTest(const wxChar* name) const;
void _DoSetThreadName(const wxString &name); void _DoSetThreadName(const wxString& name);
void _DoSetThreadName(const char *name) { SetNameOfCurrentThread(name); } void _DoSetThreadName(const char* name) { SetNameOfCurrentThread(name); }
void _internal_execute(); void _internal_execute();
void _try_virtual_invoke(void (pxThread::*method)()); void _try_virtual_invoke(void (pxThread::*method)());
void _ThreadCleanup(); void _ThreadCleanup();
static void *_internal_callback(void *func); static void* _internal_callback(void* func);
static void internal_callback_helper(void *func); static void internal_callback_helper(void* func);
static void _pt_callback_cleanup(void *handle); static void _pt_callback_cleanup(void* handle);
}; };
} } // namespace Threading

View File

@ -74,7 +74,7 @@ void Threading::BaseScopedReadWriteLock::Release()
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedReadLock / ScopedWriteLock // ScopedReadLock / ScopedWriteLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
Threading::ScopedReadLock::ScopedReadLock(RwMutex &locker) Threading::ScopedReadLock::ScopedReadLock(RwMutex& locker)
: BaseScopedReadWriteLock(locker) : BaseScopedReadWriteLock(locker)
{ {
m_IsLocked = true; m_IsLocked = true;
@ -90,7 +90,7 @@ void Threading::ScopedReadLock::Acquire()
m_IsLocked = true; m_IsLocked = true;
} }
Threading::ScopedWriteLock::ScopedWriteLock(RwMutex &locker) Threading::ScopedWriteLock::ScopedWriteLock(RwMutex& locker)
: BaseScopedReadWriteLock(locker) : BaseScopedReadWriteLock(locker)
{ {
m_IsLocked = true; m_IsLocked = true;
@ -107,7 +107,7 @@ void Threading::ScopedWriteLock::Acquire()
} }
// Special constructor used by ScopedTryLock // Special constructor used by ScopedTryLock
Threading::ScopedWriteLock::ScopedWriteLock(RwMutex &locker, bool isTryLock) Threading::ScopedWriteLock::ScopedWriteLock(RwMutex& locker, bool isTryLock)
: BaseScopedReadWriteLock(locker) : BaseScopedReadWriteLock(locker)
{ {
//m_IsLocked = isTryLock ? m_lock.TryAcquireWrite() : false; //m_IsLocked = isTryLock ? m_lock.TryAcquireWrite() : false;

View File

@ -19,17 +19,17 @@
namespace Threading namespace Threading
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// RwMutex // RwMutex
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class RwMutex class RwMutex
{ {
DeclareNoncopyableObject(RwMutex); DeclareNoncopyableObject(RwMutex);
protected: protected:
pthread_rwlock_t m_rwlock; pthread_rwlock_t m_rwlock;
public: public:
RwMutex(); RwMutex();
virtual ~RwMutex(); virtual ~RwMutex();
@ -39,21 +39,21 @@ public:
virtual bool TryAcquireWrite(); virtual bool TryAcquireWrite();
virtual void Release(); virtual void Release();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// BaseScopedReadWriteLock // BaseScopedReadWriteLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class BaseScopedReadWriteLock class BaseScopedReadWriteLock
{ {
DeclareNoncopyableObject(BaseScopedReadWriteLock); DeclareNoncopyableObject(BaseScopedReadWriteLock);
protected: protected:
RwMutex &m_lock; RwMutex& m_lock;
bool m_IsLocked; bool m_IsLocked;
public: public:
BaseScopedReadWriteLock(RwMutex &locker) BaseScopedReadWriteLock(RwMutex& locker)
: m_lock(locker) : m_lock(locker)
{ {
} }
@ -62,29 +62,29 @@ public:
void Release(); void Release();
bool IsLocked() const { return m_IsLocked; } bool IsLocked() const { return m_IsLocked; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedReadLock / ScopedWriteLock // ScopedReadLock / ScopedWriteLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class ScopedReadLock : public BaseScopedReadWriteLock class ScopedReadLock : public BaseScopedReadWriteLock
{ {
public: public:
ScopedReadLock(RwMutex &locker); ScopedReadLock(RwMutex& locker);
virtual ~ScopedReadLock() = default; virtual ~ScopedReadLock() = default;
void Acquire(); void Acquire();
}; };
class ScopedWriteLock : public BaseScopedReadWriteLock class ScopedWriteLock : public BaseScopedReadWriteLock
{ {
public: public:
ScopedWriteLock(RwMutex &locker); ScopedWriteLock(RwMutex& locker);
virtual ~ScopedWriteLock() = default; virtual ~ScopedWriteLock() = default;
void Acquire(); void Acquire();
protected: protected:
ScopedWriteLock(RwMutex &locker, bool isTryLock); ScopedWriteLock(RwMutex& locker, bool isTryLock);
}; };
} } // namespace Threading

View File

@ -47,22 +47,22 @@ public:
int ChunkSize; int ChunkSize;
protected: protected:
T *m_ptr; T* m_ptr;
int m_size; // size of the allocation of memory int m_size; // size of the allocation of memory
protected: protected:
SafeArray(const wxChar *name, T *allocated_mem, int initSize); SafeArray(const wxChar* name, T* allocated_mem, int initSize);
virtual T *_virtual_realloc(int newsize); virtual T* _virtual_realloc(int newsize);
// A safe array index fetcher. Asserts if the index is out of bounds (dev and debug // A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
// builds only -- no bounds checking is done in release builds). // builds only -- no bounds checking is done in release builds).
T *_getPtr(uint i) const; T* _getPtr(uint i) const;
public: public:
virtual ~SafeArray(); virtual ~SafeArray();
explicit SafeArray(const wxChar *name = L"Unnamed"); explicit SafeArray(const wxChar* name = L"Unnamed");
explicit SafeArray(int initialSize, const wxChar *name = L"Unnamed"); explicit SafeArray(int initialSize, const wxChar* name = L"Unnamed");
void Dispose(); void Dispose();
void ExactAlloc(int newsize); void ExactAlloc(int newsize);
@ -88,21 +88,21 @@ public:
// Gets a pointer to the requested allocation index. // Gets a pointer to the requested allocation index.
// DevBuilds : Generates assertion if the index is invalid. // DevBuilds : Generates assertion if the index is invalid.
T *GetPtr(uint idx = 0) { return _getPtr(idx); } T* GetPtr(uint idx = 0) { return _getPtr(idx); }
const T *GetPtr(uint idx = 0) const { return _getPtr(idx); } const T* GetPtr(uint idx = 0) const { return _getPtr(idx); }
// Gets a pointer to the element directly after the last element in the array. // Gets a pointer to the element directly after the last element in the array.
// This is equivalent to doing GetPtr(GetLength()), except that this call *avoids* // This is equivalent to doing GetPtr(GetLength()), except that this call *avoids*
// the out-of-bounds assertion check that typically occurs when you do that. :) // the out-of-bounds assertion check that typically occurs when you do that. :)
T *GetPtrEnd() { return &m_ptr[m_size]; } T* GetPtrEnd() { return &m_ptr[m_size]; }
const T *GetPtrEnd() const { return &m_ptr[m_size]; } const T* GetPtrEnd() const { return &m_ptr[m_size]; }
// Gets an element of this memory allocation much as if it were an array. // Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid. // DevBuilds : Generates assertion if the index is invalid.
T &operator[](int idx) { return *_getPtr((uint)idx); } T& operator[](int idx) { return *_getPtr((uint)idx); }
const T &operator[](int idx) const { return *_getPtr((uint)idx); } const T& operator[](int idx) const { return *_getPtr((uint)idx); }
virtual SafeArray<T> *Clone() const; virtual SafeArray<T>* Clone() const;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -128,28 +128,28 @@ public:
int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time. int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
protected: protected:
T *m_ptr; T* m_ptr;
int m_allocsize; // size of the allocation of memory int m_allocsize; // size of the allocation of memory
uint m_length; // length of the array (active items, not buffer allocation) uint m_length; // length of the array (active items, not buffer allocation)
protected: protected:
virtual T *_virtual_realloc(int newsize); virtual T* _virtual_realloc(int newsize);
void _MakeRoomFor_threshold(int newsize); void _MakeRoomFor_threshold(int newsize);
T *_getPtr(uint i) const; T* _getPtr(uint i) const;
public: public:
virtual ~SafeList(); virtual ~SafeList();
explicit SafeList(const wxChar *name = L"Unnamed"); explicit SafeList(const wxChar* name = L"Unnamed");
explicit SafeList(int initialSize, const wxChar *name = L"Unnamed"); explicit SafeList(int initialSize, const wxChar* name = L"Unnamed");
virtual SafeList<T> *Clone() const; virtual SafeList<T>* Clone() const;
void Remove(int index); void Remove(int index);
void MakeRoomFor(int blockSize); void MakeRoomFor(int blockSize);
T &New(); T& New();
int Add(const T &src); int Add(const T& src);
T &AddNew(const T &src); T& AddNew(const T& src);
// Returns the size of the list, as according to the array type. This includes // Returns the size of the list, as according to the array type. This includes
// mapped items only. The actual size of the allocation may differ. // mapped items only. The actual size of the allocation may differ.
@ -177,14 +177,14 @@ public:
// Gets an element of this memory allocation much as if it were an array. // Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid. // DevBuilds : Generates assertion if the index is invalid.
T &operator[](int idx) { return *_getPtr((uint)idx); } T& operator[](int idx) { return *_getPtr((uint)idx); }
const T &operator[](int idx) const { return *_getPtr((uint)idx); } const T& operator[](int idx) const { return *_getPtr((uint)idx); }
T *GetPtr() { return m_ptr; } T* GetPtr() { return m_ptr; }
const T *GetPtr() const { return m_ptr; } const T* GetPtr() const { return m_ptr; }
T &GetLast() { return m_ptr[m_length - 1]; } T& GetLast() { return m_ptr[m_length - 1]; }
const T &GetLast() const { return m_ptr[m_length - 1]; } const T& GetLast() const { return m_ptr[m_length - 1]; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -200,18 +200,18 @@ class SafeAlignedArray : public SafeArray<T>
typedef SafeArray<T> _parent; typedef SafeArray<T> _parent;
protected: protected:
T *_virtual_realloc(int newsize); T* _virtual_realloc(int newsize);
public: public:
using _parent::operator[]; using _parent::operator[];
virtual ~SafeAlignedArray(); virtual ~SafeAlignedArray();
explicit SafeAlignedArray(const wxChar *name = L"Unnamed") explicit SafeAlignedArray(const wxChar* name = L"Unnamed")
: SafeArray<T>::SafeArray(name) : SafeArray<T>::SafeArray(name)
{ {
} }
explicit SafeAlignedArray(int initialSize, const wxChar *name = L"Unnamed"); explicit SafeAlignedArray(int initialSize, const wxChar* name = L"Unnamed");
virtual SafeAlignedArray<T, Alignment> *Clone() const; virtual SafeAlignedArray<T, Alignment>* Clone() const;
}; };

View File

@ -23,7 +23,7 @@
// Throws: // Throws:
// Exception::OutOfMemory if the allocated_mem pointer is NULL. // Exception::OutOfMemory if the allocated_mem pointer is NULL.
template <typename T> template <typename T>
SafeArray<T>::SafeArray(const wxChar *name, T *allocated_mem, int initSize) SafeArray<T>::SafeArray(const wxChar* name, T* allocated_mem, int initSize)
: Name(name) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
@ -36,18 +36,19 @@ SafeArray<T>::SafeArray(const wxChar *name, T *allocated_mem, int initSize)
} }
template <typename T> template <typename T>
T *SafeArray<T>::_virtual_realloc(int newsize) T* SafeArray<T>::_virtual_realloc(int newsize)
{ {
T *retval = (T *)((m_ptr == NULL) ? T* retval = (T*)((m_ptr == NULL) ?
malloc(newsize * sizeof(T)) : malloc(newsize * sizeof(T)) :
realloc(m_ptr, newsize * sizeof(T))); realloc(m_ptr, newsize * sizeof(T)));
if (IsDebugBuild && (retval != NULL)) { if (IsDebugBuild && (retval != NULL))
{
// Zero everything out to 0xbaadf00d, so that its obviously uncleared // Zero everything out to 0xbaadf00d, so that its obviously uncleared
// to a debuggee // to a debuggee
u32 *fill = (u32 *)&retval[m_size]; u32* fill = (u32*)&retval[m_size];
const u32 *end = (u32 *)((((uptr)&retval[newsize - 1]) - 3) & ~0x3); const u32* end = (u32*)((((uptr)&retval[newsize - 1]) - 3) & ~0x3);
for (; fill < end; ++fill) for (; fill < end; ++fill)
*fill = 0xbaadf00d; *fill = 0xbaadf00d;
} }
@ -62,7 +63,7 @@ SafeArray<T>::~SafeArray()
} }
template <typename T> template <typename T>
SafeArray<T>::SafeArray(const wxChar *name) SafeArray<T>::SafeArray(const wxChar* name)
: Name(name) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
@ -71,11 +72,11 @@ SafeArray<T>::SafeArray(const wxChar *name)
} }
template <typename T> template <typename T>
SafeArray<T>::SafeArray(int initialSize, const wxChar *name) SafeArray<T>::SafeArray(int initialSize, const wxChar* name)
: Name(name) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
m_ptr = (initialSize == 0) ? NULL : (T *)malloc(initialSize * sizeof(T)); m_ptr = (initialSize == 0) ? NULL : (T*)malloc(initialSize * sizeof(T));
m_size = initialSize; m_size = initialSize;
if ((initialSize != 0) && (m_ptr == NULL)) if ((initialSize != 0) && (m_ptr == NULL))
@ -92,7 +93,7 @@ void SafeArray<T>::Dispose()
} }
template <typename T> template <typename T>
T *SafeArray<T>::_getPtr(uint i) const T* SafeArray<T>::_getPtr(uint i) const
{ {
IndexBoundsAssumeDev(WX_STR(Name), i, m_size); IndexBoundsAssumeDev(WX_STR(Name), i, m_size);
return &m_ptr[i]; return &m_ptr[i];
@ -115,9 +116,9 @@ void SafeArray<T>::ExactAlloc(int newsize)
} }
template <typename T> template <typename T>
SafeArray<T> *SafeArray<T>::Clone() const SafeArray<T>* SafeArray<T>::Clone() const
{ {
SafeArray<T> *retval = new SafeArray<T>(m_size); SafeArray<T>* retval = new SafeArray<T>(m_size);
memcpy(retval->GetPtr(), m_ptr, sizeof(T) * m_size); memcpy(retval->GetPtr(), m_ptr, sizeof(T) * m_size);
return retval; return retval;
} }
@ -128,9 +129,9 @@ SafeArray<T> *SafeArray<T>::Clone() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
template <typename T, uint Alignment> template <typename T, uint Alignment>
T *SafeAlignedArray<T, Alignment>::_virtual_realloc(int newsize) T* SafeAlignedArray<T, Alignment>::_virtual_realloc(int newsize)
{ {
return (T *)((this->m_ptr == NULL) ? return (T*)((this->m_ptr == NULL) ?
_aligned_malloc(newsize * sizeof(T), Alignment) : _aligned_malloc(newsize * sizeof(T), Alignment) :
pcsx2_aligned_realloc(this->m_ptr, newsize * sizeof(T), Alignment, this->m_size * sizeof(T))); pcsx2_aligned_realloc(this->m_ptr, newsize * sizeof(T), Alignment, this->m_size * sizeof(T)));
} }
@ -146,18 +147,18 @@ SafeAlignedArray<T, Alignment>::~SafeAlignedArray()
} }
template <typename T, uint Alignment> template <typename T, uint Alignment>
SafeAlignedArray<T, Alignment>::SafeAlignedArray(int initialSize, const wxChar *name) SafeAlignedArray<T, Alignment>::SafeAlignedArray(int initialSize, const wxChar* name)
: SafeArray<T>::SafeArray( : SafeArray<T>::SafeArray(
name, name,
(T *)_aligned_malloc(initialSize * sizeof(T), Alignment), (T*)_aligned_malloc(initialSize * sizeof(T), Alignment),
initialSize) initialSize)
{ {
} }
template <typename T, uint Alignment> template <typename T, uint Alignment>
SafeAlignedArray<T, Alignment> *SafeAlignedArray<T, Alignment>::Clone() const SafeAlignedArray<T, Alignment>* SafeAlignedArray<T, Alignment>::Clone() const
{ {
SafeAlignedArray<T, Alignment> *retval = new SafeAlignedArray<T, Alignment>(this->m_size); SafeAlignedArray<T, Alignment>* retval = new SafeAlignedArray<T, Alignment>(this->m_size);
memcpy(retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size); memcpy(retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size);
return retval; return retval;
} }
@ -167,9 +168,9 @@ SafeAlignedArray<T, Alignment> *SafeAlignedArray<T, Alignment>::Clone() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
template <typename T> template <typename T>
T *SafeList<T>::_virtual_realloc(int newsize) T* SafeList<T>::_virtual_realloc(int newsize)
{ {
return (T *)realloc(m_ptr, newsize * sizeof(T)); return (T*)realloc(m_ptr, newsize * sizeof(T));
} }
template <typename T> template <typename T>
@ -179,7 +180,7 @@ SafeList<T>::~SafeList()
} }
template <typename T> template <typename T>
SafeList<T>::SafeList(const wxChar *name) SafeList<T>::SafeList(const wxChar* name)
: Name(name) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
@ -189,25 +190,26 @@ SafeList<T>::SafeList(const wxChar *name)
} }
template <typename T> template <typename T>
SafeList<T>::SafeList(int initialSize, const wxChar *name) SafeList<T>::SafeList(int initialSize, const wxChar* name)
: Name(name) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
m_allocsize = initialSize; m_allocsize = initialSize;
m_length = 0; m_length = 0;
m_ptr = (T *)malloc(initialSize * sizeof(T)); m_ptr = (T*)malloc(initialSize * sizeof(T));
if (m_ptr == NULL) if (m_ptr == NULL)
throw Exception::OutOfMemory(Name) throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"called from 'SafeList::ctor' [length=%d]", m_length)); .SetDiagMsg(wxsFormat(L"called from 'SafeList::ctor' [length=%d]", m_length));
for (int i = 0; i < m_allocsize; ++i) { for (int i = 0; i < m_allocsize; ++i)
{
new (&m_ptr[i]) T(); new (&m_ptr[i]) T();
} }
} }
template <typename T> template <typename T>
T *SafeList<T>::_getPtr(uint i) const T* SafeList<T>::_getPtr(uint i) const
{ {
IndexBoundsAssumeDev(WX_STR(Name), i, m_length); IndexBoundsAssumeDev(WX_STR(Name), i, m_length);
return &m_ptr[i]; return &m_ptr[i];
@ -218,14 +220,16 @@ T *SafeList<T>::_getPtr(uint i) const
template <typename T> template <typename T>
void SafeList<T>::MakeRoomFor(int blockSize) void SafeList<T>::MakeRoomFor(int blockSize)
{ {
if (blockSize > m_allocsize) { if (blockSize > m_allocsize)
{
const int newalloc = blockSize + ChunkSize; const int newalloc = blockSize + ChunkSize;
m_ptr = _virtual_realloc(newalloc); m_ptr = _virtual_realloc(newalloc);
if (m_ptr == NULL) if (m_ptr == NULL)
throw Exception::OutOfMemory(Name) throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeList::MakeRoomFor' [oldlen=%d] [newlen=%d]", m_length, blockSize)); .SetDiagMsg(wxsFormat(L"Called from 'SafeList::MakeRoomFor' [oldlen=%d] [newlen=%d]", m_length, blockSize));
for (; m_allocsize < newalloc; ++m_allocsize) { for (; m_allocsize < newalloc; ++m_allocsize)
{
new (&m_ptr[m_allocsize]) T(); new (&m_ptr[m_allocsize]) T();
} }
} }
@ -233,14 +237,14 @@ void SafeList<T>::MakeRoomFor(int blockSize)
// Appends an item to the end of the list and returns a handle to it. // Appends an item to the end of the list and returns a handle to it.
template <typename T> template <typename T>
T &SafeList<T>::New() T& SafeList<T>::New()
{ {
_MakeRoomFor_threshold(m_length + 1); _MakeRoomFor_threshold(m_length + 1);
return m_ptr[m_length++]; return m_ptr[m_length++];
} }
template <typename T> template <typename T>
int SafeList<T>::Add(const T &src) int SafeList<T>::Add(const T& src)
{ {
_MakeRoomFor_threshold(m_length + 1); _MakeRoomFor_threshold(m_length + 1);
m_ptr[m_length] = src; m_ptr[m_length] = src;
@ -249,7 +253,7 @@ int SafeList<T>::Add(const T &src)
// Same as Add, but returns the handle of the new object instead of it's array index. // Same as Add, but returns the handle of the new object instead of it's array index.
template <typename T> template <typename T>
T &SafeList<T>::AddNew(const T &src) T& SafeList<T>::AddNew(const T& src)
{ {
_MakeRoomFor_threshold(m_length + 1); _MakeRoomFor_threshold(m_length + 1);
m_ptr[m_length] = src; m_ptr[m_length] = src;
@ -270,9 +274,9 @@ void SafeList<T>::Remove(int index)
} }
template <typename T> template <typename T>
SafeList<T> *SafeList<T>::Clone() const SafeList<T>* SafeList<T>::Clone() const
{ {
SafeList<T> *retval = new SafeList<T>(m_length); SafeList<T>* retval = new SafeList<T>(m_length);
memcpy(retval->m_ptr, m_ptr, sizeof(T) * m_length); memcpy(retval->m_ptr, m_ptr, sizeof(T) * m_length);
return retval; return retval;
} }

View File

@ -50,9 +50,9 @@
// aligned_malloc: Implement/declare linux equivalents here! // aligned_malloc: Implement/declare linux equivalents here!
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
extern void *__fastcall _aligned_malloc(size_t size, size_t align); extern void* __fastcall _aligned_malloc(size_t size, size_t align);
extern void *__fastcall pcsx2_aligned_realloc(void *handle, size_t new_size, size_t align, size_t old_size); extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size);
extern void _aligned_free(void *pmem); extern void _aligned_free(void* pmem);
#else #else
#define pcsx2_aligned_realloc(handle, new_size, align, old_size) \ #define pcsx2_aligned_realloc(handle, new_size, align, old_size) \
_aligned_realloc(handle, new_size, align) _aligned_realloc(handle, new_size, align)
@ -63,7 +63,7 @@ extern void _aligned_free(void *pmem);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
typedef void FnType_OutOfMemory(uptr blocksize); typedef void FnType_OutOfMemory(uptr blocksize);
typedef FnType_OutOfMemory *Fnptr_OutOfMemory; typedef FnType_OutOfMemory* Fnptr_OutOfMemory;
// This method is meant to be assigned by applications that link against pxWex. It is called // This method is meant to be assigned by applications that link against pxWex. It is called
// (invoked) prior to most pxWex built-in memory/array classes throwing exceptions, and can be // (invoked) prior to most pxWex built-in memory/array classes throwing exceptions, and can be
@ -93,7 +93,7 @@ template <typename T>
class BaseScopedAlloc class BaseScopedAlloc
{ {
protected: protected:
T *m_buffer; T* m_buffer;
uint m_size; uint m_size;
public: public:
@ -138,7 +138,7 @@ public:
Resize(size); Resize(size);
} }
T *GetPtr(uint idx = 0) const T* GetPtr(uint idx = 0) const
{ {
#if pxUSE_SECURE_MALLOC #if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
@ -146,7 +146,7 @@ public:
return &m_buffer[idx]; return &m_buffer[idx];
} }
T &operator[](uint idx) T& operator[](uint idx)
{ {
#if pxUSE_SECURE_MALLOC #if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
@ -154,7 +154,7 @@ public:
return m_buffer[idx]; return m_buffer[idx];
} }
const T &operator[](uint idx) const const T& operator[](uint idx) const
{ {
#if pxUSE_SECURE_MALLOC #if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size); IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
@ -196,7 +196,7 @@ public:
if (!this->m_size) if (!this->m_size)
return; return;
this->m_buffer = (T *)malloc(this->m_size * sizeof(T)); this->m_buffer = (T*)malloc(this->m_size * sizeof(T));
if (!this->m_buffer) if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc"); throw Exception::OutOfMemory(L"ScopedAlloc");
} }
@ -204,7 +204,7 @@ public:
virtual void Resize(size_t newsize) virtual void Resize(size_t newsize)
{ {
this->m_size = newsize; this->m_size = newsize;
this->m_buffer = (T *)realloc(this->m_buffer, this->m_size * sizeof(T)); this->m_buffer = (T*)realloc(this->m_buffer, this->m_size * sizeof(T));
if (!this->m_buffer) if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc::Resize"); throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
@ -246,14 +246,14 @@ public:
if (!this->m_size) if (!this->m_size)
return; return;
this->m_buffer = (T *)_aligned_malloc(this->m_size * sizeof(T), align); this->m_buffer = (T*)_aligned_malloc(this->m_size * sizeof(T), align);
if (!this->m_buffer) if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc"); throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
} }
virtual void Resize(size_t newsize) virtual void Resize(size_t newsize)
{ {
this->m_buffer = (T *)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T)); this->m_buffer = (T*)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
this->m_size = newsize; this->m_size = newsize;
if (!this->m_buffer) if (!this->m_buffer)

View File

@ -28,28 +28,28 @@ class ScopedPtrMT
DeclareNoncopyableObject(ScopedPtrMT); DeclareNoncopyableObject(ScopedPtrMT);
protected: protected:
std::atomic<T *> m_ptr; std::atomic<T*> m_ptr;
Threading::Mutex m_mtx; Threading::Mutex m_mtx;
public: public:
typedef T element_type; typedef T element_type;
wxEXPLICIT ScopedPtrMT(T *ptr = nullptr) wxEXPLICIT ScopedPtrMT(T* ptr = nullptr)
{ {
m_ptr = ptr; m_ptr = ptr;
} }
~ScopedPtrMT() { _Delete_unlocked(); } ~ScopedPtrMT() { _Delete_unlocked(); }
ScopedPtrMT &Reassign(T *ptr = nullptr) ScopedPtrMT& Reassign(T* ptr = nullptr)
{ {
T *doh = m_ptr.exchange(ptr); T* doh = m_ptr.exchange(ptr);
if (ptr != doh) if (ptr != doh)
delete doh; delete doh;
return *this; return *this;
} }
ScopedPtrMT &Delete() noexcept ScopedPtrMT& Delete() noexcept
{ {
ScopedLock lock(m_mtx); ScopedLock lock(m_mtx);
_Delete_unlocked(); _Delete_unlocked();
@ -57,7 +57,7 @@ public:
// Removes the pointer from scoped management, but does not delete! // Removes the pointer from scoped management, but does not delete!
// (ScopedPtr will be nullptr after this method) // (ScopedPtr will be nullptr after this method)
T *DetachPtr() T* DetachPtr()
{ {
ScopedLock lock(m_mtx); ScopedLock lock(m_mtx);
@ -66,16 +66,16 @@ public:
// Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT // Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT
// has no object in management. // has no object in management.
T *GetPtr() const T* GetPtr() const
{ {
return m_ptr; return m_ptr;
} }
void SwapPtr(ScopedPtrMT &other) void SwapPtr(ScopedPtrMT& other)
{ {
ScopedLock lock(m_mtx); ScopedLock lock(m_mtx);
m_ptr.exchange(other.m_ptr.exchange(m_ptr.load())); m_ptr.exchange(other.m_ptr.exchange(m_ptr.load()));
T *const tmp = other.m_ptr; T* const tmp = other.m_ptr;
other.m_ptr = m_ptr; other.m_ptr = m_ptr;
m_ptr = tmp; m_ptr = tmp;
} }
@ -93,20 +93,20 @@ public:
} }
// Equality // Equality
bool operator==(T *pT) const noexcept bool operator==(T* pT) const noexcept
{ {
return m_ptr == pT; return m_ptr == pT;
} }
// Inequality // Inequality
bool operator!=(T *pT) const noexcept bool operator!=(T* pT) const noexcept
{ {
return !operator==(pT); return !operator==(pT);
} }
// Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion // Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion
// of the managed pointer. // of the managed pointer.
ScopedPtrMT &operator=(T *src) ScopedPtrMT& operator=(T* src)
{ {
return Reassign(src); return Reassign(src);
} }

View File

@ -51,7 +51,8 @@ void Threading::Semaphore::Post(int multiple)
sem_post_multiple(&m_sema, multiple); sem_post_multiple(&m_sema, multiple);
#else #else
// Only w32pthreads has the post_multiple, but it's easy enough to fake: // Only w32pthreads has the post_multiple, but it's easy enough to fake:
while (multiple > 0) { while (multiple > 0)
{
multiple--; multiple--;
sem_post(&m_sema); sem_post(&m_sema);
} }
@ -64,7 +65,7 @@ void Threading::Semaphore::WaitWithoutYield()
sem_wait(&m_sema); sem_wait(&m_sema);
} }
bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout) bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout)
{ {
wxDateTime megafail(wxDateTime::UNow() + timeout); wxDateTime megafail(wxDateTime::UNow() + timeout);
const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000}; const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000};
@ -80,12 +81,17 @@ bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout)
void Threading::Semaphore::Wait() void Threading::Semaphore::Wait()
{ {
#if wxUSE_GUI #if wxUSE_GUI
if (!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL))
{
sem_wait(&m_sema); sem_wait(&m_sema);
} else if (_WaitGui_RecursionGuard(L"Semaphore::Wait")) { }
else if (_WaitGui_RecursionGuard(L"Semaphore::Wait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy); ScopedBusyCursor hourglass(Cursor_ReallyBusy);
sem_wait(&m_sema); sem_wait(&m_sema);
} else { }
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy ); //ScopedBusyCursor hourglass( Cursor_KindaBusy );
while (!WaitWithoutYield(def_yieldgui_interval)) while (!WaitWithoutYield(def_yieldgui_interval))
YieldToMain(); YieldToMain();
@ -104,19 +110,25 @@ void Threading::Semaphore::Wait()
// false if the wait timed out before the semaphore was signaled, or true if the signal was // false if the wait timed out before the semaphore was signaled, or true if the signal was
// reached prior to timeout. // reached prior to timeout.
// //
bool Threading::Semaphore::Wait(const wxTimeSpan &timeout) bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
{ {
#if wxUSE_GUI #if wxUSE_GUI
if (!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL))
{
return WaitWithoutYield(timeout); return WaitWithoutYield(timeout);
} else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait")) { }
else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait"))
{
ScopedBusyCursor hourglass(Cursor_ReallyBusy); ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return WaitWithoutYield(timeout); return WaitWithoutYield(timeout);
} else { }
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy ); //ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout)); wxTimeSpan countdown((timeout));
do { do
{
if (WaitWithoutYield(def_yieldgui_interval)) if (WaitWithoutYield(def_yieldgui_interval))
break; break;
YieldToMain(); YieldToMain();
@ -147,7 +159,7 @@ void Threading::Semaphore::WaitNoCancel()
pthread_setcancelstate(oldstate, NULL); pthread_setcancelstate(oldstate, NULL);
} }
void Threading::Semaphore::WaitNoCancel(const wxTimeSpan &timeout) void Threading::Semaphore::WaitNoCancel(const wxTimeSpan& timeout)
{ {
int oldstate; int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);

View File

@ -17,7 +17,7 @@
#include "common/Pcsx2Defs.h" #include "common/Pcsx2Defs.h"
#include "common/StringHelpers.h" #include "common/StringHelpers.h"
__fi wxString fromUTF8(const char *src) __fi wxString fromUTF8(const char* src)
{ {
// IMPORTANT: We cannot use wxString::FromUTF8 because it *stupidly* relies on a C++ global instance of // IMPORTANT: We cannot use wxString::FromUTF8 because it *stupidly* relies on a C++ global instance of
// wxMBConvUTF8(). C++ initializes and destroys these globals at random, so any object constructor or // wxMBConvUTF8(). C++ initializes and destroys these globals at random, so any object constructor or
@ -31,7 +31,7 @@ __fi wxString fromUTF8(const char *src)
return wxString(src, wxMBConvUTF8()); return wxString(src, wxMBConvUTF8());
} }
__fi wxString fromAscii(const char *src) __fi wxString fromAscii(const char* src)
{ {
return wxString::FromAscii(src); return wxString::FromAscii(src);
} }
@ -55,17 +55,17 @@ wxString u128::ToString8() const
return result; return result;
} }
void u128::WriteTo(FastFormatAscii &dest) const void u128::WriteTo(FastFormatAscii& dest) const
{ {
dest.Write("0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3]); dest.Write("0x%08X.%08X.%08X.%08X", _u32[0], _u32[1], _u32[2], _u32[3]);
} }
void u128::WriteTo64(FastFormatAscii &dest) const void u128::WriteTo64(FastFormatAscii& dest) const
{ {
dest.Write("0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3]); dest.Write("0x%08X%08X.%08X%08X", _u32[0], _u32[1], _u32[2], _u32[3]);
} }
void u128::WriteTo8(FastFormatAscii &dest) const void u128::WriteTo8(FastFormatAscii& dest) const
{ {
dest.Write("0x%02X.%02X", _u8[0], _u8[1]); dest.Write("0x%02X.%02X", _u8[0], _u8[1]);
for (uint i = 2; i < 16; i += 2) for (uint i = 2; i < 16; i += 2)
@ -78,7 +78,7 @@ void u128::WriteTo8(FastFormatAscii &dest) const
// //
// Note: wxWidgets 2.9 / 3.0 has a wxSplit function, but we're using 2.8 so I had to make // Note: wxWidgets 2.9 / 3.0 has a wxSplit function, but we're using 2.8 so I had to make
// my own. // my own.
void SplitString(wxArrayString &dest, const wxString &src, const wxString &delims, wxStringTokenizerMode mode) void SplitString(wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode)
{ {
wxStringTokenizer parts(src, delims, mode); wxStringTokenizer parts(src, delims, mode);
while (parts.HasMoreTokens()) while (parts.HasMoreTokens())
@ -91,10 +91,11 @@ void SplitString(wxArrayString &dest, const wxString &src, const wxString &delim
// //
// Note: wxWidgets 2.9 / 3.0 has a wxJoin function, but we're using 2.8 so I had to make // Note: wxWidgets 2.9 / 3.0 has a wxJoin function, but we're using 2.8 so I had to make
// my own. // my own.
wxString JoinString(const wxArrayString &src, const wxString &separator) wxString JoinString(const wxArrayString& src, const wxString& separator)
{ {
wxString dest; wxString dest;
for (int i = 0, len = src.GetCount(); i < len; ++i) { for (int i = 0, len = src.GetCount(); i < len; ++i)
{
if (src[i].IsEmpty()) if (src[i].IsEmpty())
continue; continue;
if (!dest.IsEmpty()) if (!dest.IsEmpty())
@ -104,10 +105,11 @@ wxString JoinString(const wxArrayString &src, const wxString &separator)
return dest; return dest;
} }
wxString JoinString(const wxChar **src, const wxString &separator) wxString JoinString(const wxChar** src, const wxString& separator)
{ {
wxString dest; wxString dest;
while (*src != NULL) { while (*src != NULL)
{
if (*src[0] == 0) if (*src[0] == 0)
continue; continue;
@ -127,7 +129,7 @@ wxString JoinString(const wxChar **src, const wxString &separator)
// This, so far, include types such as wxPoint, wxRect, and wxSize. // This, so far, include types such as wxPoint, wxRect, and wxSize.
// //
template <typename T> template <typename T>
T Parse(const wxString &src, const wxString &separators = L",") T Parse(const wxString& src, const wxString& separators = L",")
{ {
T retval; T retval;
if (!TryParse(retval, src, separators)) if (!TryParse(retval, src, separators))
@ -141,19 +143,19 @@ T Parse(const wxString &src, const wxString &separators = L",")
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Converts a wxPoint into a comma-delimited string! // Converts a wxPoint into a comma-delimited string!
wxString ToString(const wxPoint &src, const wxString &separator) wxString ToString(const wxPoint& src, const wxString& separator)
{ {
return wxString() << src.x << separator << src.y; return wxString() << src.x << separator << src.y;
} }
wxString ToString(const wxSize &src, const wxString &separator) wxString ToString(const wxSize& src, const wxString& separator)
{ {
return wxString() << src.GetWidth() << separator << src.GetHeight(); return wxString() << src.GetWidth() << separator << src.GetHeight();
} }
// Converts a wxRect into a comma-delimited string! // Converts a wxRect into a comma-delimited string!
// Example: 32,64,128,5 // Example: 32,64,128,5
wxString ToString(const wxRect &src, const wxString &separator) wxString ToString(const wxRect& src, const wxString& separator)
{ {
return ToString(src.GetLeftTop(), separator) << separator << ToString(src.GetSize(), separator); return ToString(src.GetLeftTop(), separator) << separator << ToString(src.GetSize(), separator);
} }
@ -162,7 +164,7 @@ wxString ToString(const wxRect &src, const wxString &separator)
// Parse helpers for wxString! // Parse helpers for wxString!
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
bool TryParse(wxPoint &dest, wxStringTokenizer &parts) bool TryParse(wxPoint& dest, wxStringTokenizer& parts)
{ {
long result[2]; long result[2];
@ -176,7 +178,7 @@ bool TryParse(wxPoint &dest, wxStringTokenizer &parts)
return true; return true;
} }
bool TryParse(wxSize &dest, wxStringTokenizer &parts) bool TryParse(wxSize& dest, wxStringTokenizer& parts)
{ {
long result[2]; long result[2];
@ -192,21 +194,21 @@ bool TryParse(wxSize &dest, wxStringTokenizer &parts)
// Tries to parse the given string into a wxPoint value at 'dest.' If the parse fails, the // Tries to parse the given string into a wxPoint value at 'dest.' If the parse fails, the
// method aborts and returns false. // method aborts and returns false.
bool TryParse(wxPoint &dest, const wxString &src, const wxPoint &defval, const wxString &separators) bool TryParse(wxPoint& dest, const wxString& src, const wxPoint& defval, const wxString& separators)
{ {
dest = defval; dest = defval;
wxStringTokenizer parts(src, separators); wxStringTokenizer parts(src, separators);
return TryParse(dest, parts); return TryParse(dest, parts);
} }
bool TryParse(wxSize &dest, const wxString &src, const wxSize &defval, const wxString &separators) bool TryParse(wxSize& dest, const wxString& src, const wxSize& defval, const wxString& separators)
{ {
dest = defval; dest = defval;
wxStringTokenizer parts(src, separators); wxStringTokenizer parts(src, separators);
return TryParse(dest, parts); return TryParse(dest, parts);
} }
bool TryParse(wxRect &dest, const wxString &src, const wxRect &defval, const wxString &separators) bool TryParse(wxRect& dest, const wxString& src, const wxRect& defval, const wxString& separators)
{ {
dest = defval; dest = defval;
@ -225,7 +227,7 @@ bool TryParse(wxRect &dest, const wxString &src, const wxRect &defval, const wxS
} }
// returns TRUE if the parse is valid, or FALSE if it's a comment. // returns TRUE if the parse is valid, or FALSE if it's a comment.
bool pxParseAssignmentString(const wxString &src, wxString &ldest, wxString &rdest) bool pxParseAssignmentString(const wxString& src, wxString& ldest, wxString& rdest)
{ {
if (src.StartsWith(L"--") || src.StartsWith(L"//") || src.StartsWith(L";")) if (src.StartsWith(L"--") || src.StartsWith(L"//") || src.StartsWith(L";"))
return false; return false;
@ -236,7 +238,7 @@ bool pxParseAssignmentString(const wxString &src, wxString &ldest, wxString &rde
return true; return true;
} }
ParsedAssignmentString::ParsedAssignmentString(const wxString &src) ParsedAssignmentString::ParsedAssignmentString(const wxString& src)
{ {
IsComment = pxParseAssignmentString(src, lvalue, rvalue); IsComment = pxParseAssignmentString(src, lvalue, rvalue);
} }
@ -249,7 +251,7 @@ ParsedAssignmentString::ParsedAssignmentString(const wxString &src)
// from incoming data. Mac platforms may need an implementation of their own that converts // from incoming data. Mac platforms may need an implementation of their own that converts
// newlines to CRs...? // newlines to CRs...?
// //
void px_fputs(FILE *fp, const char *src) void px_fputs(FILE* fp, const char* src)
{ {
if (fp == NULL) if (fp == NULL)
return; return;
@ -258,12 +260,16 @@ void px_fputs(FILE *fp, const char *src)
// Windows needs CR's partnered with all newlines, or else notepad.exe can't view // Windows needs CR's partnered with all newlines, or else notepad.exe can't view
// the stupid logfile. Best way is to write one char at a time.. >_< // the stupid logfile. Best way is to write one char at a time.. >_<
const char *curchar = src; const char* curchar = src;
bool prevcr = false; bool prevcr = false;
while (*curchar != 0) { while (*curchar != 0)
if (*curchar == '\r') { {
if (*curchar == '\r')
{
prevcr = true; prevcr = true;
} else { }
else
{
// Only write a CR/LF pair if the current LF is not prefixed nor // Only write a CR/LF pair if the current LF is not prefixed nor
// post-fixed by a CR. // post-fixed by a CR.
if (*curchar == '\n' && !prevcr && (*(curchar + 1) != '\r')) if (*curchar == '\n' && !prevcr && (*(curchar + 1) != '\r'))

View File

@ -24,7 +24,7 @@
#define WX_STR(str) (str.wc_str()) #define WX_STR(str) (str.wc_str())
#else #else
// Stupid wx3.0 doesn't support c_str for vararg function // Stupid wx3.0 doesn't support c_str for vararg function
#define WX_STR(str) (static_cast<const char *>(str.c_str())) #define WX_STR(str) (static_cast<const char*>(str.c_str()))
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -40,7 +40,7 @@ protected:
int m_length; int m_length;
public: public:
explicit pxToUTF8(const wxString &src) explicit pxToUTF8(const wxString& src)
: m_result(src.ToUTF8()) : m_result(src.ToUTF8())
{ {
m_length = -1; m_length = -1;
@ -53,39 +53,39 @@ public:
return m_length; return m_length;
} }
void Convert(const wxString &src) void Convert(const wxString& src)
{ {
m_result = src.ToUTF8(); m_result = src.ToUTF8();
m_length = -1; m_length = -1;
} }
const char *data() const { return m_result; } const char* data() const { return m_result; }
operator const char *() const operator const char*() const
{ {
return m_result.data(); return m_result.data();
} }
}; };
extern void px_fputs(FILE *fp, const char *src); extern void px_fputs(FILE* fp, const char* src);
// wxWidgets lacks one of its own... // wxWidgets lacks one of its own...
extern const wxRect wxDefaultRect; extern const wxRect wxDefaultRect;
extern void SplitString(wxArrayString &dest, const wxString &src, const wxString &delims, wxStringTokenizerMode mode = wxTOKEN_RET_EMPTY_ALL); extern void SplitString(wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode = wxTOKEN_RET_EMPTY_ALL);
extern wxString JoinString(const wxArrayString &src, const wxString &separator); extern wxString JoinString(const wxArrayString& src, const wxString& separator);
extern wxString JoinString(const wxChar **src, const wxString &separator); extern wxString JoinString(const wxChar** src, const wxString& separator);
extern wxString ToString(const wxPoint &src, const wxString &separator = L","); extern wxString ToString(const wxPoint& src, const wxString& separator = L",");
extern wxString ToString(const wxSize &src, const wxString &separator = L","); extern wxString ToString(const wxSize& src, const wxString& separator = L",");
extern wxString ToString(const wxRect &src, const wxString &separator = L","); extern wxString ToString(const wxRect& src, const wxString& separator = L",");
extern bool TryParse(wxPoint &dest, const wxStringTokenizer &parts); extern bool TryParse(wxPoint& dest, const wxStringTokenizer& parts);
extern bool TryParse(wxSize &dest, const wxStringTokenizer &parts); extern bool TryParse(wxSize& dest, const wxStringTokenizer& parts);
extern bool TryParse(wxPoint &dest, const wxString &src, const wxPoint &defval = wxDefaultPosition, const wxString &separators = L","); extern bool TryParse(wxPoint& dest, const wxString& src, const wxPoint& defval = wxDefaultPosition, const wxString& separators = L",");
extern bool TryParse(wxSize &dest, const wxString &src, const wxSize &defval = wxDefaultSize, const wxString &separators = L","); extern bool TryParse(wxSize& dest, const wxString& src, const wxSize& defval = wxDefaultSize, const wxString& separators = L",");
extern bool TryParse(wxRect &dest, const wxString &src, const wxRect &defval = wxDefaultRect, const wxString &separators = L","); extern bool TryParse(wxRect& dest, const wxString& src, const wxRect& defval = wxDefaultRect, const wxString& separators = L",");
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ParsedAssignmentString // ParsedAssignmentString
@ -107,7 +107,7 @@ struct ParsedAssignmentString
wxString rvalue; wxString rvalue;
bool IsComment; bool IsComment;
ParsedAssignmentString(const wxString &src); ParsedAssignmentString(const wxString& src);
}; };
// ====================================================================================== // ======================================================================================
@ -144,31 +144,31 @@ protected:
public: public:
FastFormatAscii(); FastFormatAscii();
~FastFormatAscii() = default; ~FastFormatAscii() = default;
FastFormatAscii &Write(const char *fmt, ...); FastFormatAscii& Write(const char* fmt, ...);
FastFormatAscii &WriteV(const char *fmt, va_list argptr); FastFormatAscii& WriteV(const char* fmt, va_list argptr);
void Clear(); void Clear();
bool IsEmpty() const; bool IsEmpty() const;
const char *c_str() const { return m_dest.GetPtr(); } const char* c_str() const { return m_dest.GetPtr(); }
operator const char *() const { return m_dest.GetPtr(); } operator const char*() const { return m_dest.GetPtr(); }
const wxString GetString() const; const wxString GetString() const;
//operator wxString() const; //operator wxString() const;
FastFormatAscii &operator+=(const wxString &s) FastFormatAscii& operator+=(const wxString& s)
{ {
Write("%s", WX_STR(s)); Write("%s", WX_STR(s));
return *this; return *this;
} }
FastFormatAscii &operator+=(const wxChar *psz) FastFormatAscii& operator+=(const wxChar* psz)
{ {
Write("%ls", psz); Write("%ls", psz);
return *this; return *this;
} }
FastFormatAscii &operator+=(const char *psz) FastFormatAscii& operator+=(const char* psz)
{ {
Write("%s", psz); Write("%s", psz);
return *this; return *this;
@ -188,47 +188,47 @@ public:
FastFormatUnicode(); FastFormatUnicode();
~FastFormatUnicode() = default; ~FastFormatUnicode() = default;
FastFormatUnicode &Write(const char *fmt, ...); FastFormatUnicode& Write(const char* fmt, ...);
FastFormatUnicode &Write(const wxChar *fmt, ...); FastFormatUnicode& Write(const wxChar* fmt, ...);
FastFormatUnicode &Write(const wxString fmt, ...); FastFormatUnicode& Write(const wxString fmt, ...);
FastFormatUnicode &WriteV(const char *fmt, va_list argptr); FastFormatUnicode& WriteV(const char* fmt, va_list argptr);
FastFormatUnicode &WriteV(const wxChar *fmt, va_list argptr); FastFormatUnicode& WriteV(const wxChar* fmt, va_list argptr);
void Clear(); void Clear();
bool IsEmpty() const; bool IsEmpty() const;
uint Length() const { return m_Length; } uint Length() const { return m_Length; }
FastFormatUnicode &ToUpper(); FastFormatUnicode& ToUpper();
FastFormatUnicode &ToLower(); FastFormatUnicode& ToLower();
const wxChar *c_str() const { return (const wxChar *)m_dest.GetPtr(); } const wxChar* c_str() const { return (const wxChar*)m_dest.GetPtr(); }
operator const wxChar *() const { return (const wxChar *)m_dest.GetPtr(); } operator const wxChar*() const { return (const wxChar*)m_dest.GetPtr(); }
operator wxString() const { return (const wxChar *)m_dest.GetPtr(); } operator wxString() const { return (const wxChar*)m_dest.GetPtr(); }
FastFormatUnicode &operator+=(const wxString &s) FastFormatUnicode& operator+=(const wxString& s)
{ {
Write(L"%s", WX_STR(s)); Write(L"%s", WX_STR(s));
return *this; return *this;
} }
FastFormatUnicode &operator+=(const wxChar *psz) FastFormatUnicode& operator+=(const wxChar* psz)
{ {
Write(L"%s", psz); Write(L"%s", psz);
return *this; return *this;
} }
FastFormatUnicode &operator+=(const char *psz); FastFormatUnicode& operator+=(const char* psz);
}; };
extern bool pxParseAssignmentString(const wxString &src, wxString &ldest, wxString &rdest); extern bool pxParseAssignmentString(const wxString& src, wxString& ldest, wxString& rdest);
#define pxsFmt FastFormatUnicode().Write #define pxsFmt FastFormatUnicode().Write
#define pxsFmtV FastFormatUnicode().WriteV #define pxsFmtV FastFormatUnicode().WriteV
#define pxsPtr(ptr) pxsFmt("0x%08X", (ptr)).c_str() #define pxsPtr(ptr) pxsFmt("0x%08X", (ptr)).c_str()
extern wxString &operator+=(wxString &str1, const FastFormatUnicode &str2); extern wxString& operator+=(wxString& str1, const FastFormatUnicode& str2);
extern wxString operator+(const wxString &str1, const FastFormatUnicode &str2); extern wxString operator+(const wxString& str1, const FastFormatUnicode& str2);
extern wxString operator+(const wxChar *str1, const FastFormatUnicode &str2); extern wxString operator+(const wxChar* str1, const FastFormatUnicode& str2);
extern wxString operator+(const FastFormatUnicode &str1, const wxString &str2); extern wxString operator+(const FastFormatUnicode& str1, const wxString& str2);
extern wxString operator+(const FastFormatUnicode &str1, const wxChar *str2); extern wxString operator+(const FastFormatUnicode& str1, const wxChar* str2);

View File

@ -47,10 +47,10 @@ ConsoleLogSource_Threading pxConLog_Thread;
class StaticMutex : public Mutex class StaticMutex : public Mutex
{ {
protected: protected:
bool &m_DeletedFlag; bool& m_DeletedFlag;
public: public:
StaticMutex(bool &deletedFlag) StaticMutex(bool& deletedFlag)
: m_DeletedFlag(deletedFlag) : m_DeletedFlag(deletedFlag)
{ {
} }
@ -67,7 +67,7 @@ static s32 total_key_count = 0;
static bool tkl_destructed = false; static bool tkl_destructed = false;
static StaticMutex total_key_lock(tkl_destructed); static StaticMutex total_key_lock(tkl_destructed);
static void make_curthread_key(const pxThread *thr) static void make_curthread_key(const pxThread* thr)
{ {
pxAssumeDev(!tkl_destructed, "total_key_lock is destroyed; program is shutting down; cannot create new thread key."); pxAssumeDev(!tkl_destructed, "total_key_lock is destroyed; program is shutting down; cannot create new thread key.");
@ -75,7 +75,8 @@ static void make_curthread_key(const pxThread *thr)
if (total_key_count++ != 0) if (total_key_count++ != 0)
return; return;
if (0 != pthread_key_create(&curthread_key, NULL)) { if (0 != pthread_key_create(&curthread_key, NULL))
{
pxThreadLog.Error(thr->GetName(), L"Thread key creation failed (probably out of memory >_<)"); pxThreadLog.Error(thr->GetName(), L"Thread key creation failed (probably out of memory >_<)");
curthread_key = 0; curthread_key = 0;
} }
@ -105,18 +106,21 @@ void Threading::pxTestCancel()
// to the pxThread table, NULL is returned. Since the main/ui thread is not created // to the pxThread table, NULL is returned. Since the main/ui thread is not created
// through pxThread it will also return NULL. Callers can use wxThread::IsMain() to // through pxThread it will also return NULL. Callers can use wxThread::IsMain() to
// test if the NULL thread is the main thread. // test if the NULL thread is the main thread.
pxThread *Threading::pxGetCurrentThread() pxThread* Threading::pxGetCurrentThread()
{ {
return !curthread_key ? NULL : (pxThread *)pthread_getspecific(curthread_key); return !curthread_key ? NULL : (pxThread*)pthread_getspecific(curthread_key);
} }
// returns the name of the current thread, or "Unknown" if the thread is neither a pxThread // returns the name of the current thread, or "Unknown" if the thread is neither a pxThread
// nor the Main/UI thread. // nor the Main/UI thread.
wxString Threading::pxGetCurrentThreadName() wxString Threading::pxGetCurrentThreadName()
{ {
if (pxThread *thr = pxGetCurrentThread()) { if (pxThread* thr = pxGetCurrentThread())
{
return thr->GetName(); return thr->GetName();
} else if (wxThread::IsMain()) { }
else if (wxThread::IsMain())
{
return L"Main/UI"; return L"Main/UI";
} }
@ -125,7 +129,7 @@ wxString Threading::pxGetCurrentThreadName()
void Threading::pxYield(int ms) void Threading::pxYield(int ms)
{ {
if (pxThread *thr = pxGetCurrentThread()) if (pxThread* thr = pxGetCurrentThread())
thr->Yield(ms); thr->Yield(ms);
else else
Sleep(ms); Sleep(ms);
@ -134,7 +138,7 @@ void Threading::pxYield(int ms)
// (intended for internal use only) // (intended for internal use only)
// Returns true if the Wait is recursive, or false if the Wait is safe and should be // Returns true if the Wait is recursive, or false if the Wait is safe and should be
// handled via normal yielding methods. // handled via normal yielding methods.
bool Threading::_WaitGui_RecursionGuard(const wxChar *name) bool Threading::_WaitGui_RecursionGuard(const wxChar* name)
{ {
AffinityAssert_AllowFrom_MainUI(); AffinityAssert_AllowFrom_MainUI();
@ -159,13 +163,13 @@ __fi void Threading::Timeslice()
sched_yield(); sched_yield();
} }
void Threading::pxThread::_pt_callback_cleanup(void *handle) void Threading::pxThread::_pt_callback_cleanup(void* handle)
{ {
((pxThread *)handle)->_ThreadCleanup(); ((pxThread*)handle)->_ThreadCleanup();
} }
Threading::pxThread::pxThread(const wxString &name) Threading::pxThread::pxThread(const wxString& name)
: m_name(name) : m_name(name)
, m_thread() , m_thread()
, m_native_id(0) , m_native_id(0)
@ -184,10 +188,12 @@ Threading::pxThread::pxThread(const wxString &name)
// like marrying your sister, and then cheating on her with your daughter. // like marrying your sister, and then cheating on her with your daughter.
Threading::pxThread::~pxThread() Threading::pxThread::~pxThread()
{ {
try { try
{
pxThreadLog.Write(GetName(), L"Executing default destructor!"); pxThreadLog.Write(GetName(), L"Executing default destructor!");
if (m_running) { if (m_running)
{
pxThreadLog.Write(GetName(), L"Waiting for running thread to end..."); pxThreadLog.Write(GetName(), L"Waiting for running thread to end...");
m_mtx_InThread.Wait(); m_mtx_InThread.Wait();
pxThreadLog.Write(GetName(), L"Thread ended gracefully."); pxThreadLog.Write(GetName(), L"Thread ended gracefully.");
@ -198,7 +204,7 @@ Threading::pxThread::~pxThread()
DESTRUCTOR_CATCHALL DESTRUCTOR_CATCHALL
} }
bool Threading::pxThread::AffinityAssert_AllowFromSelf(const DiagnosticOrigin &origin) const bool Threading::pxThread::AffinityAssert_AllowFromSelf(const DiagnosticOrigin& origin) const
{ {
if (IsSelf()) if (IsSelf())
return true; return true;
@ -209,7 +215,7 @@ bool Threading::pxThread::AffinityAssert_AllowFromSelf(const DiagnosticOrigin &o
return false; return false;
} }
bool Threading::pxThread::AffinityAssert_DisallowFromSelf(const DiagnosticOrigin &origin) const bool Threading::pxThread::AffinityAssert_DisallowFromSelf(const DiagnosticOrigin& origin) const
{ {
if (!IsSelf()) if (!IsSelf())
return true; return true;
@ -220,9 +226,10 @@ bool Threading::pxThread::AffinityAssert_DisallowFromSelf(const DiagnosticOrigin
return false; return false;
} }
void Threading::pxThread::FrankenMutex(Mutex &mutex) void Threading::pxThread::FrankenMutex(Mutex& mutex)
{ {
if (mutex.RecreateIfLocked()) { if (mutex.RecreateIfLocked())
{
// Our lock is bupkis, which means the previous thread probably deadlocked. // Our lock is bupkis, which means the previous thread probably deadlocked.
// Let's create a new mutex lock to replace it. // Let's create a new mutex lock to replace it.
@ -240,7 +247,8 @@ void Threading::pxThread::Start()
{ {
// Prevents sudden parallel startup, and or parallel startup + cancel: // Prevents sudden parallel startup, and or parallel startup + cancel:
ScopedLock startlock(m_mtx_start); ScopedLock startlock(m_mtx_start);
if (m_running) { if (m_running)
{
pxThreadLog.Write(GetName(), L"Start() called on running thread; ignorning..."); pxThreadLog.Write(GetName(), L"Start() called on running thread; ignorning...");
return; return;
} }
@ -259,12 +267,14 @@ void Threading::pxThread::Start()
// //
// In our case, the semaphore was posted (counter is 1) but thread is still // In our case, the semaphore was posted (counter is 1) but thread is still
// waiting... So waits 100ms and checks the counter value manually // waiting... So waits 100ms and checks the counter value manually
if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 0, 100))) { if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 0, 100)))
{
if (m_sem_startup.Count() == 0) if (m_sem_startup.Count() == 0)
throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: %s thread never posted startup semaphore."); throw Exception::ThreadCreationError(this).SetDiagMsg(L"Thread creation error: %s thread never posted startup semaphore.");
} }
#else #else
if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 3, 0))) { if (!m_sem_startup.WaitWithoutYield(wxTimeSpan(0, 0, 3, 0)))
{
RethrowException(); RethrowException();
// And if the thread threw nothing of its own: // And if the thread threw nothing of its own:
@ -305,7 +315,8 @@ bool Threading::pxThread::_basecancel()
if (!m_running) if (!m_running)
return false; return false;
if (m_detached) { if (m_detached)
{
pxThreadLog.Warn(GetName(), L"Ignoring attempted cancellation of detached thread."); pxThreadLog.Warn(GetName(), L"Ignoring attempted cancellation of detached thread.");
return false; return false;
} }
@ -338,13 +349,14 @@ void Threading::pxThread::Cancel(bool isBlocking)
if (!_basecancel()) if (!_basecancel())
return; return;
if (isBlocking) { if (isBlocking)
{
WaitOnSelf(m_mtx_InThread); WaitOnSelf(m_mtx_InThread);
Detach(); Detach();
} }
} }
bool Threading::pxThread::Cancel(const wxTimeSpan &timespan) bool Threading::pxThread::Cancel(const wxTimeSpan& timespan)
{ {
AffinityAssert_DisallowFromSelf(pxDiagSpot); AffinityAssert_DisallowFromSelf(pxDiagSpot);
@ -377,7 +389,7 @@ void Threading::pxThread::Block()
WaitOnSelf(m_mtx_InThread); WaitOnSelf(m_mtx_InThread);
} }
bool Threading::pxThread::Block(const wxTimeSpan &timeout) bool Threading::pxThread::Block(const wxTimeSpan& timeout)
{ {
AffinityAssert_DisallowFromSelf(pxDiagSpot); AffinityAssert_DisallowFromSelf(pxDiagSpot);
return WaitOnSelf(m_mtx_InThread, timeout); return WaitOnSelf(m_mtx_InThread, timeout);
@ -395,7 +407,7 @@ bool Threading::pxThread::IsRunning() const
return m_running; return m_running;
} }
void Threading::pxThread::AddListener(EventListener_Thread &evt) void Threading::pxThread::AddListener(EventListener_Thread& evt)
{ {
evt.SetThread(this); evt.SetThread(this);
m_evtsrc_OnDelete.Add(evt); m_evtsrc_OnDelete.Add(evt);
@ -410,7 +422,7 @@ void Threading::pxThread::RethrowException() const
// pointer might still be invalid after detachment, so might as well just detach and check // pointer might still be invalid after detachment, so might as well just detach and check
// after. // after.
ScopedExcept ptr(const_cast<pxThread *>(this)->m_except.DetachPtr()); ScopedExcept ptr(const_cast<pxThread*>(this)->m_except.DetachPtr());
if (ptr) if (ptr)
ptr->Rethrow(); ptr->Rethrow();
} }
@ -430,14 +442,16 @@ void Threading::YieldToMain()
m_BlockDeletions = false; m_BlockDeletions = false;
} }
void Threading::pxThread::_selfRunningTest(const wxChar *name) const void Threading::pxThread::_selfRunningTest(const wxChar* name) const
{ {
if (HasPendingException()) { if (HasPendingException())
{
pxThreadLog.Error(GetName(), pxsFmt(L"An exception was thrown while waiting on a %s.", name)); pxThreadLog.Error(GetName(), pxsFmt(L"An exception was thrown while waiting on a %s.", name));
RethrowException(); RethrowException();
} }
if (!m_running) { if (!m_running)
{
throw Exception::CancelEvent(pxsFmt( throw Exception::CancelEvent(pxsFmt(
L"Blocking thread %s was terminated while another thread was waiting on a %s.", L"Blocking thread %s was terminated while another thread was waiting on a %s.",
WX_STR(GetName()), name)); WX_STR(GetName()), name));
@ -462,12 +476,13 @@ void Threading::pxThread::_selfRunningTest(const wxChar *name) const
// This function will rethrow exceptions raised by the persistent thread, if it throws an error // This function will rethrow exceptions raised by the persistent thread, if it throws an error
// while the calling thread is blocking (which also means the persistent thread has terminated). // while the calling thread is blocking (which also means the persistent thread has terminated).
// //
void Threading::pxThread::WaitOnSelf(Semaphore &sem) const void Threading::pxThread::WaitOnSelf(Semaphore& sem) const
{ {
if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) if (!AffinityAssert_DisallowFromSelf(pxDiagSpot))
return; return;
while (true) { while (true)
{
if (sem.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333))) if (sem.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333)))
return; return;
_selfRunningTest(L"semaphore"); _selfRunningTest(L"semaphore");
@ -487,12 +502,13 @@ void Threading::pxThread::WaitOnSelf(Semaphore &sem) const
// error while the calling thread is blocking (which also means the persistent thread has // error while the calling thread is blocking (which also means the persistent thread has
// terminated). // terminated).
// //
void Threading::pxThread::WaitOnSelf(Mutex &mutex) const void Threading::pxThread::WaitOnSelf(Mutex& mutex) const
{ {
if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) if (!AffinityAssert_DisallowFromSelf(pxDiagSpot))
return; return;
while (true) { while (true)
{
if (mutex.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333))) if (mutex.WaitWithoutYield(wxTimeSpan(0, 0, 0, 333)))
return; return;
_selfRunningTest(L"mutex"); _selfRunningTest(L"mutex");
@ -501,14 +517,15 @@ void Threading::pxThread::WaitOnSelf(Mutex &mutex) const
static const wxTimeSpan SelfWaitInterval(0, 0, 0, 333); static const wxTimeSpan SelfWaitInterval(0, 0, 0, 333);
bool Threading::pxThread::WaitOnSelf(Semaphore &sem, const wxTimeSpan &timeout) const bool Threading::pxThread::WaitOnSelf(Semaphore& sem, const wxTimeSpan& timeout) const
{ {
if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) if (!AffinityAssert_DisallowFromSelf(pxDiagSpot))
return true; return true;
wxTimeSpan runningout(timeout); wxTimeSpan runningout(timeout);
while (runningout.GetMilliseconds() > 0) { while (runningout.GetMilliseconds() > 0)
{
const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout); const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout);
if (sem.WaitWithoutYield(interval)) if (sem.WaitWithoutYield(interval))
return true; return true;
@ -518,14 +535,15 @@ bool Threading::pxThread::WaitOnSelf(Semaphore &sem, const wxTimeSpan &timeout)
return false; return false;
} }
bool Threading::pxThread::WaitOnSelf(Mutex &mutex, const wxTimeSpan &timeout) const bool Threading::pxThread::WaitOnSelf(Mutex& mutex, const wxTimeSpan& timeout) const
{ {
if (!AffinityAssert_DisallowFromSelf(pxDiagSpot)) if (!AffinityAssert_DisallowFromSelf(pxDiagSpot))
return true; return true;
wxTimeSpan runningout(timeout); wxTimeSpan runningout(timeout);
while (runningout.GetMilliseconds() > 0) { while (runningout.GetMilliseconds() > 0)
{
const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout); const wxTimeSpan interval((SelfWaitInterval < runningout) ? SelfWaitInterval : runningout);
if (mutex.WaitWithoutYield(interval)) if (mutex.WaitWithoutYield(interval))
return true; return true;
@ -548,20 +566,23 @@ void Threading::pxThread::TestCancel() const
// Executes the virtual member method // Executes the virtual member method
void Threading::pxThread::_try_virtual_invoke(void (pxThread::*method)()) void Threading::pxThread::_try_virtual_invoke(void (pxThread::*method)())
{ {
try { try
{
(this->*method)(); (this->*method)();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Neat repackaging for STL Runtime errors... // Neat repackaging for STL Runtime errors...
// //
catch (std::runtime_error &ex) { catch (std::runtime_error& ex)
{
m_except = new Exception::RuntimeError(ex, WX_STR(GetName())); m_except = new Exception::RuntimeError(ex, WX_STR(GetName()));
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
catch (Exception::RuntimeError &ex) { catch (Exception::RuntimeError& ex)
BaseException *woot = ex.Clone(); {
BaseException* woot = ex.Clone();
woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName())); woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName()));
m_except = woot; m_except = woot;
} }
@ -585,8 +606,9 @@ void Threading::pxThread::_try_virtual_invoke(void (pxThread::*method)())
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// BaseException -- same deal as LogicErrors. // BaseException -- same deal as LogicErrors.
// //
catch (BaseException &ex) { catch (BaseException& ex)
BaseException *woot = ex.Clone(); {
BaseException* woot = ex.Clone();
woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName())); woot->DiagMsg() += pxsFmt(L"(thread:%s)", WX_STR(GetName()));
m_except = woot; m_except = woot;
} }
@ -612,7 +634,7 @@ wxString Threading::pxThread::GetName() const
return m_name; return m_name;
} }
void Threading::pxThread::SetName(const wxString &newname) void Threading::pxThread::SetName(const wxString& newname)
{ {
ScopedLock lock(m_mtx_ThreadName); ScopedLock lock(m_mtx_ThreadName);
m_name = newname; m_name = newname;
@ -679,7 +701,7 @@ void Threading::pxThread::OnCleanupInThread()
// passed into pthread_create, and is used to dispatch the thread's object oriented // passed into pthread_create, and is used to dispatch the thread's object oriented
// callback function // callback function
void *Threading::pxThread::_internal_callback(void *itsme) void* Threading::pxThread::_internal_callback(void* itsme)
{ {
if (!pxAssertDev(itsme != NULL, wxNullChar)) if (!pxAssertDev(itsme != NULL, wxNullChar))
return NULL; return NULL;
@ -691,18 +713,18 @@ void *Threading::pxThread::_internal_callback(void *itsme)
// __try is used in pthread_cleanup_push when CLEANUP_SEH is used as the cleanup model. // __try is used in pthread_cleanup_push when CLEANUP_SEH is used as the cleanup model.
// That can't be used in a function that has objects that require unwinding (compile // That can't be used in a function that has objects that require unwinding (compile
// error C2712), so move it into a separate function. // error C2712), so move it into a separate function.
void Threading::pxThread::internal_callback_helper(void *itsme) void Threading::pxThread::internal_callback_helper(void* itsme)
{ {
pxThread &owner = *static_cast<pxThread *>(itsme); pxThread& owner = *static_cast<pxThread*>(itsme);
pthread_cleanup_push(_pt_callback_cleanup, itsme); pthread_cleanup_push(_pt_callback_cleanup, itsme);
owner._internal_execute(); owner._internal_execute();
pthread_cleanup_pop(true); pthread_cleanup_pop(true);
} }
void Threading::pxThread::_DoSetThreadName(const wxString &name) void Threading::pxThread::_DoSetThreadName(const wxString& name)
{ {
_DoSetThreadName(static_cast<const char *>(name.ToUTF8())); _DoSetThreadName(static_cast<const char*>(name.ToUTF8()));
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -756,12 +778,12 @@ wxString Exception::BaseThreadError::FormatDisplayMessage() const
return pxsFmt(m_message_user, (m_thread == NULL) ? WX_STR(null_str) : WX_STR(m_thread->GetName())); return pxsFmt(m_message_user, (m_thread == NULL) ? WX_STR(null_str) : WX_STR(m_thread->GetName()));
} }
pxThread &Exception::BaseThreadError::Thread() pxThread& Exception::BaseThreadError::Thread()
{ {
pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception."); pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception.");
return *m_thread; return *m_thread;
} }
const pxThread &Exception::BaseThreadError::Thread() const const pxThread& Exception::BaseThreadError::Thread() const
{ {
pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception."); pxAssertDev(m_thread != NULL, "NULL thread object on ThreadError exception.");
return *m_thread; return *m_thread;

View File

@ -47,15 +47,15 @@ public:
ConsoleLogSource_Threading(); ConsoleLogSource_Threading();
bool Write(const wxString &thrname, const wxChar *msg) bool Write(const wxString& thrname, const wxChar* msg)
{ {
return _parent::Write(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg); return _parent::Write(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
} }
bool Warn(const wxString &thrname, const wxChar *msg) bool Warn(const wxString& thrname, const wxChar* msg)
{ {
return _parent::Warn(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg); return _parent::Warn(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
} }
bool Error(const wxString &thrname, const wxChar *msg) bool Error(const wxString& thrname, const wxChar* msg)
{ {
return _parent::Error(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg); return _parent::Error(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
} }
@ -88,44 +88,44 @@ class wxTimeSpan;
namespace Threading namespace Threading
{ {
class pxThread; class pxThread;
class RwMutex; class RwMutex;
extern void pxTestCancel(); extern void pxTestCancel();
extern pxThread *pxGetCurrentThread(); extern pxThread* pxGetCurrentThread();
extern wxString pxGetCurrentThreadName(); extern wxString pxGetCurrentThreadName();
extern u64 GetThreadCpuTime(); extern u64 GetThreadCpuTime();
extern u64 GetThreadTicksPerSecond(); extern u64 GetThreadTicksPerSecond();
// Yields the current thread and provides cancellation points if the thread is managed by // Yields the current thread and provides cancellation points if the thread is managed by
// pxThread. Unmanaged threads use standard Sleep. // pxThread. Unmanaged threads use standard Sleep.
extern void pxYield(int ms); extern void pxYield(int ms);
} } // namespace Threading
namespace Exception namespace Exception
{ {
class BaseThreadError : public RuntimeError class BaseThreadError : public RuntimeError
{ {
DEFINE_EXCEPTION_COPYTORS(BaseThreadError, RuntimeError) DEFINE_EXCEPTION_COPYTORS(BaseThreadError, RuntimeError)
DEFINE_EXCEPTION_MESSAGES(BaseThreadError) DEFINE_EXCEPTION_MESSAGES(BaseThreadError)
public: public:
Threading::pxThread *m_thread; Threading::pxThread* m_thread;
protected: protected:
BaseThreadError() BaseThreadError()
{ {
m_thread = NULL; m_thread = NULL;
} }
public: public:
explicit BaseThreadError(Threading::pxThread *_thread) explicit BaseThreadError(Threading::pxThread* _thread)
{ {
m_thread = _thread; m_thread = _thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)"; m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
} }
explicit BaseThreadError(Threading::pxThread &_thread) explicit BaseThreadError(Threading::pxThread& _thread)
{ {
m_thread = &_thread; m_thread = &_thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)"; m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
@ -134,51 +134,51 @@ public:
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
Threading::pxThread &Thread(); Threading::pxThread& Thread();
const Threading::pxThread &Thread() const; const Threading::pxThread& Thread() const;
}; };
class ThreadCreationError : public BaseThreadError class ThreadCreationError : public BaseThreadError
{ {
DEFINE_EXCEPTION_COPYTORS(ThreadCreationError, BaseThreadError) DEFINE_EXCEPTION_COPYTORS(ThreadCreationError, BaseThreadError)
public: public:
explicit ThreadCreationError(Threading::pxThread *_thread) explicit ThreadCreationError(Threading::pxThread* _thread)
{ {
m_thread = _thread; m_thread = _thread;
SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread."); SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread.");
} }
explicit ThreadCreationError(Threading::pxThread &_thread) explicit ThreadCreationError(Threading::pxThread& _thread)
{ {
m_thread = &_thread; m_thread = &_thread;
SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread."); SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread.");
} }
}; };
} } // namespace Exception
namespace Threading namespace Threading
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Platform Specific External APIs // Platform Specific External APIs
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// The following set of documented functions have Linux/Win32 specific implementations, // The following set of documented functions have Linux/Win32 specific implementations,
// which are found in WinThreads.cpp and LnxThreads.cpp // which are found in WinThreads.cpp and LnxThreads.cpp
// Releases a timeslice to other threads. // Releases a timeslice to other threads.
extern void Timeslice(); extern void Timeslice();
// For use in spin/wait loops. // For use in spin/wait loops.
extern void SpinWait(); extern void SpinWait();
// Optional implementation to enable hires thread/process scheduler for the operating system. // Optional implementation to enable hires thread/process scheduler for the operating system.
// Needed by Windows, but might not be relevant to other platforms. // Needed by Windows, but might not be relevant to other platforms.
extern void EnableHiresScheduler(); extern void EnableHiresScheduler();
extern void DisableHiresScheduler(); extern void DisableHiresScheduler();
// sleeps the current thread for the given number of milliseconds. // sleeps the current thread for the given number of milliseconds.
extern void Sleep(int ms); extern void Sleep(int ms);
// pthread Cond is an evil api that is not suited for Pcsx2 needs. // pthread Cond is an evil api that is not suited for Pcsx2 needs.
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air) // Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
@ -196,23 +196,23 @@ extern void Sleep(int ms);
}; };
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// NonblockingMutex // NonblockingMutex
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This is a very simple non-blocking mutex, which behaves similarly to pthread_mutex's // This is a very simple non-blocking mutex, which behaves similarly to pthread_mutex's
// trylock(), but without any of the extra overhead needed to set up a structure capable // trylock(), but without any of the extra overhead needed to set up a structure capable
// of blocking waits. It basically optimizes to a single InterlockedExchange. // of blocking waits. It basically optimizes to a single InterlockedExchange.
// //
// Simple use: if TryAcquire() returns false, the Bool is already interlocked by another thread. // Simple use: if TryAcquire() returns false, the Bool is already interlocked by another thread.
// If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking // If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking
// it later. // it later.
// //
class NonblockingMutex class NonblockingMutex
{ {
protected: protected:
std::atomic_flag val; std::atomic_flag val;
public: public:
NonblockingMutex() { val.clear(); } NonblockingMutex() { val.clear(); }
virtual ~NonblockingMutex() = default; virtual ~NonblockingMutex() = default;
@ -232,11 +232,11 @@ public:
{ {
val.clear(); val.clear();
} }
}; };
class Semaphore class Semaphore
{ {
protected: protected:
#ifdef __APPLE__ #ifdef __APPLE__
semaphore_t m_sema; semaphore_t m_sema;
int m_counter; int m_counter;
@ -244,7 +244,7 @@ protected:
sem_t m_sema; sem_t m_sema;
#endif #endif
public: public:
Semaphore(); Semaphore();
virtual ~Semaphore(); virtual ~Semaphore();
@ -253,21 +253,21 @@ public:
void Post(int multiple); void Post(int multiple);
void WaitWithoutYield(); void WaitWithoutYield();
bool WaitWithoutYield(const wxTimeSpan &timeout); bool WaitWithoutYield(const wxTimeSpan& timeout);
void WaitNoCancel(); void WaitNoCancel();
void WaitNoCancel(const wxTimeSpan &timeout); void WaitNoCancel(const wxTimeSpan& timeout);
int Count(); int Count();
void Wait(); void Wait();
bool Wait(const wxTimeSpan &timeout); bool Wait(const wxTimeSpan& timeout);
}; };
class Mutex class Mutex
{ {
protected: protected:
pthread_mutex_t m_mutex; pthread_mutex_t m_mutex;
public: public:
Mutex(); Mutex();
virtual ~Mutex(); virtual ~Mutex();
virtual bool IsRecursive() const { return false; } virtual bool IsRecursive() const { return false; }
@ -277,104 +277,104 @@ public:
void Detach(); void Detach();
void Acquire(); void Acquire();
bool Acquire(const wxTimeSpan &timeout); bool Acquire(const wxTimeSpan& timeout);
bool TryAcquire(); bool TryAcquire();
void Release(); void Release();
void AcquireWithoutYield(); void AcquireWithoutYield();
bool AcquireWithoutYield(const wxTimeSpan &timeout); bool AcquireWithoutYield(const wxTimeSpan& timeout);
void Wait(); void Wait();
bool Wait(const wxTimeSpan &timeout); bool Wait(const wxTimeSpan& timeout);
void WaitWithoutYield(); void WaitWithoutYield();
bool WaitWithoutYield(const wxTimeSpan &timeout); bool WaitWithoutYield(const wxTimeSpan& timeout);
protected: protected:
// empty constructor used by MutexLockRecursive // empty constructor used by MutexLockRecursive
Mutex(bool) {} Mutex(bool) {}
}; };
class MutexRecursive : public Mutex class MutexRecursive : public Mutex
{ {
public: public:
MutexRecursive(); MutexRecursive();
virtual ~MutexRecursive(); virtual ~MutexRecursive();
virtual bool IsRecursive() const { return true; } virtual bool IsRecursive() const { return true; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedLock // ScopedLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Helper class for using Mutexes. Using this class provides an exception-safe (and // Helper class for using Mutexes. Using this class provides an exception-safe (and
// generally clean) method of locking code inside a function or conditional block. The lock // generally clean) method of locking code inside a function or conditional block. The lock
// will be automatically released on any return or exit from the function. // will be automatically released on any return or exit from the function.
// //
// Const qualification note: // Const qualification note:
// ScopedLock takes const instances of the mutex, even though the mutex is modified // ScopedLock takes const instances of the mutex, even though the mutex is modified
// by locking and unlocking. Two rationales: // by locking and unlocking. Two rationales:
// //
// 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes, // 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes,
// this class needs a const hack to allow those accessors to be const (which is typically // this class needs a const hack to allow those accessors to be const (which is typically
// *very* important). // *very* important).
// //
// 2) The state of the Mutex is guaranteed to be unchanged when the calling function or // 2) The state of the Mutex is guaranteed to be unchanged when the calling function or
// scope exits, by any means. Only via manual calls to Release or Acquire does that // scope exits, by any means. Only via manual calls to Release or Acquire does that
// change, and typically those are only used in very special circumstances of their own. // change, and typically those are only used in very special circumstances of their own.
// //
class ScopedLock class ScopedLock
{ {
DeclareNoncopyableObject(ScopedLock); DeclareNoncopyableObject(ScopedLock);
protected: protected:
Mutex *m_lock; Mutex* m_lock;
bool m_IsLocked; bool m_IsLocked;
public: public:
virtual ~ScopedLock(); virtual ~ScopedLock();
explicit ScopedLock(const Mutex *locker = NULL); explicit ScopedLock(const Mutex* locker = NULL);
explicit ScopedLock(const Mutex &locker); explicit ScopedLock(const Mutex& locker);
void AssignAndLock(const Mutex &locker); void AssignAndLock(const Mutex& locker);
void AssignAndLock(const Mutex *locker); void AssignAndLock(const Mutex* locker);
void Assign(const Mutex &locker); void Assign(const Mutex& locker);
void Assign(const Mutex *locker); void Assign(const Mutex* locker);
void Release(); void Release();
void Acquire(); void Acquire();
bool IsLocked() const { return m_IsLocked; } bool IsLocked() const { return m_IsLocked; }
protected: protected:
// Special constructor used by ScopedTryLock // Special constructor used by ScopedTryLock
ScopedLock(const Mutex &locker, bool isTryLock); ScopedLock(const Mutex& locker, bool isTryLock);
}; };
class ScopedTryLock : public ScopedLock class ScopedTryLock : public ScopedLock
{ {
public: public:
ScopedTryLock(const Mutex &locker) ScopedTryLock(const Mutex& locker)
: ScopedLock(locker, true) : ScopedLock(locker, true)
{ {
} }
virtual ~ScopedTryLock() = default; virtual ~ScopedTryLock() = default;
bool Failed() const { return !m_IsLocked; } bool Failed() const { return !m_IsLocked; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedNonblockingLock // ScopedNonblockingLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// A ScopedTryLock branded for use with Nonblocking mutexes. See ScopedTryLock for details. // A ScopedTryLock branded for use with Nonblocking mutexes. See ScopedTryLock for details.
// //
class ScopedNonblockingLock class ScopedNonblockingLock
{ {
DeclareNoncopyableObject(ScopedNonblockingLock); DeclareNoncopyableObject(ScopedNonblockingLock);
protected: protected:
NonblockingMutex &m_lock; NonblockingMutex& m_lock;
bool m_IsLocked; bool m_IsLocked;
public: public:
ScopedNonblockingLock(NonblockingMutex &locker) ScopedNonblockingLock(NonblockingMutex& locker)
: m_lock(locker) : m_lock(locker)
, m_IsLocked(m_lock.TryAcquire()) , m_IsLocked(m_lock.TryAcquire())
{ {
@ -387,21 +387,21 @@ public:
} }
bool Failed() const { return !m_IsLocked; } bool Failed() const { return !m_IsLocked; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedLockBool // ScopedLockBool
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// A ScopedLock in which you specify an external bool to get updated on locks/unlocks. // A ScopedLock in which you specify an external bool to get updated on locks/unlocks.
// Note that the isLockedBool should only be used as an indicator for the locked status, // Note that the isLockedBool should only be used as an indicator for the locked status,
// and not actually depended on for thread synchronization... // and not actually depended on for thread synchronization...
struct ScopedLockBool struct ScopedLockBool
{ {
ScopedLock m_lock; ScopedLock m_lock;
std::atomic<bool> &m_bool; std::atomic<bool>& m_bool;
ScopedLockBool(Mutex &mutexToLock, std::atomic<bool> &isLockedBool) ScopedLockBool(Mutex& mutexToLock, std::atomic<bool>& isLockedBool)
: m_lock(mutexToLock) : m_lock(mutexToLock)
, m_bool(isLockedBool) , m_bool(isLockedBool)
{ {
@ -421,5 +421,5 @@ struct ScopedLockBool
m_bool.store(false, std::memory_order_relaxed); m_bool.store(false, std::memory_order_relaxed);
m_lock.Release(); m_lock.Release();
} }
}; };
} } // namespace Threading

View File

@ -25,7 +25,7 @@ wxDEFINE_EVENT(pxEvt_ThreadedTaskComplete, wxCommandEvent);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
wxIMPLEMENT_DYNAMIC_CLASS(WaitForTaskDialog, wxDialogWithHelpers); wxIMPLEMENT_DYNAMIC_CLASS(WaitForTaskDialog, wxDialogWithHelpers);
Threading::WaitForTaskDialog::WaitForTaskDialog(const wxString &title, const wxString &heading) Threading::WaitForTaskDialog::WaitForTaskDialog(const wxString& title, const wxString& heading)
: wxDialogWithHelpers(NULL, _("Waiting for tasks...")) : wxDialogWithHelpers(NULL, _("Waiting for tasks..."))
//, m_Timer(this) //, m_Timer(this)
{ {
@ -59,7 +59,7 @@ Threading::WaitForTaskDialog::WaitForTaskDialog(const wxString &title, const wxS
//GetSysExecutorThread().PostEvent( new SysExecEvent_ApplyPlugins( this, m_sync ) ); //GetSysExecutorThread().PostEvent( new SysExecEvent_ApplyPlugins( this, m_sync ) );
} }
void Threading::WaitForTaskDialog::OnTaskComplete(wxCommandEvent &evt) void Threading::WaitForTaskDialog::OnTaskComplete(wxCommandEvent& evt)
{ {
evt.Skip(); evt.Skip();

View File

@ -22,31 +22,31 @@ wxDECLARE_EVENT(pxEvt_ThreadedTaskComplete, wxCommandEvent);
namespace Threading namespace Threading
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// WaitForTaskDialog // WaitForTaskDialog
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This dialog is displayed whenever the main thread is recursively waiting on multiple // This dialog is displayed whenever the main thread is recursively waiting on multiple
// mutexes or semaphores. wxwidgets does not support recursive yielding to pending events // mutexes or semaphores. wxwidgets does not support recursive yielding to pending events
// but it *does* support opening a modal dialog, which disables the interface (preventing // but it *does* support opening a modal dialog, which disables the interface (preventing
// the user from starting additional actions), and processes messages (allowing the system // the user from starting additional actions), and processes messages (allowing the system
// to continue to manage threads and process logging). // to continue to manage threads and process logging).
// //
class WaitForTaskDialog : public wxDialogWithHelpers class WaitForTaskDialog : public wxDialogWithHelpers
{ {
wxDECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog); wxDECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog);
typedef wxDialogWithHelpers _parent; typedef wxDialogWithHelpers _parent;
protected: protected:
SynchronousActionState m_sync; SynchronousActionState m_sync;
public: public:
WaitForTaskDialog(const wxString &title = wxEmptyString, const wxString &heading = wxEmptyString); WaitForTaskDialog(const wxString& title = wxEmptyString, const wxString& heading = wxEmptyString);
virtual ~WaitForTaskDialog() = default; virtual ~WaitForTaskDialog() = default;
virtual int ShowModal(); virtual int ShowModal();
protected: protected:
void OnTaskComplete(wxCommandEvent &evt); void OnTaskComplete(wxCommandEvent& evt);
//void OnTimer( wxTimerEvent& evt ); //void OnTimer( wxTimerEvent& evt );
}; };
} } // namespace Threading

View File

@ -21,10 +21,10 @@
namespace Threading namespace Threading
{ {
extern const wxTimeSpan def_yieldgui_interval; extern const wxTimeSpan def_yieldgui_interval;
extern bool _WaitGui_RecursionGuard(const wxChar *name); extern bool _WaitGui_RecursionGuard(const wxChar* name);
extern void YieldToMain(); extern void YieldToMain();
extern bool AllowDeletions(); extern bool AllowDeletions();
} } // namespace Threading

View File

@ -30,13 +30,13 @@
struct TraceLogDescriptor struct TraceLogDescriptor
{ {
// short name, alphanumerics only: used for saving/loading options. // short name, alphanumerics only: used for saving/loading options.
const wxChar *ShortName; const wxChar* ShortName;
// Standard UI name for this log source. Used in menus, options dialogs. // Standard UI name for this log source. Used in menus, options dialogs.
const wxChar *Name; const wxChar* Name;
// Length description for use as a tooltip or menu item description. // Length description for use as a tooltip or menu item description.
const wxChar *Description; const wxChar* Description;
wxString GetShortName() const wxString GetShortName() const
{ {
@ -66,7 +66,7 @@ struct TraceLogDescriptor
class BaseTraceLogSource class BaseTraceLogSource
{ {
protected: protected:
const TraceLogDescriptor *m_Descriptor; const TraceLogDescriptor* m_Descriptor;
public: public:
// Indicates if the user has enabled this specific log. This boolean only represents // Indicates if the user has enabled this specific log. This boolean only represents
@ -86,7 +86,7 @@ protected:
public: public:
TraceLog_ImplementBaseAPI(BaseTraceLogSource) TraceLog_ImplementBaseAPI(BaseTraceLogSource)
BaseTraceLogSource(const TraceLogDescriptor *desc) BaseTraceLogSource(const TraceLogDescriptor* desc)
{ {
pxAssumeDev(desc, "Trace logs must have a valid (non-NULL) descriptor."); pxAssumeDev(desc, "Trace logs must have a valid (non-NULL) descriptor.");
Enabled = false; Enabled = false;
@ -104,8 +104,8 @@ public:
virtual bool IsActive() const { return Enabled; } virtual bool IsActive() const { return Enabled; }
virtual wxString GetShortName() const { return m_Descriptor->GetShortName(); } virtual wxString GetShortName() const { return m_Descriptor->GetShortName(); }
virtual const wxChar *GetName() const { return m_Descriptor->Name; } virtual const wxChar* GetName() const { return m_Descriptor->Name; }
virtual const wxChar *GetDescription() const virtual const wxChar* GetDescription() const
{ {
return (m_Descriptor->Description != NULL) ? pxGetTranslation(m_Descriptor->Description) : wxEmptyString; return (m_Descriptor->Description != NULL) ? pxGetTranslation(m_Descriptor->Description) : wxEmptyString;
} }
@ -122,12 +122,12 @@ public:
class TextFileTraceLog : public BaseTraceLogSource class TextFileTraceLog : public BaseTraceLogSource
{ {
public: public:
TextFileTraceLog(const TraceLogDescriptor *desc) TextFileTraceLog(const TraceLogDescriptor* desc)
: BaseTraceLogSource(desc) : BaseTraceLogSource(desc)
{ {
} }
bool Write(const char *fmt, ...) const bool Write(const char* fmt, ...) const
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -137,7 +137,7 @@ public:
return false; return false;
} }
bool WriteV(const char *fmt, va_list list) const bool WriteV(const char* fmt, va_list list) const
{ {
FastFormatAscii ascii; FastFormatAscii ascii;
ApplyPrefix(ascii); ApplyPrefix(ascii);
@ -146,8 +146,8 @@ public:
return false; return false;
} }
virtual void ApplyPrefix(FastFormatAscii &ascii) const {} virtual void ApplyPrefix(FastFormatAscii& ascii) const {}
virtual void DoWrite(const char *fmt) const = 0; virtual void DoWrite(const char* fmt) const = 0;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -170,7 +170,7 @@ protected:
public: public:
ConsoleLog_ImplementBaseAPI(ConsoleLogSource) ConsoleLog_ImplementBaseAPI(ConsoleLogSource)
ConsoleLogSource(const TraceLogDescriptor *desc, ConsoleColors defaultColor = Color_Gray) ConsoleLogSource(const TraceLogDescriptor* desc, ConsoleColors defaultColor = Color_Gray)
: BaseTraceLogSource(desc) : BaseTraceLogSource(desc)
{ {
DefaultColor = defaultColor; DefaultColor = defaultColor;
@ -179,7 +179,7 @@ public:
// Writes to the console using the source's default color. Note that the source's default // Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the // color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default. // console's default color is Color_Default.
bool Write(const char *fmt, ...) const bool Write(const char* fmt, ...) const
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -189,7 +189,7 @@ public:
return false; return false;
} }
bool Write(const wxChar *fmt, ...) const bool Write(const wxChar* fmt, ...) const
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -211,7 +211,7 @@ public:
// Writes to the console using the specified color. This overrides the default color setting // Writes to the console using the specified color. This overrides the default color setting
// for this log. // for this log.
bool Write(ConsoleColors color, const char *fmt, ...) const bool Write(ConsoleColors color, const char* fmt, ...) const
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -221,7 +221,7 @@ public:
return false; return false;
} }
bool Write(ConsoleColors color, const wxChar *fmt, ...) const bool Write(ConsoleColors color, const wxChar* fmt, ...) const
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -233,7 +233,7 @@ public:
// Writes to the console using bold yellow text -- overrides the log source's default // Writes to the console using bold yellow text -- overrides the log source's default
// color settings. // color settings.
bool Warn(const wxChar *fmt, ...) const bool Warn(const wxChar* fmt, ...) const
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -255,7 +255,7 @@ public:
// Writes to the console using bold red text -- overrides the log source's default // Writes to the console using bold red text -- overrides the log source's default
// color settings. // color settings.
bool Error(const wxChar *fmt, ...) const bool Error(const wxChar* fmt, ...) const
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
@ -275,13 +275,13 @@ public:
return false; return false;
} }
bool WriteV(const char *fmt, va_list list) const; bool WriteV(const char* fmt, va_list list) const;
bool WriteV(const wxChar *fmt, va_list list) const; bool WriteV(const wxChar* fmt, va_list list) const;
bool WriteV(ConsoleColors color, const char *fmt, va_list list) const; bool WriteV(ConsoleColors color, const char* fmt, va_list list) const;
bool WriteV(ConsoleColors color, const wxChar *fmt, va_list list) const; bool WriteV(ConsoleColors color, const wxChar* fmt, va_list list) const;
virtual void DoWrite(const wxChar *msg) const virtual void DoWrite(const wxChar* msg) const
{ {
Console.DoWriteLn(msg); Console.DoWriteLn(msg);
} }

View File

@ -22,12 +22,13 @@
template class EventSource<IEventListener_PageFault>; template class EventSource<IEventListener_PageFault>;
SrcType_PageFault *Source_PageFault = NULL; SrcType_PageFault* Source_PageFault = NULL;
Threading::Mutex PageFault_Mutex; Threading::Mutex PageFault_Mutex;
void pxInstallSignalHandler() void pxInstallSignalHandler()
{ {
if (!Source_PageFault) { if (!Source_PageFault)
{
Source_PageFault = new SrcType_PageFault(); Source_PageFault = new SrcType_PageFault();
} }
@ -51,15 +52,16 @@ EventListener_PageFault::~EventListener_PageFault()
Source_PageFault->Remove(*this); Source_PageFault->Remove(*this);
} }
void SrcType_PageFault::Dispatch(const PageFaultInfo &params) void SrcType_PageFault::Dispatch(const PageFaultInfo& params)
{ {
m_handled = false; m_handled = false;
_parent::Dispatch(params); _parent::Dispatch(params);
} }
void SrcType_PageFault::_DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const PageFaultInfo &evt) void SrcType_PageFault::_DispatchRaw(ListenerIterator iter, const ListenerIterator& iend, const PageFaultInfo& evt)
{ {
do { do
{
(*iter)->DispatchEvent(evt, m_handled); (*iter)->DispatchEvent(evt, m_handled);
} while ((++iter != iend) && !m_handled); } while ((++iter != iend) && !m_handled);
} }
@ -73,23 +75,29 @@ static size_t pageAlign(size_t size)
// VirtualMemoryManager (implementations) // VirtualMemoryManager (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
VirtualMemoryManager::VirtualMemoryManager(const wxString &name, uptr base, size_t size, uptr upper_bounds, bool strict) VirtualMemoryManager::VirtualMemoryManager(const wxString& name, uptr base, size_t size, uptr upper_bounds, bool strict)
: m_name(name), m_baseptr(0), m_pageuse(nullptr), m_pages_reserved(0) : m_name(name)
, m_baseptr(0)
, m_pageuse(nullptr)
, m_pages_reserved(0)
{ {
if (!size) return; if (!size)
return;
uptr reserved_bytes = pageAlign(size); uptr reserved_bytes = pageAlign(size);
m_pages_reserved = reserved_bytes / __pagesize; m_pages_reserved = reserved_bytes / __pagesize;
m_baseptr = (uptr)HostSys::MmapReserve(base, reserved_bytes); m_baseptr = (uptr)HostSys::MmapReserve(base, reserved_bytes);
if (!m_baseptr || (upper_bounds != 0 && (((uptr)m_baseptr + reserved_bytes) > upper_bounds))) { if (!m_baseptr || (upper_bounds != 0 && (((uptr)m_baseptr + reserved_bytes) > upper_bounds)))
{
DevCon.Warning(L"%s: host memory @ %ls -> %ls is unavailable; attempting to map elsewhere...", DevCon.Warning(L"%s: host memory @ %ls -> %ls is unavailable; attempting to map elsewhere...",
WX_STR(m_name), pxsPtr(base), pxsPtr(base + size)); WX_STR(m_name), pxsPtr(base), pxsPtr(base + size));
SafeSysMunmap(m_baseptr, reserved_bytes); SafeSysMunmap(m_baseptr, reserved_bytes);
if (base) { if (base)
{
// Let's try again at an OS-picked memory area, and then hope it meets needed // Let's try again at an OS-picked memory area, and then hope it meets needed
// boundschecking criteria below. // boundschecking criteria below.
m_baseptr = (uptr)HostSys::MmapReserve(0, reserved_bytes); m_baseptr = (uptr)HostSys::MmapReserve(0, reserved_bytes);
@ -101,11 +109,13 @@ VirtualMemoryManager::VirtualMemoryManager(const wxString &name, uptr base, size
fulfillsRequirements = false; fulfillsRequirements = false;
if ((upper_bounds != 0) && ((m_baseptr + reserved_bytes) > upper_bounds)) if ((upper_bounds != 0) && ((m_baseptr + reserved_bytes) > upper_bounds))
fulfillsRequirements = false; fulfillsRequirements = false;
if (!fulfillsRequirements) { if (!fulfillsRequirements)
{
SafeSysMunmap(m_baseptr, reserved_bytes); SafeSysMunmap(m_baseptr, reserved_bytes);
} }
if (!m_baseptr) return; if (!m_baseptr)
return;
m_pageuse = new std::atomic<bool>[m_pages_reserved](); m_pageuse = new std::atomic<bool>[m_pages_reserved]();
@ -122,17 +132,24 @@ VirtualMemoryManager::VirtualMemoryManager(const wxString &name, uptr base, size
VirtualMemoryManager::~VirtualMemoryManager() VirtualMemoryManager::~VirtualMemoryManager()
{ {
if (m_pageuse) delete[] m_pageuse; if (m_pageuse)
if (m_baseptr) HostSys::Munmap(m_baseptr, m_pages_reserved * __pagesize); delete[] m_pageuse;
if (m_baseptr)
HostSys::Munmap(m_baseptr, m_pages_reserved * __pagesize);
} }
static bool VMMMarkPagesAsInUse(std::atomic<bool> *begin, std::atomic<bool> *end) { static bool VMMMarkPagesAsInUse(std::atomic<bool>* begin, std::atomic<bool>* end)
for (auto current = begin; current < end; current++) { {
for (auto current = begin; current < end; current++)
{
bool expected = false; bool expected = false;
if (!current->compare_exchange_strong(expected, true), std::memory_order_relaxed) { if (!current->compare_exchange_strong(expected, true), std::memory_order_relaxed)
{
// This was already allocated! Undo the things we've set until this point // This was already allocated! Undo the things we've set until this point
while (--current >= begin) { while (--current >= begin)
if (!current->compare_exchange_strong(expected, false, std::memory_order_relaxed)) { {
if (!current->compare_exchange_strong(expected, false, std::memory_order_relaxed))
{
// In the time we were doing this, someone set one of the things we just set to true back to false // In the time we were doing this, someone set one of the things we just set to true back to false
// This should never happen, but if it does we'll just stop and hope nothing bad happens // This should never happen, but if it does we'll just stop and hope nothing bad happens
pxAssert(0); pxAssert(0);
@ -145,7 +162,7 @@ static bool VMMMarkPagesAsInUse(std::atomic<bool> *begin, std::atomic<bool> *end
return true; return true;
} }
void *VirtualMemoryManager::Alloc(uptr offsetLocation, size_t size) const void* VirtualMemoryManager::Alloc(uptr offsetLocation, size_t size) const
{ {
size = pageAlign(size); size = pageAlign(size);
if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) alloc at unaligned offsetLocation")) if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) alloc at unaligned offsetLocation"))
@ -155,16 +172,17 @@ void *VirtualMemoryManager::Alloc(uptr offsetLocation, size_t size) const
if (m_baseptr == 0) if (m_baseptr == 0)
return nullptr; return nullptr;
auto puStart = &m_pageuse[offsetLocation / __pagesize]; auto puStart = &m_pageuse[offsetLocation / __pagesize];
auto puEnd = &m_pageuse[(offsetLocation+size) / __pagesize]; auto puEnd = &m_pageuse[(offsetLocation + size) / __pagesize];
if (!pxAssertDev(VMMMarkPagesAsInUse(puStart, puEnd), "(VirtualMemoryManager) allocation requests overlapped")) if (!pxAssertDev(VMMMarkPagesAsInUse(puStart, puEnd), "(VirtualMemoryManager) allocation requests overlapped"))
return nullptr; return nullptr;
return (void *)(m_baseptr + offsetLocation); return (void*)(m_baseptr + offsetLocation);
} }
void VirtualMemoryManager::Free(void *address, size_t size) const void VirtualMemoryManager::Free(void* address, size_t size) const
{ {
uptr offsetLocation = (uptr)address - m_baseptr; uptr offsetLocation = (uptr)address - m_baseptr;
if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) free at unaligned address")) { if (!pxAssertDev(offsetLocation % __pagesize == 0, "(VirtualMemoryManager) free at unaligned address"))
{
uptr newLoc = pageAlign(offsetLocation); uptr newLoc = pageAlign(offsetLocation);
size -= (offsetLocation - newLoc); size -= (offsetLocation - newLoc);
offsetLocation = newLoc; offsetLocation = newLoc;
@ -174,10 +192,12 @@ void VirtualMemoryManager::Free(void *address, size_t size) const
if (!pxAssertDev(size + offsetLocation <= m_pages_reserved * __pagesize, "(VirtualMemoryManager) free outside reserved area")) if (!pxAssertDev(size + offsetLocation <= m_pages_reserved * __pagesize, "(VirtualMemoryManager) free outside reserved area"))
return; return;
auto puStart = &m_pageuse[offsetLocation / __pagesize]; auto puStart = &m_pageuse[offsetLocation / __pagesize];
auto puEnd = &m_pageuse[(offsetLocation+size) / __pagesize]; auto puEnd = &m_pageuse[(offsetLocation + size) / __pagesize];
for (; puStart < puEnd; puStart++) { for (; puStart < puEnd; puStart++)
{
bool expected = true; bool expected = true;
if (!puStart->compare_exchange_strong(expected, false, std::memory_order_relaxed)) { if (!puStart->compare_exchange_strong(expected, false, std::memory_order_relaxed))
{
pxAssertDev(0, "(VirtaulMemoryManager) double-free"); pxAssertDev(0, "(VirtaulMemoryManager) double-free");
} }
} }
@ -187,13 +207,15 @@ void VirtualMemoryManager::Free(void *address, size_t size) const
// VirtualMemoryBumpAllocator (implementations) // VirtualMemoryBumpAllocator (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
VirtualMemoryBumpAllocator::VirtualMemoryBumpAllocator(VirtualMemoryManagerPtr allocator, uptr offsetLocation, size_t size) VirtualMemoryBumpAllocator::VirtualMemoryBumpAllocator(VirtualMemoryManagerPtr allocator, uptr offsetLocation, size_t size)
: m_allocator(std::move(allocator)), m_baseptr((uptr)m_allocator->Alloc(offsetLocation, size)), m_endptr(m_baseptr + size) : m_allocator(std::move(allocator))
, m_baseptr((uptr)m_allocator->Alloc(offsetLocation, size))
, m_endptr(m_baseptr + size)
{ {
if (m_baseptr.load() == 0) if (m_baseptr.load() == 0)
pxAssertDev(0, "(VirtualMemoryBumpAllocator) tried to construct from bad VirtualMemoryManager"); pxAssertDev(0, "(VirtualMemoryBumpAllocator) tried to construct from bad VirtualMemoryManager");
} }
void *VirtualMemoryBumpAllocator::Alloc(size_t size) void* VirtualMemoryBumpAllocator::Alloc(size_t size)
{ {
if (m_baseptr.load() == 0) // True if constructed from bad VirtualMemoryManager (assertion was on initialization) if (m_baseptr.load() == 0) // True if constructed from bad VirtualMemoryManager (assertion was on initialization)
return nullptr; return nullptr;
@ -205,13 +227,13 @@ void *VirtualMemoryBumpAllocator::Alloc(size_t size)
if (!pxAssertDev(out - reservedSize + size <= m_endptr, "(VirtualMemoryBumpAllocator) ran out of memory")) if (!pxAssertDev(out - reservedSize + size <= m_endptr, "(VirtualMemoryBumpAllocator) ran out of memory"))
return nullptr; return nullptr;
return (void *)out; return (void*)out;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// VirtualMemoryReserve (implementations) // VirtualMemoryReserve (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
VirtualMemoryReserve::VirtualMemoryReserve(const wxString &name, size_t size) VirtualMemoryReserve::VirtualMemoryReserve(const wxString& name, size_t size)
: m_name(name) : m_name(name)
{ {
m_defsize = size; m_defsize = size;
@ -224,7 +246,7 @@ VirtualMemoryReserve::VirtualMemoryReserve(const wxString &name, size_t size)
m_allow_writes = true; m_allow_writes = true;
} }
VirtualMemoryReserve &VirtualMemoryReserve::SetPageAccessOnCommit(const PageProtectionMode &mode) VirtualMemoryReserve& VirtualMemoryReserve::SetPageAccessOnCommit(const PageProtectionMode& mode)
{ {
m_prot_mode = mode; m_prot_mode = mode;
return *this; return *this;
@ -245,7 +267,7 @@ size_t VirtualMemoryReserve::GetSize(size_t requestedSize)
// baseptr - the new base pointer that's about to be assigned // baseptr - the new base pointer that's about to be assigned
// size - size of the region pointed to by baseptr // size - size of the region pointed to by baseptr
// //
void *VirtualMemoryReserve::Assign(VirtualMemoryManagerPtr allocator, void * baseptr, size_t size) void* VirtualMemoryReserve::Assign(VirtualMemoryManagerPtr allocator, void* baseptr, size_t size)
{ {
if (!pxAssertDev(m_baseptr == NULL, "(VirtualMemoryReserve) Invalid object state; object has already been reserved.")) if (!pxAssertDev(m_baseptr == NULL, "(VirtualMemoryReserve) Invalid object state; object has already been reserved."))
return m_baseptr; return m_baseptr;
@ -276,7 +298,7 @@ void *VirtualMemoryReserve::Assign(VirtualMemoryManagerPtr allocator, void * bas
return m_baseptr; return m_baseptr;
} }
void VirtualMemoryReserve::ReprotectCommittedBlocks(const PageProtectionMode &newmode) void VirtualMemoryReserve::ReprotectCommittedBlocks(const PageProtectionMode& newmode)
{ {
if (!m_pages_commited) if (!m_pages_commited)
return; return;
@ -296,7 +318,8 @@ void VirtualMemoryReserve::Reset()
void VirtualMemoryReserve::Release() void VirtualMemoryReserve::Release()
{ {
if (!m_baseptr) return; if (!m_baseptr)
return;
Reset(); Reset();
m_allocator->Free(m_baseptr, m_pages_reserved * __pagesize); m_allocator->Free(m_baseptr, m_pages_reserved * __pagesize);
m_baseptr = nullptr; m_baseptr = nullptr;
@ -339,13 +362,15 @@ bool VirtualMemoryReserve::TryResize(uint newsize)
{ {
uint newPages = pageAlign(newsize) / __pagesize; uint newPages = pageAlign(newsize) / __pagesize;
if (newPages > m_pages_reserved) { if (newPages > m_pages_reserved)
{
uint toReservePages = newPages - m_pages_reserved; uint toReservePages = newPages - m_pages_reserved;
uint toReserveBytes = toReservePages * __pagesize; uint toReserveBytes = toReservePages * __pagesize;
DevCon.WriteLn(L"%-32s is being expanded by %u pages.", WX_STR(m_name), toReservePages); DevCon.WriteLn(L"%-32s is being expanded by %u pages.", WX_STR(m_name), toReservePages);
if (!m_allocator->AllocAtAddress(GetPtrEnd(), toReserveBytes)) { if (!m_allocator->AllocAtAddress(GetPtrEnd(), toReserveBytes))
{
Console.Warning("%-32s could not be passively resized due to virtual memory conflict!", WX_STR(m_name)); Console.Warning("%-32s could not be passively resized due to virtual memory conflict!", WX_STR(m_name));
Console.Indent().Warning("(attempted to map memory @ %08p -> %08p)", m_baseptr, (uptr)m_baseptr + toReserveBytes); Console.Indent().Warning("(attempted to map memory @ %08p -> %08p)", m_baseptr, (uptr)m_baseptr + toReserveBytes);
return false; return false;
@ -353,7 +378,9 @@ bool VirtualMemoryReserve::TryResize(uint newsize)
DevCon.WriteLn(Color_Gray, L"%-32s @ %08p -> %08p [%umb]", WX_STR(m_name), DevCon.WriteLn(Color_Gray, L"%-32s @ %08p -> %08p [%umb]", WX_STR(m_name),
m_baseptr, (uptr)m_baseptr + toReserveBytes, toReserveBytes / _1mb); m_baseptr, (uptr)m_baseptr + toReserveBytes, toReserveBytes / _1mb);
} else if (newPages < m_pages_reserved) { }
else if (newPages < m_pages_reserved)
{
if (m_pages_commited > newsize) if (m_pages_commited > newsize)
return false; return false;
@ -397,7 +424,7 @@ wxString PageProtectionMode::ToString() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Common HostSys implementation // Common HostSys implementation
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
void HostSys::Munmap(void *base, size_t size) void HostSys::Munmap(void* base, size_t size)
{ {
Munmap((uptr)base, size); Munmap((uptr)base, size);
} }

View File

@ -18,7 +18,7 @@
#include "common/RedtapeWindows.h" #include "common/RedtapeWindows.h"
#include "common/PageFaultSource.h" #include "common/PageFaultSource.h"
static long DoSysPageFaultExceptionFilter(EXCEPTION_POINTERS *eps) static long DoSysPageFaultExceptionFilter(EXCEPTION_POINTERS* eps)
{ {
if (eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) if (eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
@ -31,7 +31,7 @@ static long DoSysPageFaultExceptionFilter(EXCEPTION_POINTERS *eps)
return Source_PageFault->WasHandled() ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; return Source_PageFault->WasHandled() ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
} }
long __stdcall SysPageFaultExceptionFilter(EXCEPTION_POINTERS *eps) long __stdcall SysPageFaultExceptionFilter(EXCEPTION_POINTERS* eps)
{ {
// Prevent recursive exception filtering by catching the exception from the filter here. // Prevent recursive exception filtering by catching the exception from the filter here.
// In the event that the filter causes an access violation (happened during shutdown // In the event that the filter causes an access violation (happened during shutdown
@ -39,9 +39,12 @@ long __stdcall SysPageFaultExceptionFilter(EXCEPTION_POINTERS *eps)
// exception. // exception.
// TODO: find a reliable way to debug the filter itself, I've come up with a few ways that // TODO: find a reliable way to debug the filter itself, I've come up with a few ways that
// work but I don't fully understand why some do and some don't. // work but I don't fully understand why some do and some don't.
__try { __try
{
return DoSysPageFaultExceptionFilter(eps); return DoSysPageFaultExceptionFilter(eps);
} __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { }
__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
} }
@ -54,7 +57,7 @@ void _platform_InstallSignalHandler()
} }
static DWORD ConvertToWinApi(const PageProtectionMode &mode) static DWORD ConvertToWinApi(const PageProtectionMode& mode)
{ {
DWORD winmode = PAGE_NOACCESS; DWORD winmode = PAGE_NOACCESS;
@ -62,31 +65,37 @@ static DWORD ConvertToWinApi(const PageProtectionMode &mode)
// numbering (like flags) but is in fact not a flag value. *Someone* from the early // numbering (like flags) but is in fact not a flag value. *Someone* from the early
// microsoft days wasn't a very good coder, me thinks. --air // microsoft days wasn't a very good coder, me thinks. --air
if (mode.CanExecute()) { if (mode.CanExecute())
{
winmode = mode.CanWrite() ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; winmode = mode.CanWrite() ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
} else if (mode.CanRead()) { }
else if (mode.CanRead())
{
winmode = mode.CanWrite() ? PAGE_READWRITE : PAGE_READONLY; winmode = mode.CanWrite() ? PAGE_READWRITE : PAGE_READONLY;
} }
return winmode; return winmode;
} }
void *HostSys::MmapReservePtr(void *base, size_t size) void* HostSys::MmapReservePtr(void* base, size_t size)
{ {
return VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS); return VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS);
} }
bool HostSys::MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode) bool HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode)
{ {
void *result = VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)); void* result = VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode));
if (result) if (result)
return true; return true;
const DWORD errcode = GetLastError(); const DWORD errcode = GetLastError();
if (errcode == ERROR_COMMITMENT_MINIMUM) { if (errcode == ERROR_COMMITMENT_MINIMUM)
{
Console.Warning("(MmapCommit) Received windows error %u {Virtual Memory Minimum Too Low}.", ERROR_COMMITMENT_MINIMUM); Console.Warning("(MmapCommit) Received windows error %u {Virtual Memory Minimum Too Low}.", ERROR_COMMITMENT_MINIMUM);
Sleep(1000); // Cut windows some time to rework its memory... Sleep(1000); // Cut windows some time to rework its memory...
} else if (errcode != ERROR_NOT_ENOUGH_MEMORY && errcode != ERROR_OUTOFMEMORY) { }
else if (errcode != ERROR_NOT_ENOUGH_MEMORY && errcode != ERROR_OUTOFMEMORY)
{
pxFailDev(L"VirtualAlloc COMMIT failed: " + Exception::WinApiError().GetMsgFromWindows()); pxFailDev(L"VirtualAlloc COMMIT failed: " + Exception::WinApiError().GetMsgFromWindows());
return false; return false;
} }
@ -97,31 +106,31 @@ bool HostSys::MmapCommitPtr(void *base, size_t size, const PageProtectionMode &m
return VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)) != NULL; return VirtualAlloc(base, size, MEM_COMMIT, ConvertToWinApi(mode)) != NULL;
} }
void HostSys::MmapResetPtr(void *base, size_t size) void HostSys::MmapResetPtr(void* base, size_t size)
{ {
VirtualFree(base, size, MEM_DECOMMIT); VirtualFree(base, size, MEM_DECOMMIT);
} }
void *HostSys::MmapReserve(uptr base, size_t size) void* HostSys::MmapReserve(uptr base, size_t size)
{ {
return MmapReservePtr((void *)base, size); return MmapReservePtr((void*)base, size);
} }
bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode &mode) bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode& mode)
{ {
return MmapCommitPtr((void *)base, size, mode); return MmapCommitPtr((void*)base, size, mode);
} }
void HostSys::MmapReset(uptr base, size_t size) void HostSys::MmapReset(uptr base, size_t size)
{ {
MmapResetPtr((void *)base, size); MmapResetPtr((void*)base, size);
} }
void *HostSys::Mmap(uptr base, size_t size) void* HostSys::Mmap(uptr base, size_t size)
{ {
return VirtualAlloc((void *)base, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); return VirtualAlloc((void*)base, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
} }
void HostSys::Munmap(uptr base, size_t size) void HostSys::Munmap(uptr base, size_t size)
@ -129,10 +138,10 @@ void HostSys::Munmap(uptr base, size_t size)
if (!base) if (!base)
return; return;
//VirtualFree((void*)base, size, MEM_DECOMMIT); //VirtualFree((void*)base, size, MEM_DECOMMIT);
VirtualFree((void *)base, 0, MEM_RELEASE); VirtualFree((void*)base, 0, MEM_RELEASE);
} }
void HostSys::MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode) void HostSys::MemProtect(void* baseaddr, size_t size, const PageProtectionMode& mode)
{ {
pxAssertDev(((size & (__pagesize - 1)) == 0), pxsFmt( pxAssertDev(((size & (__pagesize - 1)) == 0), pxsFmt(
L"Memory block size must be a multiple of the target platform's page size.\n" L"Memory block size must be a multiple of the target platform's page size.\n"
@ -140,7 +149,8 @@ void HostSys::MemProtect(void *baseaddr, size_t size, const PageProtectionMode &
__pagesize, __pagesize, size, size)); __pagesize, __pagesize, size, size));
DWORD OldProtect; // enjoy my uselessness, yo! DWORD OldProtect; // enjoy my uselessness, yo!
if (!VirtualProtect(baseaddr, size, ConvertToWinApi(mode), &OldProtect)) { if (!VirtualProtect(baseaddr, size, ConvertToWinApi(mode), &OldProtect))
{
Exception::WinApiError apiError; Exception::WinApiError apiError;
apiError.SetDiagMsg( apiError.SetDiagMsg(

View File

@ -98,9 +98,9 @@ void Threading::pxThread::_platform_specific_OnCleanupInThread()
CloseHandle((HANDLE)m_native_handle); CloseHandle((HANDLE)m_native_handle);
} }
void Threading::SetNameOfCurrentThread(const char *name) void Threading::SetNameOfCurrentThread(const char* name)
{ {
// This feature needs Windows headers and MSVC's SEH support: // This feature needs Windows headers and MSVC's SEH support:
#if defined(_WIN32) && defined(_MSC_VER) #if defined(_WIN32) && defined(_MSC_VER)
@ -126,9 +126,12 @@ void Threading::SetNameOfCurrentThread(const char *name)
info.dwThreadID = GetCurrentThreadId(); info.dwThreadID = GetCurrentThreadId();
info.dwFlags = 0; info.dwFlags = 0;
__try { __try
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info); {
} __except (EXCEPTION_EXECUTE_HANDLER) { RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
} }
#endif #endif
} }

View File

@ -55,7 +55,8 @@ SingleCoreAffinity::SingleCoreAffinity()
s_threadId = GetCurrentThread(); s_threadId = GetCurrentThread();
s_oldmask = SetThreadAffinityMask(s_threadId, affinityMask); s_oldmask = SetThreadAffinityMask(s_threadId, affinityMask);
if (s_oldmask == ERROR_INVALID_PARAMETER) { if (s_oldmask == ERROR_INVALID_PARAMETER)
{
const int hexWidth = 2 * sizeof(DWORD_PTR); const int hexWidth = 2 * sizeof(DWORD_PTR);
Console.Warning( Console.Warning(
"CpuDetect: SetThreadAffinityMask failed...\n" "CpuDetect: SetThreadAffinityMask failed...\n"

View File

@ -19,17 +19,17 @@
namespace x86Emitter namespace x86Emitter
{ {
const xImplBMI_RVM xMULX = {0xF2, 0x38, 0xF6}; const xImplBMI_RVM xMULX = {0xF2, 0x38, 0xF6};
const xImplBMI_RVM xPDEP = {0xF2, 0x38, 0xF5}; const xImplBMI_RVM xPDEP = {0xF2, 0x38, 0xF5};
const xImplBMI_RVM xPEXT = {0xF3, 0x38, 0xF5}; const xImplBMI_RVM xPEXT = {0xF3, 0x38, 0xF5};
const xImplBMI_RVM xANDN_S = {0x00, 0x38, 0xF2}; const xImplBMI_RVM xANDN_S = {0x00, 0x38, 0xF2};
void xImplBMI_RVM::operator()(const xRegisterInt &to, const xRegisterInt &from1, const xRegisterInt &from2) const void xImplBMI_RVM::operator()(const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const
{ {
xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2);
} }
void xImplBMI_RVM::operator()(const xRegisterInt &to, const xRegisterInt &from1, const xIndirectVoid &from2) const void xImplBMI_RVM::operator()(const xRegisterInt& to, const xRegisterInt& from1, const xIndirectVoid& from2) const
{ {
xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2); xOpWriteC4(Prefix, MbPrefix, Opcode, to, from1, from2);
} }
} } // namespace x86Emitter

View File

@ -77,7 +77,8 @@ void x86capabilities::SIMD_EstablishMXCSRmask()
MXCSR_Mask.bitmask = 0xFFBF; // MMX/SSE default MXCSR_Mask.bitmask = 0xFFBF; // MMX/SSE default
if (hasStreamingSIMD2Extensions) { if (hasStreamingSIMD2Extensions)
{
// This is generally safe assumption, but FXSAVE is the "correct" way to // This is generally safe assumption, but FXSAVE is the "correct" way to
// detect MXCSR masking features of the cpu, so we use it's result below // detect MXCSR masking features of the cpu, so we use it's result below
// and override this. // and override this.
@ -113,12 +114,14 @@ s64 x86capabilities::_CPUSpeedHz(u64 time) const
// Align the cpu execution to a cpuTick boundary. // Align the cpu execution to a cpuTick boundary.
do { do
{
timeStart = GetCPUTicks(); timeStart = GetCPUTicks();
startCycle = __rdtsc(); startCycle = __rdtsc();
} while (GetCPUTicks() == timeStart); } while (GetCPUTicks() == timeStart);
do { do
{
timeStop = GetCPUTicks(); timeStop = GetCPUTicks();
endCycle = __rdtsc(); endCycle = __rdtsc();
} while ((timeStop - timeStart) < time); } while ((timeStop - timeStart) < time);
@ -139,7 +142,8 @@ s64 x86capabilities::_CPUSpeedHz(u64 time) const
wxString x86capabilities::GetTypeName() const wxString x86capabilities::GetTypeName() const
{ {
switch (TypeID) { switch (TypeID)
{
case 0: case 0:
return L"Standard OEM"; return L"Standard OEM";
case 1: case 1:
@ -165,7 +169,8 @@ void x86capabilities::CountCores()
// detect multicore for AMD cpu // detect multicore for AMD cpu
if ((cmds >= 0x80000008) && (VendorID == x86Vendor_AMD)) { if ((cmds >= 0x80000008) && (VendorID == x86Vendor_AMD))
{
// AMD note: they don't support hyperthreading, but they like to flag this true // AMD note: they don't support hyperthreading, but they like to flag this true
// anyway. Let's force-unflag it until we come up with a better solution. // anyway. Let's force-unflag it until we come up with a better solution.
// (note: seems to affect some Phenom II's only? -- Athlon X2's and PhenomI's do // (note: seems to affect some Phenom II's only? -- Athlon X2's and PhenomI's do
@ -177,7 +182,7 @@ void x86capabilities::CountCores()
CountLogicalCores(); CountLogicalCores();
} }
static const char *tbl_x86vendors[] = static const char* tbl_x86vendors[] =
{ {
"GenuineIntel", "GenuineIntel",
"AuthenticAMD", "AuthenticAMD",
@ -209,13 +214,15 @@ void x86capabilities::Identify()
// and threads used by the CPU (AMD and Intel can't agree on how to make this info available). // and threads used by the CPU (AMD and Intel can't agree on how to make this info available).
int vid; int vid;
for (vid = 0; vid < x86Vendor_Unknown; ++vid) { for (vid = 0; vid < x86Vendor_Unknown; ++vid)
{
if (memcmp(VendorName, tbl_x86vendors[vid], 12) == 0) if (memcmp(VendorName, tbl_x86vendors[vid], 12) == 0)
break; break;
} }
VendorID = static_cast<x86VendorType>(vid); VendorID = static_cast<x86VendorType>(vid);
if (cmds >= 0x00000001) { if (cmds >= 0x00000001)
{
cpuid(regs, 0x00000001); cpuid(regs, 0x00000001);
StepID = regs[0] & 0xf; StepID = regs[0] & 0xf;
@ -229,7 +236,8 @@ void x86capabilities::Identify()
Flags2 = regs[2]; Flags2 = regs[2];
} }
if (cmds >= 0x00000007) { if (cmds >= 0x00000007)
{
// Note: ECX must be 0 for AVX2 detection. // Note: ECX must be 0 for AVX2 detection.
cpuidex(regs, 0x00000007, 0); cpuidex(regs, 0x00000007, 0);
@ -238,7 +246,8 @@ void x86capabilities::Identify()
cpuid(regs, 0x80000000); cpuid(regs, 0x80000000);
cmds = regs[0]; cmds = regs[0];
if (cmds >= 0x80000001) { if (cmds >= 0x80000001)
{
cpuid(regs, 0x80000001); cpuid(regs, 0x80000001);
#ifdef __M_X86_64 #ifdef __M_X86_64
@ -249,9 +258,9 @@ void x86capabilities::Identify()
} }
memzero(FamilyName); memzero(FamilyName);
cpuid((int *)FamilyName, 0x80000002); cpuid((int*)FamilyName, 0x80000002);
cpuid((int *)(FamilyName + 16), 0x80000003); cpuid((int*)(FamilyName + 16), 0x80000003);
cpuid((int *)(FamilyName + 32), 0x80000004); cpuid((int*)(FamilyName + 32), 0x80000004);
hasFloatingPointUnit = (Flags >> 0) & 1; hasFloatingPointUnit = (Flags >> 0) & 1;
hasVirtual8086ModeEnhancements = (Flags >> 1) & 1; hasVirtual8086ModeEnhancements = (Flags >> 1) & 1;

View File

@ -34,20 +34,23 @@
namespace x86Emitter namespace x86Emitter
{ {
// ===================================================================================================== // =====================================================================================================
// Group 1 Instructions - ADD, SUB, ADC, etc. // Group 1 Instructions - ADD, SUB, ADC, etc.
// ===================================================================================================== // =====================================================================================================
// Note on "[Indirect],Imm" forms : use int as the source operand since it's "reasonably inert" from a // Note on "[Indirect],Imm" forms : use int as the source operand since it's "reasonably inert" from a
// compiler perspective. (using uint tends to make the compiler try and fail to match signed immediates // compiler perspective. (using uint tends to make the compiler try and fail to match signed immediates
// with one of the other overloads). // with one of the other overloads).
static void _g1_IndirectImm(G1Type InstType, const xIndirect64orLess &sibdest, int imm) static void _g1_IndirectImm(G1Type InstType, const xIndirect64orLess& sibdest, int imm)
{ {
if (sibdest.Is8BitOp()) { if (sibdest.Is8BitOp())
{
xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest); xOpWrite(sibdest.GetPrefix16(), 0x80, InstType, sibdest);
xWrite<s8>(imm); xWrite<s8>(imm);
} else { }
else
{
u8 opcode = is_s8(imm) ? 0x83 : 0x81; u8 opcode = is_s8(imm) ? 0x83 : 0x81;
xOpWrite(sibdest.GetPrefix16(), opcode, InstType, sibdest, is_s8(imm) ? 1 : sibdest.GetImmSize()); xOpWrite(sibdest.GetPrefix16(), opcode, InstType, sibdest, is_s8(imm) ? 1 : sibdest.GetImmSize());
@ -56,142 +59,154 @@ static void _g1_IndirectImm(G1Type InstType, const xIndirect64orLess &sibdest, i
else else
sibdest.xWriteImm(imm); sibdest.xWriteImm(imm);
} }
} }
void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, const xRegisterInt &from) void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xRegisterInt& from)
{ {
pxAssert(to.GetOperandSize() == from.GetOperandSize()); pxAssert(to.GetOperandSize() == from.GetOperandSize());
u8 opcode = (to.Is8BitOp() ? 0 : 1) | (InstType << 3); u8 opcode = (to.Is8BitOp() ? 0 : 1) | (InstType << 3);
xOpWrite(to.GetPrefix16(), opcode, from, to); xOpWrite(to.GetPrefix16(), opcode, from, to);
} }
static void _g1_EmitOp(G1Type InstType, const xIndirectVoid &sibdest, const xRegisterInt &from) static void _g1_EmitOp(G1Type InstType, const xIndirectVoid& sibdest, const xRegisterInt& from)
{ {
u8 opcode = (from.Is8BitOp() ? 0 : 1) | (InstType << 3); u8 opcode = (from.Is8BitOp() ? 0 : 1) | (InstType << 3);
xOpWrite(from.GetPrefix16(), opcode, from, sibdest); xOpWrite(from.GetPrefix16(), opcode, from, sibdest);
} }
static void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, const xIndirectVoid &sibsrc) static void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xIndirectVoid& sibsrc)
{ {
u8 opcode = (to.Is8BitOp() ? 2 : 3) | (InstType << 3); u8 opcode = (to.Is8BitOp() ? 2 : 3) | (InstType << 3);
xOpWrite(to.GetPrefix16(), opcode, to, sibsrc); xOpWrite(to.GetPrefix16(), opcode, to, sibsrc);
} }
static void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, int imm) static void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, int imm)
{ {
if (!to.Is8BitOp() && is_s8(imm)) { if (!to.Is8BitOp() && is_s8(imm))
{
xOpWrite(to.GetPrefix16(), 0x83, InstType, to); xOpWrite(to.GetPrefix16(), 0x83, InstType, to);
xWrite<s8>(imm); xWrite<s8>(imm);
} else { }
if (to.IsAccumulator()) { else
{
if (to.IsAccumulator())
{
u8 opcode = (to.Is8BitOp() ? 4 : 5) | (InstType << 3); u8 opcode = (to.Is8BitOp() ? 4 : 5) | (InstType << 3);
xOpAccWrite(to.GetPrefix16(), opcode, InstType, to); xOpAccWrite(to.GetPrefix16(), opcode, InstType, to);
} else { }
else
{
u8 opcode = to.Is8BitOp() ? 0x80 : 0x81; u8 opcode = to.Is8BitOp() ? 0x80 : 0x81;
xOpWrite(to.GetPrefix16(), opcode, InstType, to); xOpWrite(to.GetPrefix16(), opcode, InstType, to);
} }
to.xWriteImm(imm); to.xWriteImm(imm);
} }
} }
#define ImplementGroup1(g1type, insttype) \ #define ImplementGroup1(g1type, insttype) \
void g1type::operator()(const xRegisterInt &to, const xRegisterInt &from) const { _g1_EmitOp(insttype, to, from); } \ void g1type::operator()(const xRegisterInt& to, const xRegisterInt& from) const { _g1_EmitOp(insttype, to, from); } \
void g1type::operator()(const xIndirectVoid &to, const xRegisterInt &from) const { _g1_EmitOp(insttype, to, from); } \ void g1type::operator()(const xIndirectVoid& to, const xRegisterInt& from) const { _g1_EmitOp(insttype, to, from); } \
void g1type::operator()(const xRegisterInt &to, const xIndirectVoid &from) const { _g1_EmitOp(insttype, to, from); } \ void g1type::operator()(const xRegisterInt& to, const xIndirectVoid& from) const { _g1_EmitOp(insttype, to, from); } \
void g1type::operator()(const xRegisterInt &to, int imm) const { _g1_EmitOp(insttype, to, imm); } \ void g1type::operator()(const xRegisterInt& to, int imm) const { _g1_EmitOp(insttype, to, imm); } \
void g1type::operator()(const xIndirect64orLess &sibdest, int imm) const { _g1_IndirectImm(insttype, sibdest, imm); } void g1type::operator()(const xIndirect64orLess& sibdest, int imm) const { _g1_IndirectImm(insttype, sibdest, imm); }
ImplementGroup1(xImpl_Group1, InstType) ImplementGroup1(xImpl_Group1, InstType)
ImplementGroup1(xImpl_G1Logic, InstType) ImplementGroup1(xImpl_G1Logic, InstType)
ImplementGroup1(xImpl_G1Arith, InstType) ImplementGroup1(xImpl_G1Arith, InstType)
ImplementGroup1(xImpl_G1Compare, G1Type_CMP) ImplementGroup1(xImpl_G1Compare, G1Type_CMP)
const xImpl_G1Logic xAND = {G1Type_AND, {0x00, 0x54}, {0x66, 0x54}}; const xImpl_G1Logic xAND = {G1Type_AND, {0x00, 0x54}, {0x66, 0x54}};
const xImpl_G1Logic xOR = {G1Type_OR, {0x00, 0x56}, {0x66, 0x56}}; const xImpl_G1Logic xOR = {G1Type_OR, {0x00, 0x56}, {0x66, 0x56}};
const xImpl_G1Logic xXOR = {G1Type_XOR, {0x00, 0x57}, {0x66, 0x57}}; const xImpl_G1Logic xXOR = {G1Type_XOR, {0x00, 0x57}, {0x66, 0x57}};
const xImpl_G1Arith xADD = {G1Type_ADD, {0x00, 0x58}, {0x66, 0x58}, {0xf3, 0x58}, {0xf2, 0x58}}; const xImpl_G1Arith xADD = {G1Type_ADD, {0x00, 0x58}, {0x66, 0x58}, {0xf3, 0x58}, {0xf2, 0x58}};
const xImpl_G1Arith xSUB = {G1Type_SUB, {0x00, 0x5c}, {0x66, 0x5c}, {0xf3, 0x5c}, {0xf2, 0x5c}}; const xImpl_G1Arith xSUB = {G1Type_SUB, {0x00, 0x5c}, {0x66, 0x5c}, {0xf3, 0x5c}, {0xf2, 0x5c}};
const xImpl_G1Compare xCMP = {{0x00, 0xc2}, {0x66, 0xc2}, {0xf3, 0xc2}, {0xf2, 0xc2}}; const xImpl_G1Compare xCMP = {{0x00, 0xc2}, {0x66, 0xc2}, {0xf3, 0xc2}, {0xf2, 0xc2}};
const xImpl_Group1 xADC = {G1Type_ADC}; const xImpl_Group1 xADC = {G1Type_ADC};
const xImpl_Group1 xSBB = {G1Type_SBB}; const xImpl_Group1 xSBB = {G1Type_SBB};
// ===================================================================================================== // =====================================================================================================
// Group 2 Instructions - SHR, SHL, etc. // Group 2 Instructions - SHR, SHL, etc.
// ===================================================================================================== // =====================================================================================================
void xImpl_Group2::operator()(const xRegisterInt &to, const xRegisterCL & /* from */) const void xImpl_Group2::operator()(const xRegisterInt& to, const xRegisterCL& /* from */) const
{ {
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd2 : 0xd3, InstType, to); xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd2 : 0xd3, InstType, to);
} }
void xImpl_Group2::operator()(const xRegisterInt &to, u8 imm) const void xImpl_Group2::operator()(const xRegisterInt& to, u8 imm) const
{ {
if (imm == 0) if (imm == 0)
return; return;
if (imm == 1) { if (imm == 1)
{
// special encoding of 1's // special encoding of 1's
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd0 : 0xd1, InstType, to); xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xd0 : 0xd1, InstType, to);
} else { }
else
{
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xc0 : 0xc1, InstType, to); xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xc0 : 0xc1, InstType, to);
xWrite8(imm); xWrite8(imm);
} }
} }
void xImpl_Group2::operator()(const xIndirect64orLess &sibdest, const xRegisterCL & /* from */) const void xImpl_Group2::operator()(const xIndirect64orLess& sibdest, const xRegisterCL& /* from */) const
{ {
xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd2 : 0xd3, InstType, sibdest); xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd2 : 0xd3, InstType, sibdest);
} }
void xImpl_Group2::operator()(const xIndirect64orLess &sibdest, u8 imm) const void xImpl_Group2::operator()(const xIndirect64orLess& sibdest, u8 imm) const
{ {
if (imm == 0) if (imm == 0)
return; return;
if (imm == 1) { if (imm == 1)
{
// special encoding of 1's // special encoding of 1's
xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd0 : 0xd1, InstType, sibdest); xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xd0 : 0xd1, InstType, sibdest);
} else { }
else
{
xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xc0 : 0xc1, InstType, sibdest, 1); xOpWrite(sibdest.GetPrefix16(), sibdest.Is8BitOp() ? 0xc0 : 0xc1, InstType, sibdest, 1);
xWrite8(imm); xWrite8(imm);
} }
} }
const xImpl_Group2 xROL = {G2Type_ROL}; const xImpl_Group2 xROL = {G2Type_ROL};
const xImpl_Group2 xROR = {G2Type_ROR}; const xImpl_Group2 xROR = {G2Type_ROR};
const xImpl_Group2 xRCL = {G2Type_RCL}; const xImpl_Group2 xRCL = {G2Type_RCL};
const xImpl_Group2 xRCR = {G2Type_RCR}; const xImpl_Group2 xRCR = {G2Type_RCR};
const xImpl_Group2 xSHL = {G2Type_SHL}; const xImpl_Group2 xSHL = {G2Type_SHL};
const xImpl_Group2 xSHR = {G2Type_SHR}; const xImpl_Group2 xSHR = {G2Type_SHR};
const xImpl_Group2 xSAR = {G2Type_SAR}; const xImpl_Group2 xSAR = {G2Type_SAR};
// ===================================================================================================== // =====================================================================================================
// Group 3 Instructions - NOT, NEG, MUL, DIV // Group 3 Instructions - NOT, NEG, MUL, DIV
// ===================================================================================================== // =====================================================================================================
static void _g3_EmitOp(G3Type InstType, const xRegisterInt &from) static void _g3_EmitOp(G3Type InstType, const xRegisterInt& from)
{ {
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from);
} }
static void _g3_EmitOp(G3Type InstType, const xIndirect64orLess &from) static void _g3_EmitOp(G3Type InstType, const xIndirect64orLess& from)
{ {
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from);
} }
void xImpl_Group3::operator()(const xRegisterInt &from) const { _g3_EmitOp(InstType, from); } void xImpl_Group3::operator()(const xRegisterInt& from) const { _g3_EmitOp(InstType, from); }
void xImpl_Group3::operator()(const xIndirect64orLess &from) const { _g3_EmitOp(InstType, from); } void xImpl_Group3::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(InstType, from); }
void xImpl_iDiv::operator()(const xRegisterInt &from) const { _g3_EmitOp(G3Type_iDIV, from); } void xImpl_iDiv::operator()(const xRegisterInt& from) const { _g3_EmitOp(G3Type_iDIV, from); }
void xImpl_iDiv::operator()(const xIndirect64orLess &from) const { _g3_EmitOp(G3Type_iDIV, from); } void xImpl_iDiv::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(G3Type_iDIV, from); }
template <typename SrcType> template <typename SrcType>
static void _imul_ImmStyle(const xRegisterInt &param1, const SrcType &param2, int imm) static void _imul_ImmStyle(const xRegisterInt& param1, const SrcType& param2, int imm)
{ {
pxAssert(param1.GetOperandSize() == param2.GetOperandSize()); pxAssert(param1.GetOperandSize() == param2.GetOperandSize());
xOpWrite0F(param1.GetPrefix16(), is_s8(imm) ? 0x6b : 0x69, param1, param2, is_s8(imm) ? 1 : param1.GetImmSize()); xOpWrite0F(param1.GetPrefix16(), is_s8(imm) ? 0x6b : 0x69, param1, param2, is_s8(imm) ? 1 : param1.GetImmSize());
@ -200,56 +215,56 @@ static void _imul_ImmStyle(const xRegisterInt &param1, const SrcType &param2, in
xWrite8((u8)imm); xWrite8((u8)imm);
else else
param1.xWriteImm(imm); param1.xWriteImm(imm);
} }
void xImpl_iMul::operator()(const xRegisterInt &from) const { _g3_EmitOp(G3Type_iMUL, from); } void xImpl_iMul::operator()(const xRegisterInt& from) const { _g3_EmitOp(G3Type_iMUL, from); }
void xImpl_iMul::operator()(const xIndirect64orLess &from) const { _g3_EmitOp(G3Type_iMUL, from); } void xImpl_iMul::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(G3Type_iMUL, from); }
void xImpl_iMul::operator()(const xRegister32 &to, const xRegister32 &from) const { xOpWrite0F(0xaf, to, from); } void xImpl_iMul::operator()(const xRegister32& to, const xRegister32& from) const { xOpWrite0F(0xaf, to, from); }
void xImpl_iMul::operator()(const xRegister32 &to, const xIndirectVoid &src) const { xOpWrite0F(0xaf, to, src); } void xImpl_iMul::operator()(const xRegister32& to, const xIndirectVoid& src) const { xOpWrite0F(0xaf, to, src); }
void xImpl_iMul::operator()(const xRegister16 &to, const xRegister16 &from) const { xOpWrite0F(0x66, 0xaf, to, from); } void xImpl_iMul::operator()(const xRegister16& to, const xRegister16& from) const { xOpWrite0F(0x66, 0xaf, to, from); }
void xImpl_iMul::operator()(const xRegister16 &to, const xIndirectVoid &src) const { xOpWrite0F(0x66, 0xaf, to, src); } void xImpl_iMul::operator()(const xRegister16& to, const xIndirectVoid& src) const { xOpWrite0F(0x66, 0xaf, to, src); }
void xImpl_iMul::operator()(const xRegister32 &to, const xRegister32 &from, s32 imm) const { _imul_ImmStyle(to, from, imm); } void xImpl_iMul::operator()(const xRegister32& to, const xRegister32& from, s32 imm) const { _imul_ImmStyle(to, from, imm); }
void xImpl_iMul::operator()(const xRegister32 &to, const xIndirectVoid &from, s32 imm) const { _imul_ImmStyle(to, from, imm); } void xImpl_iMul::operator()(const xRegister32& to, const xIndirectVoid& from, s32 imm) const { _imul_ImmStyle(to, from, imm); }
void xImpl_iMul::operator()(const xRegister16 &to, const xRegister16 &from, s16 imm) const { _imul_ImmStyle(to, from, imm); } void xImpl_iMul::operator()(const xRegister16& to, const xRegister16& from, s16 imm) const { _imul_ImmStyle(to, from, imm); }
void xImpl_iMul::operator()(const xRegister16 &to, const xIndirectVoid &from, s16 imm) const { _imul_ImmStyle(to, from, imm); } void xImpl_iMul::operator()(const xRegister16& to, const xIndirectVoid& from, s16 imm) const { _imul_ImmStyle(to, from, imm); }
const xImpl_Group3 xNOT = {G3Type_NOT}; const xImpl_Group3 xNOT = {G3Type_NOT};
const xImpl_Group3 xNEG = {G3Type_NEG}; const xImpl_Group3 xNEG = {G3Type_NEG};
const xImpl_Group3 xUMUL = {G3Type_MUL}; const xImpl_Group3 xUMUL = {G3Type_MUL};
const xImpl_Group3 xUDIV = {G3Type_DIV}; const xImpl_Group3 xUDIV = {G3Type_DIV};
const xImpl_iDiv xDIV = {{0x00, 0x5e}, {0x66, 0x5e}, {0xf3, 0x5e}, {0xf2, 0x5e}}; const xImpl_iDiv xDIV = {{0x00, 0x5e}, {0x66, 0x5e}, {0xf3, 0x5e}, {0xf2, 0x5e}};
const xImpl_iMul xMUL = {{0x00, 0x59}, {0x66, 0x59}, {0xf3, 0x59}, {0xf2, 0x59}}; const xImpl_iMul xMUL = {{0x00, 0x59}, {0x66, 0x59}, {0xf3, 0x59}, {0xf2, 0x59}};
// ===================================================================================================== // =====================================================================================================
// Group 8 Instructions // Group 8 Instructions
// ===================================================================================================== // =====================================================================================================
void xImpl_Group8::operator()(const xRegister16or32or64 &bitbase, const xRegister16or32or64 &bitoffset) const void xImpl_Group8::operator()(const xRegister16or32or64& bitbase, const xRegister16or32or64& bitoffset) const
{ {
pxAssert(bitbase->GetOperandSize() == bitoffset->GetOperandSize()); pxAssert(bitbase->GetOperandSize() == bitoffset->GetOperandSize());
xOpWrite0F(bitbase->GetPrefix16(), 0xa3 | (InstType << 3), bitbase, bitoffset); xOpWrite0F(bitbase->GetPrefix16(), 0xa3 | (InstType << 3), bitbase, bitoffset);
} }
void xImpl_Group8::operator()(const xIndirect64 &bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); } void xImpl_Group8::operator()(const xIndirect64& bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); }
void xImpl_Group8::operator()(const xIndirect32 &bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); } void xImpl_Group8::operator()(const xIndirect32& bitbase, u8 bitoffset) const { xOpWrite0F(0xba, InstType, bitbase, bitoffset); }
void xImpl_Group8::operator()(const xIndirect16 &bitbase, u8 bitoffset) const { xOpWrite0F(0x66, 0xba, InstType, bitbase, bitoffset); } void xImpl_Group8::operator()(const xIndirect16& bitbase, u8 bitoffset) const { xOpWrite0F(0x66, 0xba, InstType, bitbase, bitoffset); }
void xImpl_Group8::operator()(const xRegister16or32or64 &bitbase, u8 bitoffset) const void xImpl_Group8::operator()(const xRegister16or32or64& bitbase, u8 bitoffset) const
{ {
xOpWrite0F(bitbase->GetPrefix16(), 0xba, InstType, bitbase, bitoffset); xOpWrite0F(bitbase->GetPrefix16(), 0xba, InstType, bitbase, bitoffset);
} }
void xImpl_Group8::operator()(const xIndirectVoid &bitbase, const xRegister16or32or64 &bitoffset) const void xImpl_Group8::operator()(const xIndirectVoid& bitbase, const xRegister16or32or64& bitoffset) const
{ {
xOpWrite0F(bitoffset->GetPrefix16(), 0xa3 | (InstType << 3), bitoffset, bitbase); xOpWrite0F(bitoffset->GetPrefix16(), 0xa3 | (InstType << 3), bitoffset, bitbase);
} }
const xImpl_Group8 xBT = {G8Type_BT}; const xImpl_Group8 xBT = {G8Type_BT};
const xImpl_Group8 xBTR = {G8Type_BTR}; const xImpl_Group8 xBTR = {G8Type_BTR};
const xImpl_Group8 xBTS = {G8Type_BTS}; const xImpl_Group8 xBTS = {G8Type_BTS};
const xImpl_Group8 xBTC = {G8Type_BTC}; const xImpl_Group8 xBTC = {G8Type_BTC};

View File

@ -20,8 +20,8 @@
namespace x86Emitter namespace x86Emitter
{ {
struct xImplBMI_RVM struct xImplBMI_RVM
{ {
u8 Prefix; u8 Prefix;
u8 MbPrefix; u8 MbPrefix;
u8 Opcode; u8 Opcode;
@ -31,8 +31,8 @@ struct xImplBMI_RVM
// PDEP Parallel bits deposit // PDEP Parallel bits deposit
// PEXT Parallel bits extract // PEXT Parallel bits extract
// ANDN Logical and not ~x & y // ANDN Logical and not ~x & y
void operator()(const xRegisterInt &to, const xRegisterInt &from1, const xRegisterInt &from2) const; void operator()(const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const;
void operator()(const xRegisterInt &to, const xRegisterInt &from1, const xIndirectVoid &from2) const; void operator()(const xRegisterInt& to, const xRegisterInt& from1, const xIndirectVoid& from2) const;
#if 0 #if 0
// RMV // RMV
@ -57,5 +57,5 @@ struct xImplBMI_RVM
void operator()( const xRegisterInt& to, const xRegisterInt& from, u8 imm) const; void operator()( const xRegisterInt& to, const xRegisterInt& from, u8 imm) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from, u8 imm) const; void operator()( const xRegisterInt& to, const xIndirectVoid& from, u8 imm) const;
#endif #endif
}; };
} } // namespace x86Emitter

View File

@ -18,27 +18,27 @@
namespace x86Emitter namespace x86Emitter
{ {
// Implementations here cover SHLD and SHRD. // Implementations here cover SHLD and SHRD.
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_DowrdShift // xImpl_DowrdShift
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// I use explicit method declarations here instead of templates, in order to provide // I use explicit method declarations here instead of templates, in order to provide
// *only* 32 and 16 bit register operand forms (8 bit registers are not valid in SHLD/SHRD). // *only* 32 and 16 bit register operand forms (8 bit registers are not valid in SHLD/SHRD).
// //
// Optimization Note: Imm shifts by 0 are ignore (no code generated). This is a safe optimization // Optimization Note: Imm shifts by 0 are ignore (no code generated). This is a safe optimization
// because shifts by 0 do *not* affect flags status (intel docs cited). // because shifts by 0 do *not* affect flags status (intel docs cited).
// //
struct xImpl_DwordShift struct xImpl_DwordShift
{ {
u16 OpcodeBase; u16 OpcodeBase;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, const xRegisterCL &clreg) const; void operator()(const xRegister16or32or64& to, const xRegister16or32or64& from, const xRegisterCL& clreg) const;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, u8 shiftcnt) const; void operator()(const xRegister16or32or64& to, const xRegister16or32or64& from, u8 shiftcnt) const;
void operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, const xRegisterCL &clreg) const; void operator()(const xIndirectVoid& dest, const xRegister16or32or64& from, const xRegisterCL& clreg) const;
void operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, u8 shiftcnt) const; void operator()(const xIndirectVoid& dest, const xRegister16or32or64& from, u8 shiftcnt) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,7 +18,8 @@
namespace x86Emitter namespace x86Emitter
{ {
enum G1Type { enum G1Type
{
G1Type_ADD = 0, G1Type_ADD = 0,
G1Type_OR, G1Type_OR,
G1Type_ADC, G1Type_ADC,
@ -27,23 +28,23 @@ enum G1Type {
G1Type_SUB, G1Type_SUB,
G1Type_XOR, G1Type_XOR,
G1Type_CMP G1Type_CMP
}; };
extern void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, const xRegisterInt &from); extern void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xRegisterInt& from);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_Group1 // xImpl_Group1
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_Group1 struct xImpl_Group1
{ {
G1Type InstType; G1Type InstType;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const; void operator()(const xRegisterInt& to, const xRegisterInt& from) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const; void operator()(const xIndirectVoid& to, const xRegisterInt& from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const; void operator()(const xRegisterInt& to, const xIndirectVoid& from) const;
void operator()(const xRegisterInt &to, int imm) const; void operator()(const xRegisterInt& to, int imm) const;
void operator()(const xIndirect64orLess &to, int imm) const; void operator()(const xIndirect64orLess& to, int imm) const;
#if 0 #if 0
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -79,64 +80,64 @@ struct xImpl_Group1
_DoI_helpermess( *this, to, xDirectOrIndirect<T>( from ) ); _DoI_helpermess( *this, to, xDirectOrIndirect<T>( from ) );
} }
#endif #endif
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// This class combines x86 with SSE/SSE2 logic operations (ADD, OR, and NOT). // This class combines x86 with SSE/SSE2 logic operations (ADD, OR, and NOT).
// Note: ANDN [AndNot] is handled below separately. // Note: ANDN [AndNot] is handled below separately.
// //
struct xImpl_G1Logic struct xImpl_G1Logic
{ {
G1Type InstType; G1Type InstType;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const; void operator()(const xRegisterInt& to, const xRegisterInt& from) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const; void operator()(const xIndirectVoid& to, const xRegisterInt& from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const; void operator()(const xRegisterInt& to, const xIndirectVoid& from) const;
void operator()(const xRegisterInt &to, int imm) const; void operator()(const xRegisterInt& to, int imm) const;
void operator()(const xIndirect64orLess &to, int imm) const; void operator()(const xIndirect64orLess& to, int imm) const;
xImplSimd_DestRegSSE PS; // packed single precision xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision xImplSimd_DestRegSSE PD; // packed double precision
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// This class combines x86 with SSE/SSE2 arithmetic operations (ADD/SUB). // This class combines x86 with SSE/SSE2 arithmetic operations (ADD/SUB).
// //
struct xImpl_G1Arith struct xImpl_G1Arith
{ {
G1Type InstType; G1Type InstType;
void operator()(const xRegisterInt &to, const xRegisterInt &from) const; void operator()(const xRegisterInt& to, const xRegisterInt& from) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const; void operator()(const xIndirectVoid& to, const xRegisterInt& from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const; void operator()(const xRegisterInt& to, const xIndirectVoid& from) const;
void operator()(const xRegisterInt &to, int imm) const; void operator()(const xRegisterInt& to, int imm) const;
void operator()(const xIndirect64orLess &to, int imm) const; void operator()(const xIndirect64orLess& to, int imm) const;
xImplSimd_DestRegSSE PS; // packed single precision xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision xImplSimd_DestRegSSE PD; // packed double precision
xImplSimd_DestRegSSE SS; // scalar single precision xImplSimd_DestRegSSE SS; // scalar single precision
xImplSimd_DestRegSSE SD; // scalar double precision xImplSimd_DestRegSSE SD; // scalar double precision
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct xImpl_G1Compare struct xImpl_G1Compare
{ {
void operator()(const xRegisterInt &to, const xRegisterInt &from) const; void operator()(const xRegisterInt& to, const xRegisterInt& from) const;
void operator()(const xIndirectVoid &to, const xRegisterInt &from) const; void operator()(const xIndirectVoid& to, const xRegisterInt& from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &from) const; void operator()(const xRegisterInt& to, const xIndirectVoid& from) const;
void operator()(const xRegisterInt &to, int imm) const; void operator()(const xRegisterInt& to, int imm) const;
void operator()(const xIndirect64orLess &to, int imm) const; void operator()(const xIndirect64orLess& to, int imm) const;
xImplSimd_DestSSE_CmpImm PS; xImplSimd_DestSSE_CmpImm PS;
xImplSimd_DestSSE_CmpImm PD; xImplSimd_DestSSE_CmpImm PD;
xImplSimd_DestSSE_CmpImm SS; xImplSimd_DestSSE_CmpImm SS;
xImplSimd_DestSSE_CmpImm SD; xImplSimd_DestSSE_CmpImm SD;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,7 +18,8 @@
namespace x86Emitter namespace x86Emitter
{ {
enum G2Type { enum G2Type
{
G2Type_ROL = 0, G2Type_ROL = 0,
G2Type_ROR, G2Type_ROR,
G2Type_RCL, G2Type_RCL,
@ -27,23 +28,23 @@ enum G2Type {
G2Type_SHR, G2Type_SHR,
G2Type_Unused, G2Type_Unused,
G2Type_SAR G2Type_SAR
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_Group2 // xImpl_Group2
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Group 2 (shift) instructions have no Sib/ModRM forms. // Group 2 (shift) instructions have no Sib/ModRM forms.
// Optimization Note: For Imm forms, we ignore the instruction if the shift count is zero. // Optimization Note: For Imm forms, we ignore the instruction if the shift count is zero.
// This is a safe optimization since any zero-value shift does not affect any flags. // This is a safe optimization since any zero-value shift does not affect any flags.
// //
struct xImpl_Group2 struct xImpl_Group2
{ {
G2Type InstType; G2Type InstType;
void operator()(const xRegisterInt &to, const xRegisterCL &from) const; void operator()(const xRegisterInt& to, const xRegisterCL& from) const;
void operator()(const xIndirect64orLess &to, const xRegisterCL &from) const; void operator()(const xIndirect64orLess& to, const xRegisterCL& from) const;
void operator()(const xRegisterInt &to, u8 imm) const; void operator()(const xRegisterInt& to, u8 imm) const;
void operator()(const xIndirect64orLess &to, u8 imm) const; void operator()(const xIndirect64orLess& to, u8 imm) const;
#if 0 #if 0
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -57,6 +58,6 @@ struct xImpl_Group2
_DoI_helpermess( *this, to, from ); _DoI_helpermess( *this, to, from );
} }
#endif #endif
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,24 +18,25 @@
namespace x86Emitter namespace x86Emitter
{ {
enum G3Type { enum G3Type
{
G3Type_NOT = 2, G3Type_NOT = 2,
G3Type_NEG = 3, G3Type_NEG = 3,
G3Type_MUL = 4, G3Type_MUL = 4,
G3Type_iMUL = 5, // partial implementation, iMul has additional forms in ix86.cpp G3Type_iMUL = 5, // partial implementation, iMul has additional forms in ix86.cpp
G3Type_DIV = 6, G3Type_DIV = 6,
G3Type_iDIV = 7 G3Type_iDIV = 7
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_Group3 // xImpl_Group3
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_Group3 struct xImpl_Group3
{ {
G3Type InstType; G3Type InstType;
void operator()(const xRegisterInt &from) const; void operator()(const xRegisterInt& from) const;
void operator()(const xIndirect64orLess &from) const; void operator()(const xIndirect64orLess& from) const;
#if 0 #if 0
template< typename T > template< typename T >
@ -44,65 +45,65 @@ struct xImpl_Group3
_DoI_helpermess( *this, from ); _DoI_helpermess( *this, from );
} }
#endif #endif
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_MulDivBase // xImpl_MulDivBase
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This class combines x86 and SSE/SSE2 instructions for iMUL and iDIV. // This class combines x86 and SSE/SSE2 instructions for iMUL and iDIV.
// //
struct xImpl_MulDivBase struct xImpl_MulDivBase
{ {
G3Type InstType; G3Type InstType;
u16 OpcodeSSE; u16 OpcodeSSE;
void operator()(const xRegisterInt &from) const; void operator()(const xRegisterInt& from) const;
void operator()(const xIndirect64orLess &from) const; void operator()(const xIndirect64orLess& from) const;
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_iDiv // xImpl_iDiv
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_iDiv struct xImpl_iDiv
{ {
void operator()(const xRegisterInt &from) const; void operator()(const xRegisterInt& from) const;
void operator()(const xIndirect64orLess &from) const; void operator()(const xIndirect64orLess& from) const;
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_iMul // xImpl_iMul
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// //
struct xImpl_iMul struct xImpl_iMul
{ {
void operator()(const xRegisterInt &from) const; void operator()(const xRegisterInt& from) const;
void operator()(const xIndirect64orLess &from) const; void operator()(const xIndirect64orLess& from) const;
// The following iMul-specific forms are valid for 16 and 32 bit register operands only! // The following iMul-specific forms are valid for 16 and 32 bit register operands only!
void operator()(const xRegister32 &to, const xRegister32 &from) const; void operator()(const xRegister32& to, const xRegister32& from) const;
void operator()(const xRegister32 &to, const xIndirectVoid &src) const; void operator()(const xRegister32& to, const xIndirectVoid& src) const;
void operator()(const xRegister16 &to, const xRegister16 &from) const; void operator()(const xRegister16& to, const xRegister16& from) const;
void operator()(const xRegister16 &to, const xIndirectVoid &src) const; void operator()(const xRegister16& to, const xIndirectVoid& src) const;
void operator()(const xRegister32 &to, const xRegister32 &from, s32 imm) const; void operator()(const xRegister32& to, const xRegister32& from, s32 imm) const;
void operator()(const xRegister32 &to, const xIndirectVoid &from, s32 imm) const; void operator()(const xRegister32& to, const xIndirectVoid& from, s32 imm) const;
void operator()(const xRegister16 &to, const xRegister16 &from, s16 imm) const; void operator()(const xRegister16& to, const xRegister16& from, s16 imm) const;
void operator()(const xRegister16 &to, const xIndirectVoid &from, s16 imm) const; void operator()(const xRegister16& to, const xIndirectVoid& from, s16 imm) const;
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
} } // namespace x86Emitter

View File

@ -21,15 +21,15 @@
namespace x86Emitter namespace x86Emitter
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_IncDec // xImpl_IncDec
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_IncDec struct xImpl_IncDec
{ {
bool isDec; bool isDec;
void operator()(const xRegisterInt &to) const; void operator()(const xRegisterInt& to) const;
void operator()(const xIndirect64orLess &to) const; void operator()(const xIndirect64orLess& to) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -20,23 +20,24 @@
namespace x86Emitter namespace x86Emitter
{ {
extern void xJccKnownTarget(JccComparisonType comparison, const void *target, bool slideForward); extern void xJccKnownTarget(JccComparisonType comparison, const void* target, bool slideForward);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct xImpl_JmpCall struct xImpl_JmpCall
{ {
bool isJmp; bool isJmp;
void operator()(const xAddressReg &absreg) const; void operator()(const xAddressReg& absreg) const;
void operator()(const xIndirectNative &src) const; void operator()(const xIndirectNative& src) const;
// Special form for calling functions. This form automatically resolves the // Special form for calling functions. This form automatically resolves the
// correct displacement based on the size of the instruction being generated. // correct displacement based on the size of the instruction being generated.
void operator()(void *func) const void operator()(void* func) const
{ {
if (isJmp) if (isJmp)
xJccKnownTarget(Jcc_Unconditional, (void *)(uptr)func, false); // double cast to/from (uptr) needed to appease GCC xJccKnownTarget(Jcc_Unconditional, (void*)(uptr)func, false); // double cast to/from (uptr) needed to appease GCC
else { else
{
// calls are relative to the instruction after this one, and length is // calls are relative to the instruction after this one, and length is
// always 5 bytes (16 bit calls are bad mojo, so no bother to do special logic). // always 5 bytes (16 bit calls are bad mojo, so no bother to do special logic).
@ -46,48 +47,48 @@ struct xImpl_JmpCall
xWrite32(dest); xWrite32(dest);
} }
} }
}; };
// yes it is awful. Due to template code is in a header with a nice circular dep. // yes it is awful. Due to template code is in a header with a nice circular dep.
extern const xImpl_Mov xMOV; extern const xImpl_Mov xMOV;
extern const xImpl_JmpCall xCALL; extern const xImpl_JmpCall xCALL;
struct xImpl_FastCall struct xImpl_FastCall
{ {
// FIXME: current 64 bits is mostly a copy/past potentially it would require to push/pop // FIXME: current 64 bits is mostly a copy/past potentially it would require to push/pop
// some registers. But I think it is enough to handle the first call. // some registers. But I think it is enough to handle the first call.
void operator()(void *f, const xRegister32 &a1 = xEmptyReg, const xRegister32 &a2 = xEmptyReg) const; void operator()(void* f, const xRegister32& a1 = xEmptyReg, const xRegister32& a2 = xEmptyReg) const;
void operator()(void *f, u32 a1, const xRegister32 &a2) const; void operator()(void* f, u32 a1, const xRegister32& a2) const;
void operator()(void *f, const xIndirect32 &a1) const; void operator()(void* f, const xIndirect32& a1) const;
void operator()(void *f, u32 a1, u32 a2) const; void operator()(void* f, u32 a1, u32 a2) const;
void operator()(void *f, void *a1) const; void operator()(void* f, void* a1) const;
#ifdef __M_X86_64 #ifdef __M_X86_64
void operator()(void *f, const xRegisterLong &a1, const xRegisterLong &a2 = xEmptyReg) const; void operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2 = xEmptyReg) const;
void operator()(void *f, u32 a1, const xRegisterLong &a2) const; void operator()(void* f, u32 a1, const xRegisterLong& a2) const;
#endif #endif
template <typename T> template <typename T>
__fi void operator()(T *func, u32 a1, const xRegisterLong &a2 = xEmptyReg) const __fi void operator()(T* func, u32 a1, const xRegisterLong& a2 = xEmptyReg) const
{ {
(*this)((void *)func, a1, a2); (*this)((void*)func, a1, a2);
} }
template <typename T> template <typename T>
__fi void operator()(T *func, const xIndirect32 &a1) const __fi void operator()(T* func, const xIndirect32& a1) const
{ {
(*this)((void*)func, a1); (*this)((void*)func, a1);
} }
template <typename T> template <typename T>
__fi void operator()(T *func, u32 a1, u32 a2) const __fi void operator()(T* func, u32 a1, u32 a2) const
{ {
(*this)((void*)func, a1, a2); (*this)((void*)func, a1, a2);
} }
void operator()(const xIndirectNative &f, const xRegisterLong &a1 = xEmptyReg, const xRegisterLong &a2 = xEmptyReg) const; void operator()(const xIndirectNative& f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -21,20 +21,20 @@
namespace x86Emitter namespace x86Emitter
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// MovImplAll // MovImplAll
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// MOV instruction Implementation, plus many SIMD sub-mov variants. // MOV instruction Implementation, plus many SIMD sub-mov variants.
// //
struct xImpl_Mov struct xImpl_Mov
{ {
xImpl_Mov() {} // Satisfy GCC's whims. xImpl_Mov() {} // Satisfy GCC's whims.
void operator()(const xRegisterInt &to, const xRegisterInt &from) const; void operator()(const xRegisterInt& to, const xRegisterInt& from) const;
void operator()(const xIndirectVoid &dest, const xRegisterInt &from) const; void operator()(const xIndirectVoid& dest, const xRegisterInt& from) const;
void operator()(const xRegisterInt &to, const xIndirectVoid &src) const; void operator()(const xRegisterInt& to, const xIndirectVoid& src) const;
void operator()(const xIndirect64orLess &dest, sptr imm) const; void operator()(const xIndirect64orLess& dest, sptr imm) const;
void operator()(const xRegisterInt &to, sptr imm, bool preserve_flags = false) const; void operator()(const xRegisterInt& to, sptr imm, bool preserve_flags = false) const;
#if 0 #if 0
template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg<T>& immOrReg ) const template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg<T>& immOrReg ) const
@ -68,73 +68,73 @@ struct xImpl_Mov
_DoI_helpermess( *this, to, xDirectOrIndirect<T>( from ) ); _DoI_helpermess( *this, to, xDirectOrIndirect<T>( from ) );
}*/ }*/
#endif #endif
}; };
#ifdef __M_X86_64 #ifdef __M_X86_64
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_MovImm64 // xImpl_MovImm64
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Mov with 64-bit immediates (only available on 64-bit platforms) // Mov with 64-bit immediates (only available on 64-bit platforms)
// //
struct xImpl_MovImm64 struct xImpl_MovImm64
{ {
xImpl_MovImm64() {} // Satisfy GCC's whims. xImpl_MovImm64() {} // Satisfy GCC's whims.
void operator()(const xRegister64 &to, s64 imm, bool preserve_flags = false) const; void operator()(const xRegister64& to, s64 imm, bool preserve_flags = false) const;
}; };
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_CMov // xImpl_CMov
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// CMOVcc !! [in all of it's disappointing lack-of glory] .. and .. // CMOVcc !! [in all of it's disappointing lack-of glory] .. and ..
// SETcc !! [more glory, less lack!] // SETcc !! [more glory, less lack!]
// //
// CMOV Disclaimer: Caution! This instruction can look exciting and cool, until you // CMOV Disclaimer: Caution! This instruction can look exciting and cool, until you
// realize that it cannot load immediate values into registers. -_- // realize that it cannot load immediate values into registers. -_-
// //
// I use explicit method declarations here instead of templates, in order to provide // I use explicit method declarations here instead of templates, in order to provide
// *only* 32 and 16 bit register operand forms (8 bit registers are not valid in CMOV). // *only* 32 and 16 bit register operand forms (8 bit registers are not valid in CMOV).
// //
struct xImpl_CMov struct xImpl_CMov
{ {
JccComparisonType ccType; JccComparisonType ccType;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const; void operator()(const xRegister16or32or64& to, const xRegister16or32or64& from) const;
void operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const; void operator()(const xRegister16or32or64& to, const xIndirectVoid& sibsrc) const;
//void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ); //void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from );
//void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const; //void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const;
}; };
struct xImpl_Set struct xImpl_Set
{ {
JccComparisonType ccType; JccComparisonType ccType;
void operator()(const xRegister8 &to) const; void operator()(const xRegister8& to) const;
void operator()(const xIndirect8 &dest) const; void operator()(const xIndirect8& dest) const;
//void operator()( const xDirectOrIndirect8& dest ) const; //void operator()( const xDirectOrIndirect8& dest ) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_MovExtend // xImpl_MovExtend
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Mov with sign/zero extension implementations (movsx / movzx) // Mov with sign/zero extension implementations (movsx / movzx)
// //
struct xImpl_MovExtend struct xImpl_MovExtend
{ {
bool SignExtend; bool SignExtend;
void operator()(const xRegister16or32or64 &to, const xRegister8 &from) const; void operator()(const xRegister16or32or64& to, const xRegister8& from) const;
void operator()(const xRegister16or32or64 &to, const xIndirect8 &sibsrc) const; void operator()(const xRegister16or32or64& to, const xIndirect8& sibsrc) const;
void operator()(const xRegister32or64 &to, const xRegister16 &from) const; void operator()(const xRegister32or64& to, const xRegister16& from) const;
void operator()(const xRegister32or64 &to, const xIndirect16 &sibsrc) const; void operator()(const xRegister32or64& to, const xIndirect16& sibsrc) const;
//void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const; //void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const;
//void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const; //void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const;
//void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const; //void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,49 +18,49 @@
namespace x86Emitter namespace x86Emitter
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// _SimdShiftHelper // _SimdShiftHelper
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct _SimdShiftHelper struct _SimdShiftHelper
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
u16 OpcodeImm; u16 OpcodeImm;
u8 Modcode; u8 Modcode;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const; void operator()(const xRegisterSSE& to, const xRegisterSSE& from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from) const;
void operator()(const xRegisterSSE &to, u8 imm8) const; void operator()(const xRegisterSSE& to, u8 imm8) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_Shift / xImplSimd_ShiftWithoutQ // xImplSimd_Shift / xImplSimd_ShiftWithoutQ
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Used for PSRA, which lacks the Q form. // Used for PSRA, which lacks the Q form.
// //
struct xImplSimd_ShiftWithoutQ struct xImplSimd_ShiftWithoutQ
{ {
const _SimdShiftHelper W; const _SimdShiftHelper W;
const _SimdShiftHelper D; const _SimdShiftHelper D;
}; };
// Implements PSRL and PSLL // Implements PSRL and PSLL
// //
struct xImplSimd_Shift struct xImplSimd_Shift
{ {
const _SimdShiftHelper W; const _SimdShiftHelper W;
const _SimdShiftHelper D; const _SimdShiftHelper D;
const _SimdShiftHelper Q; const _SimdShiftHelper Q;
void DQ(const xRegisterSSE &to, u8 imm8) const; void DQ(const xRegisterSSE& to, u8 imm8) const;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_AddSub struct xImplSimd_AddSub
{ {
const xImplSimd_DestRegEither B; const xImplSimd_DestRegEither B;
const xImplSimd_DestRegEither W; const xImplSimd_DestRegEither W;
const xImplSimd_DestRegEither D; const xImplSimd_DestRegEither D;
@ -77,12 +77,12 @@ struct xImplSimd_AddSub
// Add/Sub packed unsigned word [16bit] integers from src into dest, and saturate the results. // Add/Sub packed unsigned word [16bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither USW; const xImplSimd_DestRegEither USW;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_PMul struct xImplSimd_PMul
{ {
const xImplSimd_DestRegEither LW; const xImplSimd_DestRegEither LW;
const xImplSimd_DestRegEither HW; const xImplSimd_DestRegEither HW;
const xImplSimd_DestRegEither HUW; const xImplSimd_DestRegEither HUW;
@ -106,40 +106,40 @@ struct xImplSimd_PMul
// [SSE-4.1] Multiply the packed signed dword integers in dest with src. // [SSE-4.1] Multiply the packed signed dword integers in dest with src.
const xImplSimd_DestRegSSE DQ; const xImplSimd_DestRegSSE DQ;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// For instructions that have PS/SS form only (most commonly reciprocal Sqrt functions) // For instructions that have PS/SS form only (most commonly reciprocal Sqrt functions)
// //
struct xImplSimd_rSqrt struct xImplSimd_rSqrt
{ {
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// SQRT has PS/SS/SD forms, but not the PD form. // SQRT has PS/SS/SD forms, but not the PD form.
// //
struct xImplSimd_Sqrt struct xImplSimd_Sqrt
{ {
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_AndNot struct xImplSimd_AndNot
{ {
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Packed absolute value. [sSSE3 only] // Packed absolute value. [sSSE3 only]
// //
struct xImplSimd_PAbsolute struct xImplSimd_PAbsolute
{ {
// [sSSE-3] Computes the absolute value of bytes in the src, and stores the result // [sSSE-3] Computes the absolute value of bytes in the src, and stores the result
// in dest, as UNSIGNED. // in dest, as UNSIGNED.
const xImplSimd_DestRegEither B; const xImplSimd_DestRegEither B;
@ -151,14 +151,14 @@ struct xImplSimd_PAbsolute
// [sSSE-3] Computes the absolute value of doublewords in the src, and stores the // [sSSE-3] Computes the absolute value of doublewords in the src, and stores the
// result in dest, as UNSIGNED. // result in dest, as UNSIGNED.
const xImplSimd_DestRegEither D; const xImplSimd_DestRegEither D;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Packed Sign [sSSE3 only] - Negate/zero/preserve packed integers in dest depending on the // Packed Sign [sSSE3 only] - Negate/zero/preserve packed integers in dest depending on the
// corresponding sign in src. // corresponding sign in src.
// //
struct xImplSimd_PSign struct xImplSimd_PSign
{ {
// [sSSE-3] negates each byte element of dest if the signed integer value of the // [sSSE-3] negates each byte element of dest if the signed integer value of the
// corresponding data element in src is less than zero. If the signed integer value // corresponding data element in src is less than zero. If the signed integer value
// of a data element in src is positive, the corresponding data element in dest is // of a data element in src is positive, the corresponding data element in dest is
@ -179,13 +179,13 @@ struct xImplSimd_PSign
// is unchanged. If a data element in src is zero, the corresponding data element in // is unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero. // dest is set to zero.
const xImplSimd_DestRegEither D; const xImplSimd_DestRegEither D;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Packed Multiply and Add!! // Packed Multiply and Add!!
// //
struct xImplSimd_PMultAdd struct xImplSimd_PMultAdd
{ {
// Multiplies the individual signed words of dest by the corresponding signed words // Multiplies the individual signed words of dest by the corresponding signed words
// of src, producing temporary signed, doubleword results. The adjacent doubleword // of src, producing temporary signed, doubleword results. The adjacent doubleword
// results are then summed and stored in the destination operand. // results are then summed and stored in the destination operand.
@ -211,13 +211,13 @@ struct xImplSimd_PMultAdd
// [.. repeat for each 16 bits up to 64 (mmx) or 128 (xmm) ..] // [.. repeat for each 16 bits up to 64 (mmx) or 128 (xmm) ..]
// //
const xImplSimd_DestRegEither UBSW; const xImplSimd_DestRegEither UBSW;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Packed Horizontal Add [SSE3 only] // Packed Horizontal Add [SSE3 only]
// //
struct xImplSimd_HorizAdd struct xImplSimd_HorizAdd
{ {
// [SSE-3] Horizontal Add of Packed Data. A three step process: // [SSE-3] Horizontal Add of Packed Data. A three step process:
// * Adds the single-precision floating-point values in the first and second dwords of // * Adds the single-precision floating-point values in the first and second dwords of
// dest and stores the result in the first dword of dest. // dest and stores the result in the first dword of dest.
@ -233,13 +233,13 @@ struct xImplSimd_HorizAdd
// * Adds the double-precision floating-point values in the high and low quadwords of // * Adds the double-precision floating-point values in the high and low quadwords of
// *src* stores the result in the high quadword of dest. // *src* stores the result in the high quadword of dest.
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// DotProduct calculation (SSE4.1 only!) // DotProduct calculation (SSE4.1 only!)
// //
struct xImplSimd_DotProduct struct xImplSimd_DotProduct
{ {
// [SSE-4.1] Conditionally multiplies the packed single precision floating-point // [SSE-4.1] Conditionally multiplies the packed single precision floating-point
// values in dest with the packed single-precision floats in src depending on a // values in dest with the packed single-precision floats in src depending on a
// mask extracted from the high 4 bits of the immediate byte. If a condition mask // mask extracted from the high 4 bits of the immediate byte. If a condition mask
@ -257,13 +257,13 @@ struct xImplSimd_DotProduct
// [SSE-4.1] // [SSE-4.1]
xImplSimd_DestRegImmSSE PD; xImplSimd_DestRegImmSSE PD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Rounds floating point values (packed or single scalar) by an arbitrary rounding mode. // Rounds floating point values (packed or single scalar) by an arbitrary rounding mode.
// (SSE4.1 only!) // (SSE4.1 only!)
struct xImplSimd_Round struct xImplSimd_Round
{ {
// [SSE-4.1] Rounds the 4 packed single-precision src values and stores them in dest. // [SSE-4.1] Rounds the 4 packed single-precision src values and stores them in dest.
// //
// Imm8 specifies control fields for the rounding operation: // Imm8 specifies control fields for the rounding operation:
@ -311,6 +311,6 @@ struct xImplSimd_Round
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate. // 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
// //
const xImplSimd_DestRegImmSSE SD; const xImplSimd_DestRegImmSSE SD;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,48 +18,48 @@
namespace x86Emitter namespace x86Emitter
{ {
struct xImplSimd_MinMax struct xImplSimd_MinMax
{ {
const xImplSimd_DestRegSSE PS; // packed single precision const xImplSimd_DestRegSSE PS; // packed single precision
const xImplSimd_DestRegSSE PD; // packed double precision const xImplSimd_DestRegSSE PD; // packed double precision
const xImplSimd_DestRegSSE SS; // scalar single precision const xImplSimd_DestRegSSE SS; // scalar single precision
const xImplSimd_DestRegSSE SD; // scalar double precision const xImplSimd_DestRegSSE SD; // scalar double precision
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_Compare struct xImplSimd_Compare
{ {
SSE2_ComparisonType CType; SSE2_ComparisonType CType;
void PS(const xRegisterSSE &to, const xRegisterSSE &from) const; void PS(const xRegisterSSE& to, const xRegisterSSE& from) const;
void PS(const xRegisterSSE &to, const xIndirectVoid &from) const; void PS(const xRegisterSSE& to, const xIndirectVoid& from) const;
void PD(const xRegisterSSE &to, const xRegisterSSE &from) const; void PD(const xRegisterSSE& to, const xRegisterSSE& from) const;
void PD(const xRegisterSSE &to, const xIndirectVoid &from) const; void PD(const xRegisterSSE& to, const xIndirectVoid& from) const;
void SS(const xRegisterSSE &to, const xRegisterSSE &from) const; void SS(const xRegisterSSE& to, const xRegisterSSE& from) const;
void SS(const xRegisterSSE &to, const xIndirectVoid &from) const; void SS(const xRegisterSSE& to, const xIndirectVoid& from) const;
void SD(const xRegisterSSE &to, const xRegisterSSE &from) const; void SD(const xRegisterSSE& to, const xRegisterSSE& from) const;
void SD(const xRegisterSSE &to, const xIndirectVoid &from) const; void SD(const xRegisterSSE& to, const xIndirectVoid& from) const;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Compare scalar floating point values and set EFLAGS (Ordered or Unordered) // Compare scalar floating point values and set EFLAGS (Ordered or Unordered)
// //
struct xImplSimd_COMI struct xImplSimd_COMI
{ {
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_PCompare struct xImplSimd_PCompare
{ {
public: public:
// Compare packed bytes for equality. // Compare packed bytes for equality.
// If a data element in dest is equal to the corresponding date element src, the // If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
@ -89,12 +89,12 @@ public:
// If a data element in dest is greater than the corresponding date element src, the // If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTD; const xImplSimd_DestRegEither GTD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_PMinMax struct xImplSimd_PMinMax
{ {
// Compare packed unsigned byte integers in dest to src and store packed min/max // Compare packed unsigned byte integers in dest to src and store packed min/max
// values in dest. // values in dest.
const xImplSimd_DestRegEither UB; const xImplSimd_DestRegEither UB;
@ -118,6 +118,6 @@ struct xImplSimd_PMinMax
// [SSE-4.1] Compare packed unsigned doubleword integers in dest to src and store // [SSE-4.1] Compare packed unsigned doubleword integers in dest to src and store
// packed min/max values in dest. (SSE operands only) // packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE UD; const xImplSimd_DestRegSSE UD;
}; };
} // end namespace x86Emitter } // end namespace x86Emitter

View File

@ -18,56 +18,56 @@
namespace x86Emitter namespace x86Emitter
{ {
// ===================================================================================================== // =====================================================================================================
// xImpl_SIMD Types (template free!) // xImpl_SIMD Types (template free!)
// ===================================================================================================== // =====================================================================================================
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// For implementing SSE-only logic operations that have xmmreg,xmmreg/rm forms only, // For implementing SSE-only logic operations that have xmmreg,xmmreg/rm forms only,
// like ANDPS/ANDPD // like ANDPS/ANDPD
// //
struct xImplSimd_DestRegSSE struct xImplSimd_DestRegSSE
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const; void operator()(const xRegisterSSE& to, const xRegisterSSE& from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from) const;
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// For implementing SSE-only logic operations that have xmmreg,reg/rm,imm forms only // For implementing SSE-only logic operations that have xmmreg,reg/rm,imm forms only
// (PSHUFD / PSHUFHW / etc). // (PSHUFD / PSHUFHW / etc).
// //
struct xImplSimd_DestRegImmSSE struct xImplSimd_DestRegImmSSE
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm) const; void operator()(const xRegisterSSE& to, const xRegisterSSE& from, u8 imm) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from, u8 imm) const;
}; };
struct xImplSimd_DestSSE_CmpImm struct xImplSimd_DestSSE_CmpImm
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from, SSE2_ComparisonType imm) const; void operator()(const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from, SSE2_ComparisonType imm) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm) const;
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// For implementing SSE operations that have reg,reg/rm forms only, // For implementing SSE operations that have reg,reg/rm forms only,
// but accept either MM or XMM destinations (most PADD/PSUB and other P arithmetic ops). // but accept either MM or XMM destinations (most PADD/PSUB and other P arithmetic ops).
// //
struct xImplSimd_DestRegEither struct xImplSimd_DestRegEither
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const; void operator()(const xRegisterSSE& to, const xRegisterSSE& from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from) const;
}; };
} // end namespace x86Emitter } // end namespace x86Emitter

View File

@ -18,82 +18,82 @@
namespace x86Emitter namespace x86Emitter
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_MovHL // xImplSimd_MovHL
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Moves to/from high/low portions of an xmm register. // Moves to/from high/low portions of an xmm register.
// These instructions cannot be used in reg/reg form. // These instructions cannot be used in reg/reg form.
// //
struct xImplSimd_MovHL struct xImplSimd_MovHL
{ {
u16 Opcode; u16 Opcode;
void PS(const xRegisterSSE &to, const xIndirectVoid &from) const; void PS(const xRegisterSSE& to, const xIndirectVoid& from) const;
void PS(const xIndirectVoid &to, const xRegisterSSE &from) const; void PS(const xIndirectVoid& to, const xRegisterSSE& from) const;
void PD(const xRegisterSSE &to, const xIndirectVoid &from) const; void PD(const xRegisterSSE& to, const xIndirectVoid& from) const;
void PD(const xIndirectVoid &to, const xRegisterSSE &from) const; void PD(const xIndirectVoid& to, const xRegisterSSE& from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_MovHL_RtoR // xImplSimd_MovHL_RtoR
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// RegtoReg forms of MOVHL/MOVLH -- these are the same opcodes as MOVH/MOVL but // RegtoReg forms of MOVHL/MOVLH -- these are the same opcodes as MOVH/MOVL but
// do something kinda different! Fun! // do something kinda different! Fun!
// //
struct xImplSimd_MovHL_RtoR struct xImplSimd_MovHL_RtoR
{ {
u16 Opcode; u16 Opcode;
void PS(const xRegisterSSE &to, const xRegisterSSE &from) const; void PS(const xRegisterSSE& to, const xRegisterSSE& from) const;
void PD(const xRegisterSSE &to, const xRegisterSSE &from) const; void PD(const xRegisterSSE& to, const xRegisterSSE& from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_MoveSSE // xImplSimd_MoveSSE
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Legends in their own right: MOVAPS / MOVAPD / MOVUPS / MOVUPD // Legends in their own right: MOVAPS / MOVAPD / MOVUPS / MOVUPD
// //
// All implementations of Unaligned Movs will, when possible, use aligned movs instead. // All implementations of Unaligned Movs will, when possible, use aligned movs instead.
// This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement // This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement
// which can be checked for alignment at runtime. // which can be checked for alignment at runtime.
// //
struct xImplSimd_MoveSSE struct xImplSimd_MoveSSE
{ {
u8 Prefix; u8 Prefix;
bool isAligned; bool isAligned;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const; void operator()(const xRegisterSSE& to, const xRegisterSSE& from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from) const;
void operator()(const xIndirectVoid &to, const xRegisterSSE &from) const; void operator()(const xIndirectVoid& to, const xRegisterSSE& from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_MoveDQ // xImplSimd_MoveDQ
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Implementations for MOVDQA / MOVDQU // Implementations for MOVDQA / MOVDQU
// //
// All implementations of Unaligned Movs will, when possible, use aligned movs instead. // All implementations of Unaligned Movs will, when possible, use aligned movs instead.
// This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement // This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement
// which can be checked for alignment at runtime. // which can be checked for alignment at runtime.
struct xImplSimd_MoveDQ struct xImplSimd_MoveDQ
{ {
u8 Prefix; u8 Prefix;
bool isAligned; bool isAligned;
void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const; void operator()(const xRegisterSSE& to, const xRegisterSSE& from) const;
void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from) const;
void operator()(const xIndirectVoid &to, const xRegisterSSE &from) const; void operator()(const xIndirectVoid& to, const xRegisterSSE& from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_Blend // xImplSimd_Blend
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Blend - Conditional copying of values in src into dest. // Blend - Conditional copying of values in src into dest.
// //
struct xImplSimd_Blend struct xImplSimd_Blend
{ {
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the // [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
// mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a // mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a
// dword element in a 128-bit operand. // dword element in a 128-bit operand.
@ -129,45 +129,45 @@ struct xImplSimd_Blend
// to dest, else the dword element in dest is left unchanged. // to dest, else the dword element in dest is left unchanged.
// //
xImplSimd_DestRegSSE VPD; xImplSimd_DestRegSSE VPD;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_PMove // xImplSimd_PMove
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Packed Move with Sign or Zero extension. // Packed Move with Sign or Zero extension.
// //
struct xImplSimd_PMove struct xImplSimd_PMove
{ {
u16 OpcodeBase; u16 OpcodeBase;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into word integers // [SSE-4.1] Zero/Sign-extend the low byte values in src into word integers
// and store them in dest. // and store them in dest.
void BW(const xRegisterSSE &to, const xRegisterSSE &from) const; void BW(const xRegisterSSE& to, const xRegisterSSE& from) const;
void BW(const xRegisterSSE &to, const xIndirect64 &from) const; void BW(const xRegisterSSE& to, const xIndirect64& from) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into dword integers // [SSE-4.1] Zero/Sign-extend the low byte values in src into dword integers
// and store them in dest. // and store them in dest.
void BD(const xRegisterSSE &to, const xRegisterSSE &from) const; void BD(const xRegisterSSE& to, const xRegisterSSE& from) const;
void BD(const xRegisterSSE &to, const xIndirect32 &from) const; void BD(const xRegisterSSE& to, const xIndirect32& from) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers // [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers
// and store them in dest. // and store them in dest.
void BQ(const xRegisterSSE &to, const xRegisterSSE &from) const; void BQ(const xRegisterSSE& to, const xRegisterSSE& from) const;
void BQ(const xRegisterSSE &to, const xIndirect16 &from) const; void BQ(const xRegisterSSE& to, const xIndirect16& from) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers // [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers
// and store them in dest. // and store them in dest.
void WD(const xRegisterSSE &to, const xRegisterSSE &from) const; void WD(const xRegisterSSE& to, const xRegisterSSE& from) const;
void WD(const xRegisterSSE &to, const xIndirect64 &from) const; void WD(const xRegisterSSE& to, const xIndirect64& from) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into qword integers // [SSE-4.1] Zero/Sign-extend the low word values in src into qword integers
// and store them in dest. // and store them in dest.
void WQ(const xRegisterSSE &to, const xRegisterSSE &from) const; void WQ(const xRegisterSSE& to, const xRegisterSSE& from) const;
void WQ(const xRegisterSSE &to, const xIndirect32 &from) const; void WQ(const xRegisterSSE& to, const xIndirect32& from) const;
// [SSE-4.1] Zero/Sign-extend the low dword values in src into qword integers // [SSE-4.1] Zero/Sign-extend the low dword values in src into qword integers
// and store them in dest. // and store them in dest.
void DQ(const xRegisterSSE &to, const xRegisterSSE &from) const; void DQ(const xRegisterSSE& to, const xRegisterSSE& from) const;
void DQ(const xRegisterSSE &to, const xIndirect64 &from) const; void DQ(const xRegisterSSE& to, const xIndirect64& from) const;
}; };
} } // namespace x86Emitter

View File

@ -18,25 +18,25 @@
namespace x86Emitter namespace x86Emitter
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_Shuffle // xImplSimd_Shuffle
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImplSimd_Shuffle struct xImplSimd_Shuffle
{ {
inline void _selector_assertion_check(u8 selector) const; inline void _selector_assertion_check(u8 selector) const;
void PS(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const; void PS(const xRegisterSSE& to, const xRegisterSSE& from, u8 selector) const;
void PS(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const; void PS(const xRegisterSSE& to, const xIndirectVoid& from, u8 selector) const;
void PD(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const; void PD(const xRegisterSSE& to, const xRegisterSSE& from, u8 selector) const;
void PD(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const; void PD(const xRegisterSSE& to, const xIndirectVoid& from, u8 selector) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_PShuffle // xImplSimd_PShuffle
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImplSimd_PShuffle struct xImplSimd_PShuffle
{ {
// Copies doublewords from src and inserts them into dest at dword locations selected // Copies doublewords from src and inserts them into dest at dword locations selected
// with the order operand (8 bit immediate). // with the order operand (8 bit immediate).
const xImplSimd_DestRegImmSSE D; const xImplSimd_DestRegImmSSE D;
@ -60,8 +60,8 @@ struct xImplSimd_PShuffle
// //
const xImplSimd_DestRegEither B; const xImplSimd_DestRegEither B;
// below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense // below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense
// but it doesn't (makes it worse). Will try again in MSVC 2010. --air // but it doesn't (makes it worse). Will try again in MSVC 2010. --air
#if 0 #if 0
// Copies words from src and inserts them into dest at word locations selected with // Copies words from src and inserts them into dest at word locations selected with
@ -94,13 +94,13 @@ struct xImplSimd_PShuffle
void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); } void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); } void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
#endif #endif
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SimdImpl_PUnpack // SimdImpl_PUnpack
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct SimdImpl_PUnpack struct SimdImpl_PUnpack
{ {
// Unpack and interleave low-order bytes from src and dest into dest. // Unpack and interleave low-order bytes from src and dest into dest.
const xImplSimd_DestRegEither LBW; const xImplSimd_DestRegEither LBW;
// Unpack and interleave low-order words from src and dest into dest. // Unpack and interleave low-order words from src and dest into dest.
@ -118,15 +118,15 @@ struct SimdImpl_PUnpack
const xImplSimd_DestRegEither HDQ; const xImplSimd_DestRegEither HDQ;
// Unpack and interleave high-order quadwords from src and dest into dest. // Unpack and interleave high-order quadwords from src and dest into dest.
const xImplSimd_DestRegSSE HQDQ; const xImplSimd_DestRegSSE HQDQ;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SimdImpl_Pack // SimdImpl_Pack
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Pack with Signed or Unsigned Saturation // Pack with Signed or Unsigned Saturation
// //
struct SimdImpl_Pack struct SimdImpl_Pack
{ {
// Converts packed signed word integers from src and dest into packed signed // Converts packed signed word integers from src and dest into packed signed
// byte integers in dest, using signed saturation. // byte integers in dest, using signed saturation.
const xImplSimd_DestRegEither SSWB; const xImplSimd_DestRegEither SSWB;
@ -142,13 +142,13 @@ struct SimdImpl_Pack
// [SSE-4.1] Converts packed unsigned dword integers from src and dest into packed // [SSE-4.1] Converts packed unsigned dword integers from src and dest into packed
// unsigned word integers in dest, using signed saturation. // unsigned word integers in dest, using signed saturation.
const xImplSimd_DestRegSSE USDW; const xImplSimd_DestRegSSE USDW;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SimdImpl_Unpack // SimdImpl_Unpack
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImplSimd_Unpack struct xImplSimd_Unpack
{ {
// Unpacks the high doubleword [single-precision] values from src and dest into // Unpacks the high doubleword [single-precision] values from src and dest into
// dest, such that the result of dest looks like this: // dest, such that the result of dest looks like this:
// dest[0] <- dest[2] // dest[0] <- dest[2]
@ -181,53 +181,53 @@ struct xImplSimd_Unpack
// dest.lo <- dest.lo [remains unchanged!] // dest.lo <- dest.lo [remains unchanged!]
// //
const xImplSimd_DestRegSSE LPD; const xImplSimd_DestRegSSE LPD;
}; };
struct xImplSimd_InsertExtractHelper struct xImplSimd_InsertExtractHelper
{ {
u16 Opcode; u16 Opcode;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const; void operator()(const xRegisterSSE& to, const xRegister32& from, u8 imm8) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const; void operator()(const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SimdImpl_PInsert // SimdImpl_PInsert
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// PINSRW/B/D [all but Word form are SSE4.1 only!] // PINSRW/B/D [all but Word form are SSE4.1 only!]
// //
struct xImplSimd_PInsert struct xImplSimd_PInsert
{ {
void W(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const; void W(const xRegisterSSE& to, const xRegister32& from, u8 imm8) const;
void W(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const; void W(const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper B; xImplSimd_InsertExtractHelper B;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper D; xImplSimd_InsertExtractHelper D;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// PEXTRW/B/D [all but Word form are SSE4.1 only!] // PEXTRW/B/D [all but Word form are SSE4.1 only!]
// //
// Note: Word form's indirect memory form is only available in SSE4.1. // Note: Word form's indirect memory form is only available in SSE4.1.
// //
struct SimdImpl_PExtract struct SimdImpl_PExtract
{ {
// Copies the word element specified by imm8 from src to dest. The upper bits // Copies the word element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed // of dest are zero-extended (cleared). This can be used to extract any single packed
// word value from src into an x86 32 bit register. // word value from src into an x86 32 bit register.
// //
// [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension! // [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension!
// //
void W(const xRegister32 &to, const xRegisterSSE &from, u8 imm8) const; void W(const xRegister32& to, const xRegisterSSE& from, u8 imm8) const;
void W(const xIndirectVoid &dest, const xRegisterSSE &from, u8 imm8) const; void W(const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8) const;
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits // [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed // of dest are zero-extended (cleared). This can be used to extract any single packed
@ -237,5 +237,5 @@ struct SimdImpl_PExtract
// [SSE-4.1] Copies the dword element specified by imm8 from src to dest. This can be // [SSE-4.1] Copies the dword element specified by imm8 from src to dest. This can be
// used to extract any single packed dword value from src into an x86 32 bit register. // used to extract any single packed dword value from src into an x86 32 bit register.
const xImplSimd_InsertExtractHelper D; const xImplSimd_InsertExtractHelper D;
}; };
} } // namespace x86Emitter

View File

@ -26,8 +26,8 @@ template <u8 Prefix, u16 Opcode>
class SimdImpl_DestRegSSE class SimdImpl_DestRegSSE
{ {
public: public:
__forceinline void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(Prefix, Opcode, to, from); } __forceinline void operator()(const xRegisterSSE& to, const xRegisterSSE& from) const { xOpWrite0F(Prefix, Opcode, to, from); }
__forceinline void operator()(const xRegisterSSE &to, const ModSibBase &from) const __forceinline void operator()(const xRegisterSSE& to, const ModSibBase& from) const
{ {
bool isReallyAligned = ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty(); bool isReallyAligned = ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty();
pxAssertDev(isReallyAligned, "Alignment check failed on SSE indirect load."); pxAssertDev(isReallyAligned, "Alignment check failed on SSE indirect load.");

View File

@ -20,55 +20,56 @@
namespace x86Emitter namespace x86Emitter
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_Test // xImpl_Test
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// //
struct xImpl_Test struct xImpl_Test
{ {
void operator()(const xRegisterInt &to, const xRegisterInt &from) const; void operator()(const xRegisterInt& to, const xRegisterInt& from) const;
void operator()(const xIndirect64orLess &dest, int imm) const; void operator()(const xIndirect64orLess& dest, int imm) const;
void operator()(const xRegisterInt &to, int imm) const; void operator()(const xRegisterInt& to, int imm) const;
}; };
enum G8Type { enum G8Type
{
G8Type_BT = 4, G8Type_BT = 4,
G8Type_BTS, G8Type_BTS,
G8Type_BTR, G8Type_BTR,
G8Type_BTC, G8Type_BTC,
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// BSF / BSR // BSF / BSR
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// 16/32 operands are available. No 8 bit ones, not that any of you cared, I bet. // 16/32 operands are available. No 8 bit ones, not that any of you cared, I bet.
// //
struct xImpl_BitScan struct xImpl_BitScan
{ {
// 0xbc [fwd] / 0xbd [rev] // 0xbc [fwd] / 0xbd [rev]
u16 Opcode; u16 Opcode;
void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const; void operator()(const xRegister16or32or64& to, const xRegister16or32or64& from) const;
void operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const; void operator()(const xRegister16or32or64& to, const xIndirectVoid& sibsrc) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_Group8 // xImpl_Group8
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Bit Test Instructions - Valid on 16/32 bit instructions only. // Bit Test Instructions - Valid on 16/32 bit instructions only.
// //
struct xImpl_Group8 struct xImpl_Group8
{ {
G8Type InstType; G8Type InstType;
void operator()(const xRegister16or32or64 &bitbase, const xRegister16or32or64 &bitoffset) const; void operator()(const xRegister16or32or64& bitbase, const xRegister16or32or64& bitoffset) const;
void operator()(const xRegister16or32or64 &bitbase, u8 bitoffset) const; void operator()(const xRegister16or32or64& bitbase, u8 bitoffset) const;
void operator()(const xIndirectVoid &bitbase, const xRegister16or32or64 &bitoffset) const; void operator()(const xIndirectVoid& bitbase, const xRegister16or32or64& bitoffset) const;
void operator()(const xIndirect64 &bitbase, u8 bitoffset) const; void operator()(const xIndirect64& bitbase, u8 bitoffset) const;
void operator()(const xIndirect32 &bitbase, u8 bitoffset) const; void operator()(const xIndirect32& bitbase, u8 bitoffset) const;
void operator()(const xIndirect16 &bitbase, u8 bitoffset) const; void operator()(const xIndirect16& bitbase, u8 bitoffset) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -32,68 +32,68 @@
namespace x86Emitter namespace x86Emitter
{ {
extern void xStoreReg(const xRegisterSSE &src); extern void xStoreReg(const xRegisterSSE& src);
extern void xRestoreReg(const xRegisterSSE &dest); extern void xRestoreReg(const xRegisterSSE& dest);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Group 1 Instruction Class // Group 1 Instruction Class
extern const xImpl_Group1 xADC; extern const xImpl_Group1 xADC;
extern const xImpl_Group1 xSBB; extern const xImpl_Group1 xSBB;
extern const xImpl_G1Logic xAND; extern const xImpl_G1Logic xAND;
extern const xImpl_G1Logic xOR; extern const xImpl_G1Logic xOR;
extern const xImpl_G1Logic xXOR; extern const xImpl_G1Logic xXOR;
extern const xImpl_G1Arith xADD; extern const xImpl_G1Arith xADD;
extern const xImpl_G1Arith xSUB; extern const xImpl_G1Arith xSUB;
extern const xImpl_G1Compare xCMP; extern const xImpl_G1Compare xCMP;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Group 2 Instruction Class // Group 2 Instruction Class
// //
// Optimization Note: For Imm forms, we ignore the instruction if the shift count is // Optimization Note: For Imm forms, we ignore the instruction if the shift count is
// zero. This is a safe optimization since any zero-value shift does not affect any // zero. This is a safe optimization since any zero-value shift does not affect any
// flags. // flags.
extern const xImpl_Mov xMOV; extern const xImpl_Mov xMOV;
#ifdef __M_X86_64 #ifdef __M_X86_64
extern const xImpl_MovImm64 xMOV64; extern const xImpl_MovImm64 xMOV64;
#endif #endif
extern const xImpl_Test xTEST; extern const xImpl_Test xTEST;
extern const xImpl_Group2 xROL, xROR, extern const xImpl_Group2 xROL, xROR,
xRCL, xRCR, xRCL, xRCR,
xSHL, xSHR, xSHL, xSHR,
xSAR; xSAR;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Group 3 Instruction Class // Group 3 Instruction Class
extern const xImpl_Group3 xNOT, xNEG; extern const xImpl_Group3 xNOT, xNEG;
extern const xImpl_Group3 xUMUL, xUDIV; extern const xImpl_Group3 xUMUL, xUDIV;
extern const xImpl_iDiv xDIV; extern const xImpl_iDiv xDIV;
extern const xImpl_iMul xMUL; extern const xImpl_iMul xMUL;
extern const xImpl_IncDec xINC, xDEC; extern const xImpl_IncDec xINC, xDEC;
extern const xImpl_MovExtend xMOVZX, xMOVSX; extern const xImpl_MovExtend xMOVZX, xMOVSX;
extern const xImpl_DwordShift xSHLD, xSHRD; extern const xImpl_DwordShift xSHLD, xSHRD;
extern const xImpl_Group8 xBT; extern const xImpl_Group8 xBT;
extern const xImpl_Group8 xBTR; extern const xImpl_Group8 xBTR;
extern const xImpl_Group8 xBTS; extern const xImpl_Group8 xBTS;
extern const xImpl_Group8 xBTC; extern const xImpl_Group8 xBTC;
extern const xImpl_BitScan xBSF, xBSR; extern const xImpl_BitScan xBSF, xBSR;
extern const xImpl_JmpCall xJMP; extern const xImpl_JmpCall xJMP;
extern const xImpl_JmpCall xCALL; extern const xImpl_JmpCall xCALL;
extern const xImpl_FastCall xFastCall; extern const xImpl_FastCall xFastCall;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
extern const xImpl_CMov xCMOVA, xCMOVAE, extern const xImpl_CMov xCMOVA, xCMOVAE,
xCMOVB, xCMOVBE, xCMOVB, xCMOVBE,
xCMOVG, xCMOVGE, xCMOVG, xCMOVGE,
xCMOVL, xCMOVLE, xCMOVL, xCMOVLE,
@ -106,8 +106,8 @@ extern const xImpl_CMov xCMOVA, xCMOVAE,
xCMOVS, xCMOVNS, xCMOVS, xCMOVNS,
xCMOVPE, xCMOVPO; xCMOVPE, xCMOVPO;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
extern const xImpl_Set xSETA, xSETAE, extern const xImpl_Set xSETA, xSETAE,
xSETB, xSETBE, xSETB, xSETBE,
xSETG, xSETGE, xSETG, xSETGE,
xSETL, xSETLE, xSETL, xSETLE,
@ -120,222 +120,223 @@ extern const xImpl_Set xSETA, xSETAE,
xSETS, xSETNS, xSETS, xSETNS,
xSETPE, xSETPO; xSETPE, xSETPO;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// BMI extra instruction requires BMI1/BMI2 // BMI extra instruction requires BMI1/BMI2
extern const xImplBMI_RVM xMULX, xPDEP, xPEXT, xANDN_S; // Warning xANDN is already used by SSE extern const xImplBMI_RVM xMULX, xPDEP, xPEXT, xANDN_S; // Warning xANDN is already used by SSE
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Miscellaneous Instructions // Miscellaneous Instructions
// These are all defined inline or in ix86.cpp. // These are all defined inline or in ix86.cpp.
// //
extern void xBSWAP(const xRegister32or64 &to); extern void xBSWAP(const xRegister32or64& to);
// ----- Lea Instructions (Load Effective Address) ----- // ----- Lea Instructions (Load Effective Address) -----
// Note: alternate (void*) forms of these instructions are not provided since those // Note: alternate (void*) forms of these instructions are not provided since those
// forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs // forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs
// instead. // instead.
extern void xLEA(xRegister64 to, const xIndirectVoid &src, bool preserve_flags = false); extern void xLEA(xRegister64 to, const xIndirectVoid& src, bool preserve_flags = false);
extern void xLEA(xRegister32 to, const xIndirectVoid &src, bool preserve_flags = false); extern void xLEA(xRegister32 to, const xIndirectVoid& src, bool preserve_flags = false);
extern void xLEA(xRegister16 to, const xIndirectVoid &src, bool preserve_flags = false); extern void xLEA(xRegister16 to, const xIndirectVoid& src, bool preserve_flags = false);
/// LEA with a target that will be decided later, guarantees that no optimizations are performed that could change what needs to be written in /// LEA with a target that will be decided later, guarantees that no optimizations are performed that could change what needs to be written in
extern u32* xLEA_Writeback(xAddressReg to); extern u32* xLEA_Writeback(xAddressReg to);
// ----- Push / Pop Instructions ----- // ----- Push / Pop Instructions -----
// Note: pushad/popad implementations are intentionally left out. The instructions are // Note: pushad/popad implementations are intentionally left out. The instructions are
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead. // invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
extern void xPOP(const xIndirectVoid &from); extern void xPOP(const xIndirectVoid& from);
extern void xPUSH(const xIndirectVoid &from); extern void xPUSH(const xIndirectVoid& from);
extern void xPOP(xRegister32or64 from); extern void xPOP(xRegister32or64 from);
extern void xPUSH(u32 imm); extern void xPUSH(u32 imm);
extern void xPUSH(xRegister32or64 from); extern void xPUSH(xRegister32or64 from);
// pushes the EFLAGS register onto the stack // pushes the EFLAGS register onto the stack
extern void xPUSHFD(); extern void xPUSHFD();
// pops the EFLAGS register from the stack // pops the EFLAGS register from the stack
extern void xPOPFD(); extern void xPOPFD();
// ----- Miscellaneous Instructions ----- // ----- Miscellaneous Instructions -----
// Various Instructions with no parameter and no special encoding logic. // Various Instructions with no parameter and no special encoding logic.
extern void xLEAVE(); extern void xLEAVE();
extern void xRET(); extern void xRET();
extern void xCBW(); extern void xCBW();
extern void xCWD(); extern void xCWD();
extern void xCDQ(); extern void xCDQ();
extern void xCWDE(); extern void xCWDE();
extern void xLAHF(); extern void xLAHF();
extern void xSAHF(); extern void xSAHF();
extern void xSTC(); extern void xSTC();
extern void xCLC(); extern void xCLC();
// NOP 1-byte // NOP 1-byte
extern void xNOP(); extern void xNOP();
extern void xINT(u8 imm); extern void xINT(u8 imm);
extern void xINTO(); extern void xINTO();
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Helper object to handle the various functions ABI // Helper object to handle the various functions ABI
class xScopedStackFrame class xScopedStackFrame
{ {
bool m_base_frame; bool m_base_frame;
bool m_save_base_pointer; bool m_save_base_pointer;
int m_offset; int m_offset;
public: public:
xScopedStackFrame(bool base_frame, bool save_base_pointer = false, int offset = 0); xScopedStackFrame(bool base_frame, bool save_base_pointer = false, int offset = 0);
~xScopedStackFrame(); ~xScopedStackFrame();
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
/// Helper object to save some temporary registers before the call /// Helper object to save some temporary registers before the call
class xScopedSavedRegisters class xScopedSavedRegisters
{ {
std::vector<std::reference_wrapper<const xAddressReg>> regs; std::vector<std::reference_wrapper<const xAddressReg>> regs;
public:
public:
xScopedSavedRegisters(std::initializer_list<std::reference_wrapper<const xAddressReg>> regs); xScopedSavedRegisters(std::initializer_list<std::reference_wrapper<const xAddressReg>> regs);
~xScopedSavedRegisters(); ~xScopedSavedRegisters();
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
/// Helper function to calculate base+offset taking into account the limitations of x86-64's RIP-relative addressing /// Helper function to calculate base+offset taking into account the limitations of x86-64's RIP-relative addressing
/// (Will either return `base+offset` or LEA `base` into `tmpRegister` and return `tmpRegister+offset`) /// (Will either return `base+offset` or LEA `base` into `tmpRegister` and return `tmpRegister+offset`)
xAddressVoid xComplexAddress(const xAddressReg& tmpRegister, void *base, const xAddressVoid& offset); xAddressVoid xComplexAddress(const xAddressReg& tmpRegister, void* base, const xAddressVoid& offset);
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
/// Helper function to load addresses that may be far from the current instruction pointer /// Helper function to load addresses that may be far from the current instruction pointer
/// On i386, resolves to `mov dst, (sptr)addr` /// On i386, resolves to `mov dst, (sptr)addr`
/// On x86-64, resolves to either `mov dst, (sptr)addr` or `lea dst, [addr]` depending on the distance from RIP /// On x86-64, resolves to either `mov dst, (sptr)addr` or `lea dst, [addr]` depending on the distance from RIP
void xLoadFarAddr(const xAddressReg& dst, void *addr); void xLoadFarAddr(const xAddressReg& dst, void* addr);
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// JMP / Jcc Instructions! // JMP / Jcc Instructions!
extern void xJcc(JccComparisonType comparison, const void *target); extern void xJcc(JccComparisonType comparison, const void* target);
extern s8 *xJcc8(JccComparisonType comparison = Jcc_Unconditional, s8 displacement = 0); extern s8* xJcc8(JccComparisonType comparison = Jcc_Unconditional, s8 displacement = 0);
extern s32 *xJcc32(JccComparisonType comparison = Jcc_Unconditional, s32 displacement = 0); extern s32* xJcc32(JccComparisonType comparison = Jcc_Unconditional, s32 displacement = 0);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Conditional jumps to fixed targets. // Conditional jumps to fixed targets.
// Jumps accept any pointer as a valid target (function or data), and will generate either // Jumps accept any pointer as a valid target (function or data), and will generate either
// 8 or 32 bit displacement versions of the jump, depending on relative displacement of // 8 or 32 bit displacement versions of the jump, depending on relative displacement of
// the target (efficient!) // the target (efficient!)
// //
template <typename T> template <typename T>
__fi void xJE(T *func) __fi void xJE(T* func)
{ {
xJcc(Jcc_Equal, (void *)(uptr)func); xJcc(Jcc_Equal, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJZ(T *func) __fi void xJZ(T* func)
{ {
xJcc(Jcc_Zero, (void *)(uptr)func); xJcc(Jcc_Zero, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJNE(T *func) __fi void xJNE(T* func)
{ {
xJcc(Jcc_NotEqual, (void *)(uptr)func); xJcc(Jcc_NotEqual, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJNZ(T *func) __fi void xJNZ(T* func)
{ {
xJcc(Jcc_NotZero, (void *)(uptr)func); xJcc(Jcc_NotZero, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJO(T *func) __fi void xJO(T* func)
{ {
xJcc(Jcc_Overflow, (void *)(uptr)func); xJcc(Jcc_Overflow, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJNO(T *func) __fi void xJNO(T* func)
{ {
xJcc(Jcc_NotOverflow, (void *)(uptr)func); xJcc(Jcc_NotOverflow, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJC(T *func) __fi void xJC(T* func)
{ {
xJcc(Jcc_Carry, (void *)(uptr)func); xJcc(Jcc_Carry, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJNC(T *func) __fi void xJNC(T* func)
{ {
xJcc(Jcc_NotCarry, (void *)(uptr)func); xJcc(Jcc_NotCarry, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJS(T *func) __fi void xJS(T* func)
{ {
xJcc(Jcc_Signed, (void *)(uptr)func); xJcc(Jcc_Signed, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJNS(T *func) __fi void xJNS(T* func)
{ {
xJcc(Jcc_Unsigned, (void *)(uptr)func); xJcc(Jcc_Unsigned, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJPE(T *func) __fi void xJPE(T* func)
{ {
xJcc(Jcc_ParityEven, (void *)(uptr)func); xJcc(Jcc_ParityEven, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJPO(T *func) __fi void xJPO(T* func)
{ {
xJcc(Jcc_ParityOdd, (void *)(uptr)func); xJcc(Jcc_ParityOdd, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJL(T *func) __fi void xJL(T* func)
{ {
xJcc(Jcc_Less, (void *)(uptr)func); xJcc(Jcc_Less, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJLE(T *func) __fi void xJLE(T* func)
{ {
xJcc(Jcc_LessOrEqual, (void *)(uptr)func); xJcc(Jcc_LessOrEqual, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJG(T *func) __fi void xJG(T* func)
{ {
xJcc(Jcc_Greater, (void *)(uptr)func); xJcc(Jcc_Greater, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJGE(T *func) __fi void xJGE(T* func)
{ {
xJcc(Jcc_GreaterOrEqual, (void *)(uptr)func); xJcc(Jcc_GreaterOrEqual, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJB(T *func) __fi void xJB(T* func)
{ {
xJcc(Jcc_Below, (void *)(uptr)func); xJcc(Jcc_Below, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJBE(T *func) __fi void xJBE(T* func)
{ {
xJcc(Jcc_BelowOrEqual, (void *)(uptr)func); xJcc(Jcc_BelowOrEqual, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJA(T *func) __fi void xJA(T* func)
{ {
xJcc(Jcc_Above, (void *)(uptr)func); xJcc(Jcc_Above, (void*)(uptr)func);
} }
template <typename T> template <typename T>
__fi void xJAE(T *func) __fi void xJAE(T* func)
{ {
xJcc(Jcc_AboveOrEqual, (void *)(uptr)func); xJcc(Jcc_AboveOrEqual, (void*)(uptr)func);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Forward Jump Helpers (act as labels!) // Forward Jump Helpers (act as labels!)
#define DEFINE_FORWARD_JUMP(label, cond) \ #define DEFINE_FORWARD_JUMP(label, cond) \
template <typename OperandType> \ template <typename OperandType> \
@ -348,255 +349,255 @@ __fi void xJAE(T *func)
} \ } \
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Note: typedefs below are defined individually in order to appease Intellisense // Note: typedefs below are defined individually in order to appease Intellisense
// resolution. Including them into the class definition macro above breaks it. // resolution. Including them into the class definition macro above breaks it.
typedef xForwardJump<s8> xForwardJump8; typedef xForwardJump<s8> xForwardJump8;
typedef xForwardJump<s32> xForwardJump32; typedef xForwardJump<s32> xForwardJump32;
DEFINE_FORWARD_JUMP(JA, Jcc_Above); DEFINE_FORWARD_JUMP(JA, Jcc_Above);
DEFINE_FORWARD_JUMP(JB, Jcc_Below); DEFINE_FORWARD_JUMP(JB, Jcc_Below);
DEFINE_FORWARD_JUMP(JAE, Jcc_AboveOrEqual); DEFINE_FORWARD_JUMP(JAE, Jcc_AboveOrEqual);
DEFINE_FORWARD_JUMP(JBE, Jcc_BelowOrEqual); DEFINE_FORWARD_JUMP(JBE, Jcc_BelowOrEqual);
typedef xForwardJA<s8> xForwardJA8; typedef xForwardJA<s8> xForwardJA8;
typedef xForwardJA<s32> xForwardJA32; typedef xForwardJA<s32> xForwardJA32;
typedef xForwardJB<s8> xForwardJB8; typedef xForwardJB<s8> xForwardJB8;
typedef xForwardJB<s32> xForwardJB32; typedef xForwardJB<s32> xForwardJB32;
typedef xForwardJAE<s8> xForwardJAE8; typedef xForwardJAE<s8> xForwardJAE8;
typedef xForwardJAE<s32> xForwardJAE32; typedef xForwardJAE<s32> xForwardJAE32;
typedef xForwardJBE<s8> xForwardJBE8; typedef xForwardJBE<s8> xForwardJBE8;
typedef xForwardJBE<s32> xForwardJBE32; typedef xForwardJBE<s32> xForwardJBE32;
DEFINE_FORWARD_JUMP(JG, Jcc_Greater); DEFINE_FORWARD_JUMP(JG, Jcc_Greater);
DEFINE_FORWARD_JUMP(JL, Jcc_Less); DEFINE_FORWARD_JUMP(JL, Jcc_Less);
DEFINE_FORWARD_JUMP(JGE, Jcc_GreaterOrEqual); DEFINE_FORWARD_JUMP(JGE, Jcc_GreaterOrEqual);
DEFINE_FORWARD_JUMP(JLE, Jcc_LessOrEqual); DEFINE_FORWARD_JUMP(JLE, Jcc_LessOrEqual);
typedef xForwardJG<s8> xForwardJG8; typedef xForwardJG<s8> xForwardJG8;
typedef xForwardJG<s32> xForwardJG32; typedef xForwardJG<s32> xForwardJG32;
typedef xForwardJL<s8> xForwardJL8; typedef xForwardJL<s8> xForwardJL8;
typedef xForwardJL<s32> xForwardJL32; typedef xForwardJL<s32> xForwardJL32;
typedef xForwardJGE<s8> xForwardJGE8; typedef xForwardJGE<s8> xForwardJGE8;
typedef xForwardJGE<s32> xForwardJGE32; typedef xForwardJGE<s32> xForwardJGE32;
typedef xForwardJLE<s8> xForwardJLE8; typedef xForwardJLE<s8> xForwardJLE8;
typedef xForwardJLE<s32> xForwardJLE32; typedef xForwardJLE<s32> xForwardJLE32;
DEFINE_FORWARD_JUMP(JZ, Jcc_Zero); DEFINE_FORWARD_JUMP(JZ, Jcc_Zero);
DEFINE_FORWARD_JUMP(JE, Jcc_Equal); DEFINE_FORWARD_JUMP(JE, Jcc_Equal);
DEFINE_FORWARD_JUMP(JNZ, Jcc_NotZero); DEFINE_FORWARD_JUMP(JNZ, Jcc_NotZero);
DEFINE_FORWARD_JUMP(JNE, Jcc_NotEqual); DEFINE_FORWARD_JUMP(JNE, Jcc_NotEqual);
typedef xForwardJZ<s8> xForwardJZ8; typedef xForwardJZ<s8> xForwardJZ8;
typedef xForwardJZ<s32> xForwardJZ32; typedef xForwardJZ<s32> xForwardJZ32;
typedef xForwardJE<s8> xForwardJE8; typedef xForwardJE<s8> xForwardJE8;
typedef xForwardJE<s32> xForwardJE32; typedef xForwardJE<s32> xForwardJE32;
typedef xForwardJNZ<s8> xForwardJNZ8; typedef xForwardJNZ<s8> xForwardJNZ8;
typedef xForwardJNZ<s32> xForwardJNZ32; typedef xForwardJNZ<s32> xForwardJNZ32;
typedef xForwardJNE<s8> xForwardJNE8; typedef xForwardJNE<s8> xForwardJNE8;
typedef xForwardJNE<s32> xForwardJNE32; typedef xForwardJNE<s32> xForwardJNE32;
DEFINE_FORWARD_JUMP(JS, Jcc_Signed); DEFINE_FORWARD_JUMP(JS, Jcc_Signed);
DEFINE_FORWARD_JUMP(JNS, Jcc_Unsigned); DEFINE_FORWARD_JUMP(JNS, Jcc_Unsigned);
typedef xForwardJS<s8> xForwardJS8; typedef xForwardJS<s8> xForwardJS8;
typedef xForwardJS<s32> xForwardJS32; typedef xForwardJS<s32> xForwardJS32;
typedef xForwardJNS<s8> xForwardJNS8; typedef xForwardJNS<s8> xForwardJNS8;
typedef xForwardJNS<s32> xForwardJNS32; typedef xForwardJNS<s32> xForwardJNS32;
DEFINE_FORWARD_JUMP(JO, Jcc_Overflow); DEFINE_FORWARD_JUMP(JO, Jcc_Overflow);
DEFINE_FORWARD_JUMP(JNO, Jcc_NotOverflow); DEFINE_FORWARD_JUMP(JNO, Jcc_NotOverflow);
typedef xForwardJO<s8> xForwardJO8; typedef xForwardJO<s8> xForwardJO8;
typedef xForwardJO<s32> xForwardJO32; typedef xForwardJO<s32> xForwardJO32;
typedef xForwardJNO<s8> xForwardJNO8; typedef xForwardJNO<s8> xForwardJNO8;
typedef xForwardJNO<s32> xForwardJNO32; typedef xForwardJNO<s32> xForwardJNO32;
DEFINE_FORWARD_JUMP(JC, Jcc_Carry); DEFINE_FORWARD_JUMP(JC, Jcc_Carry);
DEFINE_FORWARD_JUMP(JNC, Jcc_NotCarry); DEFINE_FORWARD_JUMP(JNC, Jcc_NotCarry);
typedef xForwardJC<s8> xForwardJC8; typedef xForwardJC<s8> xForwardJC8;
typedef xForwardJC<s32> xForwardJC32; typedef xForwardJC<s32> xForwardJC32;
typedef xForwardJNC<s8> xForwardJNC8; typedef xForwardJNC<s8> xForwardJNC8;
typedef xForwardJNC<s32> xForwardJNC32; typedef xForwardJNC<s32> xForwardJNC32;
DEFINE_FORWARD_JUMP(JPE, Jcc_ParityEven); DEFINE_FORWARD_JUMP(JPE, Jcc_ParityEven);
DEFINE_FORWARD_JUMP(JPO, Jcc_ParityOdd); DEFINE_FORWARD_JUMP(JPO, Jcc_ParityOdd);
typedef xForwardJPE<s8> xForwardJPE8; typedef xForwardJPE<s8> xForwardJPE8;
typedef xForwardJPE<s32> xForwardJPE32; typedef xForwardJPE<s32> xForwardJPE32;
typedef xForwardJPO<s8> xForwardJPO8; typedef xForwardJPO<s8> xForwardJPO8;
typedef xForwardJPO<s32> xForwardJPO32; typedef xForwardJPO<s32> xForwardJPO32;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
extern void xEMMS(); extern void xEMMS();
extern void xSTMXCSR(const xIndirect32 &dest); extern void xSTMXCSR(const xIndirect32& dest);
extern void xLDMXCSR(const xIndirect32 &src); extern void xLDMXCSR(const xIndirect32& src);
extern void xFXSAVE(const xIndirectVoid &dest); extern void xFXSAVE(const xIndirectVoid& dest);
extern void xFXRSTOR(const xIndirectVoid &src); extern void xFXRSTOR(const xIndirectVoid& src);
extern void xMOVDZX(const xRegisterSSE &to, const xRegister32or64 &from); extern void xMOVDZX(const xRegisterSSE& to, const xRegister32or64& from);
extern void xMOVDZX(const xRegisterSSE &to, const xIndirectVoid &src); extern void xMOVDZX(const xRegisterSSE& to, const xIndirectVoid& src);
extern void xMOVD(const xRegister32or64 &to, const xRegisterSSE &from); extern void xMOVD(const xRegister32or64& to, const xRegisterSSE& from);
extern void xMOVD(const xIndirectVoid &dest, const xRegisterSSE &from); extern void xMOVD(const xIndirectVoid& dest, const xRegisterSSE& from);
extern void xMOVQ(const xIndirectVoid &dest, const xRegisterSSE &from); extern void xMOVQ(const xIndirectVoid& dest, const xRegisterSSE& from);
extern void xMOVQZX(const xRegisterSSE &to, const xIndirectVoid &src); extern void xMOVQZX(const xRegisterSSE& to, const xIndirectVoid& src);
extern void xMOVQZX(const xRegisterSSE &to, const xRegisterSSE &from); extern void xMOVQZX(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xMOVSS(const xRegisterSSE &to, const xRegisterSSE &from); extern void xMOVSS(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xMOVSS(const xIndirectVoid &to, const xRegisterSSE &from); extern void xMOVSS(const xIndirectVoid& to, const xRegisterSSE& from);
extern void xMOVSD(const xRegisterSSE &to, const xRegisterSSE &from); extern void xMOVSD(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xMOVSD(const xIndirectVoid &to, const xRegisterSSE &from); extern void xMOVSD(const xIndirectVoid& to, const xRegisterSSE& from);
extern void xMOVSSZX(const xRegisterSSE &to, const xIndirectVoid &from); extern void xMOVSSZX(const xRegisterSSE& to, const xIndirectVoid& from);
extern void xMOVSDZX(const xRegisterSSE &to, const xIndirectVoid &from); extern void xMOVSDZX(const xRegisterSSE& to, const xIndirectVoid& from);
extern void xMOVNTDQA(const xRegisterSSE &to, const xIndirectVoid &from); extern void xMOVNTDQA(const xRegisterSSE& to, const xIndirectVoid& from);
extern void xMOVNTDQA(const xIndirectVoid &to, const xRegisterSSE &from); extern void xMOVNTDQA(const xIndirectVoid& to, const xRegisterSSE& from);
extern void xMOVNTPD(const xIndirectVoid &to, const xRegisterSSE &from); extern void xMOVNTPD(const xIndirectVoid& to, const xRegisterSSE& from);
extern void xMOVNTPS(const xIndirectVoid &to, const xRegisterSSE &from); extern void xMOVNTPS(const xIndirectVoid& to, const xRegisterSSE& from);
extern void xMOVMSKPS(const xRegister32 &to, const xRegisterSSE &from); extern void xMOVMSKPS(const xRegister32& to, const xRegisterSSE& from);
extern void xMOVMSKPD(const xRegister32 &to, const xRegisterSSE &from); extern void xMOVMSKPD(const xRegister32& to, const xRegisterSSE& from);
extern void xMASKMOV(const xRegisterSSE &to, const xRegisterSSE &from); extern void xMASKMOV(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xPMOVMSKB(const xRegister32or64 &to, const xRegisterSSE &from); extern void xPMOVMSKB(const xRegister32or64& to, const xRegisterSSE& from);
extern void xPALIGNR(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8); extern void xPALIGNR(const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
extern const xImplSimd_MoveSSE xMOVAPS; extern const xImplSimd_MoveSSE xMOVAPS;
extern const xImplSimd_MoveSSE xMOVUPS; extern const xImplSimd_MoveSSE xMOVUPS;
extern const xImplSimd_MoveSSE xMOVAPD; extern const xImplSimd_MoveSSE xMOVAPD;
extern const xImplSimd_MoveSSE xMOVUPD; extern const xImplSimd_MoveSSE xMOVUPD;
#ifdef ALWAYS_USE_MOVAPS #ifdef ALWAYS_USE_MOVAPS
extern const xImplSimd_MoveSSE xMOVDQA; extern const xImplSimd_MoveSSE xMOVDQA;
extern const xImplSimd_MoveSSE xMOVDQU; extern const xImplSimd_MoveSSE xMOVDQU;
#else #else
extern const xImplSimd_MoveDQ xMOVDQA; extern const xImplSimd_MoveDQ xMOVDQA;
extern const xImplSimd_MoveDQ xMOVDQU; extern const xImplSimd_MoveDQ xMOVDQU;
#endif #endif
extern const xImplSimd_MovHL xMOVH; extern const xImplSimd_MovHL xMOVH;
extern const xImplSimd_MovHL xMOVL; extern const xImplSimd_MovHL xMOVL;
extern const xImplSimd_MovHL_RtoR xMOVLH; extern const xImplSimd_MovHL_RtoR xMOVLH;
extern const xImplSimd_MovHL_RtoR xMOVHL; extern const xImplSimd_MovHL_RtoR xMOVHL;
extern const xImplSimd_Blend xBLEND; extern const xImplSimd_Blend xBLEND;
extern const xImplSimd_PMove xPMOVSX; extern const xImplSimd_PMove xPMOVSX;
extern const xImplSimd_PMove xPMOVZX; extern const xImplSimd_PMove xPMOVZX;
extern const xImplSimd_DestRegSSE xMOVSLDUP; extern const xImplSimd_DestRegSSE xMOVSLDUP;
extern const xImplSimd_DestRegSSE xMOVSHDUP; extern const xImplSimd_DestRegSSE xMOVSHDUP;
extern void xINSERTPS(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8); extern void xINSERTPS(const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8);
extern void xINSERTPS(const xRegisterSSE &to, const xIndirect32 &from, u8 imm8); extern void xINSERTPS(const xRegisterSSE& to, const xIndirect32& from, u8 imm8);
extern void xEXTRACTPS(const xRegister32or64 &to, const xRegisterSSE &from, u8 imm8); extern void xEXTRACTPS(const xRegister32or64& to, const xRegisterSSE& from, u8 imm8);
extern void xEXTRACTPS(const xIndirect32 &dest, const xRegisterSSE &from, u8 imm8); extern void xEXTRACTPS(const xIndirect32& dest, const xRegisterSSE& from, u8 imm8);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
extern const xImplSimd_DestRegEither xPAND; extern const xImplSimd_DestRegEither xPAND;
extern const xImplSimd_DestRegEither xPANDN; extern const xImplSimd_DestRegEither xPANDN;
extern const xImplSimd_DestRegEither xPOR; extern const xImplSimd_DestRegEither xPOR;
extern const xImplSimd_DestRegEither xPXOR; extern const xImplSimd_DestRegEither xPXOR;
extern const xImplSimd_Shuffle xSHUF; extern const xImplSimd_Shuffle xSHUF;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
extern const xImplSimd_DestRegSSE xPTEST; extern const xImplSimd_DestRegSSE xPTEST;
extern const xImplSimd_MinMax xMIN; extern const xImplSimd_MinMax xMIN;
extern const xImplSimd_MinMax xMAX; extern const xImplSimd_MinMax xMAX;
extern const xImplSimd_Compare xCMPEQ, xCMPLT, extern const xImplSimd_Compare xCMPEQ, xCMPLT,
xCMPLE, xCMPUNORD, xCMPLE, xCMPUNORD,
xCMPNE, xCMPNLT, xCMPNE, xCMPNLT,
xCMPNLE, xCMPORD; xCMPNLE, xCMPORD;
extern const xImplSimd_COMI xCOMI; extern const xImplSimd_COMI xCOMI;
extern const xImplSimd_COMI xUCOMI; extern const xImplSimd_COMI xUCOMI;
extern const xImplSimd_PCompare xPCMP; extern const xImplSimd_PCompare xPCMP;
extern const xImplSimd_PMinMax xPMIN; extern const xImplSimd_PMinMax xPMIN;
extern const xImplSimd_PMinMax xPMAX; extern const xImplSimd_PMinMax xPMAX;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// //
// //
extern void xCVTDQ2PD(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTDQ2PD(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTDQ2PD(const xRegisterSSE &to, const xIndirect64 &from); extern void xCVTDQ2PD(const xRegisterSSE& to, const xIndirect64& from);
extern void xCVTDQ2PS(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTDQ2PS(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTDQ2PS(const xRegisterSSE &to, const xIndirect128 &from); extern void xCVTDQ2PS(const xRegisterSSE& to, const xIndirect128& from);
extern void xCVTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from); extern void xCVTPD2DQ(const xRegisterSSE& to, const xIndirect128& from);
extern void xCVTPD2PS(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTPD2PS(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTPD2PS(const xRegisterSSE &to, const xIndirect128 &from); extern void xCVTPD2PS(const xRegisterSSE& to, const xIndirect128& from);
extern void xCVTPI2PD(const xRegisterSSE &to, const xIndirect64 &from); extern void xCVTPI2PD(const xRegisterSSE& to, const xIndirect64& from);
extern void xCVTPI2PS(const xRegisterSSE &to, const xIndirect64 &from); extern void xCVTPI2PS(const xRegisterSSE& to, const xIndirect64& from);
extern void xCVTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from); extern void xCVTPS2DQ(const xRegisterSSE& to, const xIndirect128& from);
extern void xCVTPS2PD(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTPS2PD(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTPS2PD(const xRegisterSSE &to, const xIndirect64 &from); extern void xCVTPS2PD(const xRegisterSSE& to, const xIndirect64& from);
extern void xCVTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from); extern void xCVTSD2SI(const xRegister32or64& to, const xRegisterSSE& from);
extern void xCVTSD2SI(const xRegister32or64 &to, const xIndirect64 &from); extern void xCVTSD2SI(const xRegister32or64& to, const xIndirect64& from);
extern void xCVTSD2SS(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTSD2SS(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTSD2SS(const xRegisterSSE &to, const xIndirect64 &from); extern void xCVTSD2SS(const xRegisterSSE& to, const xIndirect64& from);
extern void xCVTSI2SS(const xRegisterSSE &to, const xRegister32or64 &from); extern void xCVTSI2SS(const xRegisterSSE& to, const xRegister32or64& from);
extern void xCVTSI2SS(const xRegisterSSE &to, const xIndirect32 &from); extern void xCVTSI2SS(const xRegisterSSE& to, const xIndirect32& from);
extern void xCVTSS2SD(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTSS2SD(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTSS2SD(const xRegisterSSE &to, const xIndirect32 &from); extern void xCVTSS2SD(const xRegisterSSE& to, const xIndirect32& from);
extern void xCVTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from); extern void xCVTSS2SI(const xRegister32or64& to, const xRegisterSSE& from);
extern void xCVTSS2SI(const xRegister32or64 &to, const xIndirect32 &from); extern void xCVTSS2SI(const xRegister32or64& to, const xIndirect32& from);
extern void xCVTTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from); extern void xCVTTPD2DQ(const xRegisterSSE& to, const xIndirect128& from);
extern void xCVTTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from); extern void xCVTTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from);
extern void xCVTTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from); extern void xCVTTPS2DQ(const xRegisterSSE& to, const xIndirect128& from);
extern void xCVTTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from); extern void xCVTTSD2SI(const xRegister32or64& to, const xRegisterSSE& from);
extern void xCVTTSD2SI(const xRegister32or64 &to, const xIndirect64 &from); extern void xCVTTSD2SI(const xRegister32or64& to, const xIndirect64& from);
extern void xCVTTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from); extern void xCVTTSS2SI(const xRegister32or64& to, const xRegisterSSE& from);
extern void xCVTTSS2SI(const xRegister32or64 &to, const xIndirect32 &from); extern void xCVTTSS2SI(const xRegister32or64& to, const xIndirect32& from);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
extern const xImplSimd_AndNot xANDN; extern const xImplSimd_AndNot xANDN;
extern const xImplSimd_rSqrt xRCP; extern const xImplSimd_rSqrt xRCP;
extern const xImplSimd_rSqrt xRSQRT; extern const xImplSimd_rSqrt xRSQRT;
extern const xImplSimd_Sqrt xSQRT; extern const xImplSimd_Sqrt xSQRT;
extern const xImplSimd_Shift xPSLL; extern const xImplSimd_Shift xPSLL;
extern const xImplSimd_Shift xPSRL; extern const xImplSimd_Shift xPSRL;
extern const xImplSimd_ShiftWithoutQ xPSRA; extern const xImplSimd_ShiftWithoutQ xPSRA;
extern const xImplSimd_AddSub xPADD; extern const xImplSimd_AddSub xPADD;
extern const xImplSimd_AddSub xPSUB; extern const xImplSimd_AddSub xPSUB;
extern const xImplSimd_PMul xPMUL; extern const xImplSimd_PMul xPMUL;
extern const xImplSimd_PAbsolute xPABS; extern const xImplSimd_PAbsolute xPABS;
extern const xImplSimd_PSign xPSIGN; extern const xImplSimd_PSign xPSIGN;
extern const xImplSimd_PMultAdd xPMADD; extern const xImplSimd_PMultAdd xPMADD;
extern const xImplSimd_HorizAdd xHADD; extern const xImplSimd_HorizAdd xHADD;
extern const xImplSimd_DotProduct xDP; extern const xImplSimd_DotProduct xDP;
extern const xImplSimd_Round xROUND; extern const xImplSimd_Round xROUND;
extern const xImplSimd_PShuffle xPSHUF; extern const xImplSimd_PShuffle xPSHUF;
extern const SimdImpl_PUnpack xPUNPCK; extern const SimdImpl_PUnpack xPUNPCK;
extern const xImplSimd_Unpack xUNPCK; extern const xImplSimd_Unpack xUNPCK;
extern const SimdImpl_Pack xPACK; extern const SimdImpl_Pack xPACK;
extern const xImplSimd_PInsert xPINSR; extern const xImplSimd_PInsert xPINSR;
extern const SimdImpl_PExtract xPEXTR; extern const SimdImpl_PExtract xPEXTR;
} } // namespace x86Emitter

View File

@ -23,33 +23,33 @@ namespace x86Emitter
#define OpWriteSSE(pre, op) xOpWrite0F(pre, op, to, from) #define OpWriteSSE(pre, op) xOpWrite0F(pre, op, to, from)
extern void SimdPrefix(u8 prefix, u16 opcode); extern void SimdPrefix(u8 prefix, u16 opcode);
extern void EmitSibMagic(uint regfield, const void *address, int extraRIPOffset = 0); extern void EmitSibMagic(uint regfield, const void* address, int extraRIPOffset = 0);
extern void EmitSibMagic(uint regfield, const xIndirectVoid &info, int extraRIPOffset = 0); extern void EmitSibMagic(uint regfield, const xIndirectVoid& info, int extraRIPOffset = 0);
extern void EmitSibMagic(uint reg1, const xRegisterBase &reg2, int = 0); extern void EmitSibMagic(uint reg1, const xRegisterBase& reg2, int = 0);
extern void EmitSibMagic(const xRegisterBase &reg1, const xRegisterBase &reg2, int = 0); extern void EmitSibMagic(const xRegisterBase& reg1, const xRegisterBase& reg2, int = 0);
extern void EmitSibMagic(const xRegisterBase &reg1, const void *src, int extraRIPOffset = 0); extern void EmitSibMagic(const xRegisterBase& reg1, const void* src, int extraRIPOffset = 0);
extern void EmitSibMagic(const xRegisterBase &reg1, const xIndirectVoid &sib, int extraRIPOffset = 0); extern void EmitSibMagic(const xRegisterBase& reg1, const xIndirectVoid& sib, int extraRIPOffset = 0);
extern void EmitRex(uint regfield, const void *address); extern void EmitRex(uint regfield, const void* address);
extern void EmitRex(uint regfield, const xIndirectVoid &info); extern void EmitRex(uint regfield, const xIndirectVoid& info);
extern void EmitRex(uint reg1, const xRegisterBase &reg2); extern void EmitRex(uint reg1, const xRegisterBase& reg2);
extern void EmitRex(const xRegisterBase &reg1, const xRegisterBase &reg2); extern void EmitRex(const xRegisterBase& reg1, const xRegisterBase& reg2);
extern void EmitRex(const xRegisterBase &reg1, const void *src); extern void EmitRex(const xRegisterBase& reg1, const void* src);
extern void EmitRex(const xRegisterBase &reg1, const xIndirectVoid &sib); extern void EmitRex(const xRegisterBase& reg1, const xIndirectVoid& sib);
extern void _xMovRtoR(const xRegisterInt &to, const xRegisterInt &from); extern void _xMovRtoR(const xRegisterInt& to, const xRegisterInt& from);
template <typename T> template <typename T>
inline void xWrite(T val) inline void xWrite(T val)
{ {
*(T *)x86Ptr = val; *(T*)x86Ptr = val;
x86Ptr += sizeof(T); x86Ptr += sizeof(T);
} }
template <typename T1, typename T2> template <typename T1, typename T2>
__emitinline void xOpWrite(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2, int extraRIPOffset = 0) __emitinline void xOpWrite(u8 prefix, u8 opcode, const T1& param1, const T2& param2, int extraRIPOffset = 0)
{ {
if (prefix != 0) if (prefix != 0)
xWrite8(prefix); xWrite8(prefix);
EmitRex(param1, param2); EmitRex(param1, param2);
@ -57,32 +57,32 @@ __emitinline void xOpWrite(u8 prefix, u8 opcode, const T1 &param1, const T2 &par
xWrite8(opcode); xWrite8(opcode);
EmitSibMagic(param1, param2, extraRIPOffset); EmitSibMagic(param1, param2, extraRIPOffset);
} }
template <typename T1, typename T2> template <typename T1, typename T2>
__emitinline void xOpAccWrite(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2) __emitinline void xOpAccWrite(u8 prefix, u8 opcode, const T1& param1, const T2& param2)
{ {
if (prefix != 0) if (prefix != 0)
xWrite8(prefix); xWrite8(prefix);
EmitRex(param1, param2); EmitRex(param1, param2);
xWrite8(opcode); xWrite8(opcode);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// emitter helpers for xmm instruction with prefixes, most of which are using // emitter helpers for xmm instruction with prefixes, most of which are using
// the basic opcode format (items inside braces denote optional or conditional // the basic opcode format (items inside braces denote optional or conditional
// emission): // emission):
// //
// [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB] // [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
// //
// Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or // Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or
// 0x3a [and other value will result in assertion failue]. // 0x3a [and other value will result in assertion failue].
// //
template <typename T1, typename T2> template <typename T1, typename T2>
__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &param2) __emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1& param1, const T2& param2)
{ {
if (prefix != 0) if (prefix != 0)
xWrite8(prefix); xWrite8(prefix);
EmitRex(param1, param2); EmitRex(param1, param2);
@ -90,11 +90,11 @@ __emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &
SimdPrefix(0, opcode); SimdPrefix(0, opcode);
EmitSibMagic(param1, param2); EmitSibMagic(param1, param2);
} }
template <typename T1, typename T2> template <typename T1, typename T2>
__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &param2, u8 imm8) __emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8)
{ {
if (prefix != 0) if (prefix != 0)
xWrite8(prefix); xWrite8(prefix);
EmitRex(param1, param2); EmitRex(param1, param2);
@ -103,27 +103,27 @@ __emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &
EmitSibMagic(param1, param2, 1); EmitSibMagic(param1, param2, 1);
xWrite8(imm8); xWrite8(imm8);
} }
template <typename T1, typename T2> template <typename T1, typename T2>
__emitinline void xOpWrite0F(u16 opcode, const T1 &param1, const T2 &param2) __emitinline void xOpWrite0F(u16 opcode, const T1& param1, const T2& param2)
{ {
xOpWrite0F(0, opcode, param1, param2); xOpWrite0F(0, opcode, param1, param2);
} }
template <typename T1, typename T2> template <typename T1, typename T2>
__emitinline void xOpWrite0F(u16 opcode, const T1 &param1, const T2 &param2, u8 imm8) __emitinline void xOpWrite0F(u16 opcode, const T1& param1, const T2& param2, u8 imm8)
{ {
xOpWrite0F(0, opcode, param1, param2, imm8); xOpWrite0F(0, opcode, param1, param2, imm8);
} }
// VEX 2 Bytes Prefix // VEX 2 Bytes Prefix
template <typename T1, typename T2, typename T3> template <typename T1, typename T2, typename T3>
__emitinline void xOpWriteC5(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2, const T3 &param3) __emitinline void xOpWriteC5(u8 prefix, u8 opcode, const T1& param1, const T2& param2, const T3& param3)
{ {
pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2); pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2);
const xRegisterInt &reg = param1.IsReg() ? param1 : param2; const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __M_X86_64 #ifdef __M_X86_64
u8 nR = reg.IsExtended() ? 0x00 : 0x80; u8 nR = reg.IsExtended() ? 0x00 : 0x80;
@ -137,22 +137,23 @@ __emitinline void xOpWriteC5(u8 prefix, u8 opcode, const T1 &param1, const T2 &p
u8 p = u8 p =
prefix == 0xF2 ? 3 : prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 : prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0; prefix == 0x66 ? 1 :
0;
xWrite8(0xC5); xWrite8(0xC5);
xWrite8(nR | nv | L | p); xWrite8(nR | nv | L | p);
xWrite8(opcode); xWrite8(opcode);
EmitSibMagic(param1, param3); EmitSibMagic(param1, param3);
} }
// VEX 3 Bytes Prefix // VEX 3 Bytes Prefix
template <typename T1, typename T2, typename T3> template <typename T1, typename T2, typename T3>
__emitinline void xOpWriteC4(u8 prefix, u8 mb_prefix, u8 opcode, const T1 &param1, const T2 &param2, const T3 &param3, int w = -1) __emitinline void xOpWriteC4(u8 prefix, u8 mb_prefix, u8 opcode, const T1& param1, const T2& param2, const T3& param3, int w = -1)
{ {
pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2); pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2);
pxAssert(mb_prefix == 0x0F || mb_prefix == 0x38 || mb_prefix == 0x3A); pxAssert(mb_prefix == 0x0F || mb_prefix == 0x38 || mb_prefix == 0x3A);
const xRegisterInt &reg = param1.IsReg() ? param1 : param2; const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __M_X86_64 #ifdef __M_X86_64
u8 nR = reg.IsExtended() ? 0x00 : 0x80; u8 nR = reg.IsExtended() ? 0x00 : 0x80;
@ -172,16 +173,18 @@ __emitinline void xOpWriteC4(u8 prefix, u8 mb_prefix, u8 opcode, const T1 &param
u8 p = u8 p =
prefix == 0xF2 ? 3 : prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 : prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0; prefix == 0x66 ? 1 :
0;
u8 m = u8 m =
mb_prefix == 0x3A ? 3 : mb_prefix == 0x3A ? 3 :
mb_prefix == 0x38 ? 2 : 1; mb_prefix == 0x38 ? 2 :
1;
xWrite8(0xC4); xWrite8(0xC4);
xWrite8(nR | nX | nB | m); xWrite8(nR | nX | nB | m);
xWrite8(W | nv | L | p); xWrite8(W | nv | L | p);
xWrite8(opcode); xWrite8(opcode);
EmitSibMagic(param1, param3); EmitSibMagic(param1, param3);
} }
} } // namespace x86Emitter

View File

@ -33,152 +33,185 @@
namespace x86Emitter namespace x86Emitter
{ {
void xImpl_JmpCall::operator()(const xAddressReg &absreg) const { void xImpl_JmpCall::operator()(const xAddressReg& absreg) const
{
// Jumps are always wide and don't need the rex.W // Jumps are always wide and don't need the rex.W
xOpWrite(0, 0xff, isJmp ? 4 : 2, absreg.GetNonWide()); xOpWrite(0, 0xff, isJmp ? 4 : 2, absreg.GetNonWide());
} }
void xImpl_JmpCall::operator()(const xIndirectNative &src) const { void xImpl_JmpCall::operator()(const xIndirectNative& src) const
{
// Jumps are always wide and don't need the rex.W // Jumps are always wide and don't need the rex.W
EmitRex(0, xIndirect32(src.Base, src.Index, 1, 0)); EmitRex(0, xIndirect32(src.Base, src.Index, 1, 0));
xWrite8(0xff); xWrite8(0xff);
EmitSibMagic(isJmp ? 4 : 2, src); EmitSibMagic(isJmp ? 4 : 2, src);
} }
const xImpl_JmpCall xJMP = {true}; const xImpl_JmpCall xJMP = {true};
const xImpl_JmpCall xCALL = {false}; const xImpl_JmpCall xCALL = {false};
template <typename Reg1, typename Reg2> template <typename Reg1, typename Reg2>
void prepareRegsForFastcall(const Reg1 &a1, const Reg2 &a2) { void prepareRegsForFastcall(const Reg1& a1, const Reg2& a2)
if (a1.IsEmpty()) return; {
if (a1.IsEmpty())
return;
// Make sure we don't mess up if someone tries to fastcall with a1 in arg2reg and a2 in arg1reg // Make sure we don't mess up if someone tries to fastcall with a1 in arg2reg and a2 in arg1reg
if (a2.Id != arg1reg.Id) { if (a2.Id != arg1reg.Id)
{
xMOV(Reg1(arg1reg), a1); xMOV(Reg1(arg1reg), a1);
if (!a2.IsEmpty()) { if (!a2.IsEmpty())
{
xMOV(Reg2(arg2reg), a2); xMOV(Reg2(arg2reg), a2);
} }
} else if (a1.Id != arg2reg.Id) { }
else if (a1.Id != arg2reg.Id)
{
xMOV(Reg2(arg2reg), a2); xMOV(Reg2(arg2reg), a2);
xMOV(Reg1(arg1reg), a1); xMOV(Reg1(arg1reg), a1);
} else { }
else
{
xPUSH(a1); xPUSH(a1);
xMOV(Reg2(arg2reg), a2); xMOV(Reg2(arg2reg), a2);
xPOP(Reg1(arg1reg)); xPOP(Reg1(arg1reg));
} }
} }
void xImpl_FastCall::operator()(void *f, const xRegister32 &a1, const xRegister32 &a2) const { void xImpl_FastCall::operator()(void* f, const xRegister32& a1, const xRegister32& a2) const
{
prepareRegsForFastcall(a1, a2); prepareRegsForFastcall(a1, a2);
uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f; uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f;
if ((sptr)disp == (s32)disp) { if ((sptr)disp == (s32)disp)
{
xCALL(f); xCALL(f);
} else { }
else
{
xMOV(rax, ptrNative[f]); xMOV(rax, ptrNative[f]);
xCALL(rax); xCALL(rax);
} }
} }
#ifdef __M_X86_64 #ifdef __M_X86_64
void xImpl_FastCall::operator()(void *f, const xRegisterLong &a1, const xRegisterLong &a2) const { void xImpl_FastCall::operator()(void* f, const xRegisterLong& a1, const xRegisterLong& a2) const
{
prepareRegsForFastcall(a1, a2); prepareRegsForFastcall(a1, a2);
uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f; uptr disp = ((uptr)xGetPtr() + 5) - (uptr)f;
if ((sptr)disp == (s32)disp) { if ((sptr)disp == (s32)disp)
{
xCALL(f); xCALL(f);
} else { }
else
{
xMOV(rax, ptrNative[f]); xMOV(rax, ptrNative[f]);
xCALL(rax); xCALL(rax);
} }
} }
void xImpl_FastCall::operator()(void *f, u32 a1, const xRegisterLong &a2) const { void xImpl_FastCall::operator()(void* f, u32 a1, const xRegisterLong& a2) const
if (!a2.IsEmpty()) { xMOV(arg2reg, a2); } {
if (!a2.IsEmpty())
{
xMOV(arg2reg, a2);
}
xMOV(arg1reg, a1); xMOV(arg1reg, a1);
(*this)(f, arg1reg, arg2reg); (*this)(f, arg1reg, arg2reg);
} }
#endif #endif
void xImpl_FastCall::operator()(void *f, void *a1) const { void xImpl_FastCall::operator()(void* f, void* a1) const
{
xLEA(arg1reg, ptr[a1]); xLEA(arg1reg, ptr[a1]);
(*this)(f, arg1reg, arg2reg); (*this)(f, arg1reg, arg2reg);
} }
void xImpl_FastCall::operator()(void *f, u32 a1, const xRegister32 &a2) const { void xImpl_FastCall::operator()(void* f, u32 a1, const xRegister32& a2) const
if (!a2.IsEmpty()) { xMOV(arg2regd, a2); } {
if (!a2.IsEmpty())
{
xMOV(arg2regd, a2);
}
xMOV(arg1regd, a1); xMOV(arg1regd, a1);
(*this)(f, arg1regd, arg2regd); (*this)(f, arg1regd, arg2regd);
} }
void xImpl_FastCall::operator()(void *f, const xIndirect32 &a1) const { void xImpl_FastCall::operator()(void* f, const xIndirect32& a1) const
{
xMOV(arg1regd, a1); xMOV(arg1regd, a1);
(*this)(f, arg1regd); (*this)(f, arg1regd);
} }
void xImpl_FastCall::operator()(void *f, u32 a1, u32 a2) const { void xImpl_FastCall::operator()(void* f, u32 a1, u32 a2) const
{
xMOV(arg1regd, a1); xMOV(arg1regd, a1);
xMOV(arg2regd, a2); xMOV(arg2regd, a2);
(*this)(f, arg1regd, arg2regd); (*this)(f, arg1regd, arg2regd);
} }
void xImpl_FastCall::operator()(const xIndirectNative &f, const xRegisterLong &a1, const xRegisterLong &a2) const { void xImpl_FastCall::operator()(const xIndirectNative& f, const xRegisterLong& a1, const xRegisterLong& a2) const
{
prepareRegsForFastcall(a1, a2); prepareRegsForFastcall(a1, a2);
xCALL(f); xCALL(f);
} }
const xImpl_FastCall xFastCall = {}; const xImpl_FastCall xFastCall = {};
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Emits a 32 bit jump, and returns a pointer to the 32 bit displacement. // Emits a 32 bit jump, and returns a pointer to the 32 bit displacement.
// (displacements should be assigned relative to the end of the jump instruction, // (displacements should be assigned relative to the end of the jump instruction,
// or in other words *(retval+1) ) // or in other words *(retval+1) )
__emitinline s32 *xJcc32(JccComparisonType comparison, s32 displacement) __emitinline s32* xJcc32(JccComparisonType comparison, s32 displacement)
{ {
if (comparison == Jcc_Unconditional) if (comparison == Jcc_Unconditional)
xWrite8(0xe9); xWrite8(0xe9);
else { else
{
xWrite8(0x0f); xWrite8(0x0f);
xWrite8(0x80 | comparison); xWrite8(0x80 | comparison);
} }
xWrite<s32>(displacement); xWrite<s32>(displacement);
return ((s32 *)xGetPtr()) - 1; return ((s32*)xGetPtr()) - 1;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Emits a 32 bit jump, and returns a pointer to the 8 bit displacement. // Emits a 32 bit jump, and returns a pointer to the 8 bit displacement.
// (displacements should be assigned relative to the end of the jump instruction, // (displacements should be assigned relative to the end of the jump instruction,
// or in other words *(retval+1) ) // or in other words *(retval+1) )
__emitinline s8 *xJcc8(JccComparisonType comparison, s8 displacement) __emitinline s8* xJcc8(JccComparisonType comparison, s8 displacement)
{ {
xWrite8((comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison)); xWrite8((comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison));
xWrite<s8>(displacement); xWrite<s8>(displacement);
return (s8 *)xGetPtr() - 1; return (s8*)xGetPtr() - 1;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Writes a jump at the current x86Ptr, which targets a pre-established target address. // Writes a jump at the current x86Ptr, which targets a pre-established target address.
// (usually a backwards jump) // (usually a backwards jump)
// //
// slideForward - used internally by xSmartJump to indicate that the jump target is going // slideForward - used internally by xSmartJump to indicate that the jump target is going
// to slide forward in the event of an 8 bit displacement. // to slide forward in the event of an 8 bit displacement.
// //
__emitinline void xJccKnownTarget(JccComparisonType comparison, const void *target, bool slideForward) __emitinline void xJccKnownTarget(JccComparisonType comparison, const void* target, bool slideForward)
{ {
// Calculate the potential j8 displacement first, assuming an instruction length of 2: // Calculate the potential j8 displacement first, assuming an instruction length of 2:
sptr displacement8 = (sptr)target - (sptr)(xGetPtr() + 2); sptr displacement8 = (sptr)target - (sptr)(xGetPtr() + 2);
const int slideVal = slideForward ? ((comparison == Jcc_Unconditional) ? 3 : 4) : 0; const int slideVal = slideForward ? ((comparison == Jcc_Unconditional) ? 3 : 4) : 0;
displacement8 -= slideVal; displacement8 -= slideVal;
if (slideForward) { if (slideForward)
{
pxAssertDev(displacement8 >= 0, "Used slideForward on a backward jump; nothing to slide!"); pxAssertDev(displacement8 >= 0, "Used slideForward on a backward jump; nothing to slide!");
} }
if (is_s8(displacement8)) if (is_s8(displacement8))
xJcc8(comparison, displacement8); xJcc8(comparison, displacement8);
else { else
{
// Perform a 32 bit jump instead. :( // Perform a 32 bit jump instead. :(
s32 *bah = xJcc32(comparison); s32* bah = xJcc32(comparison);
sptr distance = (sptr)target - (sptr)xGetPtr(); sptr distance = (sptr)target - (sptr)xGetPtr();
#ifdef __M_X86_64 #ifdef __M_X86_64
@ -188,60 +221,65 @@ __emitinline void xJccKnownTarget(JccComparisonType comparison, const void *targ
*bah = (s32)distance; *bah = (s32)distance;
} }
} }
// Low-level jump instruction! Specify a comparison type and a target in void* form, and // Low-level jump instruction! Specify a comparison type and a target in void* form, and
// a jump (either 8 or 32 bit) is generated. // a jump (either 8 or 32 bit) is generated.
__emitinline void xJcc(JccComparisonType comparison, const void *target) __emitinline void xJcc(JccComparisonType comparison, const void* target)
{ {
xJccKnownTarget(comparison, target, false); xJccKnownTarget(comparison, target, false);
} }
xForwardJumpBase::xForwardJumpBase(uint opsize, JccComparisonType cctype) xForwardJumpBase::xForwardJumpBase(uint opsize, JccComparisonType cctype)
{ {
pxAssert(opsize == 1 || opsize == 4); pxAssert(opsize == 1 || opsize == 4);
pxAssertDev(cctype != Jcc_Unknown, "Invalid ForwardJump conditional type."); pxAssertDev(cctype != Jcc_Unknown, "Invalid ForwardJump conditional type.");
BasePtr = (s8 *)xGetPtr() + BasePtr = (s8*)xGetPtr() +
((opsize == 1) ? 2 : // j8's are always 2 bytes. ((opsize == 1) ? 2 : // j8's are always 2 bytes.
((cctype == Jcc_Unconditional) ? 5 : 6)); // j32's are either 5 or 6 bytes ((cctype == Jcc_Unconditional) ? 5 : 6)); // j32's are either 5 or 6 bytes
if (opsize == 1) if (opsize == 1)
xWrite8((cctype == Jcc_Unconditional) ? 0xeb : (0x70 | cctype)); xWrite8((cctype == Jcc_Unconditional) ? 0xeb : (0x70 | cctype));
else { else
{
if (cctype == Jcc_Unconditional) if (cctype == Jcc_Unconditional)
xWrite8(0xe9); xWrite8(0xe9);
else { else
{
xWrite8(0x0f); xWrite8(0x0f);
xWrite8(0x80 | cctype); xWrite8(0x80 | cctype);
} }
} }
xAdvancePtr(opsize); xAdvancePtr(opsize);
} }
void xForwardJumpBase::_setTarget(uint opsize) const void xForwardJumpBase::_setTarget(uint opsize) const
{ {
pxAssertDev(BasePtr != NULL, ""); pxAssertDev(BasePtr != NULL, "");
sptr displacement = (sptr)xGetPtr() - (sptr)BasePtr; sptr displacement = (sptr)xGetPtr() - (sptr)BasePtr;
if (opsize == 1) { if (opsize == 1)
{
pxAssertDev(is_s8(displacement), "Emitter Error: Invalid short jump displacement."); pxAssertDev(is_s8(displacement), "Emitter Error: Invalid short jump displacement.");
BasePtr[-1] = (s8)displacement; BasePtr[-1] = (s8)displacement;
} else {
// full displacement, no sanity checks needed :D
((s32 *)BasePtr)[-1] = displacement;
} }
} else
{
// full displacement, no sanity checks needed :D
((s32*)BasePtr)[-1] = displacement;
}
}
// returns the inverted conditional type for this Jcc condition. Ie, JNS will become JS. // returns the inverted conditional type for this Jcc condition. Ie, JNS will become JS.
__fi JccComparisonType xInvertCond(JccComparisonType src) __fi JccComparisonType xInvertCond(JccComparisonType src)
{ {
pxAssert(src != Jcc_Unknown); pxAssert(src != Jcc_Unknown);
if (Jcc_Unconditional == src) if (Jcc_Unconditional == src)
return Jcc_Unconditional; return Jcc_Unconditional;
// x86 conditionals are clever! To invert conditional types, just invert the lower bit: // x86 conditionals are clever! To invert conditional types, just invert the lower bit:
return (JccComparisonType)((int)src ^ 1); return (JccComparisonType)((int)src ^ 1);
} }
} } // namespace x86Emitter

View File

@ -57,31 +57,31 @@ using namespace x86Emitter;
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
emitterT u8 *J8Rel(int cc, int to) emitterT u8* J8Rel(int cc, int to)
{ {
xWrite8(cc); xWrite8(cc);
xWrite8(to); xWrite8(to);
return (u8 *)(x86Ptr - 1); return (u8*)(x86Ptr - 1);
} }
emitterT u16 *J16Rel(int cc, u32 to) emitterT u16* J16Rel(int cc, u32 to)
{ {
xWrite16(0x0F66); xWrite16(0x0F66);
xWrite8(cc); xWrite8(cc);
xWrite16(to); xWrite16(to);
return (u16 *)(x86Ptr - 2); return (u16*)(x86Ptr - 2);
} }
emitterT u32 *J32Rel(int cc, u32 to) emitterT u32* J32Rel(int cc, u32 to)
{ {
xWrite8(0x0F); xWrite8(0x0F);
xWrite8(cc); xWrite8(cc);
xWrite32(to); xWrite32(to);
return (u32 *)(x86Ptr - 4); return (u32*)(x86Ptr - 4);
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
emitterT void x86SetPtr(u8 *ptr) emitterT void x86SetPtr(u8* ptr)
{ {
x86Ptr = ptr; x86Ptr = ptr;
} }
@ -92,31 +92,35 @@ emitterT void x86SetPtr(u8 *ptr)
// I don't auto-inline these because of the console logging in case of error, which tends // I don't auto-inline these because of the console logging in case of error, which tends
// to cause quite a bit of code bloat. // to cause quite a bit of code bloat.
// //
void x86SetJ8(u8 *j8) void x86SetJ8(u8* j8)
{ {
u32 jump = (x86Ptr - j8) - 1; u32 jump = (x86Ptr - j8) - 1;
if (jump > 0x7f) { if (jump > 0x7f)
{
Console.Error("j8 greater than 0x7f!!"); Console.Error("j8 greater than 0x7f!!");
assert(0); assert(0);
} }
*j8 = (u8)jump; *j8 = (u8)jump;
} }
void x86SetJ8A(u8 *j8) void x86SetJ8A(u8* j8)
{ {
u32 jump = (x86Ptr - j8) - 1; u32 jump = (x86Ptr - j8) - 1;
if (jump > 0x7f) { if (jump > 0x7f)
{
Console.Error("j8 greater than 0x7f!!"); Console.Error("j8 greater than 0x7f!!");
assert(0); assert(0);
} }
if (((uptr)x86Ptr & 0xf) > 4) { if (((uptr)x86Ptr & 0xf) > 4)
{
uptr newjump = jump + 16 - ((uptr)x86Ptr & 0xf); uptr newjump = jump + 16 - ((uptr)x86Ptr & 0xf);
if (newjump <= 0x7f) { if (newjump <= 0x7f)
{
jump = newjump; jump = newjump;
while ((uptr)x86Ptr & 0xf) while ((uptr)x86Ptr & 0xf)
*x86Ptr++ = 0x90; *x86Ptr++ = 0x90;
@ -126,12 +130,12 @@ void x86SetJ8A(u8 *j8)
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
emitterT void x86SetJ32(u32 *j32) emitterT void x86SetJ32(u32* j32)
{ {
*j32 = (x86Ptr - (u8 *)j32) - 4; *j32 = (x86Ptr - (u8*)j32) - 4;
} }
emitterT void x86SetJ32A(u32 *j32) emitterT void x86SetJ32A(u32* j32)
{ {
while ((uptr)x86Ptr & 0xf) while ((uptr)x86Ptr & 0xf)
*x86Ptr++ = 0x90; *x86Ptr++ = 0x90;
@ -142,7 +146,7 @@ emitterT void x86SetJ32A(u32 *j32)
emitterT void x86Align(int bytes) emitterT void x86Align(int bytes)
{ {
// forward align // forward align
x86Ptr = (u8 *)(((uptr)x86Ptr + bytes - 1) & ~(bytes - 1)); x86Ptr = (u8*)(((uptr)x86Ptr + bytes - 1) & ~(bytes - 1));
} }
/********************/ /********************/
@ -154,7 +158,7 @@ emitterT void x86Align(int bytes)
//////////////////////////////////// ////////////////////////////////////
/* jmp rel8 */ /* jmp rel8 */
emitterT u8 *JMP8(u8 to) emitterT u8* JMP8(u8 to)
{ {
xWrite8(0xEB); xWrite8(0xEB);
xWrite8(to); xWrite8(to);
@ -162,254 +166,254 @@ emitterT u8 *JMP8(u8 to)
} }
/* jmp rel32 */ /* jmp rel32 */
emitterT u32 *JMP32(uptr to) emitterT u32* JMP32(uptr to)
{ {
assert((sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff); assert((sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff);
xWrite8(0xE9); xWrite8(0xE9);
xWrite32(to); xWrite32(to);
return (u32 *)(x86Ptr - 4); return (u32*)(x86Ptr - 4);
} }
/* jp rel8 */ /* jp rel8 */
emitterT u8 *JP8(u8 to) emitterT u8* JP8(u8 to)
{ {
return J8Rel(0x7A, to); return J8Rel(0x7A, to);
} }
/* jnp rel8 */ /* jnp rel8 */
emitterT u8 *JNP8(u8 to) emitterT u8* JNP8(u8 to)
{ {
return J8Rel(0x7B, to); return J8Rel(0x7B, to);
} }
/* je rel8 */ /* je rel8 */
emitterT u8 *JE8(u8 to) emitterT u8* JE8(u8 to)
{ {
return J8Rel(0x74, to); return J8Rel(0x74, to);
} }
/* jz rel8 */ /* jz rel8 */
emitterT u8 *JZ8(u8 to) emitterT u8* JZ8(u8 to)
{ {
return J8Rel(0x74, to); return J8Rel(0x74, to);
} }
/* js rel8 */ /* js rel8 */
emitterT u8 *JS8(u8 to) emitterT u8* JS8(u8 to)
{ {
return J8Rel(0x78, to); return J8Rel(0x78, to);
} }
/* jns rel8 */ /* jns rel8 */
emitterT u8 *JNS8(u8 to) emitterT u8* JNS8(u8 to)
{ {
return J8Rel(0x79, to); return J8Rel(0x79, to);
} }
/* jg rel8 */ /* jg rel8 */
emitterT u8 *JG8(u8 to) emitterT u8* JG8(u8 to)
{ {
return J8Rel(0x7F, to); return J8Rel(0x7F, to);
} }
/* jge rel8 */ /* jge rel8 */
emitterT u8 *JGE8(u8 to) emitterT u8* JGE8(u8 to)
{ {
return J8Rel(0x7D, to); return J8Rel(0x7D, to);
} }
/* jl rel8 */ /* jl rel8 */
emitterT u8 *JL8(u8 to) emitterT u8* JL8(u8 to)
{ {
return J8Rel(0x7C, to); return J8Rel(0x7C, to);
} }
/* ja rel8 */ /* ja rel8 */
emitterT u8 *JA8(u8 to) emitterT u8* JA8(u8 to)
{ {
return J8Rel(0x77, to); return J8Rel(0x77, to);
} }
emitterT u8 *JAE8(u8 to) emitterT u8* JAE8(u8 to)
{ {
return J8Rel(0x73, to); return J8Rel(0x73, to);
} }
/* jb rel8 */ /* jb rel8 */
emitterT u8 *JB8(u8 to) emitterT u8* JB8(u8 to)
{ {
return J8Rel(0x72, to); return J8Rel(0x72, to);
} }
/* jbe rel8 */ /* jbe rel8 */
emitterT u8 *JBE8(u8 to) emitterT u8* JBE8(u8 to)
{ {
return J8Rel(0x76, to); return J8Rel(0x76, to);
} }
/* jle rel8 */ /* jle rel8 */
emitterT u8 *JLE8(u8 to) emitterT u8* JLE8(u8 to)
{ {
return J8Rel(0x7E, to); return J8Rel(0x7E, to);
} }
/* jne rel8 */ /* jne rel8 */
emitterT u8 *JNE8(u8 to) emitterT u8* JNE8(u8 to)
{ {
return J8Rel(0x75, to); return J8Rel(0x75, to);
} }
/* jnz rel8 */ /* jnz rel8 */
emitterT u8 *JNZ8(u8 to) emitterT u8* JNZ8(u8 to)
{ {
return J8Rel(0x75, to); return J8Rel(0x75, to);
} }
/* jng rel8 */ /* jng rel8 */
emitterT u8 *JNG8(u8 to) emitterT u8* JNG8(u8 to)
{ {
return J8Rel(0x7E, to); return J8Rel(0x7E, to);
} }
/* jnge rel8 */ /* jnge rel8 */
emitterT u8 *JNGE8(u8 to) emitterT u8* JNGE8(u8 to)
{ {
return J8Rel(0x7C, to); return J8Rel(0x7C, to);
} }
/* jnl rel8 */ /* jnl rel8 */
emitterT u8 *JNL8(u8 to) emitterT u8* JNL8(u8 to)
{ {
return J8Rel(0x7D, to); return J8Rel(0x7D, to);
} }
/* jnle rel8 */ /* jnle rel8 */
emitterT u8 *JNLE8(u8 to) emitterT u8* JNLE8(u8 to)
{ {
return J8Rel(0x7F, to); return J8Rel(0x7F, to);
} }
/* jo rel8 */ /* jo rel8 */
emitterT u8 *JO8(u8 to) emitterT u8* JO8(u8 to)
{ {
return J8Rel(0x70, to); return J8Rel(0x70, to);
} }
/* jno rel8 */ /* jno rel8 */
emitterT u8 *JNO8(u8 to) emitterT u8* JNO8(u8 to)
{ {
return J8Rel(0x71, to); return J8Rel(0x71, to);
} }
// jb rel32 // jb rel32
emitterT u32 *JB32(u32 to) emitterT u32* JB32(u32 to)
{ {
return J32Rel(0x82, to); return J32Rel(0x82, to);
} }
/* je rel32 */ /* je rel32 */
emitterT u32 *JE32(u32 to) emitterT u32* JE32(u32 to)
{ {
return J32Rel(0x84, to); return J32Rel(0x84, to);
} }
/* jz rel32 */ /* jz rel32 */
emitterT u32 *JZ32(u32 to) emitterT u32* JZ32(u32 to)
{ {
return J32Rel(0x84, to); return J32Rel(0x84, to);
} }
/* js rel32 */ /* js rel32 */
emitterT u32 *JS32(u32 to) emitterT u32* JS32(u32 to)
{ {
return J32Rel(0x88, to); return J32Rel(0x88, to);
} }
/* jns rel32 */ /* jns rel32 */
emitterT u32 *JNS32(u32 to) emitterT u32* JNS32(u32 to)
{ {
return J32Rel(0x89, to); return J32Rel(0x89, to);
} }
/* jg rel32 */ /* jg rel32 */
emitterT u32 *JG32(u32 to) emitterT u32* JG32(u32 to)
{ {
return J32Rel(0x8F, to); return J32Rel(0x8F, to);
} }
/* jge rel32 */ /* jge rel32 */
emitterT u32 *JGE32(u32 to) emitterT u32* JGE32(u32 to)
{ {
return J32Rel(0x8D, to); return J32Rel(0x8D, to);
} }
/* jl rel32 */ /* jl rel32 */
emitterT u32 *JL32(u32 to) emitterT u32* JL32(u32 to)
{ {
return J32Rel(0x8C, to); return J32Rel(0x8C, to);
} }
/* jle rel32 */ /* jle rel32 */
emitterT u32 *JLE32(u32 to) emitterT u32* JLE32(u32 to)
{ {
return J32Rel(0x8E, to); return J32Rel(0x8E, to);
} }
/* ja rel32 */ /* ja rel32 */
emitterT u32 *JA32(u32 to) emitterT u32* JA32(u32 to)
{ {
return J32Rel(0x87, to); return J32Rel(0x87, to);
} }
/* jae rel32 */ /* jae rel32 */
emitterT u32 *JAE32(u32 to) emitterT u32* JAE32(u32 to)
{ {
return J32Rel(0x83, to); return J32Rel(0x83, to);
} }
/* jne rel32 */ /* jne rel32 */
emitterT u32 *JNE32(u32 to) emitterT u32* JNE32(u32 to)
{ {
return J32Rel(0x85, to); return J32Rel(0x85, to);
} }
/* jnz rel32 */ /* jnz rel32 */
emitterT u32 *JNZ32(u32 to) emitterT u32* JNZ32(u32 to)
{ {
return J32Rel(0x85, to); return J32Rel(0x85, to);
} }
/* jng rel32 */ /* jng rel32 */
emitterT u32 *JNG32(u32 to) emitterT u32* JNG32(u32 to)
{ {
return J32Rel(0x8E, to); return J32Rel(0x8E, to);
} }
/* jnge rel32 */ /* jnge rel32 */
emitterT u32 *JNGE32(u32 to) emitterT u32* JNGE32(u32 to)
{ {
return J32Rel(0x8C, to); return J32Rel(0x8C, to);
} }
/* jnl rel32 */ /* jnl rel32 */
emitterT u32 *JNL32(u32 to) emitterT u32* JNL32(u32 to)
{ {
return J32Rel(0x8D, to); return J32Rel(0x8D, to);
} }
/* jnle rel32 */ /* jnle rel32 */
emitterT u32 *JNLE32(u32 to) emitterT u32* JNLE32(u32 to)
{ {
return J32Rel(0x8F, to); return J32Rel(0x8F, to);
} }
/* jo rel32 */ /* jo rel32 */
emitterT u32 *JO32(u32 to) emitterT u32* JO32(u32 to)
{ {
return J32Rel(0x80, to); return J32Rel(0x80, to);
} }
/* jno rel32 */ /* jno rel32 */
emitterT u32 *JNO32(u32 to) emitterT u32* JNO32(u32 to)
{ {
return J32Rel(0x81, to); return J32Rel(0x81, to);
} }

View File

@ -25,13 +25,13 @@
//------------------------------------------------------------------ //------------------------------------------------------------------
// legacy jump/align functions // legacy jump/align functions
//------------------------------------------------------------------ //------------------------------------------------------------------
ATTR_DEP extern void x86SetPtr(u8 *ptr); ATTR_DEP extern void x86SetPtr(u8* ptr);
ATTR_DEP extern void x86SetJ8(u8 *j8); ATTR_DEP extern void x86SetJ8(u8* j8);
ATTR_DEP extern void x86SetJ8A(u8 *j8); ATTR_DEP extern void x86SetJ8A(u8* j8);
ATTR_DEP extern void x86SetJ16(u16 *j16); ATTR_DEP extern void x86SetJ16(u16* j16);
ATTR_DEP extern void x86SetJ16A(u16 *j16); ATTR_DEP extern void x86SetJ16A(u16* j16);
ATTR_DEP extern void x86SetJ32(u32 *j32); ATTR_DEP extern void x86SetJ32(u32* j32);
ATTR_DEP extern void x86SetJ32A(u32 *j32); ATTR_DEP extern void x86SetJ32A(u32* j32);
ATTR_DEP extern void x86Align(int bytes); ATTR_DEP extern void x86Align(int bytes);
ATTR_DEP extern void x86AlignExecutable(int align); ATTR_DEP extern void x86AlignExecutable(int align);
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -41,55 +41,55 @@ ATTR_DEP extern void x86AlignExecutable(int align);
//////////////////////////////////// ////////////////////////////////////
// jmp rel8 // jmp rel8
ATTR_DEP extern u8 *JMP8(u8 to); ATTR_DEP extern u8* JMP8(u8 to);
// jmp rel32 // jmp rel32
ATTR_DEP extern u32 *JMP32(uptr to); ATTR_DEP extern u32* JMP32(uptr to);
// jp rel8 // jp rel8
ATTR_DEP extern u8 *JP8(u8 to); ATTR_DEP extern u8* JP8(u8 to);
// jnp rel8 // jnp rel8
ATTR_DEP extern u8 *JNP8(u8 to); ATTR_DEP extern u8* JNP8(u8 to);
// je rel8 // je rel8
ATTR_DEP extern u8 *JE8(u8 to); ATTR_DEP extern u8* JE8(u8 to);
// jz rel8 // jz rel8
ATTR_DEP extern u8 *JZ8(u8 to); ATTR_DEP extern u8* JZ8(u8 to);
// jg rel8 // jg rel8
ATTR_DEP extern u8 *JG8(u8 to); ATTR_DEP extern u8* JG8(u8 to);
// jge rel8 // jge rel8
ATTR_DEP extern u8 *JGE8(u8 to); ATTR_DEP extern u8* JGE8(u8 to);
// js rel8 // js rel8
ATTR_DEP extern u8 *JS8(u8 to); ATTR_DEP extern u8* JS8(u8 to);
// jns rel8 // jns rel8
ATTR_DEP extern u8 *JNS8(u8 to); ATTR_DEP extern u8* JNS8(u8 to);
// jl rel8 // jl rel8
ATTR_DEP extern u8 *JL8(u8 to); ATTR_DEP extern u8* JL8(u8 to);
// ja rel8 // ja rel8
ATTR_DEP extern u8 *JA8(u8 to); ATTR_DEP extern u8* JA8(u8 to);
// jae rel8 // jae rel8
ATTR_DEP extern u8 *JAE8(u8 to); ATTR_DEP extern u8* JAE8(u8 to);
// jb rel8 // jb rel8
ATTR_DEP extern u8 *JB8(u8 to); ATTR_DEP extern u8* JB8(u8 to);
// jbe rel8 // jbe rel8
ATTR_DEP extern u8 *JBE8(u8 to); ATTR_DEP extern u8* JBE8(u8 to);
// jle rel8 // jle rel8
ATTR_DEP extern u8 *JLE8(u8 to); ATTR_DEP extern u8* JLE8(u8 to);
// jne rel8 // jne rel8
ATTR_DEP extern u8 *JNE8(u8 to); ATTR_DEP extern u8* JNE8(u8 to);
// jnz rel8 // jnz rel8
ATTR_DEP extern u8 *JNZ8(u8 to); ATTR_DEP extern u8* JNZ8(u8 to);
// jng rel8 // jng rel8
ATTR_DEP extern u8 *JNG8(u8 to); ATTR_DEP extern u8* JNG8(u8 to);
// jnge rel8 // jnge rel8
ATTR_DEP extern u8 *JNGE8(u8 to); ATTR_DEP extern u8* JNGE8(u8 to);
// jnl rel8 // jnl rel8
ATTR_DEP extern u8 *JNL8(u8 to); ATTR_DEP extern u8* JNL8(u8 to);
// jnle rel8 // jnle rel8
ATTR_DEP extern u8 *JNLE8(u8 to); ATTR_DEP extern u8* JNLE8(u8 to);
// jo rel8 // jo rel8
ATTR_DEP extern u8 *JO8(u8 to); ATTR_DEP extern u8* JO8(u8 to);
// jno rel8 // jno rel8
ATTR_DEP extern u8 *JNO8(u8 to); ATTR_DEP extern u8* JNO8(u8 to);
/* /*
// jb rel16 // jb rel16
@ -103,44 +103,44 @@ ATTR_DEP extern u16* JZ16( u16 to );
*/ */
// jns rel32 // jns rel32
ATTR_DEP extern u32 *JNS32(u32 to); ATTR_DEP extern u32* JNS32(u32 to);
// js rel32 // js rel32
ATTR_DEP extern u32 *JS32(u32 to); ATTR_DEP extern u32* JS32(u32 to);
// jb rel32 // jb rel32
ATTR_DEP extern u32 *JB32(u32 to); ATTR_DEP extern u32* JB32(u32 to);
// je rel32 // je rel32
ATTR_DEP extern u32 *JE32(u32 to); ATTR_DEP extern u32* JE32(u32 to);
// jz rel32 // jz rel32
ATTR_DEP extern u32 *JZ32(u32 to); ATTR_DEP extern u32* JZ32(u32 to);
// jg rel32 // jg rel32
ATTR_DEP extern u32 *JG32(u32 to); ATTR_DEP extern u32* JG32(u32 to);
// jge rel32 // jge rel32
ATTR_DEP extern u32 *JGE32(u32 to); ATTR_DEP extern u32* JGE32(u32 to);
// jl rel32 // jl rel32
ATTR_DEP extern u32 *JL32(u32 to); ATTR_DEP extern u32* JL32(u32 to);
// jle rel32 // jle rel32
ATTR_DEP extern u32 *JLE32(u32 to); ATTR_DEP extern u32* JLE32(u32 to);
// jae rel32 // jae rel32
ATTR_DEP extern u32 *JAE32(u32 to); ATTR_DEP extern u32* JAE32(u32 to);
// jne rel32 // jne rel32
ATTR_DEP extern u32 *JNE32(u32 to); ATTR_DEP extern u32* JNE32(u32 to);
// jnz rel32 // jnz rel32
ATTR_DEP extern u32 *JNZ32(u32 to); ATTR_DEP extern u32* JNZ32(u32 to);
// jng rel32 // jng rel32
ATTR_DEP extern u32 *JNG32(u32 to); ATTR_DEP extern u32* JNG32(u32 to);
// jnge rel32 // jnge rel32
ATTR_DEP extern u32 *JNGE32(u32 to); ATTR_DEP extern u32* JNGE32(u32 to);
// jnl rel32 // jnl rel32
ATTR_DEP extern u32 *JNL32(u32 to); ATTR_DEP extern u32* JNL32(u32 to);
// jnle rel32 // jnle rel32
ATTR_DEP extern u32 *JNLE32(u32 to); ATTR_DEP extern u32* JNLE32(u32 to);
// jo rel32 // jo rel32
ATTR_DEP extern u32 *JO32(u32 to); ATTR_DEP extern u32* JO32(u32 to);
// jno rel32 // jno rel32
ATTR_DEP extern u32 *JNO32(u32 to); ATTR_DEP extern u32* JNO32(u32 to);
// js rel32 // js rel32
ATTR_DEP extern u32 *JS32(u32 to); ATTR_DEP extern u32* JS32(u32 to);
//****************** //******************
// FPU instructions // FPU instructions

View File

@ -36,5 +36,5 @@ using x86Emitter::xWrite64;
extern void ModRM(uint mod, uint reg, uint rm); extern void ModRM(uint mod, uint reg, uint rm);
extern void SibSB(uint ss, uint index, uint base); extern void SibSB(uint ss, uint index, uint base);
extern void SET8R(int cc, int to); extern void SET8R(int cc, int to);
extern u8 *J8Rel(int cc, int to); extern u8* J8Rel(int cc, int to);
extern u32 *J32Rel(int cc, u32 to); extern u32* J32Rel(int cc, u32 to);

View File

@ -34,59 +34,64 @@
namespace x86Emitter namespace x86Emitter
{ {
void _xMovRtoR(const xRegisterInt &to, const xRegisterInt &from) void _xMovRtoR(const xRegisterInt& to, const xRegisterInt& from)
{ {
pxAssert(to.GetOperandSize() == from.GetOperandSize()); pxAssert(to.GetOperandSize() == from.GetOperandSize());
if (to == from) if (to == from)
return; // ignore redundant MOVs. return; // ignore redundant MOVs.
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, to); xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, to);
} }
void xImpl_Mov::operator()(const xRegisterInt &to, const xRegisterInt &from) const void xImpl_Mov::operator()(const xRegisterInt& to, const xRegisterInt& from) const
{ {
// FIXME WTF? // FIXME WTF?
_xMovRtoR(to, from); _xMovRtoR(to, from);
} }
void xImpl_Mov::operator()(const xIndirectVoid &dest, const xRegisterInt &from) const void xImpl_Mov::operator()(const xIndirectVoid& dest, const xRegisterInt& from) const
{ {
// mov eax has a special from when writing directly to a DISP32 address // mov eax has a special from when writing directly to a DISP32 address
// (sans any register index/base registers). // (sans any register index/base registers).
#ifndef __M_X86_64 #ifndef __M_X86_64
// Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr // Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr
if (from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty()) { if (from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty())
{
xOpAccWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xa2 : 0xa3, from, dest); xOpAccWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xa2 : 0xa3, from, dest);
xWrite32(dest.Displacement); xWrite32(dest.Displacement);
} else }
else
#endif #endif
{ {
xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest); xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0x88 : 0x89, from, dest);
} }
} }
void xImpl_Mov::operator()(const xRegisterInt &to, const xIndirectVoid &src) const void xImpl_Mov::operator()(const xRegisterInt& to, const xIndirectVoid& src) const
{ {
// mov eax has a special from when reading directly from a DISP32 address // mov eax has a special from when reading directly from a DISP32 address
// (sans any register index/base registers). // (sans any register index/base registers).
#ifndef __M_X86_64 #ifndef __M_X86_64
// Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr // Note: On x86-64 this is an immediate 64-bit address, which is larger than the equivalent rip offset instr
if (to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty()) { if (to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty())
{
xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa0 : 0xa1, to, src); xOpAccWrite(to.GetPrefix16(), to.Is8BitOp() ? 0xa0 : 0xa1, to, src);
xWrite32(src.Displacement); xWrite32(src.Displacement);
} else }
else
#endif #endif
{ {
xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src); xOpWrite(to.GetPrefix16(), to.Is8BitOp() ? 0x8a : 0x8b, to, src);
} }
} }
void xImpl_Mov::operator()(const xIndirect64orLess &dest, sptr imm) const void xImpl_Mov::operator()(const xIndirect64orLess& dest, sptr imm) const
{ {
switch (dest.GetOperandSize()) { switch (dest.GetOperandSize())
{
case 1: case 1:
pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!"); pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!");
break; break;
@ -104,13 +109,14 @@ void xImpl_Mov::operator()(const xIndirect64orLess &dest, sptr imm) const
} }
xOpWrite(dest.GetPrefix16(), dest.Is8BitOp() ? 0xc6 : 0xc7, 0, dest, dest.GetImmSize()); xOpWrite(dest.GetPrefix16(), dest.Is8BitOp() ? 0xc6 : 0xc7, 0, dest, dest.GetImmSize());
dest.xWriteImm(imm); dest.xWriteImm(imm);
} }
// preserve_flags - set to true to disable optimizations which could alter the state of // preserve_flags - set to true to disable optimizations which could alter the state of
// the flags (namely replacing mov reg,0 with xor). // the flags (namely replacing mov reg,0 with xor).
void xImpl_Mov::operator()(const xRegisterInt &to, sptr imm, bool preserve_flags) const void xImpl_Mov::operator()(const xRegisterInt& to, sptr imm, bool preserve_flags) const
{ {
switch (to.GetOperandSize()) { switch (to.GetOperandSize())
{
case 1: case 1:
pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!"); pxAssertMsg(imm == (s8)imm || imm == (u8)imm, "Immediate won't fit!");
break; break;
@ -127,39 +133,47 @@ void xImpl_Mov::operator()(const xRegisterInt &to, sptr imm, bool preserve_flags
pxAssertMsg(0, "Bad indirect size!"); pxAssertMsg(0, "Bad indirect size!");
} }
const xRegisterInt& to_ = to.GetNonWide(); const xRegisterInt& to_ = to.GetNonWide();
if (!preserve_flags && (imm == 0)) { if (!preserve_flags && (imm == 0))
{
_g1_EmitOp(G1Type_XOR, to_, to_); _g1_EmitOp(G1Type_XOR, to_, to_);
} else if (imm == (u32)imm || !to.IsWide()) { }
else if (imm == (u32)imm || !to.IsWide())
{
// Note: MOV does not have (reg16/32,imm8) forms. // Note: MOV does not have (reg16/32,imm8) forms.
u8 opcode = (to_.Is8BitOp() ? 0xb0 : 0xb8) | to_.Id; u8 opcode = (to_.Is8BitOp() ? 0xb0 : 0xb8) | to_.Id;
xOpAccWrite(to_.GetPrefix16(), opcode, 0, to_); xOpAccWrite(to_.GetPrefix16(), opcode, 0, to_);
to_.xWriteImm(imm); to_.xWriteImm(imm);
} else { }
else
{
xOpWrite(to.GetPrefix16(), 0xc7, 0, to); xOpWrite(to.GetPrefix16(), 0xc7, 0, to);
to.xWriteImm(imm); to.xWriteImm(imm);
} }
} }
const xImpl_Mov xMOV; const xImpl_Mov xMOV;
#ifdef __M_X86_64 #ifdef __M_X86_64
void xImpl_MovImm64::operator()(const xRegister64& to, s64 imm, bool preserve_flags) const void xImpl_MovImm64::operator()(const xRegister64& to, s64 imm, bool preserve_flags) const
{ {
if (imm == (u32)imm || imm == (s32)imm) { if (imm == (u32)imm || imm == (s32)imm)
{
xMOV(to, imm, preserve_flags); xMOV(to, imm, preserve_flags);
} else { }
else
{
u8 opcode = 0xb8 | to.Id; u8 opcode = 0xb8 | to.Id;
xOpAccWrite(to.GetPrefix16(), opcode, 0, to); xOpAccWrite(to.GetPrefix16(), opcode, 0, to);
xWrite64(imm); xWrite64(imm);
} }
} }
const xImpl_MovImm64 xMOV64; const xImpl_MovImm64 xMOV64;
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// CMOVcc // CMOVcc
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#define ccSane() pxAssertDev(ccType >= 0 && ccType <= 0x0f, "Invalid comparison type specifier.") #define ccSane() pxAssertDev(ccType >= 0 && ccType <= 0x0f, "Invalid comparison type specifier.")
@ -169,63 +183,63 @@ const xImpl_MovImm64 xMOV64;
void xImpl_CMov::operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const void xImpl_CMov::operator()(const xRegister16or32or64& to, const xRegister16or32or64& from) const
{ {
pxAssert(to->GetOperandSize() == from->GetOperandSize()); pxAssert(to->GetOperandSize() == from->GetOperandSize());
ccSane(); ccSane();
xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, from); xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, from);
} }
void xImpl_CMov::operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const void xImpl_CMov::operator()(const xRegister16or32or64& to, const xIndirectVoid& sibsrc) const
{ {
ccSane(); ccSane();
xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, sibsrc); xOpWrite0F(to->GetPrefix16(), 0x40 | ccType, to, sibsrc);
} }
//void xImpl_CMov::operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } //void xImpl_CMov::operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
//void xImpl_CMov::operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } //void xImpl_CMov::operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
void xImpl_Set::operator()(const xRegister8 &to) const void xImpl_Set::operator()(const xRegister8& to) const
{ {
ccSane(); ccSane();
xOpWrite0F(0x90 | ccType, 0, to); xOpWrite0F(0x90 | ccType, 0, to);
} }
void xImpl_Set::operator()(const xIndirect8 &dest) const void xImpl_Set::operator()(const xIndirect8& dest) const
{ {
ccSane(); ccSane();
xOpWrite0F(0x90 | ccType, 0, dest); xOpWrite0F(0x90 | ccType, 0, dest);
} }
//void xImpl_Set::operator()( const xDirectOrIndirect8& dest ) const { ccSane(); _DoI_helpermess( *this, dest ); } //void xImpl_Set::operator()( const xDirectOrIndirect8& dest ) const { ccSane(); _DoI_helpermess( *this, dest ); }
void xImpl_MovExtend::operator()(const xRegister16or32or64 &to, const xRegister8 &from) const void xImpl_MovExtend::operator()(const xRegister16or32or64& to, const xRegister8& from) const
{ {
EbpAssert(); EbpAssert();
xOpWrite0F( xOpWrite0F(
(to->GetOperandSize() == 2) ? 0x66 : 0, (to->GetOperandSize() == 2) ? 0x66 : 0,
SignExtend ? 0xbe : 0xb6, SignExtend ? 0xbe : 0xb6,
to, from); to, from);
} }
void xImpl_MovExtend::operator()(const xRegister16or32or64 &to, const xIndirect8 &sibsrc) const void xImpl_MovExtend::operator()(const xRegister16or32or64& to, const xIndirect8& sibsrc) const
{ {
EbpAssert(); EbpAssert();
xOpWrite0F( xOpWrite0F(
(to->GetOperandSize() == 2) ? 0x66 : 0, (to->GetOperandSize() == 2) ? 0x66 : 0,
SignExtend ? 0xbe : 0xb6, SignExtend ? 0xbe : 0xb6,
to, sibsrc); to, sibsrc);
} }
void xImpl_MovExtend::operator()(const xRegister32or64 &to, const xRegister16 &from) const void xImpl_MovExtend::operator()(const xRegister32or64& to, const xRegister16& from) const
{ {
EbpAssert(); EbpAssert();
xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, from); xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, from);
} }
void xImpl_MovExtend::operator()(const xRegister32or64 &to, const xIndirect16 &sibsrc) const void xImpl_MovExtend::operator()(const xRegister32or64& to, const xIndirect16& sibsrc) const
{ {
EbpAssert(); EbpAssert();
xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, sibsrc); xOpWrite0F(SignExtend ? 0xbf : 0xb7, to, sibsrc);
} }
#if 0 #if 0
void xImpl_MovExtend::operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const void xImpl_MovExtend::operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const
@ -241,58 +255,58 @@ void xImpl_MovExtend::operator()( const xRegister16or32& to, const xDirectOrIndi
} }
#endif #endif
const xImpl_MovExtend xMOVSX = {true}; const xImpl_MovExtend xMOVSX = {true};
const xImpl_MovExtend xMOVZX = {false}; const xImpl_MovExtend xMOVZX = {false};
const xImpl_CMov xCMOVA = {Jcc_Above}; const xImpl_CMov xCMOVA = {Jcc_Above};
const xImpl_CMov xCMOVAE = {Jcc_AboveOrEqual}; const xImpl_CMov xCMOVAE = {Jcc_AboveOrEqual};
const xImpl_CMov xCMOVB = {Jcc_Below}; const xImpl_CMov xCMOVB = {Jcc_Below};
const xImpl_CMov xCMOVBE = {Jcc_BelowOrEqual}; const xImpl_CMov xCMOVBE = {Jcc_BelowOrEqual};
const xImpl_CMov xCMOVG = {Jcc_Greater}; const xImpl_CMov xCMOVG = {Jcc_Greater};
const xImpl_CMov xCMOVGE = {Jcc_GreaterOrEqual}; const xImpl_CMov xCMOVGE = {Jcc_GreaterOrEqual};
const xImpl_CMov xCMOVL = {Jcc_Less}; const xImpl_CMov xCMOVL = {Jcc_Less};
const xImpl_CMov xCMOVLE = {Jcc_LessOrEqual}; const xImpl_CMov xCMOVLE = {Jcc_LessOrEqual};
const xImpl_CMov xCMOVZ = {Jcc_Zero}; const xImpl_CMov xCMOVZ = {Jcc_Zero};
const xImpl_CMov xCMOVE = {Jcc_Equal}; const xImpl_CMov xCMOVE = {Jcc_Equal};
const xImpl_CMov xCMOVNZ = {Jcc_NotZero}; const xImpl_CMov xCMOVNZ = {Jcc_NotZero};
const xImpl_CMov xCMOVNE = {Jcc_NotEqual}; const xImpl_CMov xCMOVNE = {Jcc_NotEqual};
const xImpl_CMov xCMOVO = {Jcc_Overflow}; const xImpl_CMov xCMOVO = {Jcc_Overflow};
const xImpl_CMov xCMOVNO = {Jcc_NotOverflow}; const xImpl_CMov xCMOVNO = {Jcc_NotOverflow};
const xImpl_CMov xCMOVC = {Jcc_Carry}; const xImpl_CMov xCMOVC = {Jcc_Carry};
const xImpl_CMov xCMOVNC = {Jcc_NotCarry}; const xImpl_CMov xCMOVNC = {Jcc_NotCarry};
const xImpl_CMov xCMOVS = {Jcc_Signed}; const xImpl_CMov xCMOVS = {Jcc_Signed};
const xImpl_CMov xCMOVNS = {Jcc_Unsigned}; const xImpl_CMov xCMOVNS = {Jcc_Unsigned};
const xImpl_CMov xCMOVPE = {Jcc_ParityEven}; const xImpl_CMov xCMOVPE = {Jcc_ParityEven};
const xImpl_CMov xCMOVPO = {Jcc_ParityOdd}; const xImpl_CMov xCMOVPO = {Jcc_ParityOdd};
const xImpl_Set xSETA = {Jcc_Above}; const xImpl_Set xSETA = {Jcc_Above};
const xImpl_Set xSETAE = {Jcc_AboveOrEqual}; const xImpl_Set xSETAE = {Jcc_AboveOrEqual};
const xImpl_Set xSETB = {Jcc_Below}; const xImpl_Set xSETB = {Jcc_Below};
const xImpl_Set xSETBE = {Jcc_BelowOrEqual}; const xImpl_Set xSETBE = {Jcc_BelowOrEqual};
const xImpl_Set xSETG = {Jcc_Greater}; const xImpl_Set xSETG = {Jcc_Greater};
const xImpl_Set xSETGE = {Jcc_GreaterOrEqual}; const xImpl_Set xSETGE = {Jcc_GreaterOrEqual};
const xImpl_Set xSETL = {Jcc_Less}; const xImpl_Set xSETL = {Jcc_Less};
const xImpl_Set xSETLE = {Jcc_LessOrEqual}; const xImpl_Set xSETLE = {Jcc_LessOrEqual};
const xImpl_Set xSETZ = {Jcc_Zero}; const xImpl_Set xSETZ = {Jcc_Zero};
const xImpl_Set xSETE = {Jcc_Equal}; const xImpl_Set xSETE = {Jcc_Equal};
const xImpl_Set xSETNZ = {Jcc_NotZero}; const xImpl_Set xSETNZ = {Jcc_NotZero};
const xImpl_Set xSETNE = {Jcc_NotEqual}; const xImpl_Set xSETNE = {Jcc_NotEqual};
const xImpl_Set xSETO = {Jcc_Overflow}; const xImpl_Set xSETO = {Jcc_Overflow};
const xImpl_Set xSETNO = {Jcc_NotOverflow}; const xImpl_Set xSETNO = {Jcc_NotOverflow};
const xImpl_Set xSETC = {Jcc_Carry}; const xImpl_Set xSETC = {Jcc_Carry};
const xImpl_Set xSETNC = {Jcc_NotCarry}; const xImpl_Set xSETNC = {Jcc_NotCarry};
const xImpl_Set xSETS = {Jcc_Signed}; const xImpl_Set xSETS = {Jcc_Signed};
const xImpl_Set xSETNS = {Jcc_Unsigned}; const xImpl_Set xSETNS = {Jcc_Unsigned};
const xImpl_Set xSETPE = {Jcc_ParityEven}; const xImpl_Set xSETPE = {Jcc_ParityEven};
const xImpl_Set xSETPO = {Jcc_ParityOdd}; const xImpl_Set xSETPO = {Jcc_ParityOdd};
} // end namespace x86Emitter } // end namespace x86Emitter

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,8 @@
#include "common/Dependencies.h" #include "common/Dependencies.h"
enum x86VendorType { enum x86VendorType
{
x86Vendor_Intel = 0, x86Vendor_Intel = 0,
x86Vendor_AMD = 1, x86Vendor_AMD = 1,
x86Vendor_Unknown = 2 x86Vendor_Unknown = 2
@ -124,7 +125,8 @@ protected:
void CountLogicalCores(); void CountLogicalCores();
}; };
enum SSE_RoundMode { enum SSE_RoundMode
{
SSE_RoundMode_FIRST = 0, SSE_RoundMode_FIRST = 0,
SSEround_Nearest = 0, SSEround_Nearest = 0,
SSEround_NegInf, SSEround_NegInf,
@ -136,10 +138,12 @@ enum SSE_RoundMode {
ImplementEnumOperators(SSE_RoundMode); ImplementEnumOperators(SSE_RoundMode);
// Predeclaration for xIndirect32 // Predeclaration for xIndirect32
namespace x86Emitter { namespace x86Emitter
template <typename T> class xIndirect; {
template <typename T>
class xIndirect;
typedef xIndirect<u32> xIndirect32; typedef xIndirect<u32> xIndirect32;
} } // namespace x86Emitter
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SSE_MXCSR - Control/Status Register (bitfield) // SSE_MXCSR - Control/Status Register (bitfield)
@ -181,19 +185,19 @@ union SSE_MXCSR
}; };
SSE_RoundMode GetRoundMode() const; SSE_RoundMode GetRoundMode() const;
SSE_MXCSR &SetRoundMode(SSE_RoundMode mode); SSE_MXCSR& SetRoundMode(SSE_RoundMode mode);
SSE_MXCSR &ClearExceptionFlags(); SSE_MXCSR& ClearExceptionFlags();
SSE_MXCSR &EnableExceptions(); SSE_MXCSR& EnableExceptions();
SSE_MXCSR &DisableExceptions(); SSE_MXCSR& DisableExceptions();
SSE_MXCSR &ApplyReserveMask(); SSE_MXCSR& ApplyReserveMask();
bool operator==(const SSE_MXCSR &right) const bool operator==(const SSE_MXCSR& right) const
{ {
return bitmask == right.bitmask; return bitmask == right.bitmask;
} }
bool operator!=(const SSE_MXCSR &right) const bool operator!=(const SSE_MXCSR& right) const
{ {
return bitmask != right.bitmask; return bitmask != right.bitmask;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -22,19 +22,19 @@ using namespace pxSizerFlags;
// pxCheckBox Implementations // pxCheckBox Implementations
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
pxCheckBox::pxCheckBox(wxWindow *parent, const wxString &label, const wxString &subtext, int flags) pxCheckBox::pxCheckBox(wxWindow* parent, const wxString& label, const wxString& subtext, int flags)
: wxPanelWithHelpers(parent, wxVERTICAL) : wxPanelWithHelpers(parent, wxVERTICAL)
{ {
Init(label, subtext, flags); Init(label, subtext, flags);
} }
pxCheckBox::pxCheckBox(wxWindow *parent, const wxString &label, int flags) pxCheckBox::pxCheckBox(wxWindow* parent, const wxString& label, int flags)
: wxPanelWithHelpers(parent, wxVERTICAL) : wxPanelWithHelpers(parent, wxVERTICAL)
{ {
Init(label, wxEmptyString, flags); Init(label, wxEmptyString, flags);
} }
void pxCheckBox::Init(const wxString &label, const wxString &subtext, int flags) void pxCheckBox::Init(const wxString& label, const wxString& subtext, int flags)
{ {
m_subtext = NULL; m_subtext = NULL;
m_subPadding = StdPadding * 2; m_subPadding = StdPadding * 2;
@ -43,10 +43,11 @@ void pxCheckBox::Init(const wxString &label, const wxString &subtext, int flags)
*this += m_checkbox | pxSizerFlags::StdExpand(); *this += m_checkbox | pxSizerFlags::StdExpand();
static const int Indentation = 23; static const int Indentation = 23;
if (!subtext.IsEmpty()) { if (!subtext.IsEmpty())
{
m_subtext = new pxStaticText(this, subtext, wxALIGN_LEFT); m_subtext = new pxStaticText(this, subtext, wxALIGN_LEFT);
wxFlexGridSizer &spaced(*new wxFlexGridSizer(3)); wxFlexGridSizer& spaced(*new wxFlexGridSizer(3));
spaced.AddGrowableCol(1); spaced.AddGrowableCol(1);
spaced += Indentation; spaced += Indentation;
m_sizerItem_subtext = spaced.Add(m_subtext, pxBorder(wxBOTTOM, m_subPadding).Expand()); m_sizerItem_subtext = spaced.Add(m_subtext, pxBorder(wxBOTTOM, m_subPadding).Expand());
@ -58,10 +59,11 @@ void pxCheckBox::Init(const wxString &label, const wxString &subtext, int flags)
Bind(wxEVT_CHECKBOX, &pxCheckBox::OnCheckpartCommand, this, m_checkbox->GetId()); Bind(wxEVT_CHECKBOX, &pxCheckBox::OnCheckpartCommand, this, m_checkbox->GetId());
} }
pxCheckBox &pxCheckBox::SetSubPadding(int pad) pxCheckBox& pxCheckBox::SetSubPadding(int pad)
{ {
m_subPadding = pad; m_subPadding = pad;
if (m_sizerItem_subtext) { if (m_sizerItem_subtext)
{
m_sizerItem_subtext->SetBorder(m_subPadding); m_sizerItem_subtext->SetBorder(m_subPadding);
Fit(); Fit();
} }
@ -70,21 +72,21 @@ pxCheckBox &pxCheckBox::SetSubPadding(int pad)
// applies the tooltip to both both the checkbox and it's static subtext (if present), and // applies the tooltip to both both the checkbox and it's static subtext (if present), and
// performs word wrapping on platforms that need it (eg mswindows). // performs word wrapping on platforms that need it (eg mswindows).
pxCheckBox &pxCheckBox::SetToolTip(const wxString &tip) pxCheckBox& pxCheckBox::SetToolTip(const wxString& tip)
{ {
pxSetToolTip(m_checkbox, tip); pxSetToolTip(m_checkbox, tip);
pxSetToolTip(m_subtext, tip); pxSetToolTip(m_subtext, tip);
return *this; return *this;
} }
pxCheckBox &pxCheckBox::SetValue(bool val) pxCheckBox& pxCheckBox::SetValue(bool val)
{ {
pxAssert(m_checkbox); pxAssert(m_checkbox);
m_checkbox->SetValue(val); m_checkbox->SetValue(val);
return *this; return *this;
} }
pxCheckBox &pxCheckBox::SetIndeterminate() pxCheckBox& pxCheckBox::SetIndeterminate()
{ {
pxAssert(m_checkbox); pxAssert(m_checkbox);
m_checkbox->Set3StateValue(wxCHK_UNDETERMINED); m_checkbox->Set3StateValue(wxCHK_UNDETERMINED);
@ -92,7 +94,7 @@ pxCheckBox &pxCheckBox::SetIndeterminate()
} }
pxCheckBox &pxCheckBox::SetState(wxCheckBoxState state) pxCheckBox& pxCheckBox::SetState(wxCheckBoxState state)
{ {
pxAssert(m_checkbox); pxAssert(m_checkbox);
m_checkbox->Set3StateValue(state); m_checkbox->Set3StateValue(state);
@ -102,7 +104,7 @@ pxCheckBox &pxCheckBox::SetState(wxCheckBoxState state)
// Forwards checkbox actions on the internal checkbox (called 'checkpart') to listeners // Forwards checkbox actions on the internal checkbox (called 'checkpart') to listeners
// bound to the pxCheckBox "parent" panel. This helps the pxCheckBox behave more like a // bound to the pxCheckBox "parent" panel. This helps the pxCheckBox behave more like a
// traditional checkbox. // traditional checkbox.
void pxCheckBox::OnCheckpartCommand(wxCommandEvent &evt) void pxCheckBox::OnCheckpartCommand(wxCommandEvent& evt)
{ {
evt.Skip(); evt.Skip();
@ -112,25 +114,25 @@ void pxCheckBox::OnCheckpartCommand(wxCommandEvent &evt)
GetEventHandler()->ProcessEvent(newevt); GetEventHandler()->ProcessEvent(newevt);
} }
void pxCheckBox::OnSubtextClicked(wxCommandEvent &evt) void pxCheckBox::OnSubtextClicked(wxCommandEvent& evt)
{ {
// TODO? // TODO?
// We can enable the ability to allow clicks on the subtext desc/label to toggle // We can enable the ability to allow clicks on the subtext desc/label to toggle
// the checkmark. Not sure if that's desirable. // the checkmark. Not sure if that's desirable.
} }
void operator+=(wxSizer &target, pxCheckBox *src) void operator+=(wxSizer& target, pxCheckBox* src)
{ {
if (src) if (src)
target.Add(src, pxExpand); target.Add(src, pxExpand);
} }
void operator+=(wxSizer &target, pxCheckBox &src) void operator+=(wxSizer& target, pxCheckBox& src)
{ {
target.Add(&src, pxExpand); target.Add(&src, pxExpand);
} }
void operator+=(wxSizer *target, pxCheckBox &src) void operator+=(wxSizer* target, pxCheckBox& src)
{ {
target->Add(&src, pxExpand); target->Add(&src, pxExpand);
} }

View File

@ -29,27 +29,27 @@
class pxCheckBox : public wxPanelWithHelpers class pxCheckBox : public wxPanelWithHelpers
{ {
protected: protected:
wxCheckBox *m_checkbox; wxCheckBox* m_checkbox;
pxStaticText *m_subtext; pxStaticText* m_subtext;
// padding below the subtext (if there's subtext). If there's no subtext, this value is unused. // padding below the subtext (if there's subtext). If there's no subtext, this value is unused.
int m_subPadding; int m_subPadding;
wxSizerItem *m_sizerItem_subtext; wxSizerItem* m_sizerItem_subtext;
public: public:
pxCheckBox(wxWindow *parent, const wxString &label, const wxString &subtext = wxEmptyString, int flags = wxCHK_2STATE); pxCheckBox(wxWindow* parent, const wxString& label, const wxString& subtext = wxEmptyString, int flags = wxCHK_2STATE);
pxCheckBox(wxWindow *parent, const wxString &label, int flags); pxCheckBox(wxWindow* parent, const wxString& label, int flags);
virtual ~pxCheckBox() = default; virtual ~pxCheckBox() = default;
bool HasSubText() const { return m_subtext != NULL; } bool HasSubText() const { return m_subtext != NULL; }
const pxStaticText *GetSubText() const { return m_subtext; } const pxStaticText* GetSubText() const { return m_subtext; }
pxCheckBox &SetSubPadding(int pad); pxCheckBox& SetSubPadding(int pad);
pxCheckBox &SetToolTip(const wxString &tip); pxCheckBox& SetToolTip(const wxString& tip);
pxCheckBox &SetValue(bool val); pxCheckBox& SetValue(bool val);
pxCheckBox &SetIndeterminate(); pxCheckBox& SetIndeterminate();
pxCheckBox &SetState(wxCheckBoxState state); pxCheckBox& SetState(wxCheckBoxState state);
wxCheckBoxState GetState() const wxCheckBoxState GetState() const
{ {
@ -71,32 +71,32 @@ public:
pxAssert(m_checkbox != NULL); pxAssert(m_checkbox != NULL);
return m_checkbox->Get3StateValue() == wxCHK_UNDETERMINED; return m_checkbox->Get3StateValue() == wxCHK_UNDETERMINED;
} }
operator wxCheckBox &() operator wxCheckBox&()
{ {
pxAssert(m_checkbox != NULL); pxAssert(m_checkbox != NULL);
return *m_checkbox; return *m_checkbox;
} }
operator const wxCheckBox &() const operator const wxCheckBox&() const
{ {
pxAssert(m_checkbox != NULL); pxAssert(m_checkbox != NULL);
return *m_checkbox; return *m_checkbox;
} }
wxCheckBox *GetWxPtr() { return m_checkbox; } wxCheckBox* GetWxPtr() { return m_checkbox; }
const wxCheckBox *GetWxPtr() const { return m_checkbox; } const wxCheckBox* GetWxPtr() const { return m_checkbox; }
//wxWindowID GetId() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetId(); } //wxWindowID GetId() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetId(); }
protected: protected:
void Init(const wxString &label, const wxString &subtext, int flags); void Init(const wxString& label, const wxString& subtext, int flags);
void OnCheckpartCommand(wxCommandEvent &evt); void OnCheckpartCommand(wxCommandEvent& evt);
void OnSubtextClicked(wxCommandEvent &evt); void OnSubtextClicked(wxCommandEvent& evt);
}; };
extern void operator+=(wxSizer &target, pxCheckBox &src); extern void operator+=(wxSizer& target, pxCheckBox& src);
template <> template <>
inline void operator+=(wxSizer &target, const pxWindowAndFlags<pxCheckBox> &src) inline void operator+=(wxSizer& target, const pxWindowAndFlags<pxCheckBox>& src)
{ {
target.Add(src.window, src.flags); target.Add(src.window, src.flags);
} }

View File

@ -49,11 +49,11 @@ public:
virtual ~SynchronousActionState() = default; virtual ~SynchronousActionState() = default;
void SetException(const BaseException &ex); void SetException(const BaseException& ex);
void SetException(BaseException *ex); void SetException(BaseException* ex);
Threading::Semaphore &GetSemaphore() { return m_sema; } Threading::Semaphore& GetSemaphore() { return m_sema; }
const Threading::Semaphore &GetSemaphore() const { return m_sema; } const Threading::Semaphore& GetSemaphore() const { return m_sema; }
void RethrowException() const; void RethrowException() const;
int WaitForResult(); int WaitForResult();
@ -87,7 +87,7 @@ public:
} }
pxSimpleEvent(const pxSimpleEvent&) = default; pxSimpleEvent(const pxSimpleEvent&) = default;
virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); } virtual wxEvent* Clone() const { return new pxSimpleEvent(*this); }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -102,26 +102,26 @@ class pxActionEvent : public wxEvent
wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent); wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent);
protected: protected:
SynchronousActionState *m_state; SynchronousActionState* m_state;
public: public:
virtual ~pxActionEvent() = default; virtual ~pxActionEvent() = default;
virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); } virtual pxActionEvent* Clone() const { return new pxActionEvent(*this); }
explicit pxActionEvent(SynchronousActionState *sema = NULL, int msgtype = pxEvt_InvokeAction); explicit pxActionEvent(SynchronousActionState* sema = NULL, int msgtype = pxEvt_InvokeAction);
explicit pxActionEvent(SynchronousActionState &sema, int msgtype = pxEvt_InvokeAction); explicit pxActionEvent(SynchronousActionState& sema, int msgtype = pxEvt_InvokeAction);
pxActionEvent(const pxActionEvent &src); pxActionEvent(const pxActionEvent& src);
Threading::Semaphore *GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; } Threading::Semaphore* GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; }
const SynchronousActionState *GetSyncState() const { return m_state; } const SynchronousActionState* GetSyncState() const { return m_state; }
SynchronousActionState *GetSyncState() { return m_state; } SynchronousActionState* GetSyncState() { return m_state; }
void SetSyncState(SynchronousActionState *obj) { m_state = obj; } void SetSyncState(SynchronousActionState* obj) { m_state = obj; }
void SetSyncState(SynchronousActionState &obj) { m_state = &obj; } void SetSyncState(SynchronousActionState& obj) { m_state = &obj; }
virtual void SetException(BaseException *ex); virtual void SetException(BaseException* ex);
void SetException(const BaseException &ex); void SetException(const BaseException& ex);
virtual void _DoInvokeEvent(); virtual void _DoInvokeEvent();
@ -145,21 +145,21 @@ class pxExceptionEvent : public pxActionEvent
typedef pxActionEvent _parent; typedef pxActionEvent _parent;
protected: protected:
BaseException *m_except; BaseException* m_except;
public: public:
pxExceptionEvent(BaseException *ex = NULL) pxExceptionEvent(BaseException* ex = NULL)
{ {
m_except = ex; m_except = ex;
} }
pxExceptionEvent(const BaseException &ex); pxExceptionEvent(const BaseException& ex);
virtual ~pxExceptionEvent() virtual ~pxExceptionEvent()
{ {
} }
virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); } virtual pxExceptionEvent* Clone() const { return new pxExceptionEvent(*this); }
protected: protected:
void InvokeEvent(); void InvokeEvent();
@ -174,26 +174,26 @@ class pxSynchronousCommandEvent : public wxCommandEvent
wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent); wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent);
protected: protected:
SynchronousActionState *m_sync; SynchronousActionState* m_sync;
wxEventType m_realEvent; wxEventType m_realEvent;
public: public:
virtual ~pxSynchronousCommandEvent() = default; virtual ~pxSynchronousCommandEvent() = default;
virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); } virtual pxSynchronousCommandEvent* Clone() const { return new pxSynchronousCommandEvent(*this); }
pxSynchronousCommandEvent(SynchronousActionState *sema = NULL, wxEventType commandType = wxEVT_NULL, int winid = 0); pxSynchronousCommandEvent(SynchronousActionState* sema = NULL, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState &sema, wxEventType commandType = wxEVT_NULL, int winid = 0); pxSynchronousCommandEvent(SynchronousActionState& sema, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState *sema, const wxCommandEvent &evt); pxSynchronousCommandEvent(SynchronousActionState* sema, const wxCommandEvent& evt);
pxSynchronousCommandEvent(SynchronousActionState &sema, const wxCommandEvent &evt); pxSynchronousCommandEvent(SynchronousActionState& sema, const wxCommandEvent& evt);
pxSynchronousCommandEvent(const pxSynchronousCommandEvent &src); pxSynchronousCommandEvent(const pxSynchronousCommandEvent& src);
Threading::Semaphore *GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; } Threading::Semaphore* GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; }
wxEventType GetRealEventType() const { return m_realEvent; } wxEventType GetRealEventType() const { return m_realEvent; }
void SetException(BaseException *ex); void SetException(BaseException* ex);
void SetException(const BaseException &ex); void SetException(const BaseException& ex);
}; };
wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent); wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent);
@ -211,11 +211,11 @@ protected:
public: public:
virtual ~BaseMessageBoxEvent() = default; virtual ~BaseMessageBoxEvent() = default;
virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); } virtual BaseMessageBoxEvent* Clone() const { return new BaseMessageBoxEvent(*this); }
explicit BaseMessageBoxEvent(const wxString &content = wxEmptyString, SynchronousActionState *instdata = NULL); explicit BaseMessageBoxEvent(const wxString& content = wxEmptyString, SynchronousActionState* instdata = NULL);
BaseMessageBoxEvent(const wxString &content, SynchronousActionState &instdata); BaseMessageBoxEvent(const wxString& content, SynchronousActionState& instdata);
BaseMessageBoxEvent(const BaseMessageBoxEvent &event); BaseMessageBoxEvent(const BaseMessageBoxEvent& event);
protected: protected:
virtual void InvokeEvent(); virtual void InvokeEvent();
@ -249,58 +249,58 @@ protected:
public: public:
MsgButtons() { bitset = 0; } MsgButtons() { bitset = 0; }
MsgButtons &OK() MsgButtons& OK()
{ {
m_OK = true; m_OK = true;
return *this; return *this;
} }
MsgButtons &Cancel() MsgButtons& Cancel()
{ {
m_Cancel = true; m_Cancel = true;
return *this; return *this;
} }
MsgButtons &Apply() MsgButtons& Apply()
{ {
m_Apply = true; m_Apply = true;
return *this; return *this;
} }
MsgButtons &Yes() MsgButtons& Yes()
{ {
m_Yes = true; m_Yes = true;
return *this; return *this;
} }
MsgButtons &No() MsgButtons& No()
{ {
m_No = true; m_No = true;
return *this; return *this;
} }
MsgButtons &ToAll() MsgButtons& ToAll()
{ {
m_AllowToAll = true; m_AllowToAll = true;
return *this; return *this;
} }
MsgButtons &Abort() MsgButtons& Abort()
{ {
m_Abort = true; m_Abort = true;
return *this; return *this;
} }
MsgButtons &Retry() MsgButtons& Retry()
{ {
m_Retry = true; m_Retry = true;
return *this; return *this;
} }
MsgButtons &Ignore() MsgButtons& Ignore()
{ {
m_Ignore = true; m_Ignore = true;
return *this; return *this;
} }
MsgButtons &Reset() MsgButtons& Reset()
{ {
m_Reset = true; m_Reset = true;
return *this; return *this;
} }
MsgButtons &Close() MsgButtons& Close()
{ {
m_Close = true; m_Close = true;
return *this; return *this;
@ -308,19 +308,19 @@ public:
// label - native language label displayed to user // label - native language label displayed to user
// id - raw ASCII identifier used in the config file (do not translate, hence char*) // id - raw ASCII identifier used in the config file (do not translate, hence char*)
MsgButtons &Custom(const wxString &label, const char *id) MsgButtons& Custom(const wxString& label, const char* id)
{ {
m_CustomLabel = label; m_CustomLabel = label;
m_CustomLabelId = fromUTF8(id); m_CustomLabelId = fromUTF8(id);
return *this; return *this;
} }
MsgButtons &OKCancel() MsgButtons& OKCancel()
{ {
m_OK = m_Cancel = true; m_OK = m_Cancel = true;
return *this; return *this;
} }
MsgButtons &YesNo() MsgButtons& YesNo()
{ {
m_Yes = m_No = true; m_Yes = m_No = true;
return *this; return *this;
@ -340,19 +340,19 @@ public:
bool HasClose() const { return m_Close; } bool HasClose() const { return m_Close; }
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); } bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
const wxString &GetCustomLabel() const { return m_CustomLabel; } const wxString& GetCustomLabel() const { return m_CustomLabel; }
const wxString &GetCustomLabelId() const { return m_CustomLabelId; } const wxString& GetCustomLabelId() const { return m_CustomLabelId; }
bool Allows(wxWindowID id) const; bool Allows(wxWindowID id) const;
void SetBestFocus(wxWindow *dialog) const; void SetBestFocus(wxWindow* dialog) const;
void SetBestFocus(wxWindow &dialog) const; void SetBestFocus(wxWindow& dialog) const;
bool operator==(const MsgButtons &right) const bool operator==(const MsgButtons& right) const
{ {
return OpEqu(bitset); return OpEqu(bitset);
} }
bool operator!=(const MsgButtons &right) const bool operator!=(const MsgButtons& right) const
{ {
return !OpEqu(bitset); return !OpEqu(bitset);
} }
@ -387,12 +387,12 @@ protected:
public: public:
virtual ~pxMessageBoxEvent() = default; virtual ~pxMessageBoxEvent() = default;
virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); } virtual pxMessageBoxEvent* Clone() const { return new pxMessageBoxEvent(*this); }
pxMessageBoxEvent() {} pxMessageBoxEvent() {}
pxMessageBoxEvent(const wxString &title, const wxString &content, const MsgButtons &buttons, SynchronousActionState &instdata); pxMessageBoxEvent(const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState& instdata);
pxMessageBoxEvent(const wxString &title, const wxString &content, const MsgButtons &buttons, SynchronousActionState *instdata = NULL); pxMessageBoxEvent(const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState* instdata = NULL);
pxMessageBoxEvent(const pxMessageBoxEvent &event) = default; pxMessageBoxEvent(const pxMessageBoxEvent& event) = default;
protected: protected:
int _DoDialog() const; int _DoDialog() const;
@ -411,13 +411,13 @@ protected:
public: public:
virtual ~pxAssertionEvent() = default; virtual ~pxAssertionEvent() = default;
virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); } virtual pxAssertionEvent* Clone() const { return new pxAssertionEvent(*this); }
pxAssertionEvent(const wxString &content = wxEmptyString, const wxString &trace = wxEmptyString, SynchronousActionState *instdata = NULL); pxAssertionEvent(const wxString& content = wxEmptyString, const wxString& trace = wxEmptyString, SynchronousActionState* instdata = NULL);
pxAssertionEvent(const wxString &content, const wxString &trace, SynchronousActionState &instdata); pxAssertionEvent(const wxString& content, const wxString& trace, SynchronousActionState& instdata);
pxAssertionEvent(const pxAssertionEvent &event) = default; pxAssertionEvent(const pxAssertionEvent& event) = default;
pxAssertionEvent &SetStacktrace(const wxString &trace); pxAssertionEvent& SetStacktrace(const wxString& trace);
protected: protected:
int _DoDialog() const; int _DoDialog() const;

View File

@ -40,12 +40,12 @@ extern const wxPoint wxDefaultPosition;
namespace Threading namespace Threading
{ {
class Mutex; class Mutex;
class Semaphore; class Semaphore;
class pxThread; class pxThread;
} } // namespace Threading
namespace Exception namespace Exception
{ {
class BaseException; class BaseException;
} }

View File

@ -26,7 +26,7 @@ template class SafeArray<RadioPanelObjects>;
#define VerifyRealizedState() \ #define VerifyRealizedState() \
pxAssertDev(m_IsRealized, "Invalid object state: RadioButtonGroup as not been realized.") pxAssertDev(m_IsRealized, "Invalid object state: RadioButtonGroup as not been realized.")
void pxRadioPanel::Init(const RadioPanelItem *srcArray, int arrsize) void pxRadioPanel::Init(const RadioPanelItem* srcArray, int arrsize)
{ {
m_DefaultIdx = -1; m_DefaultIdx = -1;
m_IsRealized = false; m_IsRealized = false;
@ -38,7 +38,7 @@ void pxRadioPanel::Init(const RadioPanelItem *srcArray, int arrsize)
Append(srcArray[i]); Append(srcArray[i]);
} }
pxRadioPanel &pxRadioPanel::Append(const RadioPanelItem &entry) pxRadioPanel& pxRadioPanel::Append(const RadioPanelItem& entry)
{ {
m_buttonStrings.push_back(entry); m_buttonStrings.push_back(entry);
return *this; return *this;
@ -51,7 +51,8 @@ void pxRadioPanel::Reset()
if (numbuttons == 0) if (numbuttons == 0)
return; return;
for (int i = 0; i < numbuttons; ++i) { for (int i = 0; i < numbuttons; ++i)
{
safe_delete(m_objects[i].LabelObj); safe_delete(m_objects[i].LabelObj);
safe_delete(m_objects[i].SubTextObj); safe_delete(m_objects[i].SubTextObj);
} }
@ -80,7 +81,8 @@ void pxRadioPanel::Realize()
for (int i = 1; i < numbuttons; ++i) for (int i = 1; i < numbuttons; ++i)
m_objects[i].LabelObj = new wxRadioButton(this, wxID_ANY, m_buttonStrings[i].Label); m_objects[i].LabelObj = new wxRadioButton(this, wxID_ANY, m_buttonStrings[i].Label);
for (int i = 0; i < numbuttons; ++i) { for (int i = 0; i < numbuttons; ++i)
{
m_objects[i].SubTextObj = NULL; m_objects[i].SubTextObj = NULL;
if (m_buttonStrings[i].SubText.IsEmpty()) if (m_buttonStrings[i].SubText.IsEmpty())
continue; continue;
@ -89,10 +91,12 @@ void pxRadioPanel::Realize()
pxAssert(GetSizer() != NULL); pxAssert(GetSizer() != NULL);
for (int i = 0; i < numbuttons; ++i) { for (int i = 0; i < numbuttons; ++i)
{
*this += m_objects[i].LabelObj | pxSizerFlags::StdExpand(); *this += m_objects[i].LabelObj | pxSizerFlags::StdExpand();
if (pxStaticText *subobj = m_objects[i].SubTextObj) { if (pxStaticText* subobj = m_objects[i].SubTextObj)
{
*this += subobj | pxBorder(wxLEFT, m_Indentation).Expand(); *this += subobj | pxBorder(wxLEFT, m_Indentation).Expand();
*this += 9 + m_padding.GetHeight(); *this += 9 + m_padding.GetHeight();
} }
@ -103,19 +107,19 @@ void pxRadioPanel::Realize()
_RealizeDefaultOption(); _RealizeDefaultOption();
} }
void pxRadioPanel::_setToolTipImmediate(int idx, const wxString &tip) void pxRadioPanel::_setToolTipImmediate(int idx, const wxString& tip)
{ {
if (wxRadioButton *woot = m_objects[idx].LabelObj) if (wxRadioButton* woot = m_objects[idx].LabelObj)
woot->SetToolTip(tip); woot->SetToolTip(tip);
if (pxStaticText *woot = m_objects[idx].SubTextObj) if (pxStaticText* woot = m_objects[idx].SubTextObj)
woot->SetToolTip(tip); woot->SetToolTip(tip);
} }
// The SetToolTip API provided by this function applies the tooltip to both the radio // The SetToolTip API provided by this function applies the tooltip to both the radio
// button and it's static subtext (if present), and performs word wrapping on platforms // button and it's static subtext (if present), and performs word wrapping on platforms
// that need it (eg mswindows). // that need it (eg mswindows).
pxRadioPanel &pxRadioPanel::SetToolTip(int idx, const wxString &tip) pxRadioPanel& pxRadioPanel::SetToolTip(int idx, const wxString& tip)
{ {
m_buttonStrings[idx].SetToolTip(tip); m_buttonStrings[idx].SetToolTip(tip);
@ -125,7 +129,7 @@ pxRadioPanel &pxRadioPanel::SetToolTip(int idx, const wxString &tip)
return *this; return *this;
} }
pxRadioPanel &pxRadioPanel::SetSelection(int idx) pxRadioPanel& pxRadioPanel::SetSelection(int idx)
{ {
if (!VerifyRealizedState()) if (!VerifyRealizedState())
return *this; return *this;
@ -137,7 +141,8 @@ pxRadioPanel &pxRadioPanel::SetSelection(int idx)
void pxRadioPanel::_RealizeDefaultOption() void pxRadioPanel::_RealizeDefaultOption()
{ {
if (m_IsRealized && m_DefaultIdx != -1) { if (m_IsRealized && m_DefaultIdx != -1)
{
wxFont def(GetFont()); wxFont def(GetFont());
def.SetWeight(wxFONTWEIGHT_BOLD); def.SetWeight(wxFONTWEIGHT_BOLD);
//def.SetStyle( wxFONTSTYLE_ITALIC ); //def.SetStyle( wxFONTSTYLE_ITALIC );
@ -148,12 +153,13 @@ void pxRadioPanel::_RealizeDefaultOption()
// Highlights (bold) the text of the default radio. // Highlights (bold) the text of the default radio.
// Not intended for restoring default value at later time. // Not intended for restoring default value at later time.
pxRadioPanel &pxRadioPanel::SetDefaultItem(int idx) pxRadioPanel& pxRadioPanel::SetDefaultItem(int idx)
{ {
if (idx == m_DefaultIdx) if (idx == m_DefaultIdx)
return *this; return *this;
if (m_IsRealized && m_DefaultIdx != -1) { if (m_IsRealized && m_DefaultIdx != -1)
{
wxFont def(GetFont()); wxFont def(GetFont());
m_objects[m_DefaultIdx].LabelObj->SetFont(def); m_objects[m_DefaultIdx].LabelObj->SetFont(def);
m_objects[m_DefaultIdx].LabelObj->SetForegroundColour(GetForegroundColour()); m_objects[m_DefaultIdx].LabelObj->SetForegroundColour(GetForegroundColour());
@ -165,7 +171,7 @@ pxRadioPanel &pxRadioPanel::SetDefaultItem(int idx)
return *this; return *this;
} }
pxRadioPanel &pxRadioPanel::EnableItem(int idx, bool enable) pxRadioPanel& pxRadioPanel::EnableItem(int idx, bool enable)
{ {
pxAssertDev(m_IsRealized, "RadioPanel must be realized first, prior to enabling or disabling individual items."); pxAssertDev(m_IsRealized, "RadioPanel must be realized first, prior to enabling or disabling individual items.");
@ -178,12 +184,12 @@ pxRadioPanel &pxRadioPanel::EnableItem(int idx, bool enable)
return *this; return *this;
} }
const RadioPanelItem &pxRadioPanel::Item(int idx) const const RadioPanelItem& pxRadioPanel::Item(int idx) const
{ {
return m_buttonStrings[idx]; return m_buttonStrings[idx];
} }
RadioPanelItem &pxRadioPanel::Item(int idx) RadioPanelItem& pxRadioPanel::Item(int idx)
{ {
return m_buttonStrings[idx]; return m_buttonStrings[idx];
} }
@ -193,8 +199,9 @@ int pxRadioPanel::GetSelection() const
if (!VerifyRealizedState()) if (!VerifyRealizedState())
return 0; return 0;
for (uint i = 0; i < m_buttonStrings.size(); ++i) { for (uint i = 0; i < m_buttonStrings.size(); ++i)
if (wxRadioButton *woot = m_objects[i].LabelObj) {
if (wxRadioButton* woot = m_objects[i].LabelObj)
if (woot->GetValue()) if (woot->GetValue())
return i; return i;
} }
@ -226,28 +233,28 @@ bool pxRadioPanel::IsSelected(int idx) const
return m_objects[idx].LabelObj->GetValue(); return m_objects[idx].LabelObj->GetValue();
} }
pxStaticText *pxRadioPanel::GetSubText(int idx) pxStaticText* pxRadioPanel::GetSubText(int idx)
{ {
if (!VerifyRealizedState()) if (!VerifyRealizedState())
return NULL; return NULL;
return m_objects[idx].SubTextObj; return m_objects[idx].SubTextObj;
} }
const pxStaticText *pxRadioPanel::GetSubText(int idx) const const pxStaticText* pxRadioPanel::GetSubText(int idx) const
{ {
if (!VerifyRealizedState()) if (!VerifyRealizedState())
return NULL; return NULL;
return m_objects[idx].SubTextObj; return m_objects[idx].SubTextObj;
} }
wxRadioButton *pxRadioPanel::GetButton(int idx) wxRadioButton* pxRadioPanel::GetButton(int idx)
{ {
if (!VerifyRealizedState()) if (!VerifyRealizedState())
return NULL; return NULL;
return m_objects[idx].LabelObj; return m_objects[idx].LabelObj;
} }
const wxRadioButton *pxRadioPanel::GetButton(int idx) const const wxRadioButton* pxRadioPanel::GetButton(int idx) const
{ {
if (!VerifyRealizedState()) if (!VerifyRealizedState())
return NULL; return NULL;

View File

@ -30,9 +30,9 @@ struct RadioPanelItem
wxString ToolTip; wxString ToolTip;
int SomeInt; int SomeInt;
void *SomePtr; void* SomePtr;
RadioPanelItem(const wxString &label, const wxString &subtext = wxEmptyString, const wxString &tooltip = wxEmptyString) RadioPanelItem(const wxString& label, const wxString& subtext = wxEmptyString, const wxString& tooltip = wxEmptyString)
: Label(label) : Label(label)
, SubText(subtext) , SubText(subtext)
, ToolTip(tooltip) , ToolTip(tooltip)
@ -41,25 +41,25 @@ struct RadioPanelItem
SomePtr = NULL; SomePtr = NULL;
} }
RadioPanelItem &SetToolTip(const wxString &tip) RadioPanelItem& SetToolTip(const wxString& tip)
{ {
ToolTip = tip; ToolTip = tip;
return *this; return *this;
} }
RadioPanelItem &SetSubText(const wxString &text) RadioPanelItem& SetSubText(const wxString& text)
{ {
SubText = text; SubText = text;
return *this; return *this;
} }
RadioPanelItem &SetInt(int intval) RadioPanelItem& SetInt(int intval)
{ {
SomeInt = intval; SomeInt = intval;
return *this; return *this;
} }
RadioPanelItem &SetPtr(void *ptrval) RadioPanelItem& SetPtr(void* ptrval)
{ {
SomePtr = ptrval; SomePtr = ptrval;
return *this; return *this;
@ -71,8 +71,8 @@ struct RadioPanelItem
// wrapped and re-wrapped with multiple calls to OnResize(). // wrapped and re-wrapped with multiple calls to OnResize().
struct RadioPanelObjects struct RadioPanelObjects
{ {
wxRadioButton *LabelObj; wxRadioButton* LabelObj;
pxStaticText *SubTextObj; pxStaticText* SubTextObj;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -105,13 +105,13 @@ protected:
public: public:
template <int size> template <int size>
pxRadioPanel(wxWindow *parent, const RadioPanelItem (&src)[size]) pxRadioPanel(wxWindow* parent, const RadioPanelItem (&src)[size])
: wxPanelWithHelpers(parent, wxVERTICAL) : wxPanelWithHelpers(parent, wxVERTICAL)
{ {
Init(src, size); Init(src, size);
} }
pxRadioPanel(wxWindow *parent) pxRadioPanel(wxWindow* parent)
: wxPanelWithHelpers(parent, wxVERTICAL) : wxPanelWithHelpers(parent, wxVERTICAL)
{ {
Init(); Init();
@ -122,38 +122,38 @@ public:
void Reset(); void Reset();
void Realize(); void Realize();
pxStaticText *GetSubText(int idx); pxStaticText* GetSubText(int idx);
const pxStaticText *GetSubText(int idx) const; const pxStaticText* GetSubText(int idx) const;
pxRadioPanel &Append(const RadioPanelItem &entry); pxRadioPanel& Append(const RadioPanelItem& entry);
pxRadioPanel &SetToolTip(int idx, const wxString &tip); pxRadioPanel& SetToolTip(int idx, const wxString& tip);
pxRadioPanel &SetSelection(int idx); pxRadioPanel& SetSelection(int idx);
pxRadioPanel &SetDefaultItem(int idx); pxRadioPanel& SetDefaultItem(int idx);
pxRadioPanel &EnableItem(int idx, bool enable = true); pxRadioPanel& EnableItem(int idx, bool enable = true);
const RadioPanelItem &Item(int idx) const; const RadioPanelItem& Item(int idx) const;
RadioPanelItem &Item(int idx); RadioPanelItem& Item(int idx);
int GetSelection() const; int GetSelection() const;
wxWindowID GetSelectionId() const; wxWindowID GetSelectionId() const;
bool IsSelected(int idx) const; bool IsSelected(int idx) const;
const RadioPanelItem &SelectedItem() const { return Item(GetSelection()); } const RadioPanelItem& SelectedItem() const { return Item(GetSelection()); }
RadioPanelItem &SelectedItem() { return Item(GetSelection()); } RadioPanelItem& SelectedItem() { return Item(GetSelection()); }
wxRadioButton *GetButton(int idx); wxRadioButton* GetButton(int idx);
const wxRadioButton *GetButton(int idx) const; const wxRadioButton* GetButton(int idx) const;
int GetPaddingVert() const { return m_padding.GetHeight(); } int GetPaddingVert() const { return m_padding.GetHeight(); }
int GetIndentation() const { return m_Indentation; } int GetIndentation() const { return m_Indentation; }
pxRadioPanel &SetPaddingHoriz(int newpad) pxRadioPanel& SetPaddingHoriz(int newpad)
{ {
m_padding.SetHeight(newpad); m_padding.SetHeight(newpad);
return *this; return *this;
} }
pxRadioPanel &SetIndentation(int newdent) pxRadioPanel& SetIndentation(int newdent)
{ {
m_Indentation = newdent; m_Indentation = newdent;
return *this; return *this;
@ -164,13 +164,13 @@ public:
return !m_buttonStrings[idx].SubText.IsEmpty(); return !m_buttonStrings[idx].SubText.IsEmpty();
} }
pxRadioPanel &Append(const wxString &label, const wxString &subtext = wxEmptyString, const wxString &tooltip = wxEmptyString) pxRadioPanel& Append(const wxString& label, const wxString& subtext = wxEmptyString, const wxString& tooltip = wxEmptyString)
{ {
return Append(RadioPanelItem(label, subtext, tooltip)); return Append(RadioPanelItem(label, subtext, tooltip));
} }
protected: protected:
void Init(const RadioPanelItem *srcArray = NULL, int arrsize = 0); void Init(const RadioPanelItem* srcArray = NULL, int arrsize = 0);
void _setToolTipImmediate(int idx, const wxString &tip); void _setToolTipImmediate(int idx, const wxString& tip);
void _RealizeDefaultOption(); void _RealizeDefaultOption();
}; };

View File

@ -20,7 +20,7 @@
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxStaticText (implementations) // pxStaticText (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
pxStaticText::pxStaticText(wxWindow *parent) pxStaticText::pxStaticText(wxWindow* parent)
: _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) : _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER)
{ {
m_align = wxALIGN_CENTRE_HORIZONTAL; m_align = wxALIGN_CENTRE_HORIZONTAL;
@ -31,7 +31,7 @@ pxStaticText::pxStaticText(wxWindow *parent)
SetPaddingDefaults(); SetPaddingDefaults();
} }
pxStaticText::pxStaticText(wxWindow *parent, const wxString &label, wxAlignment align) pxStaticText::pxStaticText(wxWindow* parent, const wxString& label, wxAlignment align)
: _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) : _parent(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER)
{ {
m_heightInLines = 1; m_heightInLines = 1;
@ -41,7 +41,7 @@ pxStaticText::pxStaticText(wxWindow *parent, const wxString &label, wxAlignment
Init(label); Init(label);
} }
void pxStaticText::Init(const wxString &label) void pxStaticText::Init(const wxString& label)
{ {
m_autowrap = true; m_autowrap = true;
m_wrappedWidth = -1; m_wrappedWidth = -1;
@ -67,19 +67,19 @@ void pxStaticText::SetPaddingDefaults()
m_paddingPct_vert = 0.0f; m_paddingPct_vert = 0.0f;
} }
pxStaticText &pxStaticText::SetMinWidth(int width) pxStaticText& pxStaticText::SetMinWidth(int width)
{ {
SetMinSize(wxSize(width, GetMinHeight())); SetMinSize(wxSize(width, GetMinHeight()));
return *this; return *this;
} }
pxStaticText &pxStaticText::SetMinHeight(int height) pxStaticText& pxStaticText::SetMinHeight(int height)
{ {
SetMinSize(wxSize(GetMinWidth(), height)); SetMinSize(wxSize(GetMinWidth(), height));
return *this; return *this;
} }
pxStaticText &pxStaticText::SetHeight(int lines) pxStaticText& pxStaticText::SetHeight(int lines)
{ {
if (!pxAssert(lines > 0)) if (!pxAssert(lines > 0))
lines = 2; lines = 2;
@ -91,13 +91,13 @@ pxStaticText &pxStaticText::SetHeight(int lines)
return *this; return *this;
} }
pxStaticText &pxStaticText::Align(wxAlignment align) pxStaticText& pxStaticText::Align(wxAlignment align)
{ {
m_align = align; m_align = align;
return *this; return *this;
} }
pxStaticText &pxStaticText::Bold() pxStaticText& pxStaticText::Bold()
{ {
wxFont bold(GetFont()); wxFont bold(GetFont());
bold.SetWeight(wxFONTWEIGHT_BOLD); bold.SetWeight(wxFONTWEIGHT_BOLD);
@ -105,7 +105,7 @@ pxStaticText &pxStaticText::Bold()
return *this; return *this;
} }
pxStaticText &pxStaticText::PaddingPixH(int pixels) pxStaticText& pxStaticText::PaddingPixH(int pixels)
{ {
m_paddingPix_horiz = pixels; m_paddingPix_horiz = pixels;
UpdateWrapping(false); UpdateWrapping(false);
@ -113,14 +113,14 @@ pxStaticText &pxStaticText::PaddingPixH(int pixels)
return *this; return *this;
} }
pxStaticText &pxStaticText::PaddingPixV(int pixels) pxStaticText& pxStaticText::PaddingPixV(int pixels)
{ {
m_paddingPix_vert = pixels; m_paddingPix_vert = pixels;
Refresh(); Refresh();
return *this; return *this;
} }
pxStaticText &pxStaticText::PaddingPctH(float pct) pxStaticText& pxStaticText::PaddingPctH(float pct)
{ {
pxAssert(pct < 0.5); pxAssert(pct < 0.5);
@ -130,7 +130,7 @@ pxStaticText &pxStaticText::PaddingPctH(float pct)
return *this; return *this;
} }
pxStaticText &pxStaticText::PaddingPctV(float pct) pxStaticText& pxStaticText::PaddingPctV(float pct)
{ {
pxAssert(pct < 0.5); pxAssert(pct < 0.5);
@ -139,7 +139,7 @@ pxStaticText &pxStaticText::PaddingPctV(float pct)
return *this; return *this;
} }
pxStaticText &pxStaticText::Unwrapped() pxStaticText& pxStaticText::Unwrapped()
{ {
m_autowrap = false; m_autowrap = false;
UpdateWrapping(false); UpdateWrapping(false);
@ -156,7 +156,7 @@ int pxStaticText::calcPaddingHeight(int newHeight) const
return (int)(newHeight * m_paddingPct_vert * 2) + (m_paddingPix_vert * 2); return (int)(newHeight * m_paddingPct_vert * 2) + (m_paddingPix_vert * 2);
} }
wxSize pxStaticText::GetBestWrappedSize(const wxClientDC &dc) const wxSize pxStaticText::GetBestWrappedSize(const wxClientDC& dc) const
{ {
pxAssert(m_autowrap); pxAssert(m_autowrap);
@ -166,9 +166,10 @@ wxSize pxStaticText::GetBestWrappedSize(const wxClientDC &dc) const
int idealWidth = wxDefaultCoord; int idealWidth = wxDefaultCoord;
int parentalAdjust = 0; int parentalAdjust = 0;
double parentalFactor = 1.0; double parentalFactor = 1.0;
const wxWindow *millrun = this; const wxWindow* millrun = this;
while (millrun) { while (millrun)
{
// IMPORTANT : wxWizard changes its min size and then expects everything else // IMPORTANT : wxWizard changes its min size and then expects everything else
// to play nice and NOT resize according to the new min size. (wtf stupid) // to play nice and NOT resize according to the new min size. (wtf stupid)
// Anyway, this fixes it -- ignore min size specifier on wxWizard! // Anyway, this fixes it -- ignore min size specifier on wxWizard!
@ -177,7 +178,8 @@ wxSize pxStaticText::GetBestWrappedSize(const wxClientDC &dc) const
int min = (int)((millrun->GetMinWidth() - parentalAdjust) * parentalFactor); int min = (int)((millrun->GetMinWidth() - parentalAdjust) * parentalFactor);
if (min > 0 && ((idealWidth < 0) || (min < idealWidth))) { if (min > 0 && ((idealWidth < 0) || (min < idealWidth)))
{
idealWidth = min; idealWidth = min;
} }
@ -185,7 +187,8 @@ wxSize pxStaticText::GetBestWrappedSize(const wxClientDC &dc) const
millrun = millrun->GetParent(); millrun = millrun->GetParent();
} }
if (idealWidth <= 0) { if (idealWidth <= 0)
{
// FIXME: The minimum size of this control is unknown, so let's just pick a guess based on // FIXME: The minimum size of this control is unknown, so let's just pick a guess based on
// the size of the user's display area. // the size of the user's display area.
@ -195,7 +198,7 @@ wxSize pxStaticText::GetBestWrappedSize(const wxClientDC &dc) const
return dc.GetMultiLineTextExtent(pxTextWrapper().Wrap(this, m_label, idealWidth - calcPaddingWidth(idealWidth)).GetResult()); return dc.GetMultiLineTextExtent(pxTextWrapper().Wrap(this, m_label, idealWidth - calcPaddingWidth(idealWidth)).GetResult());
} }
pxStaticText &pxStaticText::WrapAt(int width) pxStaticText& pxStaticText::WrapAt(int width)
{ {
m_autowrap = false; m_autowrap = false;
@ -208,7 +211,8 @@ pxStaticText &pxStaticText::WrapAt(int width)
if (width > 1) if (width > 1)
wrappedLabel = pxTextWrapper().Wrap(this, m_label, width).GetResult(); wrappedLabel = pxTextWrapper().Wrap(this, m_label, width).GetResult();
if (m_wrappedLabel != wrappedLabel) { if (m_wrappedLabel != wrappedLabel)
{
m_wrappedLabel = wrappedLabel; m_wrappedLabel = wrappedLabel;
wxSize area = wxClientDC(this).GetMultiLineTextExtent(m_wrappedLabel); wxSize area = wxClientDC(this).GetMultiLineTextExtent(m_wrappedLabel);
SetMinSize(wxSize( SetMinSize(wxSize(
@ -220,7 +224,8 @@ pxStaticText &pxStaticText::WrapAt(int width)
bool pxStaticText::_updateWrapping(bool textChanged) bool pxStaticText::_updateWrapping(bool textChanged)
{ {
if (!m_autowrap) { if (!m_autowrap)
{
//m_wrappedLabel = wxEmptyString; //m_wrappedLabel = wxEmptyString;
//m_wrappedWidth = -1; //m_wrappedWidth = -1;
return false; return false;
@ -254,10 +259,11 @@ void pxStaticText::UpdateWrapping(bool textChanged)
Refresh(); Refresh();
} }
void pxStaticText::SetLabel(const wxString &label) void pxStaticText::SetLabel(const wxString& label)
{ {
const bool labelChanged(label != m_label); const bool labelChanged(label != m_label);
if (labelChanged) { if (labelChanged)
{
m_label = label; m_label = label;
Refresh(); Refresh();
} }
@ -277,14 +283,15 @@ wxFont pxStaticText::GetFontOk() const
bool pxStaticText::Enable(bool enabled) bool pxStaticText::Enable(bool enabled)
{ {
if (_parent::Enable(enabled)) { if (_parent::Enable(enabled))
{
Refresh(); Refresh();
return true; return true;
} }
return false; return false;
} }
void pxStaticText::paintEvent(wxPaintEvent &evt) void pxStaticText::paintEvent(wxPaintEvent& evt)
{ {
wxPaintDC dc(this); wxPaintDC dc(this);
const int dcWidth = dc.GetSize().GetWidth(); const int dcWidth = dc.GetSize().GetWidth();
@ -301,7 +308,7 @@ void pxStaticText::paintEvent(wxPaintEvent &evt)
pxWindowTextWriter writer(dc); pxWindowTextWriter writer(dc);
writer.Align(m_align); writer.Align(m_align);
const wxString &label(m_autowrap ? m_wrappedLabel : m_label); const wxString& label(m_autowrap ? m_wrappedLabel : m_label);
if (m_autowrap) if (m_autowrap)
_updateWrapping(false); _updateWrapping(false);
@ -323,15 +330,18 @@ void pxStaticText::paintEvent(wxPaintEvent &evt)
// Overloaded form wxPanel and friends. // Overloaded form wxPanel and friends.
wxSize pxStaticText::DoGetBestSize() const wxSize pxStaticText::DoGetBestSize() const
{ {
wxClientDC dc(const_cast<pxStaticText *>(this)); wxClientDC dc(const_cast<pxStaticText*>(this));
dc.SetFont(GetFontOk()); dc.SetFont(GetFontOk());
wxSize best; wxSize best;
if (m_autowrap) { if (m_autowrap)
{
best = GetBestWrappedSize(dc); best = GetBestWrappedSize(dc);
//best.x = wxDefaultCoord; //best.x = wxDefaultCoord;
} else { }
else
{
// No autowrapping, so we can force a specific size here! // No autowrapping, so we can force a specific size here!
best = dc.GetMultiLineTextExtent(GetLabel()); best = dc.GetMultiLineTextExtent(GetLabel());
best.x += calcPaddingWidth(best.x); best.x += calcPaddingWidth(best.x);
@ -346,7 +356,7 @@ wxSize pxStaticText::DoGetBestSize() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxStaticHeading (implementations) // pxStaticHeading (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
pxStaticHeading::pxStaticHeading(wxWindow *parent, const wxString &label) pxStaticHeading::pxStaticHeading(wxWindow* parent, const wxString& label)
: _parent(parent) : _parent(parent)
{ {
m_align = wxALIGN_CENTER; m_align = wxALIGN_CENTER;
@ -364,18 +374,18 @@ void pxStaticHeading::SetPaddingDefaults()
m_paddingPct_vert = 0.0f; m_paddingPct_vert = 0.0f;
} }
void operator+=(wxSizer &target, pxStaticText *src) void operator+=(wxSizer& target, pxStaticText* src)
{ {
if (src) if (src)
target.Add(src, pxExpand); target.Add(src, pxExpand);
} }
void operator+=(wxSizer &target, pxStaticText &src) void operator+=(wxSizer& target, pxStaticText& src)
{ {
target.Add(&src, pxExpand); target.Add(&src, pxExpand);
} }
void operator+=(wxSizer *target, pxStaticText &src) void operator+=(wxSizer* target, pxStaticText& src)
{ {
target->Add(&src, pxExpand); target->Add(&src, pxExpand);
} }

View File

@ -51,7 +51,7 @@ protected:
float m_paddingPct_vert; float m_paddingPct_vert;
protected: protected:
explicit pxStaticText(wxWindow *parent = NULL); explicit pxStaticText(wxWindow* parent = NULL);
// wxWindow overloads! // wxWindow overloads!
bool AcceptsFocus() const { return false; } bool AcceptsFocus() const { return false; }
@ -59,44 +59,44 @@ protected:
void DoSetSize(int x, int y, int w, int h, int sizeFlags = wxSIZE_AUTO); void DoSetSize(int x, int y, int w, int h, int sizeFlags = wxSIZE_AUTO);
public: public:
pxStaticText(wxWindow *parent, const wxString &label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL); pxStaticText(wxWindow* parent, const wxString& label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL);
pxStaticText(wxWindow *parent, int heightInLines, const wxString &label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL); pxStaticText(wxWindow* parent, int heightInLines, const wxString& label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL);
virtual ~pxStaticText() = default; virtual ~pxStaticText() = default;
wxFont GetFontOk() const; wxFont GetFontOk() const;
bool Enable(bool enabled = true); bool Enable(bool enabled = true);
virtual void SetLabel(const wxString &label); virtual void SetLabel(const wxString& label);
virtual wxString GetLabel() const { return m_label; } virtual wxString GetLabel() const { return m_label; }
pxStaticText &SetMinWidth(int width); pxStaticText& SetMinWidth(int width);
pxStaticText &SetMinHeight(int height); pxStaticText& SetMinHeight(int height);
pxStaticText &SetHeight(int lines); pxStaticText& SetHeight(int lines);
pxStaticText &Align(wxAlignment align); pxStaticText& Align(wxAlignment align);
pxStaticText &Bold(); pxStaticText& Bold();
pxStaticText &WrapAt(int width); pxStaticText& WrapAt(int width);
pxStaticText &Unwrapped(); pxStaticText& Unwrapped();
pxStaticText &PaddingPixH(int pixels); pxStaticText& PaddingPixH(int pixels);
pxStaticText &PaddingPixV(int pixels); pxStaticText& PaddingPixV(int pixels);
pxStaticText &PaddingPctH(float pct); pxStaticText& PaddingPctH(float pct);
pxStaticText &PaddingPctV(float pct); pxStaticText& PaddingPctV(float pct);
//pxStaticText& DoBestGuessHeight(); //pxStaticText& DoBestGuessHeight();
protected: protected:
void SetPaddingDefaults(); void SetPaddingDefaults();
void Init(const wxString &label); void Init(const wxString& label);
wxSize GetBestWrappedSize(const wxClientDC &dc) const; wxSize GetBestWrappedSize(const wxClientDC& dc) const;
wxSize DoGetBestSize() const; wxSize DoGetBestSize() const;
int calcPaddingWidth(int newWidth) const; int calcPaddingWidth(int newWidth) const;
int calcPaddingHeight(int newHeight) const; int calcPaddingHeight(int newHeight) const;
void paintEvent(wxPaintEvent &evt); void paintEvent(wxPaintEvent& evt);
void UpdateWrapping(bool textChanged); void UpdateWrapping(bool textChanged);
bool _updateWrapping(bool textChanged); bool _updateWrapping(bool textChanged);
@ -108,18 +108,18 @@ class pxStaticHeading : public pxStaticText
typedef pxStaticText _parent; typedef pxStaticText _parent;
public: public:
pxStaticHeading(wxWindow *parent = NULL, const wxString &label = wxEmptyString); pxStaticHeading(wxWindow* parent = NULL, const wxString& label = wxEmptyString);
pxStaticHeading(wxWindow *parent, int heightInLines, const wxString &label = wxEmptyString); pxStaticHeading(wxWindow* parent, int heightInLines, const wxString& label = wxEmptyString);
virtual ~pxStaticHeading() = default; virtual ~pxStaticHeading() = default;
protected: protected:
void SetPaddingDefaults(); void SetPaddingDefaults();
}; };
extern void operator+=(wxSizer &target, pxStaticText &src); extern void operator+=(wxSizer& target, pxStaticText& src);
template <> template <>
inline void operator+=(wxSizer &target, const pxWindowAndFlags<pxStaticText> &src) inline void operator+=(wxSizer& target, const pxWindowAndFlags<pxStaticText>& src)
{ {
target.Add(src.window, src.flags); target.Add(src.window, src.flags);
} }

View File

@ -23,14 +23,14 @@
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxStreamBase (implementations) // pxStreamBase (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
pxStreamBase::pxStreamBase(const wxString &filename) pxStreamBase::pxStreamBase(const wxString& filename)
: m_filename(filename) : m_filename(filename)
{ {
} }
bool pxStreamBase::IsOk() const bool pxStreamBase::IsOk() const
{ {
wxStreamBase *woot = GetWxStreamBase(); wxStreamBase* woot = GetWxStreamBase();
return woot && woot->IsOk(); return woot && woot->IsOk();
} }
@ -47,19 +47,19 @@ wxFileOffset pxStreamBase::Length() const
// Interface for reading data from a gzip stream. // Interface for reading data from a gzip stream.
// //
pxInputStream::pxInputStream(const wxString &filename, std::unique_ptr<wxInputStream> &input) pxInputStream::pxInputStream(const wxString& filename, std::unique_ptr<wxInputStream>& input)
: pxStreamBase(filename) : pxStreamBase(filename)
, m_stream_in(std::move(input)) , m_stream_in(std::move(input))
{ {
} }
pxInputStream::pxInputStream(const wxString &filename, wxInputStream *input) pxInputStream::pxInputStream(const wxString& filename, wxInputStream* input)
: pxStreamBase(filename) : pxStreamBase(filename)
, m_stream_in(input) , m_stream_in(input)
{ {
} }
wxStreamBase *pxInputStream::GetWxStreamBase() const { return m_stream_in.get(); } wxStreamBase* pxInputStream::GetWxStreamBase() const { return m_stream_in.get(); }
wxFileOffset pxInputStream::Tell() const wxFileOffset pxInputStream::Tell() const
{ {
@ -71,22 +71,23 @@ wxFileOffset pxInputStream::Seek(wxFileOffset ofs, wxSeekMode mode)
return m_stream_in->SeekI(ofs, mode); return m_stream_in->SeekI(ofs, mode);
} }
void pxInputStream::SetStream(const wxString &filename, std::unique_ptr<wxInputStream> &stream) void pxInputStream::SetStream(const wxString& filename, std::unique_ptr<wxInputStream>& stream)
{ {
m_filename = filename; m_filename = filename;
m_stream_in = std::move(stream); m_stream_in = std::move(stream);
} }
void pxInputStream::SetStream(const wxString &filename, wxInputStream *stream) void pxInputStream::SetStream(const wxString& filename, wxInputStream* stream)
{ {
m_filename = filename; m_filename = filename;
m_stream_in = std::unique_ptr<wxInputStream>(stream); m_stream_in = std::unique_ptr<wxInputStream>(stream);
} }
void pxInputStream::Read(void *dest, size_t size) void pxInputStream::Read(void* dest, size_t size)
{ {
m_stream_in->Read(dest, size); m_stream_in->Read(dest, size);
if (m_stream_in->GetLastError() == wxSTREAM_READ_ERROR) { if (m_stream_in->GetLastError() == wxSTREAM_READ_ERROR)
{
int err = errno; int err = errno;
if (!err) if (!err)
throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot read from file (bad file handle?)"); throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot read from file (bad file handle?)");
@ -107,19 +108,19 @@ void pxInputStream::Read(void *dest, size_t size)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxOutputStream // pxOutputStream
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
pxOutputStream::pxOutputStream(const wxString &filename, std::unique_ptr<wxOutputStream> &output) pxOutputStream::pxOutputStream(const wxString& filename, std::unique_ptr<wxOutputStream>& output)
: pxStreamBase(filename) : pxStreamBase(filename)
, m_stream_out(std::move(output)) , m_stream_out(std::move(output))
{ {
} }
pxOutputStream::pxOutputStream(const wxString &filename, wxOutputStream *output) pxOutputStream::pxOutputStream(const wxString& filename, wxOutputStream* output)
: pxStreamBase(filename) : pxStreamBase(filename)
, m_stream_out(output) , m_stream_out(output)
{ {
} }
wxStreamBase *pxOutputStream::GetWxStreamBase() const { return m_stream_out.get(); } wxStreamBase* pxOutputStream::GetWxStreamBase() const { return m_stream_out.get(); }
wxFileOffset pxOutputStream::Tell() const wxFileOffset pxOutputStream::Tell() const
{ {
@ -131,23 +132,24 @@ wxFileOffset pxOutputStream::Seek(wxFileOffset ofs, wxSeekMode mode)
return m_stream_out->SeekO(ofs, mode); return m_stream_out->SeekO(ofs, mode);
} }
void pxOutputStream::SetStream(const wxString &filename, std::unique_ptr<wxOutputStream> &stream) void pxOutputStream::SetStream(const wxString& filename, std::unique_ptr<wxOutputStream>& stream)
{ {
m_filename = filename; m_filename = filename;
m_stream_out = std::move(stream); m_stream_out = std::move(stream);
} }
void pxOutputStream::SetStream(const wxString &filename, wxOutputStream *stream) void pxOutputStream::SetStream(const wxString& filename, wxOutputStream* stream)
{ {
m_filename = filename; m_filename = filename;
m_stream_out = std::unique_ptr<wxOutputStream>(stream); m_stream_out = std::unique_ptr<wxOutputStream>(stream);
} }
void pxOutputStream::Write(const void *src, size_t size) void pxOutputStream::Write(const void* src, size_t size)
{ {
m_stream_out->Write(src, size); m_stream_out->Write(src, size);
if (m_stream_out->GetLastError() == wxSTREAM_WRITE_ERROR) { if (m_stream_out->GetLastError() == wxSTREAM_WRITE_ERROR)
{
int err = errno; int err = errno;
if (!err) if (!err)
throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot write to file/stream."); throw Exception::BadStream(m_filename).SetDiagMsg(L"Cannot write to file/stream.");
@ -163,11 +165,12 @@ void pxOutputStream::Write(const void *src, size_t size)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Returns TRUE if the source is UTF8, or FALSE if it's just ASCII crap. // Returns TRUE if the source is UTF8, or FALSE if it's just ASCII crap.
bool pxReadLine(wxInputStream &input, std::string &dest) bool pxReadLine(wxInputStream& input, std::string& dest)
{ {
dest.clear(); dest.clear();
bool isUTF8 = false; bool isUTF8 = false;
while (true) { while (true)
{
char c; char c;
input.Read(&c, sizeof(c)); input.Read(&c, sizeof(c));
if (c == 0) if (c == 0)
@ -176,7 +179,8 @@ bool pxReadLine(wxInputStream &input, std::string &dest)
break; break;
if (c == '\n') if (c == '\n')
break; // eat on UNIX break; // eat on UNIX
if (c == '\r') { if (c == '\r')
{
input.Read(&c, sizeof(c)); input.Read(&c, sizeof(c));
if (c == 0) if (c == 0)
break; break;
@ -196,48 +200,50 @@ bool pxReadLine(wxInputStream &input, std::string &dest)
return isUTF8; return isUTF8;
} }
void pxReadLine(wxInputStream &input, wxString &dest, std::string &intermed) void pxReadLine(wxInputStream& input, wxString& dest, std::string& intermed)
{ {
dest.clear(); dest.clear();
if (pxReadLine(input, intermed)) if (pxReadLine(input, intermed))
dest = fromUTF8(intermed.c_str()); dest = fromUTF8(intermed.c_str());
else { else
{
// Optimized ToAscii conversion. // Optimized ToAscii conversion.
// wx3.0 : NOT COMPATIBLE!! (on linux anyway) // wx3.0 : NOT COMPATIBLE!! (on linux anyway)
const char *ascii = intermed.c_str(); const char* ascii = intermed.c_str();
while (*ascii != 0) while (*ascii != 0)
dest += (wchar_t)(unsigned char)*ascii++; dest += (wchar_t)(unsigned char)*ascii++;
} }
} }
void pxReadLine(wxInputStream &input, wxString &dest) void pxReadLine(wxInputStream& input, wxString& dest)
{ {
std::string line; std::string line;
pxReadLine(input, dest, line); pxReadLine(input, dest, line);
} }
wxString pxReadLine(wxInputStream &input) wxString pxReadLine(wxInputStream& input)
{ {
wxString result; wxString result;
pxReadLine(input, result); pxReadLine(input, result);
return result; return result;
} }
void pxWriteLine(wxOutputStream &output) void pxWriteLine(wxOutputStream& output)
{ {
output.Write("\n", 1); output.Write("\n", 1);
} }
void pxWriteLine(wxOutputStream &output, const wxString &text) void pxWriteLine(wxOutputStream& output, const wxString& text)
{ {
if (!text.IsEmpty()) { if (!text.IsEmpty())
{
pxToUTF8 utf8(text); pxToUTF8 utf8(text);
output.Write(utf8, utf8.Length()); output.Write(utf8, utf8.Length());
} }
pxWriteLine(output); pxWriteLine(output);
} }
void pxWriteMultiline(wxOutputStream &output, const wxString &src) void pxWriteMultiline(wxOutputStream& output, const wxString& src)
{ {
if (src.IsEmpty()) if (src.IsEmpty())
return; return;

View File

@ -34,12 +34,12 @@ protected:
wxString m_filename; wxString m_filename;
public: public:
pxStreamBase(const wxString &filename); pxStreamBase(const wxString& filename);
virtual ~pxStreamBase() = default; virtual ~pxStreamBase() = default;
// Implementing classes should return the base wxStream object (usually either a wxInputStream // Implementing classes should return the base wxStream object (usually either a wxInputStream
// or wxOputStream derivative). // or wxOputStream derivative).
virtual wxStreamBase *GetWxStreamBase() const = 0; virtual wxStreamBase* GetWxStreamBase() const = 0;
virtual void Close() = 0; virtual void Close() = 0;
virtual wxFileOffset Tell() const = 0; virtual wxFileOffset Tell() const = 0;
virtual wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart) = 0; virtual wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart) = 0;
@ -61,21 +61,21 @@ protected:
std::unique_ptr<wxOutputStream> m_stream_out; std::unique_ptr<wxOutputStream> m_stream_out;
public: public:
pxOutputStream(const wxString &filename, std::unique_ptr<wxOutputStream> &output); pxOutputStream(const wxString& filename, std::unique_ptr<wxOutputStream>& output);
pxOutputStream(const wxString &filename, wxOutputStream *output); pxOutputStream(const wxString& filename, wxOutputStream* output);
virtual ~pxOutputStream() = default; virtual ~pxOutputStream() = default;
virtual void Write(const void *data, size_t size); virtual void Write(const void* data, size_t size);
void SetStream(const wxString &filename, std::unique_ptr<wxOutputStream> &stream); void SetStream(const wxString& filename, std::unique_ptr<wxOutputStream>& stream);
void SetStream(const wxString &filename, wxOutputStream *stream); void SetStream(const wxString& filename, wxOutputStream* stream);
void Close() { m_stream_out = nullptr; } void Close() { m_stream_out = nullptr; }
virtual wxStreamBase *GetWxStreamBase() const; virtual wxStreamBase* GetWxStreamBase() const;
template <typename T> template <typename T>
void Write(const T &data) void Write(const T& data)
{ {
Write(&data, sizeof(data)); Write(&data, sizeof(data));
} }
@ -95,21 +95,21 @@ protected:
std::unique_ptr<wxInputStream> m_stream_in; std::unique_ptr<wxInputStream> m_stream_in;
public: public:
pxInputStream(const wxString &filename, std::unique_ptr<wxInputStream> &input); pxInputStream(const wxString& filename, std::unique_ptr<wxInputStream>& input);
pxInputStream(const wxString &filename, wxInputStream *input); pxInputStream(const wxString& filename, wxInputStream* input);
virtual ~pxInputStream() = default; virtual ~pxInputStream() = default;
virtual void Read(void *dest, size_t size); virtual void Read(void* dest, size_t size);
void SetStream(const wxString &filename, std::unique_ptr<wxInputStream> &stream); void SetStream(const wxString& filename, std::unique_ptr<wxInputStream>& stream);
void SetStream(const wxString &filename, wxInputStream *stream); void SetStream(const wxString& filename, wxInputStream* stream);
void Close() { m_stream_in = nullptr; } void Close() { m_stream_in = nullptr; }
virtual wxStreamBase *GetWxStreamBase() const; virtual wxStreamBase* GetWxStreamBase() const;
template <typename T> template <typename T>
void Read(T &dest) void Read(T& dest)
{ {
Read(&dest, sizeof(dest)); Read(&dest, sizeof(dest));
} }

View File

@ -25,12 +25,12 @@ bool pxIsEnglish(int id)
// pxExpandMsg -- an Iconized Text Translator // pxExpandMsg -- an Iconized Text Translator
// Was replaced by a standard implementation of wxGetTranslation // Was replaced by a standard implementation of wxGetTranslation
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
const wxChar *__fastcall pxExpandMsg(const wxChar *message) const wxChar* __fastcall pxExpandMsg(const wxChar* message)
{ {
return wxGetTranslation(message).wc_str(); return wxGetTranslation(message).wc_str();
} }
const wxChar *__fastcall pxGetTranslation(const wxChar *message) const wxChar* __fastcall pxGetTranslation(const wxChar* message)
{ {
return wxGetTranslation(message).wc_str(); return wxGetTranslation(message).wc_str();
} }

View File

@ -20,7 +20,7 @@
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxWindowTextWriter Implementations // pxWindowTextWriter Implementations
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
pxWindowTextWriter::pxWindowTextWriter(wxDC &dc) pxWindowTextWriter::pxWindowTextWriter(wxDC& dc)
: m_dc(dc) : m_dc(dc)
{ {
m_curpos = wxPoint(); m_curpos = wxPoint();
@ -34,7 +34,7 @@ void pxWindowTextWriter::OnFontChanged()
{ {
} }
pxWindowTextWriter &pxWindowTextWriter::SetWeight(wxFontWeight weight) pxWindowTextWriter& pxWindowTextWriter::SetWeight(wxFontWeight weight)
{ {
wxFont curfont(m_dc.GetFont()); wxFont curfont(m_dc.GetFont());
curfont.SetWeight(weight); curfont.SetWeight(weight);
@ -43,7 +43,7 @@ pxWindowTextWriter &pxWindowTextWriter::SetWeight(wxFontWeight weight)
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::SetStyle(wxFontStyle style) pxWindowTextWriter& pxWindowTextWriter::SetStyle(wxFontStyle style)
{ {
wxFont curfont(m_dc.GetFont()); wxFont curfont(m_dc.GetFont());
curfont.SetStyle(style); curfont.SetStyle(style);
@ -51,7 +51,7 @@ pxWindowTextWriter &pxWindowTextWriter::SetStyle(wxFontStyle style)
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::Normal() pxWindowTextWriter& pxWindowTextWriter::Normal()
{ {
wxFont curfont(m_dc.GetFont()); wxFont curfont(m_dc.GetFont());
curfont.SetStyle(wxFONTSTYLE_NORMAL); curfont.SetStyle(wxFONTSTYLE_NORMAL);
@ -61,40 +61,43 @@ pxWindowTextWriter &pxWindowTextWriter::Normal()
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::SetPos(const wxPoint &pos) pxWindowTextWriter& pxWindowTextWriter::SetPos(const wxPoint& pos)
{ {
m_curpos = pos; m_curpos = pos;
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::MovePos(const wxSize &delta) pxWindowTextWriter& pxWindowTextWriter::MovePos(const wxSize& delta)
{ {
m_curpos += delta; m_curpos += delta;
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::SetY(int ypos) pxWindowTextWriter& pxWindowTextWriter::SetY(int ypos)
{ {
m_curpos.y = ypos; m_curpos.y = ypos;
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::MoveY(int ydelta) pxWindowTextWriter& pxWindowTextWriter::MoveY(int ydelta)
{ {
m_curpos.y += ydelta; m_curpos.y += ydelta;
return *this; return *this;
} }
void pxWindowTextWriter::_DoWriteLn(const wxString &msg) void pxWindowTextWriter::_DoWriteLn(const wxString& msg)
{ {
int tWidth, tHeight; int tWidth, tHeight;
m_dc.GetMultiLineTextExtent(msg, &tWidth, &tHeight); m_dc.GetMultiLineTextExtent(msg, &tWidth, &tHeight);
wxPoint dispos(m_curpos); wxPoint dispos(m_curpos);
if (m_align & wxALIGN_CENTER_HORIZONTAL) { if (m_align & wxALIGN_CENTER_HORIZONTAL)
{
dispos.x = (m_dc.GetSize().GetWidth() - tWidth) / 2; dispos.x = (m_dc.GetSize().GetWidth() - tWidth) / 2;
} else if (m_align & wxALIGN_RIGHT) { }
else if (m_align & wxALIGN_RIGHT)
{
dispos.x = m_dc.GetSize().GetWidth() - tWidth; dispos.x = m_dc.GetSize().GetWidth() - tWidth;
} }
@ -104,7 +107,7 @@ void pxWindowTextWriter::_DoWriteLn(const wxString &msg)
// Splits incoming multi-line strings into pieces, and dispatches each line individually // Splits incoming multi-line strings into pieces, and dispatches each line individually
// to the text writer. // to the text writer.
void pxWindowTextWriter::_DoWrite(const wxChar *msg) void pxWindowTextWriter::_DoWrite(const wxChar* msg)
{ {
pxAssert(msg); pxAssert(msg);
@ -115,32 +118,32 @@ void pxWindowTextWriter::_DoWrite(const wxChar *msg)
_DoWriteLn(parts[i]); _DoWriteLn(parts[i]);
} }
pxWindowTextWriter &pxWindowTextWriter::SetFont(const wxFont &font) pxWindowTextWriter& pxWindowTextWriter::SetFont(const wxFont& font)
{ {
m_dc.SetFont(font); m_dc.SetFont(font);
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::Align(const wxAlignment &align) pxWindowTextWriter& pxWindowTextWriter::Align(const wxAlignment& align)
{ {
m_align = align; m_align = align;
m_curpos.x = 0; m_curpos.x = 0;
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::WriteLn() pxWindowTextWriter& pxWindowTextWriter::WriteLn()
{ {
_DoWriteLn(L""); _DoWriteLn(L"");
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::WriteLn(const wxChar *fmt) pxWindowTextWriter& pxWindowTextWriter::WriteLn(const wxChar* fmt)
{ {
_DoWrite(fmt); _DoWrite(fmt);
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::FormatLn(const wxChar *fmt, ...) pxWindowTextWriter& pxWindowTextWriter::FormatLn(const wxChar* fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -149,7 +152,7 @@ pxWindowTextWriter &pxWindowTextWriter::FormatLn(const wxChar *fmt, ...)
return *this; return *this;
} }
pxWindowTextWriter &pxWindowTextWriter::WriteLn(const wxString fmt) pxWindowTextWriter& pxWindowTextWriter::WriteLn(const wxString fmt)
{ {
_DoWrite(fmt.wc_str()); _DoWrite(fmt.wc_str());
return *this; return *this;

View File

@ -39,7 +39,7 @@ ConsoleLogSource_App pxConLog_App;
void BaseDeletableObject::DoDeletion() void BaseDeletableObject::DoDeletion()
{ {
wxAppWithHelpers *app = wxDynamicCast(wxApp::GetInstance(), wxAppWithHelpers); wxAppWithHelpers* app = wxDynamicCast(wxApp::GetInstance(), wxAppWithHelpers);
pxAssert(app != NULL); pxAssert(app != NULL);
app->DeleteObject(*this); app->DeleteObject(*this);
} }
@ -49,16 +49,19 @@ void BaseDeletableObject::DoDeletion()
// SynchronousActionState Implementations // SynchronousActionState Implementations
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
void SynchronousActionState::SetException(const BaseException &ex) void SynchronousActionState::SetException(const BaseException& ex)
{ {
m_exception = ScopedExcept(ex.Clone()); m_exception = ScopedExcept(ex.Clone());
} }
void SynchronousActionState::SetException(BaseException *ex) void SynchronousActionState::SetException(BaseException* ex)
{ {
if (!m_posted) { if (!m_posted)
{
m_exception = ScopedExcept(ex); m_exception = ScopedExcept(ex);
} else if (wxTheApp) { }
else if (wxTheApp)
{
// transport the exception to the main thread, since the message is fully // transport the exception to the main thread, since the message is fully
// asynchronous, or has already entered an asynchronous state. Message is sent // asynchronous, or has already entered an asynchronous state. Message is sent
// as a non-blocking action since proper handling of user errors on async messages // as a non-blocking action since proper handling of user errors on async messages
@ -115,35 +118,36 @@ void SynchronousActionState::PostResult()
wxIMPLEMENT_DYNAMIC_CLASS(pxActionEvent, wxEvent); wxIMPLEMENT_DYNAMIC_CLASS(pxActionEvent, wxEvent);
pxActionEvent::pxActionEvent(SynchronousActionState *sema, int msgtype) pxActionEvent::pxActionEvent(SynchronousActionState* sema, int msgtype)
: wxEvent(0, msgtype) : wxEvent(0, msgtype)
{ {
m_state = sema; m_state = sema;
} }
pxActionEvent::pxActionEvent(SynchronousActionState &sema, int msgtype) pxActionEvent::pxActionEvent(SynchronousActionState& sema, int msgtype)
: wxEvent(0, msgtype) : wxEvent(0, msgtype)
{ {
m_state = &sema; m_state = &sema;
} }
pxActionEvent::pxActionEvent(const pxActionEvent &src) pxActionEvent::pxActionEvent(const pxActionEvent& src)
: wxEvent(src) : wxEvent(src)
{ {
m_state = src.m_state; m_state = src.m_state;
} }
void pxActionEvent::SetException(const BaseException &ex) void pxActionEvent::SetException(const BaseException& ex)
{ {
SetException(ex.Clone()); SetException(ex.Clone());
} }
void pxActionEvent::SetException(BaseException *ex) void pxActionEvent::SetException(BaseException* ex)
{ {
const wxString &prefix(pxsFmt(L"(%s) ", GetClassInfo()->GetClassName())); const wxString& prefix(pxsFmt(L"(%s) ", GetClassInfo()->GetClassName()));
ex->DiagMsg() = prefix + ex->DiagMsg(); ex->DiagMsg() = prefix + ex->DiagMsg();
if (!m_state) { if (!m_state)
{
ScopedExcept exptr(ex); // auto-delete it after handling. ScopedExcept exptr(ex); // auto-delete it after handling.
ex->Rethrow(); ex->Rethrow();
} }
@ -156,21 +160,21 @@ void pxActionEvent::SetException(BaseException *ex)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
wxIMPLEMENT_DYNAMIC_CLASS(pxSynchronousCommandEvent, wxCommandEvent); wxIMPLEMENT_DYNAMIC_CLASS(pxSynchronousCommandEvent, wxCommandEvent);
pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState *sema, wxEventType commandType, int winid) pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState* sema, wxEventType commandType, int winid)
: wxCommandEvent(pxEvt_SynchronousCommand, winid) : wxCommandEvent(pxEvt_SynchronousCommand, winid)
{ {
m_sync = sema; m_sync = sema;
m_realEvent = commandType; m_realEvent = commandType;
} }
pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState &sema, wxEventType commandType, int winid) pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState& sema, wxEventType commandType, int winid)
: wxCommandEvent(pxEvt_SynchronousCommand) : wxCommandEvent(pxEvt_SynchronousCommand)
{ {
m_sync = &sema; m_sync = &sema;
m_realEvent = commandType; m_realEvent = commandType;
} }
pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState *sema, const wxCommandEvent &evt) pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState* sema, const wxCommandEvent& evt)
: wxCommandEvent(evt) : wxCommandEvent(evt)
{ {
m_sync = sema; m_sync = sema;
@ -178,7 +182,7 @@ pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState *sem
SetEventType(pxEvt_SynchronousCommand); SetEventType(pxEvt_SynchronousCommand);
} }
pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState &sema, const wxCommandEvent &evt) pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState& sema, const wxCommandEvent& evt)
: wxCommandEvent(evt) : wxCommandEvent(evt)
{ {
m_sync = &sema; m_sync = &sema;
@ -186,23 +190,24 @@ pxSynchronousCommandEvent::pxSynchronousCommandEvent(SynchronousActionState &sem
SetEventType(pxEvt_SynchronousCommand); SetEventType(pxEvt_SynchronousCommand);
} }
pxSynchronousCommandEvent::pxSynchronousCommandEvent(const pxSynchronousCommandEvent &src) pxSynchronousCommandEvent::pxSynchronousCommandEvent(const pxSynchronousCommandEvent& src)
: wxCommandEvent(src) : wxCommandEvent(src)
{ {
m_sync = src.m_sync; m_sync = src.m_sync;
m_realEvent = src.m_realEvent; m_realEvent = src.m_realEvent;
} }
void pxSynchronousCommandEvent::SetException(const BaseException &ex) void pxSynchronousCommandEvent::SetException(const BaseException& ex)
{ {
if (!m_sync) if (!m_sync)
ex.Rethrow(); ex.Rethrow();
m_sync->SetException(ex); m_sync->SetException(ex);
} }
void pxSynchronousCommandEvent::SetException(BaseException *ex) void pxSynchronousCommandEvent::SetException(BaseException* ex)
{ {
if (!m_sync) { if (!m_sync)
{
ScopedExcept exptr(ex); // auto-delete it after handling. ScopedExcept exptr(ex); // auto-delete it after handling.
ex->Rethrow(); ex->Rethrow();
} }
@ -228,21 +233,21 @@ protected:
public: public:
virtual ~pxRpcEvent() = default; virtual ~pxRpcEvent() = default;
virtual pxRpcEvent *Clone() const { return new pxRpcEvent(*this); } virtual pxRpcEvent* Clone() const { return new pxRpcEvent(*this); }
explicit pxRpcEvent(void (*method)() = NULL, SynchronousActionState *sema = NULL) explicit pxRpcEvent(void (*method)() = NULL, SynchronousActionState* sema = NULL)
: pxActionEvent(sema) : pxActionEvent(sema)
{ {
m_Method = method; m_Method = method;
} }
explicit pxRpcEvent(void (*method)(), SynchronousActionState &sema) explicit pxRpcEvent(void (*method)(), SynchronousActionState& sema)
: pxActionEvent(sema) : pxActionEvent(sema)
{ {
m_Method = method; m_Method = method;
} }
pxRpcEvent(const pxRpcEvent &src) pxRpcEvent(const pxRpcEvent& src)
: pxActionEvent(src) : pxActionEvent(src)
{ {
m_Method = src.m_Method; m_Method = src.m_Method;
@ -266,7 +271,7 @@ wxIMPLEMENT_DYNAMIC_CLASS(pxRpcEvent, pxActionEvent);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxExceptionEvent implementations // pxExceptionEvent implementations
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
pxExceptionEvent::pxExceptionEvent(const BaseException &ex) pxExceptionEvent::pxExceptionEvent(const BaseException& ex)
{ {
m_except = ex.Clone(); m_except = ex.Clone();
} }
@ -291,14 +296,14 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxAppWithHelpers, wxApp);
// Posts a method to the main thread; non-blocking. Post occurs even when called from the // Posts a method to the main thread; non-blocking. Post occurs even when called from the
// main thread. // main thread.
void wxAppWithHelpers::PostMethod(FnType_Void *method) void wxAppWithHelpers::PostMethod(FnType_Void* method)
{ {
PostEvent(pxRpcEvent(method)); PostEvent(pxRpcEvent(method));
} }
// Posts a method to the main thread; non-blocking. Post occurs even when called from the // Posts a method to the main thread; non-blocking. Post occurs even when called from the
// main thread. // main thread.
void wxAppWithHelpers::PostIdleMethod(FnType_Void *method) void wxAppWithHelpers::PostIdleMethod(FnType_Void* method)
{ {
pxRpcEvent evt(method); pxRpcEvent evt(method);
AddIdleEvent(evt); AddIdleEvent(evt);
@ -316,7 +321,7 @@ void wxAppWithHelpers::PostIdleMethod(FnType_Void *method)
// TRUE if the method was invoked. // TRUE if the method was invoked.
// //
bool wxAppWithHelpers::Rpc_TryInvoke(FnType_Void *method) bool wxAppWithHelpers::Rpc_TryInvoke(FnType_Void* method)
{ {
if (wxThread::IsMain()) if (wxThread::IsMain())
return false; return false;
@ -339,7 +344,7 @@ bool wxAppWithHelpers::Rpc_TryInvoke(FnType_Void *method)
// FALSE if the method was not posted to the main thread (meaning this IS the main thread!) // FALSE if the method was not posted to the main thread (meaning this IS the main thread!)
// TRUE if the method was posted. // TRUE if the method was posted.
// //
bool wxAppWithHelpers::Rpc_TryInvokeAsync(FnType_Void *method) bool wxAppWithHelpers::Rpc_TryInvokeAsync(FnType_Void* method)
{ {
if (wxThread::IsMain()) if (wxThread::IsMain())
return false; return false;
@ -347,9 +352,10 @@ bool wxAppWithHelpers::Rpc_TryInvokeAsync(FnType_Void *method)
return true; return true;
} }
void wxAppWithHelpers::ProcessMethod(FnType_Void *method) void wxAppWithHelpers::ProcessMethod(FnType_Void* method)
{ {
if (wxThread::IsMain()) { if (wxThread::IsMain())
{
method(); method();
return; return;
} }
@ -359,7 +365,7 @@ void wxAppWithHelpers::ProcessMethod(FnType_Void *method)
sync.WaitForResult(); sync.WaitForResult();
} }
void wxAppWithHelpers::PostEvent(const wxEvent &evt) void wxAppWithHelpers::PostEvent(const wxEvent& evt)
{ {
// Const Cast is OK! // Const Cast is OK!
// Truth is, AddPendingEvent should be a const-qualified parameter, as // Truth is, AddPendingEvent should be a const-qualified parameter, as
@ -367,10 +373,10 @@ void wxAppWithHelpers::PostEvent(const wxEvent &evt)
// fails again in structured C/C++ design design. So I'm forcing it as such // fails again in structured C/C++ design design. So I'm forcing it as such
// here. -- air // here. -- air
_parent::AddPendingEvent(const_cast<wxEvent &>(evt)); _parent::AddPendingEvent(const_cast<wxEvent&>(evt));
} }
bool wxAppWithHelpers::ProcessEvent(wxEvent &evt) bool wxAppWithHelpers::ProcessEvent(wxEvent& evt)
{ {
// Note: We can't do an automatic blocking post of the message here, because wxWidgets // Note: We can't do an automatic blocking post of the message here, because wxWidgets
// isn't really designed for it (some events return data to the caller via the event // isn't really designed for it (some events return data to the caller via the event
@ -381,18 +387,19 @@ bool wxAppWithHelpers::ProcessEvent(wxEvent &evt)
return _parent::ProcessEvent(evt); return _parent::ProcessEvent(evt);
} }
bool wxAppWithHelpers::ProcessEvent(wxEvent *evt) bool wxAppWithHelpers::ProcessEvent(wxEvent* evt)
{ {
AffinityAssert_AllowFrom_MainUI(); AffinityAssert_AllowFrom_MainUI();
std::unique_ptr<wxEvent> deleteMe(evt); std::unique_ptr<wxEvent> deleteMe(evt);
return _parent::ProcessEvent(*deleteMe); return _parent::ProcessEvent(*deleteMe);
} }
bool wxAppWithHelpers::ProcessEvent(pxActionEvent &evt) bool wxAppWithHelpers::ProcessEvent(pxActionEvent& evt)
{ {
if (wxThread::IsMain()) if (wxThread::IsMain())
return _parent::ProcessEvent(evt); return _parent::ProcessEvent(evt);
else { else
{
SynchronousActionState sync; SynchronousActionState sync;
evt.SetSyncState(sync); evt.SetSyncState(sync);
AddPendingEvent(evt); AddPendingEvent(evt);
@ -401,12 +408,15 @@ bool wxAppWithHelpers::ProcessEvent(pxActionEvent &evt)
} }
} }
bool wxAppWithHelpers::ProcessEvent(pxActionEvent *evt) bool wxAppWithHelpers::ProcessEvent(pxActionEvent* evt)
{ {
if (wxThread::IsMain()) { if (wxThread::IsMain())
{
std::unique_ptr<wxEvent> deleteMe(evt); std::unique_ptr<wxEvent> deleteMe(evt);
return _parent::ProcessEvent(*deleteMe); return _parent::ProcessEvent(*deleteMe);
} else { }
else
{
SynchronousActionState sync; SynchronousActionState sync;
evt->SetSyncState(sync); evt->SetSyncState(sync);
AddPendingEvent(*evt); AddPendingEvent(*evt);
@ -436,11 +446,16 @@ void pxActionEvent::_DoInvokeEvent()
{ {
AffinityAssert_AllowFrom_MainUI(); AffinityAssert_AllowFrom_MainUI();
try { try
{
InvokeEvent(); InvokeEvent();
} catch (BaseException &ex) { }
catch (BaseException& ex)
{
SetException(ex); SetException(ex);
} catch (std::runtime_error &ex) { }
catch (std::runtime_error& ex)
{
SetException(new Exception::RuntimeError(ex)); SetException(new Exception::RuntimeError(ex));
} }
@ -448,26 +463,31 @@ void pxActionEvent::_DoInvokeEvent()
m_state->PostResult(); m_state->PostResult();
} }
void wxAppWithHelpers::OnSynchronousCommand(pxSynchronousCommandEvent &evt) void wxAppWithHelpers::OnSynchronousCommand(pxSynchronousCommandEvent& evt)
{ {
AffinityAssert_AllowFrom_MainUI(); AffinityAssert_AllowFrom_MainUI();
pxAppLog.Write(L"(App) Executing command event synchronously..."); pxAppLog.Write(L"(App) Executing command event synchronously...");
evt.SetEventType(evt.GetRealEventType()); evt.SetEventType(evt.GetRealEventType());
try { try
{
ProcessEvent(evt); ProcessEvent(evt);
} catch (BaseException &ex) { }
catch (BaseException& ex)
{
evt.SetException(ex); evt.SetException(ex);
} catch (std::runtime_error &ex) { }
catch (std::runtime_error& ex)
{
evt.SetException(new Exception::RuntimeError(ex, evt.GetClassInfo()->GetClassName())); evt.SetException(new Exception::RuntimeError(ex, evt.GetClassInfo()->GetClassName()));
} }
if (Semaphore *sema = evt.GetSemaphore()) if (Semaphore* sema = evt.GetSemaphore())
sema->Post(); sema->Post();
} }
void wxAppWithHelpers::AddIdleEvent(const wxEvent &evt) void wxAppWithHelpers::AddIdleEvent(const wxEvent& evt)
{ {
ScopedLock lock(m_IdleEventMutex); ScopedLock lock(m_IdleEventMutex);
if (m_IdleEventQueue.empty()) if (m_IdleEventQueue.empty())
@ -476,14 +496,14 @@ void wxAppWithHelpers::AddIdleEvent(const wxEvent &evt)
m_IdleEventQueue.push_back(evt.Clone()); m_IdleEventQueue.push_back(evt.Clone());
} }
void wxAppWithHelpers::OnStartIdleEventTimer(wxCommandEvent &evt) void wxAppWithHelpers::OnStartIdleEventTimer(wxCommandEvent& evt)
{ {
ScopedLock lock(m_IdleEventMutex); ScopedLock lock(m_IdleEventMutex);
if (!m_IdleEventQueue.empty()) if (!m_IdleEventQueue.empty())
m_IdleEventTimer.Start(100, true); m_IdleEventTimer.Start(100, true);
} }
void wxAppWithHelpers::IdleEventDispatcher(const wxChar *action) void wxAppWithHelpers::IdleEventDispatcher(const wxChar* action)
{ {
// Recursion is possible thanks to modal dialogs being issued from the idle event handler. // Recursion is possible thanks to modal dialogs being issued from the idle event handler.
// (recursion shouldn't hurt anything anyway, since the node system re-creates the iterator // (recursion shouldn't hurt anything anyway, since the node system re-creates the iterator
@ -498,20 +518,24 @@ void wxAppWithHelpers::IdleEventDispatcher(const wxChar *action)
ScopedLock lock(m_IdleEventMutex); ScopedLock lock(m_IdleEventMutex);
while (node = m_IdleEventQueue.begin(), node != m_IdleEventQueue.end()) { while (node = m_IdleEventQueue.begin(), node != m_IdleEventQueue.end())
{
std::unique_ptr<wxEvent> deleteMe(*node); std::unique_ptr<wxEvent> deleteMe(*node);
m_IdleEventQueue.erase(node); m_IdleEventQueue.erase(node);
lock.Release(); lock.Release();
if (!Threading::AllowDeletions() && (deleteMe->GetEventType() == pxEvt_DeleteThread)) { if (!Threading::AllowDeletions() && (deleteMe->GetEventType() == pxEvt_DeleteThread))
{
// Threads that have active semaphores or mutexes (other threads are waiting on them) cannot // Threads that have active semaphores or mutexes (other threads are waiting on them) cannot
// be deleted because those mutex/sema objects will become invalid and cause the pending // be deleted because those mutex/sema objects will become invalid and cause the pending
// thread to crash. So we disallow deletions when those waits are in action, and continue // thread to crash. So we disallow deletions when those waits are in action, and continue
// to postpone the deletion of the thread until such time that it is safe. // to postpone the deletion of the thread until such time that it is safe.
pxThreadLog.Write(((pxThread *)((wxCommandEvent *)deleteMe.get())->GetClientData())->GetName(), L"Deletion postponed due to mutex or semaphore dependency."); pxThreadLog.Write(((pxThread*)((wxCommandEvent*)deleteMe.get())->GetClientData())->GetName(), L"Deletion postponed due to mutex or semaphore dependency.");
postponed.push_back(deleteMe.release()); postponed.push_back(deleteMe.release());
} else { }
else
{
pxAppLog.Write(L"(AppIdleQueue%s) Dispatching event '%s'", action, deleteMe->GetClassInfo()->GetClassName()); pxAppLog.Write(L"(AppIdleQueue%s) Dispatching event '%s'", action, deleteMe->GetClassInfo()->GetClassName());
ProcessEvent(*deleteMe); // dereference to prevent auto-deletion by ProcessEvent ProcessEvent(*deleteMe); // dereference to prevent auto-deletion by ProcessEvent
} }
@ -523,13 +547,13 @@ void wxAppWithHelpers::IdleEventDispatcher(const wxChar *action)
pxAppLog.Write(L"(AppIdleQueue%s) %d events postponed due to dependencies.", action, m_IdleEventQueue.size()); pxAppLog.Write(L"(AppIdleQueue%s) %d events postponed due to dependencies.", action, m_IdleEventQueue.size());
} }
void wxAppWithHelpers::OnIdleEvent(wxIdleEvent &evt) void wxAppWithHelpers::OnIdleEvent(wxIdleEvent& evt)
{ {
m_IdleEventTimer.Stop(); m_IdleEventTimer.Stop();
IdleEventDispatcher(); IdleEventDispatcher();
} }
void wxAppWithHelpers::OnIdleEventTimeout(wxTimerEvent &evt) void wxAppWithHelpers::OnIdleEventTimeout(wxTimerEvent& evt)
{ {
IdleEventDispatcher(L"[Timeout]"); IdleEventDispatcher(L"[Timeout]");
} }
@ -544,7 +568,7 @@ void wxAppWithHelpers::Ping()
sync.WaitForResult(); sync.WaitForResult();
} }
void wxAppWithHelpers::PostCommand(void *clientData, int evtType, int intParam, long longParam, const wxString &stringParam) void wxAppWithHelpers::PostCommand(void* clientData, int evtType, int intParam, long longParam, const wxString& stringParam)
{ {
wxCommandEvent evt(evtType); wxCommandEvent evt(evtType);
evt.SetClientData(clientData); evt.SetClientData(clientData);
@ -554,12 +578,12 @@ void wxAppWithHelpers::PostCommand(void *clientData, int evtType, int intParam,
AddPendingEvent(evt); AddPendingEvent(evt);
} }
void wxAppWithHelpers::PostCommand(int evtType, int intParam, long longParam, const wxString &stringParam) void wxAppWithHelpers::PostCommand(int evtType, int intParam, long longParam, const wxString& stringParam)
{ {
PostCommand(NULL, evtType, intParam, longParam, stringParam); PostCommand(NULL, evtType, intParam, longParam, stringParam);
} }
sptr wxAppWithHelpers::ProcessCommand(void *clientData, int evtType, int intParam, long longParam, const wxString &stringParam) sptr wxAppWithHelpers::ProcessCommand(void* clientData, int evtType, int intParam, long longParam, const wxString& stringParam)
{ {
SynchronousActionState sync; SynchronousActionState sync;
pxSynchronousCommandEvent evt(sync, evtType); pxSynchronousCommandEvent evt(sync, evtType);
@ -574,41 +598,43 @@ sptr wxAppWithHelpers::ProcessCommand(void *clientData, int evtType, int intPara
return sync.return_value; return sync.return_value;
} }
sptr wxAppWithHelpers::ProcessCommand(int evtType, int intParam, long longParam, const wxString &stringParam) sptr wxAppWithHelpers::ProcessCommand(int evtType, int intParam, long longParam, const wxString& stringParam)
{ {
return ProcessCommand(NULL, evtType, intParam, longParam, stringParam); return ProcessCommand(NULL, evtType, intParam, longParam, stringParam);
} }
void wxAppWithHelpers::PostAction(const pxActionEvent &evt) void wxAppWithHelpers::PostAction(const pxActionEvent& evt)
{ {
PostEvent(evt); PostEvent(evt);
} }
void wxAppWithHelpers::ProcessAction(pxActionEvent &evt) void wxAppWithHelpers::ProcessAction(pxActionEvent& evt)
{ {
if (!wxThread::IsMain()) { if (!wxThread::IsMain())
{
SynchronousActionState sync; SynchronousActionState sync;
evt.SetSyncState(sync); evt.SetSyncState(sync);
AddPendingEvent(evt); AddPendingEvent(evt);
sync.WaitForResult(); sync.WaitForResult();
} else }
else
evt._DoInvokeEvent(); evt._DoInvokeEvent();
} }
void wxAppWithHelpers::DeleteObject(BaseDeletableObject &obj) void wxAppWithHelpers::DeleteObject(BaseDeletableObject& obj)
{ {
pxAssert(!obj.IsBeingDeleted()); pxAssert(!obj.IsBeingDeleted());
wxCommandEvent evt(pxEvt_DeleteObject); wxCommandEvent evt(pxEvt_DeleteObject);
evt.SetClientData((void *)&obj); evt.SetClientData((void*)&obj);
AddIdleEvent(evt); AddIdleEvent(evt);
} }
void wxAppWithHelpers::DeleteThread(pxThread &obj) void wxAppWithHelpers::DeleteThread(pxThread& obj)
{ {
pxThreadLog.Write(obj.GetName(), L"Scheduling for deletion..."); pxThreadLog.Write(obj.GetName(), L"Scheduling for deletion...");
wxCommandEvent evt(pxEvt_DeleteThread); wxCommandEvent evt(pxEvt_DeleteThread);
evt.SetClientData((void *)&obj); evt.SetClientData((void*)&obj);
AddIdleEvent(evt); AddIdleEvent(evt);
} }
@ -629,16 +655,16 @@ bool wxAppWithHelpers::OnInit()
return _parent::OnInit(); return _parent::OnInit();
} }
void wxAppWithHelpers::OnInvokeAction(pxActionEvent &evt) void wxAppWithHelpers::OnInvokeAction(pxActionEvent& evt)
{ {
evt._DoInvokeEvent(); // wow this is easy! evt._DoInvokeEvent(); // wow this is easy!
} }
void wxAppWithHelpers::OnDeleteObject(wxCommandEvent &evt) void wxAppWithHelpers::OnDeleteObject(wxCommandEvent& evt)
{ {
if (evt.GetClientData() == NULL) if (evt.GetClientData() == NULL)
return; return;
delete (BaseDeletableObject *)evt.GetClientData(); delete (BaseDeletableObject*)evt.GetClientData();
} }
// In theory we create a Pcsx2App object which inherit from wxAppWithHelpers, // In theory we create a Pcsx2App object which inherit from wxAppWithHelpers,
@ -648,17 +674,18 @@ void wxAppWithHelpers::OnDeleteObject(wxCommandEvent &evt)
// be called first. This constructor will build some wx objects (here wxTimer) // be called first. This constructor will build some wx objects (here wxTimer)
// that require a trait. In others word, wxAppWithHelpers::CreateTraits will be // that require a trait. In others word, wxAppWithHelpers::CreateTraits will be
// called instead // called instead
wxAppTraits *wxAppWithHelpers::CreateTraits() wxAppTraits* wxAppWithHelpers::CreateTraits()
{ {
return new Pcsx2AppTraits; return new Pcsx2AppTraits;
} }
// Threads have their own deletion handler that propagates exceptions thrown by the thread to the UI. // Threads have their own deletion handler that propagates exceptions thrown by the thread to the UI.
// (thus we have a fairly automatic threaded exception system!) // (thus we have a fairly automatic threaded exception system!)
void wxAppWithHelpers::OnDeleteThread(wxCommandEvent &evt) void wxAppWithHelpers::OnDeleteThread(wxCommandEvent& evt)
{ {
std::unique_ptr<pxThread> thr((pxThread *)evt.GetClientData()); std::unique_ptr<pxThread> thr((pxThread*)evt.GetClientData());
if (!thr) { if (!thr)
{
pxThreadLog.Write(L"null", L"OnDeleteThread: NULL thread object received (and ignored)."); pxThreadLog.Write(L"null", L"OnDeleteThread: NULL thread object received (and ignored).");
return; return;
} }

View File

@ -49,16 +49,16 @@ extern ConsoleLogSource_App pxConLog_App;
class ModalButtonPanel : public wxPanelWithHelpers class ModalButtonPanel : public wxPanelWithHelpers
{ {
public: public:
ModalButtonPanel(wxWindow *window, const MsgButtons &buttons); ModalButtonPanel(wxWindow* window, const MsgButtons& buttons);
virtual ~ModalButtonPanel() = default; virtual ~ModalButtonPanel() = default;
virtual void AddActionButton(wxWindowID id); virtual void AddActionButton(wxWindowID id);
virtual void AddCustomButton(wxWindowID id, const wxString &label); virtual void AddCustomButton(wxWindowID id, const wxString& label);
virtual void OnActionButtonClicked(wxCommandEvent &evt); virtual void OnActionButtonClicked(wxCommandEvent& evt);
}; };
typedef std::list<wxEvent *> wxEventList; typedef std::list<wxEvent*> wxEventList;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// wxAppWithHelpers // wxAppWithHelpers
@ -78,68 +78,68 @@ public:
wxAppWithHelpers(); wxAppWithHelpers();
virtual ~wxAppWithHelpers() {} virtual ~wxAppWithHelpers() {}
wxAppTraits *CreateTraits(); wxAppTraits* CreateTraits();
void CleanUp(); void CleanUp();
void DeleteObject(BaseDeletableObject &obj); void DeleteObject(BaseDeletableObject& obj);
void DeleteObject(BaseDeletableObject *obj) void DeleteObject(BaseDeletableObject* obj)
{ {
if (obj == NULL) if (obj == NULL)
return; return;
DeleteObject(*obj); DeleteObject(*obj);
} }
void DeleteThread(Threading::pxThread &obj); void DeleteThread(Threading::pxThread& obj);
void DeleteThread(Threading::pxThread *obj) void DeleteThread(Threading::pxThread* obj)
{ {
if (obj == NULL) if (obj == NULL)
return; return;
DeleteThread(*obj); DeleteThread(*obj);
} }
void PostCommand(void *clientData, int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString); void PostCommand(void* clientData, int evtType, int intParam = 0, long longParam = 0, const wxString& stringParam = wxEmptyString);
void PostCommand(int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString); void PostCommand(int evtType, int intParam = 0, long longParam = 0, const wxString& stringParam = wxEmptyString);
void PostMethod(FnType_Void *method); void PostMethod(FnType_Void* method);
void PostIdleMethod(FnType_Void *method); void PostIdleMethod(FnType_Void* method);
void ProcessMethod(FnType_Void *method); void ProcessMethod(FnType_Void* method);
bool Rpc_TryInvoke(FnType_Void *method); bool Rpc_TryInvoke(FnType_Void* method);
bool Rpc_TryInvokeAsync(FnType_Void *method); bool Rpc_TryInvokeAsync(FnType_Void* method);
sptr ProcessCommand(void *clientData, int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString); sptr ProcessCommand(void* clientData, int evtType, int intParam = 0, long longParam = 0, const wxString& stringParam = wxEmptyString);
sptr ProcessCommand(int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString); sptr ProcessCommand(int evtType, int intParam = 0, long longParam = 0, const wxString& stringParam = wxEmptyString);
void ProcessAction(pxActionEvent &evt); void ProcessAction(pxActionEvent& evt);
void PostAction(const pxActionEvent &evt); void PostAction(const pxActionEvent& evt);
void Ping(); void Ping();
bool OnInit(); bool OnInit();
//int OnExit(); //int OnExit();
void AddIdleEvent(const wxEvent &evt); void AddIdleEvent(const wxEvent& evt);
void PostEvent(const wxEvent &evt); void PostEvent(const wxEvent& evt);
bool ProcessEvent(wxEvent &evt); bool ProcessEvent(wxEvent& evt);
bool ProcessEvent(wxEvent *evt); bool ProcessEvent(wxEvent* evt);
bool ProcessEvent(pxActionEvent &evt); bool ProcessEvent(pxActionEvent& evt);
bool ProcessEvent(pxActionEvent *evt); bool ProcessEvent(pxActionEvent* evt);
protected: protected:
void IdleEventDispatcher(const wxChar *action = wxEmptyString); void IdleEventDispatcher(const wxChar* action = wxEmptyString);
void OnIdleEvent(wxIdleEvent &evt); void OnIdleEvent(wxIdleEvent& evt);
void OnStartIdleEventTimer(wxCommandEvent &evt); void OnStartIdleEventTimer(wxCommandEvent& evt);
void OnIdleEventTimeout(wxTimerEvent &evt); void OnIdleEventTimeout(wxTimerEvent& evt);
void OnDeleteObject(wxCommandEvent &evt); void OnDeleteObject(wxCommandEvent& evt);
void OnDeleteThread(wxCommandEvent &evt); void OnDeleteThread(wxCommandEvent& evt);
void OnSynchronousCommand(pxSynchronousCommandEvent &evt); void OnSynchronousCommand(pxSynchronousCommandEvent& evt);
void OnInvokeAction(pxActionEvent &evt); void OnInvokeAction(pxActionEvent& evt);
}; };
namespace Msgbox namespace Msgbox
{ {
extern int ShowModal(BaseMessageBoxEvent &evt); extern int ShowModal(BaseMessageBoxEvent& evt);
extern int ShowModal(const wxString &title, const wxString &content, const MsgButtons &buttons); extern int ShowModal(const wxString& title, const wxString& content, const MsgButtons& buttons);
} } // namespace Msgbox

View File

@ -26,11 +26,11 @@
// which require wxCore, see wxGuiTools.h // which require wxCore, see wxGuiTools.h
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
extern void pxExplore(const wxString &path); extern void pxExplore(const wxString& path);
extern void pxExplore(const char *path); extern void pxExplore(const char* path);
extern void pxLaunch(const wxString &path); extern void pxLaunch(const wxString& path);
extern void pxLaunch(const char *path); extern void pxLaunch(const char* path);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// wxDoNotLogInThisScope // wxDoNotLogInThisScope
@ -62,10 +62,10 @@ public:
}; };
extern wxString pxReadLine(wxInputStream &input); extern wxString pxReadLine(wxInputStream& input);
extern void pxReadLine(wxInputStream &input, wxString &dest); extern void pxReadLine(wxInputStream& input, wxString& dest);
extern void pxReadLine(wxInputStream &input, wxString &dest, std::string &intermed); extern void pxReadLine(wxInputStream& input, wxString& dest, std::string& intermed);
extern bool pxReadLine(wxInputStream &input, std::string &dest); extern bool pxReadLine(wxInputStream& input, std::string& dest);
extern void pxWriteLine(wxOutputStream &output); extern void pxWriteLine(wxOutputStream& output);
extern void pxWriteLine(wxOutputStream &output, const wxString &text); extern void pxWriteLine(wxOutputStream& output, const wxString& text);
extern void pxWriteMultiline(wxOutputStream &output, const wxString &src); extern void pxWriteMultiline(wxOutputStream& output, const wxString& src);

View File

@ -40,7 +40,8 @@ const pxStretchType
wxSizerFlags pxAlignmentType::Apply(wxSizerFlags flags) const wxSizerFlags pxAlignmentType::Apply(wxSizerFlags flags) const
{ {
switch (intval) { switch (intval)
{
case Centre: case Centre:
flags.Align(flags.GetFlags() | wxALIGN_CENTRE_HORIZONTAL); flags.Align(flags.GetFlags() | wxALIGN_CENTRE_HORIZONTAL);
break; break;
@ -70,7 +71,8 @@ wxSizerFlags pxAlignmentType::Apply(wxSizerFlags flags) const
wxSizerFlags pxStretchType::Apply(wxSizerFlags flags) const wxSizerFlags pxStretchType::Apply(wxSizerFlags flags) const
{ {
switch (intval) { switch (intval)
{
case Shrink: case Shrink:
//pxFail( "wxSHRINK is an ignored stretch flag." ); //pxFail( "wxSHRINK is an ignored stretch flag." );
break; break;
@ -98,7 +100,7 @@ wxSizerFlags pxStretchType::Apply(wxSizerFlags flags) const
return flags; return flags;
} }
wxSizerFlags operator&(const wxSizerFlags &_flgs, const wxSizerFlags &_flgs2) wxSizerFlags operator&(const wxSizerFlags& _flgs, const wxSizerFlags& _flgs2)
{ {
//return align.Apply( _flgs ); //return align.Apply( _flgs );
wxSizerFlags retval; wxSizerFlags retval;
@ -127,44 +129,44 @@ wxSizerFlags operator&(const wxSizerFlags &_flgs, const wxSizerFlags &_flgs2)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Reference/Handle versions! // Reference/Handle versions!
void operator+=(wxSizer &target, wxWindow *src) void operator+=(wxSizer& target, wxWindow* src)
{ {
target.Add(src); target.Add(src);
} }
void operator+=(wxSizer &target, wxSizer *src) void operator+=(wxSizer& target, wxSizer* src)
{ {
target.Add(src); target.Add(src);
} }
void operator+=(wxSizer &target, wxWindow &src) void operator+=(wxSizer& target, wxWindow& src)
{ {
target.Add(&src); target.Add(&src);
} }
void operator+=(wxSizer &target, wxSizer &src) void operator+=(wxSizer& target, wxSizer& src)
{ {
target.Add(&src); target.Add(&src);
} }
void operator+=(wxSizer &target, int spacer) void operator+=(wxSizer& target, int spacer)
{ {
target.AddSpacer(spacer); target.AddSpacer(spacer);
} }
void operator+=(wxSizer &target, const pxStretchSpacer &spacer) void operator+=(wxSizer& target, const pxStretchSpacer& spacer)
{ {
target.AddStretchSpacer(spacer.proportion); target.AddStretchSpacer(spacer.proportion);
} }
void operator+=(wxWindow &target, int spacer) void operator+=(wxWindow& target, int spacer)
{ {
if (!pxAssert(target.GetSizer() != NULL)) if (!pxAssert(target.GetSizer() != NULL))
return; return;
target.GetSizer()->AddSpacer(spacer); target.GetSizer()->AddSpacer(spacer);
} }
void operator+=(wxWindow &target, const pxStretchSpacer &spacer) void operator+=(wxWindow& target, const pxStretchSpacer& spacer)
{ {
if (!pxAssert(target.GetSizer() != NULL)) if (!pxAssert(target.GetSizer() != NULL))
return; return;
@ -175,14 +177,14 @@ void operator+=(wxWindow &target, const pxStretchSpacer &spacer)
// Pointer versions! (note that C++ requires one of the two operator params be a // Pointer versions! (note that C++ requires one of the two operator params be a
// "poper" object type (non-pointer), so that's why there's only a couple of these. // "poper" object type (non-pointer), so that's why there's only a couple of these.
void operator+=(wxSizer *target, wxWindow &src) void operator+=(wxSizer* target, wxWindow& src)
{ {
if (!pxAssert(target != NULL)) if (!pxAssert(target != NULL))
return; return;
target->Add(&src); target->Add(&src);
} }
void operator+=(wxSizer *target, wxSizer &src) void operator+=(wxSizer* target, wxSizer& src)
{ {
if (!pxAssert(target != NULL)) if (!pxAssert(target != NULL))
return; return;
@ -194,7 +196,7 @@ void operator+=(wxSizer *target, wxSizer &src)
// Returns FALSE if the window position is considered invalid, which means that it's title // Returns FALSE if the window position is considered invalid, which means that it's title
// bar is most likely not easily grabble. Such a window should be moved to a valid or // bar is most likely not easily grabble. Such a window should be moved to a valid or
// default position. // default position.
bool pxIsValidWindowPosition(const wxWindow &window, const wxPoint &windowPos) bool pxIsValidWindowPosition(const wxWindow& window, const wxPoint& windowPos)
{ {
// The height of the window is only revlevant to the height of a title bar, which is // The height of the window is only revlevant to the height of a title bar, which is
// all we need visible for the user to be able to drag the window into view. But // all we need visible for the user to be able to drag the window into view. But
@ -408,7 +410,7 @@ static bool no_break_before(const uint ch)
return false; return false;
} }
pxTextWrapperBase &pxTextWrapperBase::Wrap(const wxWindow &win, const wxString &text, int widthMax) pxTextWrapperBase& pxTextWrapperBase::Wrap(const wxWindow& win, const wxString& text, int widthMax)
{ {
if (text.empty()) if (text.empty())
return *this; return *this;
@ -420,8 +422,10 @@ pxTextWrapperBase &pxTextWrapperBase::Wrap(const wxWindow &win, const wxString &
wxString::const_iterator lastSpace = text.end(); wxString::const_iterator lastSpace = text.end();
wxString::const_iterator lineStart = text.begin(); wxString::const_iterator lineStart = text.begin();
for (wxString::const_iterator p = lineStart;; ++p) { for (wxString::const_iterator p = lineStart;; ++p)
if (IsStartOfNewLine()) { {
if (IsStartOfNewLine())
{
OnNewLine(); OnNewLine();
lastSpace = text.end(); lastSpace = text.end();
@ -433,28 +437,36 @@ pxTextWrapperBase &pxTextWrapperBase::Wrap(const wxWindow &win, const wxString &
line.clear(); line.clear();
} }
if (p == text.end() || *p == L'\n') { if (p == text.end() || *p == L'\n')
{
wasWrapped = false; wasWrapped = false;
DoOutputLine(line); DoOutputLine(line);
if (p == text.end()) if (p == text.end())
break; break;
} else { // not EOL }
if (is_cjk_char(*p)) { else
if (!no_break_before(*p)) { { // not EOL
if (is_cjk_char(*p))
{
if (!no_break_before(*p))
{
if (p == lineStart || !no_break_after(*(p - 1))) if (p == lineStart || !no_break_after(*(p - 1)))
lastSpace = p; lastSpace = p;
} }
} else if (*p == L' ' || *p == L',' || *p == L'/') }
else if (*p == L' ' || *p == L',' || *p == L'/')
lastSpace = p; lastSpace = p;
line += *p; line += *p;
if (widthMax >= 0 && lastSpace != text.end()) { if (widthMax >= 0 && lastSpace != text.end())
{
int width; int width;
win.GetTextExtent(line, &width, NULL); win.GetTextExtent(line, &width, NULL);
if (width > widthMax) { if (width > widthMax)
{
wasWrapped = true; wasWrapped = true;
// remove the last word from this line // remove the last word from this line
@ -476,7 +488,7 @@ pxTextWrapperBase &pxTextWrapperBase::Wrap(const wxWindow &win, const wxString &
return *this; return *this;
} }
void pxTextWrapperBase::DoOutputLine(const wxString &line) void pxTextWrapperBase::DoOutputLine(const wxString& line)
{ {
OnOutputLine(line); OnOutputLine(line);
m_linecount++; m_linecount++;
@ -495,20 +507,20 @@ bool pxTextWrapperBase::IsStartOfNewLine()
return true; return true;
} }
pxTextWrapper &pxTextWrapper::Wrap(const wxWindow &win, const wxString &text, int widthMax) pxTextWrapper& pxTextWrapper::Wrap(const wxWindow& win, const wxString& text, int widthMax)
{ {
_parent::Wrap(win, text, widthMax); _parent::Wrap(win, text, widthMax);
return *this; return *this;
} }
pxTextWrapper &pxTextWrapper::Wrap(const wxWindow *win, const wxString &text, int widthMax) pxTextWrapper& pxTextWrapper::Wrap(const wxWindow* win, const wxString& text, int widthMax)
{ {
if (win) if (win)
_parent::Wrap(*win, text, widthMax); _parent::Wrap(*win, text, widthMax);
return *this; return *this;
} }
void pxTextWrapper::OnOutputLine(const wxString &line) void pxTextWrapper::OnOutputLine(const wxString& line)
{ {
m_text += line; m_text += line;
} }
@ -544,7 +556,8 @@ ScopedBusyCursor::~ScopedBusyCursor()
if (!pxAssert(wxTheApp != NULL)) if (!pxAssert(wxTheApp != NULL))
return; return;
if (!pxAssert(!m_cursorStack.empty())) { if (!pxAssert(!m_cursorStack.empty()))
{
SetManualBusyCursor(m_defBusyType); SetManualBusyCursor(m_defBusyType);
return; return;
} }
@ -570,7 +583,8 @@ void ScopedBusyCursor::SetDefault(BusyCursorType busytype)
void ScopedBusyCursor::SetManualBusyCursor(BusyCursorType busytype) void ScopedBusyCursor::SetManualBusyCursor(BusyCursorType busytype)
{ {
switch (busytype) { switch (busytype)
{
case Cursor_NotBusy: case Cursor_NotBusy:
wxSetCursor(wxNullCursor); wxSetCursor(wxNullCursor);
break; break;
@ -583,7 +597,7 @@ void ScopedBusyCursor::SetManualBusyCursor(BusyCursorType busytype)
} }
} }
const wxCursor &MoreStockCursors::GetArrowWait() const wxCursor& MoreStockCursors::GetArrowWait()
{ {
if (!m_arrowWait) if (!m_arrowWait)
m_arrowWait = std::make_unique<wxCursor>(wxCURSOR_ARROWWAIT); m_arrowWait = std::make_unique<wxCursor>(wxCURSOR_ARROWWAIT);
@ -599,7 +613,7 @@ MoreStockCursors StockCursors;
// extends the tooltip time to the maximum possible. GTK seems to have indefinite // extends the tooltip time to the maximum possible. GTK seems to have indefinite
// tooltips, I don't know about OS X. // tooltips, I don't know about OS X.
void pxSetToolTip(wxWindow *wind, const wxString &src) void pxSetToolTip(wxWindow* wind, const wxString& src)
{ {
if (wind == NULL) if (wind == NULL)
return; // Silently ignore nulls return; // Silently ignore nulls
@ -612,7 +626,7 @@ void pxSetToolTip(wxWindow *wind, const wxString &src)
#endif #endif
} }
void pxSetToolTip(wxWindow &wind, const wxString &src) void pxSetToolTip(wxWindow& wind, const wxString& src)
{ {
pxSetToolTip(&wind, src); pxSetToolTip(&wind, src);
} }

View File

@ -36,17 +36,17 @@ class wxSpinCtrl;
namespace pxSizerFlags namespace pxSizerFlags
{ {
static int StdPadding = 4; static int StdPadding = 4;
extern wxSizerFlags StdSpace(); extern wxSizerFlags StdSpace();
extern wxSizerFlags StdCenter(); extern wxSizerFlags StdCenter();
extern wxSizerFlags StdExpand(); extern wxSizerFlags StdExpand();
extern wxSizerFlags TopLevelBox(); extern wxSizerFlags TopLevelBox();
extern wxSizerFlags SubGroup(); extern wxSizerFlags SubGroup();
extern wxSizerFlags StdButton(); extern wxSizerFlags StdButton();
extern wxSizerFlags Checkbox(); extern wxSizerFlags Checkbox();
extern void SetBestPadding(); extern void SetBestPadding();
}; }; // namespace pxSizerFlags
#define wxSF wxSizerFlags() #define wxSF wxSizerFlags()
@ -58,7 +58,8 @@ extern void SetBestPadding();
// //
struct pxAlignmentType struct pxAlignmentType
{ {
enum { enum
{
Centre, Centre,
Center = Centre, Center = Centre,
Middle, Middle,
@ -72,7 +73,7 @@ struct pxAlignmentType
wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const; wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const;
wxSizerFlags operator&(const wxSizerFlags &_flgs) const wxSizerFlags operator&(const wxSizerFlags& _flgs) const
{ {
return Apply(_flgs); return Apply(_flgs);
} }
@ -100,7 +101,8 @@ struct pxAlignmentType
struct pxStretchType struct pxStretchType
{ {
enum { enum
{
Shrink, Shrink,
Expand, Expand,
Shaped, Shaped,
@ -112,7 +114,7 @@ struct pxStretchType
wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const; wxSizerFlags Apply(wxSizerFlags flags = wxSizerFlags()) const;
wxSizerFlags operator&(const wxSizerFlags &_flgs) const wxSizerFlags operator&(const wxSizerFlags& _flgs) const
{ {
return Apply(_flgs); return Apply(_flgs);
} }
@ -188,22 +190,22 @@ extern const pxStretchType
template <typename WinType> template <typename WinType>
struct pxWindowAndFlags struct pxWindowAndFlags
{ {
WinType *window; WinType* window;
wxSizerFlags flags; wxSizerFlags flags;
}; };
extern wxSizerFlags operator&(const wxSizerFlags &_flgs, const wxSizerFlags &_flgs2); extern wxSizerFlags operator&(const wxSizerFlags& _flgs, const wxSizerFlags& _flgs2);
template <typename WinType, typename = typename std::enable_if<std::is_base_of<wxObject, WinType>::value>::type> template <typename WinType, typename = typename std::enable_if<std::is_base_of<wxObject, WinType>::value>::type>
pxWindowAndFlags<WinType> operator|(WinType *_win, const wxSizerFlags &_flgs) pxWindowAndFlags<WinType> operator|(WinType* _win, const wxSizerFlags& _flgs)
{ {
pxWindowAndFlags<WinType> result = {_win, _flgs}; pxWindowAndFlags<WinType> result = {_win, _flgs};
return result; return result;
} }
template <typename WinType, typename = typename std::enable_if<std::is_base_of<wxObject, WinType>::value>::type> template <typename WinType, typename = typename std::enable_if<std::is_base_of<wxObject, WinType>::value>::type>
pxWindowAndFlags<WinType> operator|(WinType &_win, const wxSizerFlags &_flgs) pxWindowAndFlags<WinType> operator|(WinType& _win, const wxSizerFlags& _flgs)
{ {
pxWindowAndFlags<WinType> result = {&_win, _flgs}; pxWindowAndFlags<WinType> result = {&_win, _flgs};
return result; return result;
@ -221,25 +223,25 @@ pxWindowAndFlags<WinType> operator|(WinType &_win, const wxSizerFlags &_flgs)
// has no sizer set via SetSizer(), an assertion is generated. // has no sizer set via SetSizer(), an assertion is generated.
// //
extern void operator+=(wxSizer &target, wxWindow *src); extern void operator+=(wxSizer& target, wxWindow* src);
extern void operator+=(wxSizer &target, wxSizer *src); extern void operator+=(wxSizer& target, wxSizer* src);
extern void operator+=(wxSizer &target, wxWindow &src); extern void operator+=(wxSizer& target, wxWindow& src);
extern void operator+=(wxSizer &target, wxSizer &src); extern void operator+=(wxSizer& target, wxSizer& src);
extern void operator+=(wxSizer *target, wxWindow &src); extern void operator+=(wxSizer* target, wxWindow& src);
extern void operator+=(wxSizer *target, wxSizer &src); extern void operator+=(wxSizer* target, wxSizer& src);
extern void operator+=(wxSizer &target, int spacer); extern void operator+=(wxSizer& target, int spacer);
extern void operator+=(wxWindow &target, int spacer); extern void operator+=(wxWindow& target, int spacer);
extern void operator+=(wxSizer &target, const pxStretchSpacer &spacer); extern void operator+=(wxSizer& target, const pxStretchSpacer& spacer);
extern void operator+=(wxWindow &target, const pxStretchSpacer &spacer); extern void operator+=(wxWindow& target, const pxStretchSpacer& spacer);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Important: This template is needed in order to retain window type information and // Important: This template is needed in order to retain window type information and
// invoke the proper overloaded version of += (which is used by pxStaticText and other // invoke the proper overloaded version of += (which is used by pxStaticText and other
// classes to perform special actions when added to sizers). // classes to perform special actions when added to sizers).
template <typename WinType> template <typename WinType>
void operator+=(wxWindow &target, WinType *src) void operator+=(wxWindow& target, WinType* src)
{ {
if (!pxAssert(target.GetSizer() != NULL)) if (!pxAssert(target.GetSizer() != NULL))
return; return;
@ -247,7 +249,7 @@ void operator+=(wxWindow &target, WinType *src)
} }
template <typename WinType> template <typename WinType>
void operator+=(wxWindow &target, WinType &src) void operator+=(wxWindow& target, WinType& src)
{ {
if (!pxAssert(target.GetSizer() != NULL)) if (!pxAssert(target.GetSizer() != NULL))
return; return;
@ -255,7 +257,7 @@ void operator+=(wxWindow &target, WinType &src)
} }
template <typename WinType> template <typename WinType>
void operator+=(wxWindow &target, const pxWindowAndFlags<WinType> &src) void operator+=(wxWindow& target, const pxWindowAndFlags<WinType>& src)
{ {
if (!pxAssert(target.GetSizer() != NULL)) if (!pxAssert(target.GetSizer() != NULL))
return; return;
@ -263,7 +265,7 @@ void operator+=(wxWindow &target, const pxWindowAndFlags<WinType> &src)
} }
template <typename WinType> template <typename WinType>
void operator+=(wxSizer &target, const pxWindowAndFlags<WinType> &src) void operator+=(wxSizer& target, const pxWindowAndFlags<WinType>& src)
{ {
target.Add(src.window, src.flags); target.Add(src.window, src.flags);
} }
@ -304,25 +306,25 @@ public:
hasCaption = true; hasCaption = true;
} }
pxDialogCreationFlags &SetSizerOrient(wxOrientation orient) pxDialogCreationFlags& SetSizerOrient(wxOrientation orient)
{ {
BoxSizerOrient = orient; BoxSizerOrient = orient;
return *this; return *this;
} }
pxDialogCreationFlags &SetResize(bool enable = true) pxDialogCreationFlags& SetResize(bool enable = true)
{ {
isResizable = enable; isResizable = enable;
return *this; return *this;
} }
pxDialogCreationFlags &SetMinimize(bool enable = true) pxDialogCreationFlags& SetMinimize(bool enable = true)
{ {
hasMinimizeBox = enable; hasMinimizeBox = enable;
return *this; return *this;
} }
pxDialogCreationFlags &SetMaximize(bool enable = true) pxDialogCreationFlags& SetMaximize(bool enable = true)
{ {
hasMaximizeBox = enable; hasMaximizeBox = enable;
return *this; return *this;
@ -330,19 +332,19 @@ public:
// NOTE: Enabling system menu on dialogs usually doesn't work, and might cause // NOTE: Enabling system menu on dialogs usually doesn't work, and might cause
// other unwanted behavior, such as a missing close button. // other unwanted behavior, such as a missing close button.
pxDialogCreationFlags &SetSystemMenu(bool enable = true) pxDialogCreationFlags& SetSystemMenu(bool enable = true)
{ {
hasSystemMenu = enable; hasSystemMenu = enable;
return *this; return *this;
} }
pxDialogCreationFlags &SetCaption(bool enable = true) pxDialogCreationFlags& SetCaption(bool enable = true)
{ {
hasCaption = enable; hasCaption = enable;
return *this; return *this;
} }
pxDialogCreationFlags &SetCloseBox(bool enable = true) pxDialogCreationFlags& SetCloseBox(bool enable = true)
{ {
hasCloseBox = enable; hasCloseBox = enable;
return *this; return *this;
@ -354,21 +356,21 @@ public:
return *this; return *this;
} }
pxDialogCreationFlags &SetMinWidth(int width) pxDialogCreationFlags& SetMinWidth(int width)
{ {
if (width > MinimumSize.x) if (width > MinimumSize.x)
MinimumSize.SetWidth(width); MinimumSize.SetWidth(width);
return *this; return *this;
} }
pxDialogCreationFlags &SetMinHeight(int height) pxDialogCreationFlags& SetMinHeight(int height)
{ {
if (height > MinimumSize.y) if (height > MinimumSize.y)
MinimumSize.SetHeight(height); MinimumSize.SetHeight(height);
return *this; return *this;
} }
pxDialogCreationFlags &SetMinSize(const wxSize &size) pxDialogCreationFlags& SetMinSize(const wxSize& size)
{ {
return SetMinWidth(size.x).SetMinHeight(size.y); return SetMinWidth(size.x).SetMinHeight(size.y);
} }
@ -461,7 +463,7 @@ public:
return pxDialogCreationFlags(*this).SetMinHeight(height); return pxDialogCreationFlags(*this).SetMinHeight(height);
} }
pxDialogCreationFlags MinSize(const wxSize &size) const pxDialogCreationFlags MinSize(const wxSize& size) const
{ {
return pxDialogCreationFlags(*this).SetMinSize(size); return pxDialogCreationFlags(*this).SetMinSize(size);
} }
@ -501,17 +503,17 @@ class wxDialogWithHelpers : public wxDialog
protected: protected:
bool m_hasContextHelp; bool m_hasContextHelp;
wxBoxSizer *m_extraButtonSizer; wxBoxSizer* m_extraButtonSizer;
wxRect m_CreatedRect; wxRect m_CreatedRect;
public: public:
wxDialogWithHelpers(); wxDialogWithHelpers();
wxDialogWithHelpers(wxWindow *parent, const wxString &title, const pxDialogCreationFlags &cflags = pxDialogCreationFlags()); wxDialogWithHelpers(wxWindow* parent, const wxString& title, const pxDialogCreationFlags& cflags = pxDialogCreationFlags());
virtual ~wxDialogWithHelpers() = default; virtual ~wxDialogWithHelpers() = default;
void Init(const pxDialogCreationFlags &cflags); void Init(const pxDialogCreationFlags& cflags);
void AddOkCancel(wxSizer &sizer, bool hasApply = false); void AddOkCancel(wxSizer& sizer, bool hasApply = false);
void AddOkCancel(wxSizer *sizer = NULL, bool hasApply = false); void AddOkCancel(wxSizer* sizer = NULL, bool hasApply = false);
void RememberPosition(); void RememberPosition();
virtual void SmartCenterFit(); virtual void SmartCenterFit();
@ -524,18 +526,18 @@ public:
// screenshots to disk) // screenshots to disk)
virtual wxString GetDialogName() const; virtual wxString GetDialogName() const;
virtual wxStaticText &Label(const wxString &label); virtual wxStaticText& Label(const wxString& label);
virtual pxStaticText &Text(const wxString &label); virtual pxStaticText& Text(const wxString& label);
virtual pxStaticText &Heading(const wxString &label); virtual pxStaticText& Heading(const wxString& label);
wxDialogWithHelpers &SetMinWidth(int newWidth); wxDialogWithHelpers& SetMinWidth(int newWidth);
wxDialogWithHelpers &SetMinHeight(int newHeight); wxDialogWithHelpers& SetMinHeight(int newHeight);
int GetCharHeight() const; int GetCharHeight() const;
protected: protected:
void OnDialogCreated(wxCommandEvent &evt); void OnDialogCreated(wxCommandEvent& evt);
void OnOkCancel(wxCommandEvent &evt); void OnOkCancel(wxCommandEvent& evt);
bool ShouldPreventAppExit() const { return false; } bool ShouldPreventAppExit() const { return false; }
@ -564,18 +566,18 @@ class wxPanelWithHelpers : public wxPanel
wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxPanelWithHelpers); wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxPanelWithHelpers);
public: public:
wxPanelWithHelpers(wxWindow *parent, wxOrientation orient, const wxString &staticBoxLabel); wxPanelWithHelpers(wxWindow* parent, wxOrientation orient, const wxString& staticBoxLabel);
wxPanelWithHelpers(wxWindow *parent, wxOrientation orient); wxPanelWithHelpers(wxWindow* parent, wxOrientation orient);
wxPanelWithHelpers(wxWindow *parent, const wxPoint &pos, const wxSize &size = wxDefaultSize); wxPanelWithHelpers(wxWindow* parent, const wxPoint& pos, const wxSize& size = wxDefaultSize);
explicit wxPanelWithHelpers(wxWindow *parent = NULL); explicit wxPanelWithHelpers(wxWindow* parent = NULL);
wxPanelWithHelpers *AddFrame(const wxString &label, wxOrientation orient = wxVERTICAL); wxPanelWithHelpers* AddFrame(const wxString& label, wxOrientation orient = wxVERTICAL);
wxStaticText &Label(const wxString &label); wxStaticText& Label(const wxString& label);
pxStaticText &Text(const wxString &label); pxStaticText& Text(const wxString& label);
pxStaticText &Heading(const wxString &label); pxStaticText& Heading(const wxString& label);
virtual wxPanelWithHelpers &SetMinWidth(int newWidth); virtual wxPanelWithHelpers& SetMinWidth(int newWidth);
protected: protected:
void Init(); void Init();
@ -603,7 +605,7 @@ protected:
public: public:
virtual ~pxTextWrapperBase() = default; virtual ~pxTextWrapperBase() = default;
pxTextWrapperBase(const wxString &indent = wxEmptyString) pxTextWrapperBase(const wxString& indent = wxEmptyString)
: m_indent(indent) : m_indent(indent)
{ {
m_eol = false; m_eol = false;
@ -612,7 +614,7 @@ public:
// win is used for getting the font, text is the text to wrap, width is the // win is used for getting the font, text is the text to wrap, width is the
// max line width or -1 to disable wrapping // max line width or -1 to disable wrapping
pxTextWrapperBase &Wrap(const wxWindow &win, const wxString &text, int widthMax); pxTextWrapperBase& Wrap(const wxWindow& win, const wxString& text, int widthMax);
int GetLineCount() const int GetLineCount() const
{ {
@ -621,12 +623,12 @@ public:
protected: protected:
// line may be empty // line may be empty
virtual void OnOutputLine(const wxString &line) {} virtual void OnOutputLine(const wxString& line) {}
// called at the start of every new line (except the very first one) // called at the start of every new line (except the very first one)
virtual void OnNewLine() {} virtual void OnNewLine() {}
void DoOutputLine(const wxString &line); void DoOutputLine(const wxString& line);
bool IsStartOfNewLine(); bool IsStartOfNewLine();
}; };
@ -644,23 +646,23 @@ protected:
wxString m_text; wxString m_text;
public: public:
pxTextWrapper(const wxString &wrapPrefix = wxEmptyString) pxTextWrapper(const wxString& wrapPrefix = wxEmptyString)
: pxTextWrapperBase(wrapPrefix) : pxTextWrapperBase(wrapPrefix)
{ {
} }
virtual ~pxTextWrapper() = default; virtual ~pxTextWrapper() = default;
const wxString &GetResult() const const wxString& GetResult() const
{ {
return m_text; return m_text;
} }
pxTextWrapper &Wrap(const wxWindow &win, const wxString &text, int widthMax); pxTextWrapper& Wrap(const wxWindow& win, const wxString& text, int widthMax);
pxTextWrapper &Wrap(const wxWindow *win, const wxString &text, int widthMax); pxTextWrapper& Wrap(const wxWindow* win, const wxString& text, int widthMax);
protected: protected:
void OnOutputLine(const wxString &line); void OnOutputLine(const wxString& line);
void OnNewLine(); void OnNewLine();
}; };
@ -670,63 +672,63 @@ protected:
class pxWindowTextWriter class pxWindowTextWriter
{ {
protected: protected:
wxDC &m_dc; wxDC& m_dc;
wxAlignment m_align; wxAlignment m_align;
wxPoint m_curpos; wxPoint m_curpos;
int m_leading; int m_leading;
virtual void _DoWriteLn(const wxString &msg); virtual void _DoWriteLn(const wxString& msg);
void _DoWrite(const wxChar *msg); void _DoWrite(const wxChar* msg);
public: public:
pxWindowTextWriter(wxDC &dc); pxWindowTextWriter(wxDC& dc);
virtual ~pxWindowTextWriter() = default; virtual ~pxWindowTextWriter() = default;
virtual void OnFontChanged(); virtual void OnFontChanged();
pxWindowTextWriter &WriteLn(); pxWindowTextWriter& WriteLn();
pxWindowTextWriter &FormatLn(const wxChar *fmt, ...); pxWindowTextWriter& FormatLn(const wxChar* fmt, ...);
pxWindowTextWriter &WriteLn(const wxChar *fmt); pxWindowTextWriter& WriteLn(const wxChar* fmt);
pxWindowTextWriter &SetFont(const wxFont &font); pxWindowTextWriter& SetFont(const wxFont& font);
pxWindowTextWriter &Align(const wxAlignment &align); pxWindowTextWriter& Align(const wxAlignment& align);
pxWindowTextWriter &WriteLn(const wxString fmt); pxWindowTextWriter& WriteLn(const wxString fmt);
pxWindowTextWriter &SetLeading(int lead) pxWindowTextWriter& SetLeading(int lead)
{ {
m_leading = lead; m_leading = lead;
return *this; return *this;
} }
pxWindowTextWriter &SetWeight(wxFontWeight weight); pxWindowTextWriter& SetWeight(wxFontWeight weight);
pxWindowTextWriter &SetStyle(wxFontStyle style); pxWindowTextWriter& SetStyle(wxFontStyle style);
pxWindowTextWriter &Normal(); pxWindowTextWriter& Normal();
pxWindowTextWriter &Bold() pxWindowTextWriter& Bold()
{ {
return SetWeight(wxFONTWEIGHT_BOLD); return SetWeight(wxFONTWEIGHT_BOLD);
} }
pxWindowTextWriter &Italic() pxWindowTextWriter& Italic()
{ {
return SetStyle(wxFONTSTYLE_ITALIC); return SetStyle(wxFONTSTYLE_ITALIC);
} }
pxWindowTextWriter &SetPos(const wxPoint &pos); pxWindowTextWriter& SetPos(const wxPoint& pos);
pxWindowTextWriter &MovePos(const wxSize &delta); pxWindowTextWriter& MovePos(const wxSize& delta);
pxWindowTextWriter &SetPos(int xpos, int ypos) pxWindowTextWriter& SetPos(int xpos, int ypos)
{ {
return SetPos(wxPoint(xpos, ypos)); return SetPos(wxPoint(xpos, ypos));
} }
pxWindowTextWriter &MovePos(int xdelta, int ydelta) pxWindowTextWriter& MovePos(int xdelta, int ydelta)
{ {
return MovePos(wxSize(xdelta, ydelta)); return MovePos(wxSize(xdelta, ydelta));
} }
pxWindowTextWriter &SetY(int ypos); pxWindowTextWriter& SetY(int ypos);
pxWindowTextWriter &MoveY(int ydelta); pxWindowTextWriter& MoveY(int ydelta);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -742,10 +744,11 @@ protected:
public: public:
MoreStockCursors() {} MoreStockCursors() {}
virtual ~MoreStockCursors() = default; virtual ~MoreStockCursors() = default;
const wxCursor &GetArrowWait(); const wxCursor& GetArrowWait();
}; };
enum BusyCursorType { enum BusyCursorType
{
Cursor_NotBusy, Cursor_NotBusy,
Cursor_KindaBusy, Cursor_KindaBusy,
Cursor_ReallyBusy, Cursor_ReallyBusy,
@ -779,23 +782,23 @@ public:
// Fits a given text or spinner control to the number of digits requested, since by default // Fits a given text or spinner control to the number of digits requested, since by default
// they're usually way over-sized. // they're usually way over-sized.
extern void pxFitToDigits(wxWindow *win, int digits); extern void pxFitToDigits(wxWindow* win, int digits);
extern void pxFitToDigits(wxSpinCtrl *win, int digits); extern void pxFitToDigits(wxSpinCtrl* win, int digits);
extern wxTextCtrl *CreateNumericalTextCtrl(wxWindow *parent, int digits, long flags = wxTE_RIGHT); extern wxTextCtrl* CreateNumericalTextCtrl(wxWindow* parent, int digits, long flags = wxTE_RIGHT);
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
extern bool pxDialogExists(const wxString &name); extern bool pxDialogExists(const wxString& name);
extern bool pxIsValidWindowPosition(const wxWindow &window, const wxPoint &windowPos); extern bool pxIsValidWindowPosition(const wxWindow& window, const wxPoint& windowPos);
extern wxRect wxGetDisplayArea(); extern wxRect wxGetDisplayArea();
extern wxString pxGetAppName(); extern wxString pxGetAppName();
extern int pxGetCharHeight(const wxWindow *wind, int rows = 1); extern int pxGetCharHeight(const wxWindow* wind, int rows = 1);
extern int pxGetCharHeight(const wxWindow &wind, int rows = 1); extern int pxGetCharHeight(const wxWindow& wind, int rows = 1);
extern void pxSetToolTip(wxWindow *wind, const wxString &src); extern void pxSetToolTip(wxWindow* wind, const wxString& src);
extern void pxSetToolTip(wxWindow &wind, const wxString &src); extern void pxSetToolTip(wxWindow& wind, const wxString& src);
extern wxFont pxGetFixedFont(int ptsize = 8, wxFontWeight weight = wxFONTWEIGHT_NORMAL, bool underline = false); extern wxFont pxGetFixedFont(int ptsize = 8, wxFontWeight weight = wxFONTWEIGHT_NORMAL, bool underline = false);
extern pxDialogCreationFlags pxDialogFlags(); extern pxDialogCreationFlags pxDialogFlags();

View File

@ -69,22 +69,22 @@ BaseDeletableObject::~BaseDeletableObject()
// Creates a text control which is right-justified and has it's minimum width configured to suit // Creates a text control which is right-justified and has it's minimum width configured to suit
// the number of digits requested. // the number of digits requested.
wxTextCtrl *CreateNumericalTextCtrl(wxWindow *parent, int digits, long flags) wxTextCtrl* CreateNumericalTextCtrl(wxWindow* parent, int digits, long flags)
{ {
wxTextCtrl *ctrl = new wxTextCtrl(parent, wxID_ANY); wxTextCtrl* ctrl = new wxTextCtrl(parent, wxID_ANY);
ctrl->SetWindowStyleFlag(flags); ctrl->SetWindowStyleFlag(flags);
pxFitToDigits(ctrl, digits); pxFitToDigits(ctrl, digits);
return ctrl; return ctrl;
} }
void pxFitToDigits(wxWindow *win, int digits) void pxFitToDigits(wxWindow* win, int digits)
{ {
int ex; int ex;
win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL); win->GetTextExtent(wxString(L'0', digits + 1), &ex, NULL);
win->SetMinSize(wxSize(ex + 10, wxDefaultCoord)); // +10 for text control borders/insets and junk. win->SetMinSize(wxSize(ex + 10, wxDefaultCoord)); // +10 for text control borders/insets and junk.
} }
void pxFitToDigits(wxSpinCtrl *win, int digits) void pxFitToDigits(wxSpinCtrl* win, int digits)
{ {
// HACK!! The better way would be to create a pxSpinCtrl class that extends wxSpinCtrl and thus // HACK!! The better way would be to create a pxSpinCtrl class that extends wxSpinCtrl and thus
// have access to wxSpinButton::DoGetBestSize(). But since I don't want to do that, we'll just // have access to wxSpinButton::DoGetBestSize(). But since I don't want to do that, we'll just
@ -97,7 +97,7 @@ void pxFitToDigits(wxSpinCtrl *win, int digits)
win->SetMinSize(wxSize(ex + 10 + MagicSpinnerSize, wxDefaultCoord)); // +10 for text control borders/insets and junk. win->SetMinSize(wxSize(ex + 10 + MagicSpinnerSize, wxDefaultCoord)); // +10 for text control borders/insets and junk.
} }
bool pxDialogExists(const wxString &name) bool pxDialogExists(const wxString& name)
{ {
return wxFindWindowByName(name) != NULL; return wxFindWindowByName(name) != NULL;
} }
@ -118,11 +118,12 @@ wxDialogWithHelpers::wxDialogWithHelpers()
Init(pxDialogFlags()); Init(pxDialogFlags());
} }
wxDialogWithHelpers::wxDialogWithHelpers(wxWindow *parent, const wxString &title, const pxDialogCreationFlags &cflags) wxDialogWithHelpers::wxDialogWithHelpers(wxWindow* parent, const wxString& title, const pxDialogCreationFlags& cflags)
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, cflags.GetWxWindowFlags()) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, cflags.GetWxWindowFlags())
{ {
m_hasContextHelp = cflags.hasContextHelp; m_hasContextHelp = cflags.hasContextHelp;
if ((int)cflags.BoxSizerOrient != 0) { if ((int)cflags.BoxSizerOrient != 0)
{
SetSizer(new wxBoxSizer(cflags.BoxSizerOrient)); SetSizer(new wxBoxSizer(cflags.BoxSizerOrient));
*this += StdPadding; *this += StdPadding;
} }
@ -131,7 +132,7 @@ wxDialogWithHelpers::wxDialogWithHelpers(wxWindow *parent, const wxString &title
SetMinSize(cflags.MinimumSize); SetMinSize(cflags.MinimumSize);
} }
void wxDialogWithHelpers::Init(const pxDialogCreationFlags &cflags) void wxDialogWithHelpers::Init(const pxDialogCreationFlags& cflags)
{ {
// Note to self: if any comments indicate platform specific behaviour then // Note to self: if any comments indicate platform specific behaviour then
// ifdef them out to see if they fix the issue. I wasted too much time // ifdef them out to see if they fix the issue. I wasted too much time
@ -159,7 +160,7 @@ void wxDialogWithHelpers::Init(const pxDialogCreationFlags &cflags)
AddPendingEvent(createEvent); AddPendingEvent(createEvent);
} }
void wxDialogWithHelpers::OnDialogCreated(wxCommandEvent &evt) void wxDialogWithHelpers::OnDialogCreated(wxCommandEvent& evt)
{ {
evt.Skip(); evt.Skip();
if ((evt.GetId() == GetId()) && !GetDialogName().IsEmpty()) if ((evt.GetId() == GetId()) && !GetDialogName().IsEmpty())
@ -179,10 +180,12 @@ void wxDialogWithHelpers::DoAutoCenter()
// a lot since the main window is small). // a lot since the main window is small).
bool centerfail = true; bool centerfail = true;
if (wxWindow *parent = GetParent()) { if (wxWindow* parent = GetParent())
{
const wxSize parentSize(parent->GetSize()); const wxSize parentSize(parent->GetSize());
if ((parentSize.x > ((int)GetSize().x * 1.5)) || (parentSize.y > ((int)GetSize().y * 1.5))) { if ((parentSize.x > ((int)GetSize().x * 1.5)) || (parentSize.y > ((int)GetSize().y * 1.5)))
{
CenterOnParent(); CenterOnParent();
centerfail = false; centerfail = false;
} }
@ -197,19 +200,22 @@ void wxDialogWithHelpers::SmartCenterFit()
Fit(); Fit();
const wxString dlgName(GetDialogName()); const wxString dlgName(GetDialogName());
if (dlgName.IsEmpty()) { if (dlgName.IsEmpty())
{
DoAutoCenter(); DoAutoCenter();
return; return;
} }
if (wxConfigBase *cfg = wxConfigBase::Get(false)) { if (wxConfigBase* cfg = wxConfigBase::Get(false))
{
wxRect screenRect(GetScreenRect()); wxRect screenRect(GetScreenRect());
IniLoader loader(cfg); IniLoader loader(cfg);
ScopedIniGroup group(loader, L"DialogPositions"); ScopedIniGroup group(loader, L"DialogPositions");
cfg->SetRecordDefaults(false); cfg->SetRecordDefaults(false);
if (GetWindowStyle() & wxRESIZE_BORDER) { if (GetWindowStyle() & wxRESIZE_BORDER)
{
wxSize size; wxSize size;
loader.Entry(dlgName + L"_Size", size, screenRect.GetSize()); loader.Entry(dlgName + L"_Size", size, screenRect.GetSize());
SetSize(size); SetSize(size);
@ -217,7 +223,8 @@ void wxDialogWithHelpers::SmartCenterFit()
if (!cfg->Exists(dlgName + L"_Pos")) if (!cfg->Exists(dlgName + L"_Pos"))
DoAutoCenter(); DoAutoCenter();
else { else
{
wxPoint pos; wxPoint pos;
loader.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition()); loader.Entry(dlgName + L"_Pos", pos, screenRect.GetPosition());
SetPosition(pos); SetPosition(pos);
@ -241,24 +248,25 @@ int wxDialogWithHelpers::ShowModal()
// 75% larger than the fitted dialog. // 75% larger than the fitted dialog.
bool wxDialogWithHelpers::Show(bool show) bool wxDialogWithHelpers::Show(bool show)
{ {
if (show) { if (show)
{
SmartCenterFit(); SmartCenterFit();
m_CreatedRect = GetScreenRect(); m_CreatedRect = GetScreenRect();
} }
return wxDialog::Show(show); return wxDialog::Show(show);
} }
wxStaticText &wxDialogWithHelpers::Label(const wxString &label) wxStaticText& wxDialogWithHelpers::Label(const wxString& label)
{ {
return *new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_VERTICAL); return *new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_VERTICAL);
} }
pxStaticText &wxDialogWithHelpers::Text(const wxString &label) pxStaticText& wxDialogWithHelpers::Text(const wxString& label)
{ {
return *new pxStaticText(this, label); return *new pxStaticText(this, label);
} }
pxStaticText &wxDialogWithHelpers::Heading(const wxString &label) pxStaticText& wxDialogWithHelpers::Heading(const wxString& label)
{ {
return *new pxStaticHeading(this, label); return *new pxStaticHeading(this, label);
} }
@ -270,15 +278,18 @@ void wxDialogWithHelpers::RememberPosition()
// ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers // ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers
// that systematically get closed. Seems like work, maybe later. --air // that systematically get closed. Seems like work, maybe later. --air
if (wxConfigBase *cfg = IsIconized() ? NULL : wxConfigBase::Get(false)) { if (wxConfigBase* cfg = IsIconized() ? NULL : wxConfigBase::Get(false))
{
const wxString dlgName(GetDialogName()); const wxString dlgName(GetDialogName());
const wxRect screenRect(GetScreenRect()); const wxRect screenRect(GetScreenRect());
if (!dlgName.IsEmpty() && (m_CreatedRect != screenRect)) { if (!dlgName.IsEmpty() && (m_CreatedRect != screenRect))
{
wxPoint pos(screenRect.GetPosition()); wxPoint pos(screenRect.GetPosition());
IniSaver saver(cfg); IniSaver saver(cfg);
ScopedIniGroup group(saver, L"DialogPositions"); ScopedIniGroup group(saver, L"DialogPositions");
if (GetWindowStyle() & wxRESIZE_BORDER) { if (GetWindowStyle() & wxRESIZE_BORDER)
{
wxSize size(screenRect.GetSize()); wxSize size(screenRect.GetSize());
saver.Entry(dlgName + L"_Size", size, screenRect.GetSize()); saver.Entry(dlgName + L"_Size", size, screenRect.GetSize());
} }
@ -287,7 +298,7 @@ void wxDialogWithHelpers::RememberPosition()
} }
} }
void wxDialogWithHelpers::OnOkCancel(wxCommandEvent &evt) void wxDialogWithHelpers::OnOkCancel(wxCommandEvent& evt)
{ {
RememberPosition(); RememberPosition();
@ -299,9 +310,9 @@ void wxDialogWithHelpers::OnOkCancel(wxCommandEvent &evt)
evt.Skip(); evt.Skip();
} }
void wxDialogWithHelpers::AddOkCancel(wxSizer &sizer, bool hasApply) void wxDialogWithHelpers::AddOkCancel(wxSizer& sizer, bool hasApply)
{ {
wxStdDialogButtonSizer &s_buttons(*new wxStdDialogButtonSizer()); wxStdDialogButtonSizer& s_buttons(*new wxStdDialogButtonSizer());
s_buttons.AddButton(new wxButton(this, wxID_OK)); s_buttons.AddButton(new wxButton(this, wxID_OK));
s_buttons.AddButton(new wxButton(this, wxID_CANCEL)); s_buttons.AddButton(new wxButton(this, wxID_CANCEL));
@ -313,7 +324,8 @@ void wxDialogWithHelpers::AddOkCancel(wxSizer &sizer, bool hasApply)
// Add the context-sensitive help button on the caption for the platforms // Add the context-sensitive help button on the caption for the platforms
// which support it (currently MSW only) // which support it (currently MSW only)
if (m_hasContextHelp) { if (m_hasContextHelp)
{
SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
#ifndef __WXMSW__ #ifndef __WXMSW__
*m_extraButtonSizer += new wxContextHelpButton(this) | StdButton(); *m_extraButtonSizer += new wxContextHelpButton(this) | StdButton();
@ -322,7 +334,7 @@ void wxDialogWithHelpers::AddOkCancel(wxSizer &sizer, bool hasApply)
// create a sizer to hold the help and ok/cancel buttons, for platforms // create a sizer to hold the help and ok/cancel buttons, for platforms
// that need a custom help icon. [fixme: help icon prolly better off somewhere else] // that need a custom help icon. [fixme: help icon prolly better off somewhere else]
wxFlexGridSizer &flex(*new wxFlexGridSizer(2)); wxFlexGridSizer& flex(*new wxFlexGridSizer(2));
flex.AddGrowableCol(0, 1); flex.AddGrowableCol(0, 1);
flex.AddGrowableCol(1, 15); flex.AddGrowableCol(1, 15);
@ -334,7 +346,7 @@ void wxDialogWithHelpers::AddOkCancel(wxSizer &sizer, bool hasApply)
s_buttons.Realize(); s_buttons.Realize();
} }
void wxDialogWithHelpers::AddOkCancel(wxSizer *sizer, bool hasApply) void wxDialogWithHelpers::AddOkCancel(wxSizer* sizer, bool hasApply)
{ {
if (sizer == NULL) if (sizer == NULL)
sizer = GetSizer(); sizer = GetSizer();
@ -342,18 +354,18 @@ void wxDialogWithHelpers::AddOkCancel(wxSizer *sizer, bool hasApply)
AddOkCancel(*sizer, hasApply); AddOkCancel(*sizer, hasApply);
} }
wxDialogWithHelpers &wxDialogWithHelpers::SetMinWidth(int newWidth) wxDialogWithHelpers& wxDialogWithHelpers::SetMinWidth(int newWidth)
{ {
SetMinSize(wxSize(newWidth, GetMinHeight())); SetMinSize(wxSize(newWidth, GetMinHeight()));
if (wxSizer *sizer = GetSizer()) if (wxSizer* sizer = GetSizer())
sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight())); sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight()));
return *this; return *this;
} }
wxDialogWithHelpers &wxDialogWithHelpers::SetMinHeight(int newHeight) wxDialogWithHelpers& wxDialogWithHelpers::SetMinHeight(int newHeight)
{ {
SetMinSize(wxSize(GetMinWidth(), newHeight)); SetMinSize(wxSize(GetMinWidth(), newHeight));
if (wxSizer *sizer = GetSizer()) if (wxSizer* sizer = GetSizer())
sizer->SetMinSize(wxSize(sizer->GetMinSize().GetWidth(), newHeight)); sizer->SetMinSize(wxSize(sizer->GetMinSize().GetWidth(), newHeight));
return *this; return *this;
} }
@ -377,9 +389,9 @@ void wxPanelWithHelpers::Init()
// sizer for this panel. If the panel already has a sizer set, then that sizer will be // sizer for this panel. If the panel already has a sizer set, then that sizer will be
// transfered to the new StaticBoxSizer (and will be the first item in it's list, retaining // transfered to the new StaticBoxSizer (and will be the first item in it's list, retaining
// consistent and expected layout) // consistent and expected layout)
wxPanelWithHelpers *wxPanelWithHelpers::AddFrame(const wxString &label, wxOrientation orient) wxPanelWithHelpers* wxPanelWithHelpers::AddFrame(const wxString& label, wxOrientation orient)
{ {
wxSizer *oldSizer = GetSizer(); wxSizer* oldSizer = GetSizer();
SetSizer(new wxStaticBoxSizer(orient, this, label), false); SetSizer(new wxStaticBoxSizer(orient, this, label), false);
Init(); Init();
@ -390,60 +402,60 @@ wxPanelWithHelpers *wxPanelWithHelpers::AddFrame(const wxString &label, wxOrient
return this; return this;
} }
wxStaticText &wxPanelWithHelpers::Label(const wxString &label) wxStaticText& wxPanelWithHelpers::Label(const wxString& label)
{ {
return *new wxStaticText(this, wxID_ANY, label); return *new wxStaticText(this, wxID_ANY, label);
} }
pxStaticText &wxPanelWithHelpers::Text(const wxString &label) pxStaticText& wxPanelWithHelpers::Text(const wxString& label)
{ {
return *new pxStaticText(this, label); return *new pxStaticText(this, label);
} }
pxStaticText &wxPanelWithHelpers::Heading(const wxString &label) pxStaticText& wxPanelWithHelpers::Heading(const wxString& label)
{ {
return *new pxStaticHeading(this, label); return *new pxStaticHeading(this, label);
} }
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent, wxOrientation orient, const wxString &staticBoxLabel) wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, wxOrientation orient, const wxString& staticBoxLabel)
: wxPanel(parent) : wxPanel(parent)
{ {
SetSizer(new wxStaticBoxSizer(orient, this, staticBoxLabel)); SetSizer(new wxStaticBoxSizer(orient, this, staticBoxLabel));
Init(); Init();
} }
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent, wxOrientation orient) wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, wxOrientation orient)
: wxPanel(parent) : wxPanel(parent)
{ {
SetSizer(new wxBoxSizer(orient)); SetSizer(new wxBoxSizer(orient));
Init(); Init();
} }
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent) wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent)
: wxPanel(parent) : wxPanel(parent)
{ {
Init(); Init();
} }
wxPanelWithHelpers::wxPanelWithHelpers(wxWindow *parent, const wxPoint &pos, const wxSize &size) wxPanelWithHelpers::wxPanelWithHelpers(wxWindow* parent, const wxPoint& pos, const wxSize& size)
: wxPanel(parent, wxID_ANY, pos, size) : wxPanel(parent, wxID_ANY, pos, size)
{ {
Init(); Init();
} }
wxPanelWithHelpers &wxPanelWithHelpers::SetMinWidth(int newWidth) wxPanelWithHelpers& wxPanelWithHelpers::SetMinWidth(int newWidth)
{ {
SetMinSize(wxSize(newWidth, GetMinHeight())); SetMinSize(wxSize(newWidth, GetMinHeight()));
if (wxSizer *sizer = GetSizer()) if (wxSizer* sizer = GetSizer())
sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight())); sizer->SetMinSize(wxSize(newWidth, sizer->GetMinSize().GetHeight()));
return *this; return *this;
} }
int pxGetCharHeight(const wxWindow *wind, int rows) int pxGetCharHeight(const wxWindow* wind, int rows)
{ {
if (!wind) if (!wind)
return 0; return 0;
wxClientDC dc(wx_const_cast(wxWindow *, wind)); wxClientDC dc(wx_const_cast(wxWindow*, wind));
dc.SetFont(wind->GetFont()); dc.SetFont(wind->GetFont());
#ifdef __linux__ #ifdef __linux__
// It seems there is a bad detection of the size of the font (non standard dpi ???). Font are cut in top or bottom. // It seems there is a bad detection of the size of the font (non standard dpi ???). Font are cut in top or bottom.
@ -454,7 +466,7 @@ int pxGetCharHeight(const wxWindow *wind, int rows)
#endif #endif
} }
int pxGetCharHeight(const wxWindow &wind, int rows) int pxGetCharHeight(const wxWindow& wind, int rows)
{ {
return pxGetCharHeight(&wind, rows); return pxGetCharHeight(&wind, rows);
} }