More C++11ification.

This commit is contained in:
Ben Vanik 2014-07-13 22:28:00 -07:00
parent 0a250d5e91
commit e9284dfaed
40 changed files with 211 additions and 152 deletions

View File

@ -10,6 +10,8 @@
#ifndef ALLOY_BACKEND_ASSEMBLER_H_ #ifndef ALLOY_BACKEND_ASSEMBLER_H_
#define ALLOY_BACKEND_ASSEMBLER_H_ #define ALLOY_BACKEND_ASSEMBLER_H_
#include <memory>
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
@ -40,7 +42,7 @@ class Assembler {
virtual int Assemble(runtime::FunctionInfo* symbol_info, virtual int Assemble(runtime::FunctionInfo* symbol_info,
hir::HIRBuilder* builder, uint32_t debug_info_flags, hir::HIRBuilder* builder, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info, std::unique_ptr<runtime::DebugInfo> debug_info,
runtime::Function** out_function) = 0; runtime::Function** out_function) = 0;
protected: protected:

View File

@ -10,6 +10,8 @@
#ifndef ALLOY_BACKEND_BACKEND_H_ #ifndef ALLOY_BACKEND_BACKEND_H_
#define ALLOY_BACKEND_BACKEND_H_ #define ALLOY_BACKEND_BACKEND_H_
#include <memory>
#include <alloy/core.h> #include <alloy/core.h>
#include <alloy/backend/machine_info.h> #include <alloy/backend/machine_info.h>
@ -37,7 +39,7 @@ class Backend {
virtual void* AllocThreadData(); virtual void* AllocThreadData();
virtual void FreeThreadData(void* thread_data); virtual void FreeThreadData(void* thread_data);
virtual Assembler* CreateAssembler() = 0; virtual std::unique_ptr<Assembler> CreateAssembler() = 0;
protected: protected:
runtime::Runtime* runtime_; runtime::Runtime* runtime_;

View File

@ -9,6 +9,7 @@
#include <alloy/backend/ivm/ivm_assembler.h> #include <alloy/backend/ivm/ivm_assembler.h>
#include <alloy/reset_scope.h>
#include <alloy/backend/backend.h> #include <alloy/backend/backend.h>
#include <alloy/backend/ivm/ivm_intcode.h> #include <alloy/backend/ivm/ivm_intcode.h>
#include <alloy/backend/ivm/ivm_function.h> #include <alloy/backend/ivm/ivm_function.h>
@ -21,6 +22,7 @@ namespace backend {
namespace ivm { namespace ivm {
using alloy::hir::HIRBuilder; using alloy::hir::HIRBuilder;
using alloy::runtime::DebugInfo;
using alloy::runtime::Function; using alloy::runtime::Function;
using alloy::runtime::FunctionInfo; using alloy::runtime::FunctionInfo;
@ -47,10 +49,15 @@ void IVMAssembler::Reset() {
int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info, std::unique_ptr<DebugInfo> debug_info,
Function** out_function) { Function** out_function) {
SCOPE_profile_cpu_f("alloy");
// Reset when we leave.
make_reset_scope(this);
IVMFunction* fn = new IVMFunction(symbol_info); IVMFunction* fn = new IVMFunction(symbol_info);
fn->set_debug_info(debug_info); fn->set_debug_info(std::move(debug_info));
TranslationContext ctx; TranslationContext ctx;
ctx.register_count = 0; ctx.register_count = 0;

View File

@ -21,16 +21,16 @@ namespace ivm {
class IVMAssembler : public Assembler { class IVMAssembler : public Assembler {
public: public:
IVMAssembler(Backend* backend); IVMAssembler(Backend* backend);
virtual ~IVMAssembler(); ~IVMAssembler() override;
virtual int Initialize(); int Initialize() override;
virtual void Reset(); void Reset() override;
virtual int Assemble(runtime::FunctionInfo* symbol_info, int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder,
hir::HIRBuilder* builder, uint32_t debug_info_flags, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info, std::unique_ptr<runtime::DebugInfo> debug_info,
runtime::Function** out_function); runtime::Function** out_function) override;
private: private:
Arena intcode_arena_; Arena intcode_arena_;

View File

@ -47,7 +47,9 @@ void IVMBackend::FreeThreadData(void* thread_data) {
delete stack; delete stack;
} }
Assembler* IVMBackend::CreateAssembler() { return new IVMAssembler(this); } std::unique_ptr<Assembler> IVMBackend::CreateAssembler() {
return std::make_unique<IVMAssembler>(this);
}
} // namespace ivm } // namespace ivm
} // namespace backend } // namespace backend

View File

@ -23,14 +23,14 @@ namespace ivm {
class IVMBackend : public Backend { class IVMBackend : public Backend {
public: public:
IVMBackend(runtime::Runtime* runtime); IVMBackend(runtime::Runtime* runtime);
virtual ~IVMBackend(); ~IVMBackend() override;
virtual int Initialize(); int Initialize() override;
virtual void* AllocThreadData(); void* AllocThreadData() override;
virtual void FreeThreadData(void* thread_data); void FreeThreadData(void* thread_data) override;
virtual Assembler* CreateAssembler(); std::unique_ptr<Assembler> CreateAssembler() override;
}; };
} // namespace ivm } // namespace ivm

View File

@ -216,7 +216,7 @@ int Translate_COMMENT(TranslationContext& ctx, Instr* i) {
ic->flags = i->flags; ic->flags = i->flags;
ic->debug_flags = 0; ic->debug_flags = 0;
// HACK HACK HACK // HACK HACK HACK
char* src = xestrdupa((char*)i->src1.offset); char* src = strdup(reinterpret_cast<char*>(i->src1.offset));
uint64_t src_p = (uint64_t)src; uint64_t src_p = (uint64_t)src;
ic->src1_reg = (uint32_t)src_p; ic->src1_reg = (uint32_t)src_p;
ic->src2_reg = (uint32_t)(src_p >> 32); ic->src2_reg = (uint32_t)(src_p >> 32);

View File

@ -9,6 +9,7 @@
#include <alloy/backend/x64/x64_assembler.h> #include <alloy/backend/x64/x64_assembler.h>
#include <alloy/reset_scope.h>
#include <alloy/backend/x64/x64_backend.h> #include <alloy/backend/x64/x64_backend.h>
#include <alloy/backend/x64/x64_emitter.h> #include <alloy/backend/x64/x64_emitter.h>
#include <alloy/backend/x64/x64_function.h> #include <alloy/backend/x64/x64_function.h>
@ -33,12 +34,9 @@ using alloy::runtime::Function;
using alloy::runtime::FunctionInfo; using alloy::runtime::FunctionInfo;
X64Assembler::X64Assembler(X64Backend* backend) X64Assembler::X64Assembler(X64Backend* backend)
: Assembler(backend), x64_backend_(backend), emitter_(0), allocator_(0) {} : Assembler(backend), x64_backend_(backend) {}
X64Assembler::~X64Assembler() { X64Assembler::~X64Assembler() = default;
delete emitter_;
delete allocator_;
}
int X64Assembler::Initialize() { int X64Assembler::Initialize() {
int result = Assembler::Initialize(); int result = Assembler::Initialize();
@ -46,8 +44,8 @@ int X64Assembler::Initialize() {
return result; return result;
} }
allocator_ = new XbyakAllocator(); allocator_.reset(new XbyakAllocator());
emitter_ = new X64Emitter(x64_backend_, allocator_); emitter_.reset(new X64Emitter(x64_backend_, allocator_.get()));
return result; return result;
} }
@ -58,39 +56,39 @@ void X64Assembler::Reset() {
} }
int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags, DebugInfo* debug_info, uint32_t debug_info_flags,
std::unique_ptr<DebugInfo> debug_info,
Function** out_function) { Function** out_function) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
int result = 0; // Reset when we leave.
make_reset_scope(this);
// Lower HIR -> x64. // Lower HIR -> x64.
void* machine_code = 0; void* machine_code = 0;
size_t code_size = 0; size_t code_size = 0;
result = emitter_->Emit(builder, debug_info_flags, debug_info, machine_code, int result = emitter_->Emit(builder, debug_info_flags, debug_info.get(),
code_size); machine_code, code_size);
XEEXPECTZERO(result); if (result) {
return result;
}
// Stash generated machine code. // Stash generated machine code.
if (debug_info_flags & DebugInfoFlags::DEBUG_INFO_MACHINE_CODE_DISASM) { if (debug_info_flags & DebugInfoFlags::DEBUG_INFO_MACHINE_CODE_DISASM) {
DumpMachineCode(debug_info, machine_code, code_size, &string_buffer_); DumpMachineCode(debug_info.get(), machine_code, code_size, &string_buffer_);
debug_info->set_machine_code_disasm(string_buffer_.ToString()); debug_info->set_machine_code_disasm(string_buffer_.ToString());
string_buffer_.Reset(); string_buffer_.Reset();
} }
{ {
X64Function* fn = new X64Function(symbol_info); X64Function* fn = new X64Function(symbol_info);
fn->set_debug_info(debug_info); fn->set_debug_info(std::move(debug_info));
fn->Setup(machine_code, code_size); fn->Setup(machine_code, code_size);
*out_function = fn; *out_function = fn;
result = 0;
} }
XECLEANUP: return 0;
Reset();
return result;
} }
void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code, void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,

View File

@ -10,6 +10,8 @@
#ifndef ALLOY_BACKEND_X64_X64_ASSEMBLER_H_ #ifndef ALLOY_BACKEND_X64_X64_ASSEMBLER_H_
#define ALLOY_BACKEND_X64_X64_ASSEMBLER_H_ #define ALLOY_BACKEND_X64_X64_ASSEMBLER_H_
#include <memory>
#include <alloy/core.h> #include <alloy/core.h>
#include <alloy/backend/assembler.h> #include <alloy/backend/assembler.h>
@ -25,16 +27,16 @@ class XbyakAllocator;
class X64Assembler : public Assembler { class X64Assembler : public Assembler {
public: public:
X64Assembler(X64Backend* backend); X64Assembler(X64Backend* backend);
virtual ~X64Assembler(); ~X64Assembler() override;
virtual int Initialize(); int Initialize() override;
virtual void Reset(); void Reset() override;
virtual int Assemble(runtime::FunctionInfo* symbol_info, int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder,
hir::HIRBuilder* builder, uint32_t debug_info_flags, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info, std::unique_ptr<runtime::DebugInfo> debug_info,
runtime::Function** out_function); runtime::Function** out_function) override;
private: private:
void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code, void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code,
@ -42,8 +44,8 @@ class X64Assembler : public Assembler {
private: private:
X64Backend* x64_backend_; X64Backend* x64_backend_;
X64Emitter* emitter_; std::unique_ptr<X64Emitter> emitter_;
XbyakAllocator* allocator_; std::unique_ptr<XbyakAllocator> allocator_;
StringBuffer string_buffer_; StringBuffer string_buffer_;
}; };

View File

@ -47,17 +47,18 @@ int X64Backend::Initialize() {
return result; return result;
} }
auto allocator = new XbyakAllocator(); // Generate thunks used to transition between jitted code and host code.
auto thunk_emitter = new X64ThunkEmitter(this, allocator); auto allocator = std::make_unique<XbyakAllocator>();
auto thunk_emitter = std::make_unique<X64ThunkEmitter>(this, allocator.get());
host_to_guest_thunk_ = thunk_emitter->EmitHostToGuestThunk(); host_to_guest_thunk_ = thunk_emitter->EmitHostToGuestThunk();
guest_to_host_thunk_ = thunk_emitter->EmitGuestToHostThunk(); guest_to_host_thunk_ = thunk_emitter->EmitGuestToHostThunk();
delete thunk_emitter;
delete allocator;
return result; return result;
} }
Assembler* X64Backend::CreateAssembler() { return new X64Assembler(this); } std::unique_ptr<Assembler> X64Backend::CreateAssembler() {
return std::make_unique<X64Assembler>(this);
}
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend

