Breaking Changes

Documentation of breaking changes.

Overview

AsmJit is a live project that is being actively developed. Deprecating the existing API in favor of a new one is preferred, but it's not always possible if the changes are significant. AsmJit authors prefer to do accumulated breaking changes at once instead of breaking the API often. This page documents deprecated and removed APIs and should serve as a how-to guide for people that want to port existing code to work with the newest AsmJit.

Tips

Useful tips before you start:

  • Visit our Public Gitter Channel if you need a quick help.
  • Build AsmJit with ASMJIT_NO_DEPRECATED macro defined to make sure that you are not using deprecated functionality at all. Deprecated functions are decorated with ASMJIT_DEPRECATED() macro, but sometimes it's not possible to decorate everything like classes, which are used by deprecated functions as well, because some compilers would warn about that. If your project compiles fine with ASMJIT_NO_DEPRECATED it's not using anything, which was deprecated.

Changes committed at 2020-05-30

AsmJit has been cleaned up significantly, many todo items have been fixed and many functions and classes have been redesigned, some in an incompatible way.

Core changes:

  • Imm operand has now only Imm::value() and Imm::valueAs() functions that return its value content, and Imm::setValue() function that sets the content. Functions like setI8(), setU8() were deprecated.

    Old functions were deprecated, but code using them should still compile.

  • ArchInfo has been replaced with Environment. Environment provides more details about the architecture, but drops some properties that were used by arch info - gpSize() and gpCount(). gpSize() can be replaced with registerSize() getter, which returns a native register size of the architecture the environment uses. However, gpCount() was removed - at the moment ArchRegs can be used to access such properties.

    Some other functions were renamed, like ArchInfo::isX86Family() is now Environment::isFamilyX86(), etc. The reason for changing the order was support for more propertries and all the accessors now start with the type of the property, like Environment::isPlatformWindows().

    This function causes many other classes to provide environment() getter instead of archInfo() getter. In addition, AsmJit now uses arch() to get an architecture instead of archId(). ArchInfo::kIdXXX was renamed to Environment::kArchXXX.

    Some functions were deprecated, some removed...

  • CodeInfo has been removed in favor of Environment. If you used CodeInfo to set architecture and base address, this is now possible with Environment and setting base address explicitly by CodeHolder::init() - the first argument is Environment, and the second argument is base address, which defaults to Globals::kNoBaseAddress.

    CodeInfo class was deprecated, but the code using it should still compile with warnings.

  • CallConv has been updated to offer a more unified way of representing calling conventions - many calling conventions were abstracted to follow standard naming like CallConv::kIdCDecl or CallConv::kIdStdCall.

    This change means that other APIs like FuncDetail::init() now require both, calling convention and target Environment.

  • Logging namespace has been renamed to Formatter, which now provides general functionality for formatting in AsmJit.

    Logging namespace should still work, but its use is deprecated. Unfortunately this will be without deprecation warnings, so please make sure you don't use it.

  • Data64, Data128, and Data256 structs were deprecated and should no longer be used. There is no replacement, AsmJit users should simply create their own structures if they need them or use the new repeated embed API in emitters, see BaseEmitter::embedDataArray().

Emitter changes:

Builder changes:

  • Internal functions for creating nodes were redesigned. They now accept a pointer to the node created as a first parameter. These changes should not affect AsmJit users as these functions were used internally.

Compiler changes:

  • FuncCallNode has been renamed to InvokeNode. Additionally, function calls should now use x86::Compiler::invoke() instead of call(). The reason behind this is to remove the confusion between a call instruction and AsmJit's call() intrinsic, which is now invoke().
  • Creating new nodes also changed. Now the preferred way of invoking a function is to call x86::Compiler::invoke() where the first argument is InvokeNode**. The function now returns an error and would call ErrorHandler in case of a failure. Error handling was unspecified in the past - the function was marked noexcept, but called error handler, which could throw.

    The reason behind this change is to make the API consistent with other changes and to also make it possible to inspect the possible error. In the previous API it returned a new node or nullptr in case of error, which the user couldn't inspect unless there was an attached ErrorHandler.

Samples:

#include <asmjit/x86.h>
using namespace asmjit;
// The basic setup of JitRuntime and CodeHolder changed, use environment()
// instead of codeInfo().
void basicSetup() {
CodeHolder code(rt.environment());
}
// Calling a function (Compiler) changed - use invoke() instead of call().
void functionInvocation(x86::Compiler& cc) {
InvokeNode* invokeNode;
cc.invoke(&invokeNode, targetOperand, FuncSignatureT<...>(...));
}