BaseEmitter::commentf() shouldn't format string, which will be discarded by the emitter (fixes #306)

This commit is contained in:
kobalicek
2021-01-26 14:27:57 +01:00
parent 6678143772
commit 71fb24cb11
4 changed files with 61 additions and 32 deletions

View File

@@ -1307,7 +1307,7 @@ namespace asmjit {
//! 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
//! 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.
//!
//! Since \ref BaseCompiler provides register allocation it also establishes the

View File

@@ -366,20 +366,23 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
// ============================================================================
Error BaseAssembler::comment(const char* data, size_t size) {
if (ASMJIT_UNLIKELY(!_code))
return reportError(DebugUtils::errored(kErrorNotInitialized));
#ifndef ASMJIT_NO_LOGGING
if (_logger) {
_logger->log(data, size);
_logger->log("\n", 1);
if (!hasEmitterFlag(kFlagLogComments)) {
if (!hasEmitterFlag(kFlagAttached))
return reportError(DebugUtils::errored(kErrorNotInitialized));
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
DebugUtils::unused(data, size);
#endif
return kErrorOk;
#endif
}
// ============================================================================

View File

@@ -66,22 +66,35 @@ Error BaseEmitter::finalize() {
// [asmjit::BaseEmitter - Internals]
// ============================================================================
static constexpr uint32_t kEmitterPreservedFlags =
BaseEmitter::kFlagOwnLogger |
BaseEmitter::kFlagOwnErrorHandler ;
static constexpr uint32_t kEmitterPreservedFlags = BaseEmitter::kFlagOwnLogger | BaseEmitter::kFlagOwnErrorHandler;
static ASMJIT_NOINLINE void BaseEmitter_updateForcedOptions(BaseEmitter* self) noexcept {
bool hasLogger = self->_logger != nullptr;
bool hasValidationOptions;
bool emitComments = false;
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);
else
}
else {
// Builder/Compiler: Always emit comments, we cannot assume they won't be used.
emitComments = self->_code != nullptr;
hasValidationOptions = self->hasValidationOption(BaseEmitter::kValidationOptionIntermediate);
}
self->_forcedInstOptions &= ~BaseInst::kOptionReserved;
if (hasLogger || hasValidationOptions)
if (emitComments)
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;
else
self->_forcedInstOptions &= ~BaseInst::kOptionReserved;
}
// ============================================================================
@@ -306,15 +319,22 @@ ASMJIT_FAVOR_SIZE Error BaseEmitter::emitArgsAssignment(const FuncFrame& frame,
// ============================================================================
Error BaseEmitter::commentf(const char* fmt, ...) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
if (!hasEmitterFlag(kFlagLogComments)) {
if (!hasEmitterFlag(kFlagAttached))
return reportError(DebugUtils::errored(kErrorNotInitialized));
return kErrorOk;
}
#ifndef ASMJIT_NO_LOGGING
StringTmp<1024> sb;
va_list ap;
va_start(ap, fmt);
Error err = commentv(fmt, ap);
Error err = sb.appendVFormat(fmt, ap);
va_end(ap);
return err;
ASMJIT_PROPAGATE(err);
return comment(sb.data(), sb.size());
#else
DebugUtils::unused(fmt);
return kErrorOk;
@@ -322,16 +342,17 @@ Error BaseEmitter::commentf(const char* fmt, ...) {
}
Error BaseEmitter::commentv(const char* fmt, va_list ap) {
if (ASMJIT_UNLIKELY(!_code))
return DebugUtils::errored(kErrorNotInitialized);
if (!hasEmitterFlag(kFlagLogComments)) {
if (!hasEmitterFlag(kFlagAttached))
return reportError(DebugUtils::errored(kErrorNotInitialized));
return kErrorOk;
}
#ifndef ASMJIT_NO_LOGGING
StringTmp<1024> sb;
Error err = sb.appendVFormat(fmt, ap);
if (ASMJIT_UNLIKELY(err))
return err;
ASMJIT_PROPAGATE(err);
return comment(sb.data(), sb.size());
#else
DebugUtils::unused(fmt, ap);
@@ -346,6 +367,7 @@ Error BaseEmitter::commentv(const char* fmt, va_list ap) {
Error BaseEmitter::onAttach(CodeHolder* code) noexcept {
_code = code;
_environment = code->environment();
_addEmitterFlags(kFlagAttached);
const ArchTraits& archTraits = ArchTraits::byArch(code->arch());
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 {
DebugUtils::unused(code);
_clearEmitterFlags(~kEmitterPreservedFlags);
_forcedInstOptions = BaseInst::kOptionReserved;
_privateData = 0;
if (!hasOwnLogger())
_logger = nullptr;
if (!hasOwnErrorHandler())
_errorHandler = nullptr;
_clearEmitterFlags(~kEmitterPreservedFlags);
_forcedInstOptions = BaseInst::kOptionReserved;
_privateData = 0;
_environment.reset();
_gpRegInfo.reset();

View File

@@ -109,6 +109,10 @@ public:
//! Emitter flags.
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).
kFlagOwnLogger = 0x10u,
//! The emitter has its own \ref ErrorHandler (not propagated from \ref CodeHolder).