View File

@ -28,15 +28,15 @@ typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1);
class X64Backend : public Backend { class X64Backend : public Backend {
public: public:
X64Backend(runtime::Runtime* runtime); X64Backend(runtime::Runtime* runtime);
virtual ~X64Backend(); ~X64Backend() override;
X64CodeCache* code_cache() const { return code_cache_; } X64CodeCache* code_cache() const { return code_cache_; }
HostToGuestThunk host_to_guest_thunk() const { return host_to_guest_thunk_; } HostToGuestThunk host_to_guest_thunk() const { return host_to_guest_thunk_; }
GuestToHostThunk guest_to_host_thunk() const { return guest_to_host_thunk_; } GuestToHostThunk guest_to_host_thunk() const { return guest_to_host_thunk_; }
virtual int Initialize(); int Initialize() override;
virtual Assembler* CreateAssembler(); std::unique_ptr<Assembler> CreateAssembler() override;
private: private:
X64CodeCache* code_cache_; X64CodeCache* code_cache_;

View File

@ -61,7 +61,7 @@ EMITTER(COMMENT, MATCH(I<OPCODE_COMMENT, VoidOp, OffsetOp>)) {
auto str = reinterpret_cast<const char*>(i.src1.value); auto str = reinterpret_cast<const char*>(i.src1.value);
// TODO(benvanik): pass through. // TODO(benvanik): pass through.
// TODO(benvanik): don't just leak this memory. // TODO(benvanik): don't just leak this memory.
auto str_copy = xestrdupa(str); auto str_copy = strdup(str);
e.mov(e.rdx, reinterpret_cast<uint64_t>(str_copy)); e.mov(e.rdx, reinterpret_cast<uint64_t>(str_copy));
e.CallNative(TraceString); e.CallNative(TraceString);
} }

View File

@ -10,6 +10,7 @@
#include <alloy/frontend/ppc/ppc_translator.h> #include <alloy/frontend/ppc/ppc_translator.h>
#include <alloy/alloy-private.h> #include <alloy/alloy-private.h>
#include <alloy/reset_scope.h>
#include <alloy/compiler/compiler_passes.h> #include <alloy/compiler/compiler_passes.h>
#include <alloy/frontend/ppc/ppc_disasm.h> #include <alloy/frontend/ppc/ppc_disasm.h>
#include <alloy/frontend/ppc/ppc_frontend.h> #include <alloy/frontend/ppc/ppc_frontend.h>
@ -34,10 +35,10 @@ namespace passes = alloy::compiler::passes;
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
Backend* backend = frontend->runtime()->backend(); Backend* backend = frontend->runtime()->backend();
scanner_ = new PPCScanner(frontend); scanner_.reset(new PPCScanner(frontend));
builder_ = new PPCHIRBuilder(frontend); builder_.reset(new PPCHIRBuilder(frontend));
compiler_ = new Compiler(frontend->runtime()); compiler_.reset(new Compiler(frontend->runtime()));
assembler_ = backend->CreateAssembler(); assembler_ = std::move(backend->CreateAssembler());
assembler_->Initialize(); assembler_->Initialize();
bool validate = FLAGS_validate_hir; bool validate = FLAGS_validate_hir;
@ -78,18 +79,19 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
compiler_->AddPass(std::make_unique<passes::FinalizationPass>()); compiler_->AddPass(std::make_unique<passes::FinalizationPass>());
} }
PPCTranslator::~PPCTranslator() { PPCTranslator::~PPCTranslator() = default;
delete assembler_;
delete compiler_;
delete builder_;
delete scanner_;
}
int PPCTranslator::Translate(FunctionInfo* symbol_info, int PPCTranslator::Translate(FunctionInfo* symbol_info,
uint32_t debug_info_flags, uint32_t debug_info_flags,
Function** out_function) { Function** out_function) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
// Reset() all caching when we leave.
make_reset_scope(builder_);
make_reset_scope(compiler_);
make_reset_scope(assembler_);
make_reset_scope(&string_buffer_);
// Scan the function to find its extents. We only need to do this if we // Scan the function to find its extents. We only need to do this if we
// haven't already been provided with them from some other source. // haven't already been provided with them from some other source.
if (!symbol_info->has_end_address()) { if (!symbol_info->has_end_address()) {
@ -106,9 +108,9 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
if (FLAGS_always_disasm) { if (FLAGS_always_disasm) {
debug_info_flags |= DEBUG_INFO_ALL_DISASM; debug_info_flags |= DEBUG_INFO_ALL_DISASM;
} }
DebugInfo* debug_info = NULL; std::unique_ptr<DebugInfo> debug_info;
if (debug_info_flags) { if (debug_info_flags) {
debug_info = new DebugInfo(); debug_info.reset(new DebugInfo());
} }
// Stash source. // Stash source.
@ -119,8 +121,10 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
} }
// Emit function. // Emit function.
int result = builder_->Emit(symbol_info, debug_info != NULL); int result = builder_->Emit(symbol_info, debug_info != nullptr);
XEEXPECTZERO(result); if (result) {
return result;
}
// Stash raw HIR. // Stash raw HIR.
if (debug_info_flags & DEBUG_INFO_RAW_HIR_DISASM) { if (debug_info_flags & DEBUG_INFO_RAW_HIR_DISASM) {
@ -130,8 +134,10 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
} }
// Compile/optimize/etc. // Compile/optimize/etc.
result = compiler_->Compile(builder_); result = compiler_->Compile(builder_.get());
XEEXPECTZERO(result); if (result) {
return result;
}
// Stash optimized HIR. // Stash optimized HIR.
if (debug_info_flags & DEBUG_INFO_HIR_DISASM) { if (debug_info_flags & DEBUG_INFO_HIR_DISASM) {
@ -141,21 +147,13 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
} }
// Assemble to backend machine code. // Assemble to backend machine code.
result = assembler_->Assemble(symbol_info, builder_, debug_info_flags, result = assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags,
debug_info, out_function); std::move(debug_info), out_function);
XEEXPECTZERO(result);
result = 0;
XECLEANUP:
if (result) { if (result) {
delete debug_info;
}
builder_->Reset();
compiler_->Reset();
assembler_->Reset();
string_buffer_.Reset();
return result; return result;
}
return 0;
}; };
void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info, void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info,

