NOTE: This document was largely AI-generated based on offlineasm/*.rb sources and offlineasm code in llint/*.asm files. Exercise healthy skepticism.
This document describes the correspondence between offlineasm logical registers, interpreter-specific aliases (LowLevelInterpreter and InPlaceInterpreter), and physical platform registers.
JavaScriptCore's offline assembler (offlineasm) uses portable logical register names that are mapped to platform-specific physical registers during code generation. The LowLevelInterpreter (LLInt) and InPlaceInterpreter (IPInt) define their own register aliases for clarity and portability.
NOTE: This document was largely AI-generated based on offlineasm/*.rb sources and offlineasm code in llint/*.asm files. Exercise healthy skepticism.
This document provides a comprehensive reference for the offlineasm assembly language used in JavaScriptCore's Low Level Interpreter (LLInt).
Offlineasm is a portable assembly language that is translated to native assembly for different architectures (ARM64, x86-64, RISC-V, etc.). Instructions are categorized by data size suffixes:
i- 32-bit integer (word)
ThrowScope is a mechanism for throwing JS exceptions and for ensuring their correct handling in C++ code.
If a function can throw a JS exception, whether directly or indirectly by calling other functions that throw exceptions, it should declare a ThrowScope at the top of the function using the DECLARE_THROW_SCOPE macro. The scope supports throwing exceptions and in debug builds verifies that the required exception checks have been missed. Its presence is also an indication that the function can throw, and its callers should check for exceptions as explained below.
Let's consider this example of a function that calls two other functions, both of which may throw JS exceptions. We give it a throw scope and initially write the code as follows:
int functionA(VM& vm) {
auto scope = DECLARE_THROW_SCOPE(vm);
int x = functionB(vm);
int y = functionC(vm);
| ;; Delimited continuations | |
| #lang racket ; but will work in any Scheme (without this line) | |
| ;; There are other implementations along the same lines floating around. | |
| ;; Here we are trying to paint a more comprehensible (or at least a less | |
| ;; incomprehensible) picture by structuring the implementation as three | |
| ;; distinct layers: | |
| ;; Layer 1 |