mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 12:34:35 +03:00
[ABI] Added implementation of all pure virtual functions
This changes virtually nothing from API perspective, however, it allows to embed asmjit well in C projects that do not link to C++ standard library. In normal circumstances, when a pure virtual function is declared, but not implemented, the compiler would replace it with it's default version, which would print a message and terminate the program. However, this function is part of a C++ standard library, so we don't want to use it.
This commit is contained in:
@@ -886,6 +886,15 @@ Pass::Pass(const char* name) noexcept
|
|||||||
: _name(name) {}
|
: _name(name) {}
|
||||||
Pass::~Pass() noexcept {}
|
Pass::~Pass() noexcept {}
|
||||||
|
|
||||||
|
// Pass - Interface
|
||||||
|
// ================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error Pass::run(Zone* zone, Logger* logger) {
|
||||||
|
DebugUtils::unused(zone, logger);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
ASMJIT_END_NAMESPACE
|
ASMJIT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // !ASMJIT_NO_BUILDER
|
#endif // !ASMJIT_NO_BUILDER
|
||||||
|
|||||||
@@ -1378,7 +1378,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! This is the only function that is called by the `BaseBuilder` to process the code. It passes `zone`,
|
//! This is the only function that is called by the `BaseBuilder` to process the code. It passes `zone`,
|
||||||
//! which will be reset after the `run()` finishes.
|
//! which will be reset after the `run()` finishes.
|
||||||
virtual Error run(Zone* zone, Logger* logger) = 0;
|
ASMJIT_API virtual Error run(Zone* zone, Logger* logger) = 0;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -587,6 +587,12 @@ Error FuncPass::run(Zone* zone, Logger* logger) {
|
|||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error FuncPass::runOnFunction(Zone* zone, Logger* logger, FuncNode* func) {
|
||||||
|
DebugUtils::unused(zone, logger, func);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
ASMJIT_END_NAMESPACE
|
ASMJIT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // !ASMJIT_NO_COMPILER
|
#endif // !ASMJIT_NO_COMPILER
|
||||||
|
|||||||
@@ -712,7 +712,7 @@ public:
|
|||||||
ASMJIT_API Error run(Zone* zone, Logger* logger) override;
|
ASMJIT_API Error run(Zone* zone, Logger* logger) override;
|
||||||
|
|
||||||
//! Called once per `FuncNode`.
|
//! Called once per `FuncNode`.
|
||||||
virtual Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) = 0;
|
ASMJIT_API virtual Error runOnFunction(Zone* zone, Logger* logger, FuncNode* func) = 0;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -61,6 +61,24 @@ static void dumpAssignment(String& sb, const FuncArgsContext& ctx) noexcept {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// BaseEmitHelper - Abstract
|
||||||
|
// =========================
|
||||||
|
|
||||||
|
Error BaseEmitHelper::emitRegMove(const Operand_& dst_, const Operand_& src_, TypeId typeId, const char* comment) {
|
||||||
|
DebugUtils::unused(dst_, src_, typeId, comment);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error BaseEmitHelper::emitRegSwap(const BaseReg& a, const BaseReg& b, const char* comment) {
|
||||||
|
DebugUtils::unused(a, b, comment);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error BaseEmitHelper::emitArgMove(const BaseReg& dst_, TypeId dstTypeId, const Operand_& src_, TypeId srcTypeId, const char* comment) {
|
||||||
|
DebugUtils::unused(dst_, dstTypeId, src_, srcTypeId, comment);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
// BaseEmitHelper - EmitArgsAssignment
|
// BaseEmitHelper - EmitArgsAssignment
|
||||||
// ===================================
|
// ===================================
|
||||||
|
|
||||||
|
|||||||
@@ -125,13 +125,39 @@ Error BaseEmitter::reportError(Error err, const char* message) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BaseEmitter - Sections
|
||||||
|
// ======================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::section(Section* section) {
|
||||||
|
DebugUtils::unused(section);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
// BaseEmitter - Labels
|
// BaseEmitter - Labels
|
||||||
// ====================
|
// ====================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Label BaseEmitter::newLabel() {
|
||||||
|
return Label(Globals::kInvalidId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Label BaseEmitter::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) {
|
||||||
|
DebugUtils::unused(name, nameSize, type, parentId);
|
||||||
|
return Label(Globals::kInvalidId);
|
||||||
|
}
|
||||||
|
|
||||||
Label BaseEmitter::labelByName(const char* name, size_t nameSize, uint32_t parentId) noexcept {
|
Label BaseEmitter::labelByName(const char* name, size_t nameSize, uint32_t parentId) noexcept {
|
||||||
return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : Globals::kInvalidId);
|
return Label(_code ? _code->labelIdByName(name, nameSize, parentId) : Globals::kInvalidId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::bind(const Label& label) {
|
||||||
|
DebugUtils::unused(label);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
bool BaseEmitter::isLabelValid(uint32_t labelId) const noexcept {
|
bool BaseEmitter::isLabelValid(uint32_t labelId) const noexcept {
|
||||||
return _code && labelId < _code->labelCount();
|
return _code && labelId < _code->labelCount();
|
||||||
}
|
}
|
||||||
@@ -172,6 +198,12 @@ Error BaseEmitter::_emitI(InstId instId, const Operand_& o0, const Operand_& o1,
|
|||||||
return _emit(instId, o0, o1, o2, opExt);
|
return _emit(instId, o0, o1, o2, opExt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::_emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) {
|
||||||
|
DebugUtils::unused(instId, o0, o1, o2, oExt);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
Error BaseEmitter::_emitOpArray(InstId instId, const Operand_* operands, size_t opCount) {
|
Error BaseEmitter::_emitOpArray(InstId instId, const Operand_* operands, size_t opCount) {
|
||||||
const Operand_* op = operands;
|
const Operand_* op = operands;
|
||||||
Operand_ opExt[3];
|
Operand_ opExt[3];
|
||||||
@@ -233,9 +265,51 @@ Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssi
|
|||||||
return _funcs.emitArgsAssignment(this, frame, args);
|
return _funcs.emitArgsAssignment(this, frame, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BaseEmitter - Align
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::align(AlignMode alignMode, uint32_t alignment) {
|
||||||
|
DebugUtils::unused(alignMode, alignment);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseEmitter - Embed
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::embed(const void* data, size_t dataSize) {
|
||||||
|
DebugUtils::unused(data, dataSize);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) {
|
||||||
|
DebugUtils::unused(typeId, data, itemCount, repeatCount);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::embedLabel(const Label& label, size_t dataSize) {
|
||||||
|
DebugUtils::unused(label, dataSize);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseEmitter::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
|
||||||
|
DebugUtils::unused(label, base, dataSize);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
// BaseEmitter - Comment
|
// BaseEmitter - Comment
|
||||||
// =====================
|
// =====================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error comment(const char* data, size_t size = SIZE_MAX) {
|
||||||
|
DebugUtils::unused(data, size);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
Error BaseEmitter::commentf(const char* fmt, ...) {
|
Error BaseEmitter::commentf(const char* fmt, ...) {
|
||||||
if (!hasEmitterFlag(EmitterFlags::kLogComments)) {
|
if (!hasEmitterFlag(EmitterFlags::kLogComments)) {
|
||||||
if (!hasEmitterFlag(EmitterFlags::kAttached))
|
if (!hasEmitterFlag(EmitterFlags::kAttached))
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ public:
|
|||||||
//! \name Sections
|
//! \name Sections
|
||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
virtual Error section(Section* section) = 0;
|
ASMJIT_API virtual Error section(Section* section) = 0;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
@@ -565,9 +565,9 @@ public:
|
|||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
//! Creates a new label.
|
//! Creates a new label.
|
||||||
virtual Label newLabel() = 0;
|
ASMJIT_API virtual Label newLabel() = 0;
|
||||||
//! Creates a new named label.
|
//! Creates a new named label.
|
||||||
virtual Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId) = 0;
|
ASMJIT_API virtual Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId) = 0;
|
||||||
|
|
||||||
//! Creates a new anonymous label with a name, which can only be used for debugging purposes.
|
//! Creates a new anonymous label with a name, which can only be used for debugging purposes.
|
||||||
ASMJIT_INLINE_NODEBUG Label newAnonymousLabel(const char* name, size_t nameSize = SIZE_MAX) { return newNamedLabel(name, nameSize, LabelType::kAnonymous); }
|
ASMJIT_INLINE_NODEBUG Label newAnonymousLabel(const char* name, size_t nameSize = SIZE_MAX) { return newNamedLabel(name, nameSize, LabelType::kAnonymous); }
|
||||||
@@ -585,7 +585,7 @@ public:
|
|||||||
//! Binds the `label` to the current position of the current section.
|
//! Binds the `label` to the current position of the current section.
|
||||||
//!
|
//!
|
||||||
//! \note Attempt to bind the same label multiple times will return an error.
|
//! \note Attempt to bind the same label multiple times will return an error.
|
||||||
virtual Error bind(const Label& label) = 0;
|
ASMJIT_API virtual Error bind(const Label& label) = 0;
|
||||||
|
|
||||||
//! Tests whether the label `id` is valid (i.e. registered).
|
//! Tests whether the label `id` is valid (i.e. registered).
|
||||||
ASMJIT_API bool isLabelValid(uint32_t labelId) const noexcept;
|
ASMJIT_API bool isLabelValid(uint32_t labelId) const noexcept;
|
||||||
@@ -637,7 +637,7 @@ public:
|
|||||||
|
|
||||||
//! \cond INTERNAL
|
//! \cond INTERNAL
|
||||||
//! Emits an instruction - all 6 operands must be defined.
|
//! Emits an instruction - all 6 operands must be defined.
|
||||||
virtual Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) = 0;
|
ASMJIT_API virtual Error _emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* oExt) = 0;
|
||||||
//! Emits instruction having operands stored in array.
|
//! Emits instruction having operands stored in array.
|
||||||
ASMJIT_API virtual Error _emitOpArray(InstId instId, const Operand_* operands, size_t opCount);
|
ASMJIT_API virtual Error _emitOpArray(InstId instId, const Operand_* operands, size_t opCount);
|
||||||
//! \endcond
|
//! \endcond
|
||||||
@@ -661,7 +661,7 @@ public:
|
|||||||
//! The sequence that is used to fill the gap between the aligned location and the current location depends on the
|
//! The sequence that is used to fill the gap between the aligned location and the current location depends on the
|
||||||
//! align `mode`, see \ref AlignMode. The `alignment` argument specifies alignment in bytes, so for example when
|
//! align `mode`, see \ref AlignMode. The `alignment` argument specifies alignment in bytes, so for example when
|
||||||
//! it's `32` it means that the code buffer will be aligned to `32` bytes.
|
//! it's `32` it means that the code buffer will be aligned to `32` bytes.
|
||||||
virtual Error align(AlignMode alignMode, uint32_t alignment) = 0;
|
ASMJIT_API virtual Error align(AlignMode alignMode, uint32_t alignment) = 0;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
@@ -669,7 +669,7 @@ public:
|
|||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
//! Embeds raw data into the \ref CodeBuffer.
|
//! Embeds raw data into the \ref CodeBuffer.
|
||||||
virtual Error embed(const void* data, size_t dataSize) = 0;
|
ASMJIT_API virtual Error embed(const void* data, size_t dataSize) = 0;
|
||||||
|
|
||||||
//! Embeds a typed data array.
|
//! Embeds a typed data array.
|
||||||
//!
|
//!
|
||||||
@@ -680,7 +680,7 @@ public:
|
|||||||
//!
|
//!
|
||||||
//! - Repeat the given data `repeatCount` times, so the data can be used as a fill pattern for example, or as a
|
//! - Repeat the given data `repeatCount` times, so the data can be used as a fill pattern for example, or as a
|
||||||
//! pattern used by SIMD instructions.
|
//! pattern used by SIMD instructions.
|
||||||
virtual Error embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) = 0;
|
ASMJIT_API virtual Error embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) = 0;
|
||||||
|
|
||||||
//! Embeds int8_t `value` repeated by `repeatCount`.
|
//! Embeds int8_t `value` repeated by `repeatCount`.
|
||||||
ASMJIT_INLINE_NODEBUG Error embedInt8(int8_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kInt8, &value, 1, repeatCount); }
|
ASMJIT_INLINE_NODEBUG Error embedInt8(int8_t value, size_t repeatCount = 1) { return embedDataArray(TypeId::kInt8, &value, 1, repeatCount); }
|
||||||
@@ -707,17 +707,17 @@ public:
|
|||||||
//! 1. Aligns by using AlignMode::kData to the minimum `pool` alignment.
|
//! 1. Aligns by using AlignMode::kData to the minimum `pool` alignment.
|
||||||
//! 2. Binds the ConstPool label so it's bound to an aligned location.
|
//! 2. Binds the ConstPool label so it's bound to an aligned location.
|
||||||
//! 3. Emits ConstPool content.
|
//! 3. Emits ConstPool content.
|
||||||
virtual Error embedConstPool(const Label& label, const ConstPool& pool) = 0;
|
ASMJIT_API virtual Error embedConstPool(const Label& label, const ConstPool& pool) = 0;
|
||||||
|
|
||||||
//! Embeds an absolute `label` address as data.
|
//! Embeds an absolute `label` address as data.
|
||||||
//!
|
//!
|
||||||
//! The `dataSize` is an optional argument that can be used to specify the size of the address data. If it's zero
|
//! The `dataSize` is an optional argument that can be used to specify the size of the address data. If it's zero
|
||||||
//! (default) the address size is deduced from the target architecture (either 4 or 8 bytes).
|
//! (default) the address size is deduced from the target architecture (either 4 or 8 bytes).
|
||||||
virtual Error embedLabel(const Label& label, size_t dataSize = 0) = 0;
|
ASMJIT_API virtual Error embedLabel(const Label& label, size_t dataSize = 0) = 0;
|
||||||
|
|
||||||
//! Embeds a delta (distance) between the `label` and `base` calculating it as `label - base`. This function was
|
//! Embeds a delta (distance) between the `label` and `base` calculating it as `label - base`. This function was
|
||||||
//! designed to make it easier to embed lookup tables where each index is a relative distance of two labels.
|
//! designed to make it easier to embed lookup tables where each index is a relative distance of two labels.
|
||||||
virtual Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) = 0;
|
ASMJIT_API virtual Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) = 0;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
@@ -725,7 +725,7 @@ public:
|
|||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
//! Emits a comment stored in `data` with an optional `size` parameter.
|
//! Emits a comment stored in `data` with an optional `size` parameter.
|
||||||
virtual Error comment(const char* data, size_t size = SIZE_MAX) = 0;
|
ASMJIT_API virtual Error comment(const char* data, size_t size = SIZE_MAX) = 0;
|
||||||
|
|
||||||
//! Emits a formatted comment specified by `fmt` and variable number of arguments.
|
//! Emits a formatted comment specified by `fmt` and variable number of arguments.
|
||||||
ASMJIT_API Error commentf(const char* fmt, ...);
|
ASMJIT_API Error commentf(const char* fmt, ...);
|
||||||
@@ -738,9 +738,9 @@ public:
|
|||||||
//! \{
|
//! \{
|
||||||
|
|
||||||
//! Called after the emitter was attached to `CodeHolder`.
|
//! Called after the emitter was attached to `CodeHolder`.
|
||||||
virtual Error onAttach(CodeHolder* ASMJIT_NONNULL(code)) noexcept = 0;
|
ASMJIT_API virtual Error onAttach(CodeHolder* ASMJIT_NONNULL(code)) noexcept;
|
||||||
//! Called after the emitter was detached from `CodeHolder`.
|
//! Called after the emitter was detached from `CodeHolder`.
|
||||||
virtual Error onDetach(CodeHolder* ASMJIT_NONNULL(code)) noexcept = 0;
|
ASMJIT_API virtual Error onDetach(CodeHolder* ASMJIT_NONNULL(code)) noexcept;
|
||||||
|
|
||||||
//! Called when \ref CodeHolder has updated an important setting, which involves the following:
|
//! Called when \ref CodeHolder has updated an important setting, which involves the following:
|
||||||
//!
|
//!
|
||||||
|
|||||||
@@ -11,4 +11,8 @@ ASMJIT_BEGIN_NAMESPACE
|
|||||||
ErrorHandler::ErrorHandler() noexcept {}
|
ErrorHandler::ErrorHandler() noexcept {}
|
||||||
ErrorHandler::~ErrorHandler() noexcept {}
|
ErrorHandler::~ErrorHandler() noexcept {}
|
||||||
|
|
||||||
|
void ErrorHandler::handleError(Error err, const char* message, BaseEmitter* origin) {
|
||||||
|
DebugUtils::unused(err, message, origin);
|
||||||
|
}
|
||||||
|
|
||||||
ASMJIT_END_NAMESPACE
|
ASMJIT_END_NAMESPACE
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ public:
|
|||||||
//! calling `handleError()` so `longjmp()` can be used without any issues to cancel the code generation if an
|
//! calling `handleError()` so `longjmp()` can be used without any issues to cancel the code generation if an
|
||||||
//! error occurred. There is no difference between exceptions and `longjmp()` from AsmJit's perspective, however,
|
//! error occurred. There is no difference between exceptions and `longjmp()` from AsmJit's perspective, however,
|
||||||
//! never jump outside of `CodeHolder` and `BaseEmitter` scope as you would leak memory.
|
//! never jump outside of `CodeHolder` and `BaseEmitter` scope as you would leak memory.
|
||||||
virtual void handleError(Error err, const char* message, BaseEmitter* origin) = 0;
|
ASMJIT_API virtual void handleError(Error err, const char* message, BaseEmitter* origin) = 0;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,6 +19,14 @@ Logger::Logger() noexcept
|
|||||||
: _options() {}
|
: _options() {}
|
||||||
Logger::~Logger() noexcept {}
|
Logger::~Logger() noexcept {}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error Logger::_log(const char* data, size_t size) noexcept {
|
||||||
|
DebugUtils::unused(data, size);
|
||||||
|
|
||||||
|
// Do not error in this case - the logger would just sink to /dev/null.
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
Error Logger::logf(const char* fmt, ...) noexcept {
|
Error Logger::logf(const char* fmt, ...) noexcept {
|
||||||
Error err;
|
Error err;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public:
|
|||||||
//! The function can accept either a null terminated string if `size` is `SIZE_MAX` or a non-null terminated
|
//! The function can accept either a null terminated string if `size` is `SIZE_MAX` or a non-null terminated
|
||||||
//! string of the given `size`. The function cannot assume that the data is null terminated and must handle
|
//! string of the given `size`. The function cannot assume that the data is null terminated and must handle
|
||||||
//! non-null terminated inputs.
|
//! non-null terminated inputs.
|
||||||
virtual Error _log(const char* data, size_t size) noexcept = 0;
|
ASMJIT_API virtual Error _log(const char* data, size_t size) noexcept = 0;
|
||||||
|
|
||||||
//! Logs string `str`, which is either null terminated or having size `size`.
|
//! Logs string `str`, which is either null terminated or having size `size`.
|
||||||
ASMJIT_INLINE_NODEBUG Error log(const char* data, size_t size = SIZE_MAX) noexcept { return _log(data, size); }
|
ASMJIT_INLINE_NODEBUG Error log(const char* data, size_t size = SIZE_MAX) noexcept { return _log(data, size); }
|
||||||
|
|||||||
@@ -196,6 +196,12 @@ Error BaseRAPass::onPerformAllSteps() noexcept {
|
|||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BaseRAPass - Events
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
void BaseRAPass::onInit() noexcept {}
|
||||||
|
void BaseRAPass::onDone() noexcept {}
|
||||||
|
|
||||||
// BaseRAPass - CFG - Basic Block Management
|
// BaseRAPass - CFG - Basic Block Management
|
||||||
// =========================================
|
// =========================================
|
||||||
|
|
||||||
@@ -307,6 +313,11 @@ Error BaseRAPass::addBlock(RABlock* block) noexcept {
|
|||||||
// BaseRAPass - CFG - Build
|
// BaseRAPass - CFG - Build
|
||||||
// ========================
|
// ========================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseRAPass::buildCFG() noexcept {
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssignmentsMap) noexcept {
|
Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssignmentsMap) noexcept {
|
||||||
if (sharedAssignmentsMap.empty())
|
if (sharedAssignmentsMap.empty())
|
||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
@@ -1814,6 +1825,50 @@ Error BaseRAPass::rewrite() noexcept {
|
|||||||
return _rewrite(_func, _stop);
|
return _rewrite(_func, _stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseRAPass::_rewrite(BaseNode* first, BaseNode* stop) noexcept {
|
||||||
|
DebugUtils::unused(first, stop);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseRAPass - Emit
|
||||||
|
// =================
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseRAPass::emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
|
||||||
|
DebugUtils::unused(workId, dstPhysId, srcPhysId);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseRAPass::emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
|
||||||
|
DebugUtils::unused(aWorkId, aPhysId, bWorkId, bPhysId);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseRAPass::emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept {
|
||||||
|
DebugUtils::unused(workId, dstPhysId);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseRAPass::emitSave(uint32_t workId, uint32_t srcPhysId) noexcept {
|
||||||
|
DebugUtils::unused(workId, srcPhysId);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [[pure virtual]]
|
||||||
|
Error BaseRAPass::emitJump(const Label& label) noexcept {
|
||||||
|
DebugUtils::unused(label);
|
||||||
|
return DebugUtils::errored(kErrorInvalidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error BaseRAPass::emitPreCall(InvokeNode* invokeNode) noexcept {
|
||||||
|
DebugUtils::unused(invokeNode);
|
||||||
|
return DebugUtils::errored(kErrorOk);
|
||||||
|
}
|
||||||
|
|
||||||
// BaseRAPass - Logging
|
// BaseRAPass - Logging
|
||||||
// ====================
|
// ====================
|
||||||
|
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ public:
|
|||||||
ASMJIT_INLINE_NODEBUG uint32_t endPosition() const noexcept { return _instructionCount * 2; }
|
ASMJIT_INLINE_NODEBUG uint32_t endPosition() const noexcept { return _instructionCount * 2; }
|
||||||
|
|
||||||
ASMJIT_INLINE_NODEBUG const RARegMask& availableRegs() const noexcept { return _availableRegs; }
|
ASMJIT_INLINE_NODEBUG const RARegMask& availableRegs() const noexcept { return _availableRegs; }
|
||||||
ASMJIT_INLINE_NODEBUG const RARegMask& cloberredRegs() const noexcept { return _clobberedRegs; }
|
ASMJIT_INLINE_NODEBUG const RARegMask& clobberedRegs() const noexcept { return _clobberedRegs; }
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
@@ -818,11 +818,11 @@ public:
|
|||||||
|
|
||||||
//! Called by \ref runOnFunction() before the register allocation to initialize
|
//! Called by \ref runOnFunction() before the register allocation to initialize
|
||||||
//! architecture-specific data and constraints.
|
//! architecture-specific data and constraints.
|
||||||
virtual void onInit() noexcept = 0;
|
virtual void onInit() noexcept;
|
||||||
|
|
||||||
//! Called by \ref runOnFunction(` after register allocation to clean everything
|
//! Called by \ref runOnFunction(` after register allocation to clean everything
|
||||||
//! up. Called even if the register allocation failed.
|
//! up. Called even if the register allocation failed.
|
||||||
virtual void onDone() noexcept = 0;
|
virtual void onDone() noexcept;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
|
|
||||||
@@ -1160,7 +1160,7 @@ public:
|
|||||||
virtual Error emitSave(uint32_t workId, uint32_t srcPhysId) noexcept = 0;
|
virtual Error emitSave(uint32_t workId, uint32_t srcPhysId) noexcept = 0;
|
||||||
|
|
||||||
virtual Error emitJump(const Label& label) noexcept = 0;
|
virtual Error emitJump(const Label& label) noexcept = 0;
|
||||||
virtual Error emitPreCall(InvokeNode* invokeNode) noexcept = 0;
|
virtual Error emitPreCall(InvokeNode* invokeNode) noexcept;
|
||||||
|
|
||||||
//! \}
|
//! \}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user