View File

@ -10,6 +10,8 @@
#ifndef ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_ #ifndef ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_
#define ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_ #define ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_
#include <memory>
#include <alloy/core.h> #include <alloy/core.h>
#include <alloy/backend/assembler.h> #include <alloy/backend/assembler.h>
#include <alloy/compiler/compiler.h> #include <alloy/compiler/compiler.h>
@ -37,10 +39,10 @@ class PPCTranslator {
private: private:
PPCFrontend* frontend_; PPCFrontend* frontend_;
PPCScanner* scanner_; std::unique_ptr<PPCScanner> scanner_;
PPCHIRBuilder* builder_; std::unique_ptr<PPCHIRBuilder> builder_;
compiler::Compiler* compiler_; std::unique_ptr<compiler::Compiler> compiler_;
backend::Assembler* assembler_; std::unique_ptr<backend::Assembler> assembler_;
StringBuffer string_buffer_; StringBuffer string_buffer_;
}; };

View File

@ -544,7 +544,7 @@ void HIRBuilder::Comment(const char* format, ...) {
va_start(args, format); va_start(args, format);
xevsnprintfa(buffer, 1024, format, args); xevsnprintfa(buffer, 1024, format, args);
va_end(args); va_end(args);
size_t len = xestrlena(buffer); size_t len = strlen(buffer);
if (!len) { if (!len) {
return; return;
} }

45
src/alloy/reset_scope.h Normal file
View File

@ -0,0 +1,45 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_RESET_SCOPE_H_
#define ALLOY_RESET_SCOPE_H_
#include <mutex>
#include <alloy/core.h>
namespace alloy {
template <typename T>
class ResetScope {
public:
ResetScope(T* value) : value_(value) {}
~ResetScope() {
if (value_) {
value_->Reset();
}
}
private:
T* value_;
};
template <typename T>
inline ResetScope<T> make_reset_scope(T* value) {
return ResetScope<T>(value);
}
template <typename T>
inline ResetScope<T> make_reset_scope(const std::unique_ptr<T>& value) {
return ResetScope<T>(value.get());
}
} // namespace alloy
#endif // ALLOY_RESET_SCOPE_H_

View File

@ -18,8 +18,7 @@ namespace runtime {
Function::Function(FunctionInfo* symbol_info) Function::Function(FunctionInfo* symbol_info)
: address_(symbol_info->address()), : address_(symbol_info->address()),
symbol_info_(symbol_info), symbol_info_(symbol_info) {}
debug_info_(0) {}
Function::~Function() = default; Function::~Function() = default;

View File

@ -10,6 +10,7 @@
#ifndef ALLOY_RUNTIME_FUNCTION_H_ #ifndef ALLOY_RUNTIME_FUNCTION_H_
#define ALLOY_RUNTIME_FUNCTION_H_ #define ALLOY_RUNTIME_FUNCTION_H_
#include <memory>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
@ -31,8 +32,10 @@ class Function {
uint64_t address() const { return address_; } uint64_t address() const { return address_; }
FunctionInfo* symbol_info() const { return symbol_info_; } FunctionInfo* symbol_info() const { return symbol_info_; }
DebugInfo* debug_info() const { return debug_info_; } DebugInfo* debug_info() const { return debug_info_.get(); }
void set_debug_info(DebugInfo* debug_info) { debug_info_ = debug_info; } void set_debug_info(std::unique_ptr<DebugInfo> debug_info) {
debug_info_ = std::move(debug_info);
}
int AddBreakpoint(Breakpoint* breakpoint); int AddBreakpoint(Breakpoint* breakpoint);
int RemoveBreakpoint(Breakpoint* breakpoint); int RemoveBreakpoint(Breakpoint* breakpoint);
@ -48,7 +51,7 @@ class Function {
protected: protected:
uint64_t address_; uint64_t address_;
FunctionInfo* symbol_info_; FunctionInfo* symbol_info_;
DebugInfo* debug_info_; std::unique_ptr<DebugInfo> debug_info_;
// TODO(benvanik): move elsewhere? DebugData? // TODO(benvanik): move elsewhere? DebugData?
std::mutex lock_; std::mutex lock_;

View File

@ -21,8 +21,8 @@ RawModule::~RawModule() {
} }
} }
int RawModule::LoadFile(uint64_t base_address, const char* path) { int RawModule::LoadFile(uint64_t base_address, const std::string& path) {
FILE* file = fopen(path, "rb"); FILE* file = fopen(path.c_str(), "rb");
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
size_t file_length = ftell(file); size_t file_length = ftell(file);
fseek(file, 0, SEEK_SET); fseek(file, 0, SEEK_SET);
@ -42,7 +42,12 @@ int RawModule::LoadFile(uint64_t base_address, const char* path) {
fclose(file); fclose(file);
// Setup debug info. // Setup debug info.
name_ = std::string(xestrrchra(path, XE_PATH_SEPARATOR) + 1); auto last_slash = path.find_last_of(poly::path_separator);
if (last_slash != std::string::npos) {
name_ = path.substr(last_slash + 1);
} else {
name_ = path;
}
// TODO(benvanik): debug info // TODO(benvanik): debug info
low_address_ = base_address; low_address_ = base_address;

View File

@ -22,7 +22,7 @@ class RawModule : public Module {
RawModule(Runtime* runtime); RawModule(Runtime* runtime);
~RawModule() override; ~RawModule() override;
int LoadFile(uint64_t base_address, const char* path); int LoadFile(uint64_t base_address, const std::string& path);
const std::string& name() const override { return name_; } const std::string& name() const override { return name_; }

View File

@ -10,6 +10,7 @@
'delegate.h', 'delegate.h',
'memory.cc', 'memory.cc',
'memory.h', 'memory.h',
'reset_scope.h',
'string_buffer.cc', 'string_buffer.cc',
'string_buffer.h', 'string_buffer.h',
'type_pool.h', 'type_pool.h',

View File

@ -52,8 +52,7 @@ class TypePool {
private: private:
std::mutex lock_; std::mutex lock_;
typedef std::vector<T*> TList; std::vector<T*> list_;
TList list_;
}; };
} // namespace alloy } // namespace alloy

View File

@ -161,4 +161,16 @@ XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN
#include <x86intrin.h> #include <x86intrin.h>
#endif // MSVC #endif // MSVC
namespace poly {
#if XE_LIKE_WIN32
const char path_separator = '\\';
const size_t max_path = _MAX_PATH;
#else
const char path_separator = '/';
const size_t max_path = PATH_MAX;
#endif // WIN32
} // namespace poly
#endif // POLY_PLATFORM_H_ #endif // POLY_PLATFORM_H_

View File

@ -30,12 +30,12 @@ xe_file_ref xe_file_open(const xe_file_mode mode, const xechar_t *path) {
xechar_t mode_string[10]; xechar_t mode_string[10];
mode_string[0] = 0; mode_string[0] = 0;
if (mode & kXEFileModeRead) { if (mode & kXEFileModeRead) {
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("r"))); XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"r"));
} }
if (mode & kXEFileModeWrite) { if (mode & kXEFileModeWrite) {
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("w"))); XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"w"));
} }
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("b"))); XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"b"));
#if XE_LIKE_WIN32 && XE_WCHAR #if XE_LIKE_WIN32 && XE_WCHAR
XEEXPECTZERO(_wfopen_s((FILE**)&file->handle, path, mode_string)); XEEXPECTZERO(_wfopen_s((FILE**)&file->handle, path, mode_string));

