mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 21:14:35 +03:00
BaseEmitter::commentf() shouldn't format string, which will be discarded by the emitter (fixes #306)
This commit is contained in:
@@ -1307,7 +1307,7 @@ namespace asmjit {
|
|||||||
//! invoking functions. At the moment it's the easiest way of generating code
|
//! invoking functions. At the moment it's the easiest way of generating code
|
||||||
//! in AsmJit as most architecture and OS specifics is properly abstracted and
|
//! in AsmJit as most architecture and OS specifics is properly abstracted and
|
||||||
//! handled by AsmJit automatically. However, abstractions also mean restrictions,
|
//! handled by AsmJit automatically. However, abstractions also mean restrictions,
|
||||||
//! which means that \ref BaseCompiler has more limitations that \ref BaseAssembler
|
//! which means that \ref BaseCompiler has more limitations than \ref BaseAssembler
|
||||||
//! or \ref BaseBuilder.
|
//! or \ref BaseBuilder.
|
||||||
//!
|
//!
|
||||||
//! Since \ref BaseCompiler provides register allocation it also establishes the
|
//! Since \ref BaseCompiler provides register allocation it also establishes the
|
||||||
|
|||||||
@@ -366,20 +366,23 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
Error BaseAssembler::comment(const char* data, size_t size) {
|
Error BaseAssembler::comment(const char* data, size_t size) {
|
||||||
if (ASMJIT_UNLIKELY(!_code))
|
if (!hasEmitterFlag(kFlagLogComments)) {
|
||||||
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
if (!hasEmitterFlag(kFlagAttached))
|
||||||
|
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
||||||
#ifndef ASMJIT_NO_LOGGING
|
|
||||||
if (_logger) {
|
|
||||||
_logger->log(data, size);
|
|
||||||
_logger->log("\n", 1);
|
|
||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ASMJIT_NO_LOGGING
|
||||||
|
// Logger cannot be NULL if `kFlagLogComments` is set.
|
||||||
|
ASMJIT_ASSERT(_logger != nullptr);
|
||||||
|
|
||||||
|
_logger->log(data, size);
|
||||||
|
_logger->log("\n", 1);
|
||||||
|
return kErrorOk;
|
||||||
#else
|
#else
|
||||||
DebugUtils::unused(data, size);
|
DebugUtils::unused(data, size);
|
||||||
#endif
|
|
||||||
|
|
||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -66,22 +66,35 @@ Error BaseEmitter::finalize() {
|
|||||||
// [asmjit::BaseEmitter - Internals]
|
// [asmjit::BaseEmitter - Internals]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
static constexpr uint32_t kEmitterPreservedFlags =
|
static constexpr uint32_t kEmitterPreservedFlags = BaseEmitter::kFlagOwnLogger | BaseEmitter::kFlagOwnErrorHandler;
|
||||||
BaseEmitter::kFlagOwnLogger |
|
|
||||||
BaseEmitter::kFlagOwnErrorHandler ;
|
|
||||||
|
|
||||||
static ASMJIT_NOINLINE void BaseEmitter_updateForcedOptions(BaseEmitter* self) noexcept {
|
static ASMJIT_NOINLINE void BaseEmitter_updateForcedOptions(BaseEmitter* self) noexcept {
|
||||||
bool hasLogger = self->_logger != nullptr;
|
bool emitComments = false;
|
||||||
bool hasValidationOptions;
|
bool hasValidationOptions = false;
|
||||||
|
|
||||||
if (self->emitterType() == BaseEmitter::kTypeAssembler)
|
if (self->emitterType() == BaseEmitter::kTypeAssembler) {
|
||||||
|
// Assembler: Don't emit comments if logger is not attached.
|
||||||
|
emitComments = self->_code != nullptr && self->_logger != nullptr;
|
||||||
hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionAssembler);
|
hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionAssembler);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
// Builder/Compiler: Always emit comments, we cannot assume they won't be used.
|
||||||
|
emitComments = self->_code != nullptr;
|
||||||
hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionIntermediate);
|
hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionIntermediate);
|
||||||
|
}
|
||||||
|
|
||||||
self->_forcedInstOptions &= ~BaseInst::kOptionReserved;
|
if (emitComments)
|
||||||
if (hasLogger || hasValidationOptions)
|
self->_addEmitterFlags(BaseEmitter::kFlagLogComments);
|
||||||
|
else
|
||||||
|
self->_clearEmitterFlags(BaseEmitter::kFlagLogComments);
|
||||||
|
|
||||||
|
// The reserved option tells emitter (Assembler/Builder/Compiler) that there
|
||||||
|
// may be either a border case (CodeHolder not attached, for example) or that
|
||||||
|
// logging or validation is required.
|
||||||
|
if (self->_code == nullptr || self->_logger || hasValidationOptions)
|
||||||
self->_forcedInstOptions |= BaseInst::kOptionReserved;
|
self->_forcedInstOptions |= BaseInst::kOptionReserved;
|
||||||
|
else
|
||||||
|
self->_forcedInstOptions &= ~BaseInst::kOptionReserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -306,15 +319,22 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame,
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
Error BaseEmitter::commentf(const char* fmt, ...) {
|
Error BaseEmitter::commentf(const char* fmt, ...) {
|
||||||
if (ASMJIT_UNLIKELY(!_code))
|
if (!hasEmitterFlag(kFlagLogComments)) {
|
||||||
return DebugUtils::errored(kErrorNotInitialized);
|
if (!hasEmitterFlag(kFlagAttached))
|
||||||
|
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ASMJIT_NO_LOGGING
|
#ifndef ASMJIT_NO_LOGGING
|
||||||
|
StringTmp<1024> sb;
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
Error err = commentv(fmt, ap);
|
Error err = sb.appendVFormat(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return err;
|
|
||||||
|
ASMJIT_PROPAGATE(err);
|
||||||
|
return comment(sb.data(), sb.size());
|
||||||
#else
|
#else
|
||||||
DebugUtils::unused(fmt);
|
DebugUtils::unused(fmt);
|
||||||
return kErrorOk;
|
return kErrorOk;
|
||||||
@@ -322,16 +342,17 @@ Error BaseEmitter::commentf(const char* fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error BaseEmitter::commentv(const char* fmt, va_list ap) {
|
Error BaseEmitter::commentv(const char* fmt, va_list ap) {
|
||||||
if (ASMJIT_UNLIKELY(!_code))
|
if (!hasEmitterFlag(kFlagLogComments)) {
|
||||||
return DebugUtils::errored(kErrorNotInitialized);
|
if (!hasEmitterFlag(kFlagAttached))
|
||||||
|
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
||||||
|
return kErrorOk;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ASMJIT_NO_LOGGING
|
#ifndef ASMJIT_NO_LOGGING
|
||||||
StringTmp<1024> sb;
|
StringTmp<1024> sb;
|
||||||
Error err = sb.appendVFormat(fmt, ap);
|
Error err = sb.appendVFormat(fmt, ap);
|
||||||
|
|
||||||
if (ASMJIT_UNLIKELY(err))
|
ASMJIT_PROPAGATE(err);
|
||||||
return err;
|
|
||||||
|
|
||||||
return comment(sb.data(), sb.size());
|
return comment(sb.data(), sb.size());
|
||||||
#else
|
#else
|
||||||
DebugUtils::unused(fmt, ap);
|
DebugUtils::unused(fmt, ap);
|
||||||
@@ -346,6 +367,7 @@ Error BaseEmitter::commentv(const char* fmt, va_list ap) {
|
|||||||
Error BaseEmitter::onAttach(CodeHolder* code) noexcept {
|
Error BaseEmitter::onAttach(CodeHolder* code) noexcept {
|
||||||
_code = code;
|
_code = code;
|
||||||
_environment = code->environment();
|
_environment = code->environment();
|
||||||
|
_addEmitterFlags(kFlagAttached);
|
||||||
|
|
||||||
const ArchTraits& archTraits = ArchTraits::byArch(code->arch());
|
const ArchTraits& archTraits = ArchTraits::byArch(code->arch());
|
||||||
uint32_t nativeRegType = Environment::is32Bit(code->arch()) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64;
|
uint32_t nativeRegType = Environment::is32Bit(code->arch()) ? BaseReg::kTypeGp32 : BaseReg::kTypeGp64;
|
||||||
@@ -358,16 +380,16 @@ Error BaseEmitter::onAttach(CodeHolder* code) noexcept {
|
|||||||
Error BaseEmitter::onDetach(CodeHolder* code) noexcept {
|
Error BaseEmitter::onDetach(CodeHolder* code) noexcept {
|
||||||
DebugUtils::unused(code);
|
DebugUtils::unused(code);
|
||||||
|
|
||||||
_clearEmitterFlags(~kEmitterPreservedFlags);
|
|
||||||
_forcedInstOptions = BaseInst::kOptionReserved;
|
|
||||||
_privateData = 0;
|
|
||||||
|
|
||||||
if (!hasOwnLogger())
|
if (!hasOwnLogger())
|
||||||
_logger = nullptr;
|
_logger = nullptr;
|
||||||
|
|
||||||
if (!hasOwnErrorHandler())
|
if (!hasOwnErrorHandler())
|
||||||
_errorHandler = nullptr;
|
_errorHandler = nullptr;
|
||||||
|
|
||||||
|
_clearEmitterFlags(~kEmitterPreservedFlags);
|
||||||
|
_forcedInstOptions = BaseInst::kOptionReserved;
|
||||||
|
_privateData = 0;
|
||||||
|
|
||||||
_environment.reset();
|
_environment.reset();
|
||||||
_gpRegInfo.reset();
|
_gpRegInfo.reset();
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,10 @@ public:
|
|||||||
|
|
||||||
//! Emitter flags.
|
//! Emitter flags.
|
||||||
enum EmitterFlags : uint32_t {
|
enum EmitterFlags : uint32_t {
|
||||||
|
//! Emitter is attached to CodeHolder.
|
||||||
|
kFlagAttached = 0x01u,
|
||||||
|
//! The emitter must emit comments.
|
||||||
|
kFlagLogComments = 0x08u,
|
||||||
//! The emitter has its own \ref Logger (not propagated from \ref CodeHolder).
|
//! The emitter has its own \ref Logger (not propagated from \ref CodeHolder).
|
||||||
kFlagOwnLogger = 0x10u,
|
kFlagOwnLogger = 0x10u,
|
||||||
//! The emitter has its own \ref ErrorHandler (not propagated from \ref CodeHolder).
|
//! The emitter has its own \ref ErrorHandler (not propagated from \ref CodeHolder).
|
||||||
|
|||||||
Reference in New Issue
Block a user