View File

@ -75,7 +75,7 @@ int xe_pal_get_system_info(xe_system_info* out_info) {
LPFN_GLPI glpi = NULL; LPFN_GLPI glpi = NULL;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
kernel32 = GetModuleHandle(TEXT("kernel32")); kernel32 = GetModuleHandle(L"kernel32");
XEEXPECTNOTNULL(kernel32); XEEXPECTNOTNULL(kernel32);
glpi = (LPFN_GLPI)GetProcAddress(kernel32, "GetLogicalProcessorInformation"); glpi = (LPFN_GLPI)GetProcAddress(kernel32, "GetLogicalProcessorInformation");
XEEXPECTNOTNULL(glpi); XEEXPECTNOTNULL(glpi);

View File

@ -13,11 +13,11 @@
void xe_path_join(const xechar_t* left, const xechar_t* right, void xe_path_join(const xechar_t* left, const xechar_t* right,
xechar_t* out_path, size_t out_path_size) { xechar_t* out_path, size_t out_path_size) {
#if XE_WCHAR #if XE_WCHAR
xesnprintf(out_path, out_path_size, XT("%ls%c%ls"), xesnprintf(out_path, out_path_size, L"%ls%c%ls",
left, XE_PATH_SEPARATOR, right); left, poly::path_separator, right);
#else #else
xesnprintf(out_path, out_path_size, XT("%s%c%s"), xesnprintf(out_path, out_path_size, L"%s%c%s",
left, XE_PATH_SEPARATOR, right); left, poly::path_separator, right);
#endif // XE_WCHAR #endif // XE_WCHAR
} }

View File

@ -147,7 +147,7 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) {
int result_code = 0; int result_code = 0;
// Get just the filename (foo.xex). // Get just the filename (foo.xex).
const xechar_t* file_name = xestrrchr(path, XE_PATH_SEPARATOR); const xechar_t* file_name = xestrrchr(path, poly::path_separator);
if (file_name) { if (file_name) {
// Skip slash. // Skip slash.
file_name++; file_name++;
@ -157,7 +157,7 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) {
} }
// Get the parent path of the file. // Get the parent path of the file.
xechar_t parent_path[XE_MAX_PATH]; xechar_t parent_path[poly::max_path];
XEIGNORE(xestrcpy(parent_path, XECOUNT(parent_path), path)); XEIGNORE(xestrcpy(parent_path, XECOUNT(parent_path), path));
parent_path[file_name - path] = 0; parent_path[file_name - path] = 0;
@ -176,7 +176,7 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) {
"d:", "\\Device\\Harddisk1\\Partition0"); "d:", "\\Device\\Harddisk1\\Partition0");
// Get the file name of the module to load from the filesystem. // Get the file name of the module to load from the filesystem.
char fs_path[XE_MAX_PATH]; char fs_path[poly::max_path];
XEIGNORE(xestrcpya(fs_path, XECOUNT(fs_path), "game:\\")); XEIGNORE(xestrcpya(fs_path, XECOUNT(fs_path), "game:\\"));
char* fs_path_ptr = fs_path + xestrlena(fs_path); char* fs_path_ptr = fs_path + xestrlena(fs_path);
*fs_path_ptr = 0; *fs_path_ptr = 0;

View File

@ -65,7 +65,7 @@ public:
X_STATUS LaunchSTFSTitle(const xechar_t* path); X_STATUS LaunchSTFSTitle(const xechar_t* path);
private: private:
xechar_t command_line_[XE_MAX_PATH]; xechar_t command_line_[poly::max_path];
ui::Window* main_window_; ui::Window* main_window_;

View File

@ -96,7 +96,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) {
base_path = FLAGS_dump_shaders.c_str(); base_path = FLAGS_dump_shaders.c_str();
} }
uint64_t hash = xe_hash64(shader_source, xestrlena(shader_source)); // ? uint64_t hash = xe_hash64(shader_source, xestrlena(shader_source)); // ?
char file_name[XE_MAX_PATH]; char file_name[poly::max_path];
xesnprintfa(file_name, XECOUNT(file_name), xesnprintfa(file_name, XECOUNT(file_name),
"%s/gen_%.16llX.gs", "%s/gen_%.16llX.gs",
base_path, base_path,

View File

@ -47,7 +47,7 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type,
base_path = FLAGS_dump_shaders.c_str(); base_path = FLAGS_dump_shaders.c_str();
} }
size_t hash = xe_hash64(disasm_source, xestrlena(disasm_source)); // ? size_t hash = xe_hash64(disasm_source, xestrlena(disasm_source)); // ?
char file_name[XE_MAX_PATH]; char file_name[poly::max_path];
xesnprintfa(file_name, XECOUNT(file_name), xesnprintfa(file_name, XECOUNT(file_name),
"%s/gen_%.16llX.%s", "%s/gen_%.16llX.%s",
base_path, base_path,

View File

@ -62,7 +62,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) {
// Walk the path, one separator at a time. // Walk the path, one separator at a time.
// We copy it into the buffer and shift it left over and over. // We copy it into the buffer and shift it left over and over.
char remaining[XE_MAX_PATH]; char remaining[poly::max_path];
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path));
while (remaining[0]) { while (remaining[0]) {
char* next_slash = xestrchra(remaining, '\\'); char* next_slash = xestrchra(remaining, '\\');

View File

@ -35,23 +35,23 @@ Entry* HostPathDevice::ResolvePath(const char* path) {
XELOGFS("HostPathDevice::ResolvePath(%s)", path); XELOGFS("HostPathDevice::ResolvePath(%s)", path);
#if XE_WCHAR #if XE_WCHAR
xechar_t rel_path[XE_MAX_PATH]; xechar_t rel_path[poly::max_path];
XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path)); XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path));
#else #else
const xechar_t* rel_path = path; const xechar_t* rel_path = path;
#endif #endif
xechar_t full_path[XE_MAX_PATH]; xechar_t full_path[poly::max_path];
xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path)); xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path));
// Swap around path separators. // Swap around path separators.
if (XE_PATH_SEPARATOR != '\\') { if (poly::path_separator != '\\') {
for (size_t n = 0; n < XECOUNT(full_path); n++) { for (size_t n = 0; n < XECOUNT(full_path); n++) {
if (full_path[n] == 0) { if (full_path[n] == 0) {
break; break;
} }
if (full_path[n] == '\\') { if (full_path[n] == '\\') {
full_path[n] = XE_PATH_SEPARATOR; full_path[n] = poly::path_separator;
} }
} }
} }

View File

@ -87,10 +87,10 @@ X_STATUS HostPathEntry::QueryDirectory(
} }
if (handle == INVALID_HANDLE_VALUE) { if (handle == INVALID_HANDLE_VALUE) {
xechar_t target_path[XE_MAX_PATH]; xechar_t target_path[poly::max_path];
xestrcpy(target_path, XE_MAX_PATH, local_path_); xestrcpy(target_path, poly::max_path, local_path_);
if (file_name == NULL) { if (file_name == NULL) {
xestrcat(target_path, XE_MAX_PATH, XETEXT("*")); xestrcat(target_path, poly::max_path, L"*");
} }
else { else {
auto target_length = xestrlen(local_path_); auto target_length = xestrlen(local_path_);

View File

@ -63,7 +63,7 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) {
// Walk the path, one separator at a time. // Walk the path, one separator at a time.
// We copy it into the buffer and shift it left over and over. // We copy it into the buffer and shift it left over and over.
char remaining[XE_MAX_PATH]; char remaining[poly::max_path];
XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path));
while (remaining[0]) { while (remaining[0]) {
char* next_slash = xestrchra(remaining, '\\'); char* next_slash = xestrchra(remaining, '\\');

View File

@ -91,7 +91,7 @@ Entry* FileSystem::ResolvePath(const char* path) {
// Resolve symlinks. // Resolve symlinks.
// TODO(benvanik): more robust symlink handling - right now we assume simple // TODO(benvanik): more robust symlink handling - right now we assume simple
// drive path -> device mappings with nothing nested. // drive path -> device mappings with nothing nested.
char full_path[XE_MAX_PATH]; char full_path[poly::max_path];
XEIGNORE(xestrcpya(full_path, XECOUNT(full_path), path)); XEIGNORE(xestrcpya(full_path, XECOUNT(full_path), path));
for (std::unordered_map<std::string, std::string>::iterator it = for (std::unordered_map<std::string, std::string>::iterator it =
symlinks_.begin(); it != symlinks_.end(); ++it) { symlinks_.begin(); it != symlinks_.end(); ++it) {
@ -111,7 +111,7 @@ Entry* FileSystem::ResolvePath(const char* path) {
if (xestrcasestra(full_path, device->path()) == full_path) { if (xestrcasestra(full_path, device->path()) == full_path) {
// Found! // Found!
// Trim the device prefix off and pass down. // Trim the device prefix off and pass down.
char device_path[XE_MAX_PATH]; char device_path[poly::max_path];
XEIGNORE(xestrcpya(device_path, XECOUNT(device_path), XEIGNORE(xestrcpya(device_path, XECOUNT(device_path),
full_path + xestrlena(device->path()))); full_path + xestrlena(device->path())));
return device->ResolvePath(device_path); return device->ResolvePath(device_path);

View File

@ -34,7 +34,7 @@ public:
protected: protected:
char name_[256]; char name_[256];
char path_[XE_MAX_PATH]; char path_[poly::max_path];
}; };

View File

@ -31,7 +31,7 @@ void xe_format_log_line(
const char* function_name, const char level_char, const char* function_name, const char level_char,
const char* fmt, va_list args) { const char* fmt, va_list args) {
// Strip out just the filename from the path. // Strip out just the filename from the path.
const char* filename = xestrrchra(file_path, XE_PATH_SEPARATOR); const char* filename = xestrrchra(file_path, poly::path_separator);
if (filename) { if (filename) {
// Slash - skip over it. // Slash - skip over it.
filename++; filename++;

View File

@ -94,7 +94,7 @@ int xe_main_window_thunk(
xe_attach_console(); xe_attach_console();
wchar_t buffer[2048]; wchar_t buffer[2048];
xestrcpy(buffer, XECOUNT(buffer), name); xestrcpy(buffer, XECOUNT(buffer), name);
xestrcat(buffer, XECOUNT(buffer), XETEXT(" ")); xestrcat(buffer, XECOUNT(buffer), L" ");
xestrcat(buffer, XECOUNT(buffer), command_line); xestrcat(buffer, XECOUNT(buffer), command_line);
int argc; int argc;
wchar_t** argv = CommandLineToArgvW(buffer, &argc); wchar_t** argv = CommandLineToArgvW(buffer, &argc);

View File

@ -40,7 +40,6 @@ char* xestrcasestra(const char* str, const char* substr);
#define xestrdupw _wcsdup #define xestrdupw _wcsdup
#define xestrchrw wcschr #define xestrchrw wcschr
#define xestrrchrw wcsrchr #define xestrrchrw wcsrchr
#define xestrstrw wcsstr
#define xestrcasestrw ?? #define xestrcasestrw ??
#define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0) #define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0)
#define xestrncpyw(dest, destLength, source, count) (wcsncpy_s(dest, destLength, source, count) == 0) #define xestrncpyw(dest, destLength, source, count) (wcsncpy_s(dest, destLength, source, count) == 0)
@ -54,7 +53,6 @@ char* xestrcasestra(const char* str, const char* substr);
#define xestrcasecmpa strcasecmp #define xestrcasecmpa strcasecmp
#define xestrchra strchr #define xestrchra strchr
#define xestrrchra strrchr #define xestrrchra strrchr
#define xestrstra strstr
#define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0) #define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0)
#define xestrncpya(dest, destLength, source, count) (strncpy_s(dest, destLength, source, count) == 0) #define xestrncpya(dest, destLength, source, count) (strncpy_s(dest, destLength, source, count) == 0)
#define xestrcata(dest, destLength, source) (strcat_s(dest, destLength, source) == 0) #define xestrcata(dest, destLength, source) (strcat_s(dest, destLength, source) == 0)
@ -65,8 +63,6 @@ char* xestrcasestra(const char* str, const char* substr);
typedef wchar_t xechar_t; typedef wchar_t xechar_t;
#define XE_WCHAR 1 #define XE_WCHAR 1
#define XETEXT(s) L ## s
#define XESTRFORMAT L"%ls"
#define xestrlen xestrlenw #define xestrlen xestrlenw
#define xestrcmp xestrcmpw #define xestrcmp xestrcmpw
@ -74,7 +70,6 @@ typedef wchar_t xechar_t;
#define xestrdup xestrdupw #define xestrdup xestrdupw
#define xestrchr xestrchrw #define xestrchr xestrchrw
#define xestrrchr xestrrchrw #define xestrrchr xestrrchrw
#define xestrstr xestrstrw
#define xestrcasestr xestrcasestrw #define xestrcasestr xestrcasestrw
#define xestrtoull xestrtoullw #define xestrtoull xestrtoullw
#define xestrcpy xestrcpyw #define xestrcpy xestrcpyw
@ -89,8 +84,6 @@ typedef wchar_t xechar_t;
typedef char xechar_t; typedef char xechar_t;
#define XE_CHAR 1 #define XE_CHAR 1
#define XETEXT(s) s
#define XESTRFORMAT "%s"
#define xestrlen xestrlena #define xestrlen xestrlena
#define xestrcmp xestrcmpa #define xestrcmp xestrcmpa
@ -98,7 +91,6 @@ typedef char xechar_t;
#define xestrdup xestrdupa #define xestrdup xestrdupa
#define xestrchr xestrchra #define xestrchr xestrchra
#define xestrrchr xestrrchra #define xestrrchr xestrrchra
#define xestrstr xestrstra
#define xestrcasestr xestrcasestra #define xestrcasestr xestrcasestra
#define xestrtoull xestrtoulla #define xestrtoull xestrtoulla
#define xestrcpy xestrcpya #define xestrcpy xestrcpya
@ -111,15 +103,4 @@ typedef char xechar_t;
#endif // WIN32 #endif // WIN32
#define XT XETEXT
#define XTS XESTRFORMAT
#if XE_LIKE_WIN32
#define XE_PATH_SEPARATOR ((xechar_t)'\\')
#define XE_MAX_PATH _MAX_PATH
#else
#define XE_PATH_SEPARATOR ((xechar_t)'/')
#define XE_MAX_PATH PATH_MAX
#endif // WIN32
#endif // XENIA_STRING_H_ #endif // XENIA_STRING_H_

View File

@ -37,7 +37,7 @@ int xenia_run(int argc, xechar_t** argv) {
if (FLAGS_target.size()) { if (FLAGS_target.size()) {
// Passed as a named argument. // Passed as a named argument.
// TODO(benvanik): find something better than gflags that supports unicode. // TODO(benvanik): find something better than gflags that supports unicode.
xechar_t buffer[XE_MAX_PATH]; xechar_t buffer[poly::max_path];
XEIGNORE(xestrwiden(buffer, sizeof(buffer), FLAGS_target.c_str())); XEIGNORE(xestrwiden(buffer, sizeof(buffer), FLAGS_target.c_str()));
path = buffer; path = buffer;
} else { } else {
@ -52,7 +52,7 @@ int xenia_run(int argc, xechar_t** argv) {
// Normalize the path and make absolute. // Normalize the path and make absolute.
// TODO(benvanik): move this someplace common. // TODO(benvanik): move this someplace common.
xechar_t abs_path[XE_MAX_PATH]; xechar_t abs_path[poly::max_path];
xe_path_get_absolute(path, abs_path, XECOUNT(abs_path)); xe_path_get_absolute(path, abs_path, XECOUNT(abs_path));
// Grab file extension. // Grab file extension.
@ -60,7 +60,7 @@ int xenia_run(int argc, xechar_t** argv) {
const xechar_t* dot = xestrrchr(abs_path, '.'); const xechar_t* dot = xestrrchr(abs_path, '.');
// Create the emulator. // Create the emulator.
emulator = new Emulator(XT("")); emulator = new Emulator(L"");
XEEXPECTNOTNULL(emulator); XEEXPECTNOTNULL(emulator);
X_STATUS result = emulator->Setup(); X_STATUS result = emulator->Setup();
if (XFAILED(result)) { if (XFAILED(result)) {
@ -74,7 +74,7 @@ int xenia_run(int argc, xechar_t** argv) {
if (!dot) { if (!dot) {
// Likely an STFS container. // Likely an STFS container.
result = emulator->LaunchSTFSTitle(abs_path); result = emulator->LaunchSTFSTitle(abs_path);
} else if (xestrcmp(dot, XT(".xex")) == 0) { } else if (xestrcmp(dot, L".xex") == 0) {
// Treat as a naked xex file. // Treat as a naked xex file.
result = emulator->LaunchXexFile(abs_path); result = emulator->LaunchXexFile(abs_path);
} else { } else {
@ -96,4 +96,4 @@ XECLEANUP:
Profiler::Shutdown(); Profiler::Shutdown();
return result_code; return result_code;
} }
XE_MAIN_WINDOW_THUNK(xenia_run, XETEXT("xenia-run"), "xenia-run some.xex"); XE_MAIN_WINDOW_THUNK(xenia_run, L"xenia-run", "xenia-run some.xex");