quickjs-jit-sys 0.12.2

QuickJS native bindings with the versioned JIT ABI
Documentation
diff --git a/quickjs-jit.h b/quickjs-jit.h
--- a/quickjs-jit.h
+++ b/quickjs-jit.h
@@ -17,6 +17,6 @@ extern "C" {
 #endif
 
 #define QJSJIT_ABI_MAJOR 1u
-#define QJSJIT_ABI_MINOR 12u
+#define QJSJIT_ABI_MINOR 13u
 
 /* Frame flags are append-only. Stress collection is a test/debug contract:
@@ -341,4 +341,29 @@ struct JSJitExecFrame {
     JSValue *stack_capacity;
 };
 
+typedef struct JSJitElementLayout {
+    uint32_t struct_size;
+    uint32_t object_class_id_offset;
+    uint32_t object_flags_offset;
+    uint32_t object_fast_array_mask;
+    uint32_t object_exotic_mask;
+    uint32_t object_union_offset;
+    uint32_t array_size_offset;
+    uint32_t array_count_offset;
+    uint32_t array_data_offset;
+    uint32_t typed_array_ptr_offset;
+    uint32_t typed_array_buffer_offset;
+    uint32_t typed_array_byte_offset_offset;
+    uint32_t typed_array_byte_length_offset;
+    uint32_t typed_array_track_rab_offset;
+    uint32_t array_buffer_data_offset;
+    uint32_t array_buffer_byte_length_offset;
+    uint32_t array_buffer_max_byte_length_offset;
+    uint32_t array_buffer_detached_offset;
+    uint32_t array_buffer_immutable_offset;
+    uint32_t array_class_id;
+    uint32_t int32_array_class_id;
+    uint32_t float64_array_class_id;
+} JSJitElementLayout;
+
 typedef struct JSJitABIInfo {
@@ -363,4 +387,6 @@ typedef struct JSJitABIInfo {
     uint64_t exit_layout_fingerprint;
     uint64_t runtime_api_layout_fingerprint;
     uint64_t helper_table_fingerprint;
+    uint64_t element_layout_fingerprint;
+    JSJitElementLayout element_layout;
 } JSJitABIInfo;
diff --git a/quickjs.c b/quickjs.c
--- a/quickjs.c
+++ b/quickjs.c
@@ -2290,6 +2290,82 @@ static uint64_t qjsjit_abi_info_layout(void)
                               exit_layout_fingerprint);
     hash = QJSJIT_LAYOUT_FIELD(hash, JSJitABIInfo,
                                runtime_api_layout_fingerprint);
-    return QJSJIT_LAYOUT_FIELD(hash, JSJitABIInfo,
-                               helper_table_fingerprint);
+    hash = QJSJIT_LAYOUT_FIELD(hash, JSJitABIInfo,
+                              helper_table_fingerprint);
+    hash = QJSJIT_LAYOUT_FIELD(hash, JSJitABIInfo,
+                              element_layout_fingerprint);
+    return QJSJIT_LAYOUT_FIELD(hash, JSJitABIInfo, element_layout);
+}
+
+static uint64_t qjsjit_element_layout_layout(void)
+{
+    uint64_t hash = QJSJIT_LAYOUT_START(JSJitElementLayout);
+#define QJSJIT_ELEMENT_LAYOUT_FIELD(field) \
+    hash = QJSJIT_LAYOUT_FIELD(hash, JSJitElementLayout, field)
+    QJSJIT_ELEMENT_LAYOUT_FIELD(struct_size);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(object_class_id_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(object_flags_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(object_fast_array_mask);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(object_exotic_mask);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(object_union_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_size_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_count_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_data_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(typed_array_ptr_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(typed_array_buffer_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(typed_array_byte_offset_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(typed_array_byte_length_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(typed_array_track_rab_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_buffer_data_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_buffer_byte_length_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_buffer_max_byte_length_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_buffer_detached_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_buffer_immutable_offset);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(array_class_id);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(int32_array_class_id);
+    QJSJIT_ELEMENT_LAYOUT_FIELD(float64_array_class_id);
+#undef QJSJIT_ELEMENT_LAYOUT_FIELD
+    return hash;
+}
+
+static void qjsjit_init_element_layout(JSJitElementLayout *out)
+{
+    JSObject probe;
+    uint8_t *bytes = (uint8_t *)&probe;
+    uint32_t i, fast_offset = UINT32_MAX, exotic_offset = UINT32_MAX;
+    uint8_t fast_mask = 0, exotic_mask = 0;
+
+    memset(out, 0, sizeof(*out));
+    memset(&probe, 0, sizeof(probe));
+    probe.fast_array = 1;
+    for (i = 0; i < sizeof(probe); i++) {
+        if (bytes[i]) { fast_offset = i; fast_mask = bytes[i]; break; }
+    }
+    memset(&probe, 0, sizeof(probe));
+    probe.is_exotic = 1;
+    for (i = 0; i < sizeof(probe); i++) {
+        if (bytes[i]) { exotic_offset = i; exotic_mask = bytes[i]; break; }
+    }
+    out->struct_size = sizeof(*out);
+    out->object_class_id_offset = offsetof(JSObject, class_id);
+    out->object_flags_offset = fast_offset;
+    out->object_fast_array_mask = fast_mask;
+    out->object_exotic_mask = exotic_offset == fast_offset ? exotic_mask : 0;
+    out->object_union_offset = offsetof(JSObject, u);
+    out->array_size_offset = offsetof(JSObject, u.array.u1.size);
+    out->array_count_offset = offsetof(JSObject, u.array.count);
+    out->array_data_offset = offsetof(JSObject, u.array.u.values);
+    out->typed_array_ptr_offset = offsetof(JSObject, u.array.u1.typed_array);
+    out->typed_array_buffer_offset = offsetof(JSTypedArray, buffer);
+    out->typed_array_byte_offset_offset = offsetof(JSTypedArray, offset);
+    out->typed_array_byte_length_offset = offsetof(JSTypedArray, length);
+    out->typed_array_track_rab_offset = offsetof(JSTypedArray, track_rab);
+    out->array_buffer_data_offset = offsetof(JSArrayBuffer, data);
+    out->array_buffer_byte_length_offset = offsetof(JSArrayBuffer, byte_length);
+    out->array_buffer_max_byte_length_offset = offsetof(JSArrayBuffer, max_byte_length);
+    out->array_buffer_detached_offset = offsetof(JSArrayBuffer, detached);
+    out->array_buffer_immutable_offset = offsetof(JSArrayBuffer, immutable);
+    out->array_class_id = JS_CLASS_ARRAY;
+    out->int32_array_class_id = JS_CLASS_INT32_ARRAY;
+    out->float64_array_class_id = JS_CLASS_FLOAT64_ARRAY;
 }
@@ -2842,5 +2916,7 @@ int JS_GetJitABIInfo(JSJitABIInfo *out)
     info.exit_layout_fingerprint = qjsjit_exit_layout();
     info.runtime_api_layout_fingerprint = qjsjit_runtime_api_layout();
     info.helper_table_fingerprint = QJSJIT_GENERATED_HELPER_FINGERPRINT;
+    info.element_layout_fingerprint = qjsjit_element_layout_layout();
+    qjsjit_init_element_layout(&info.element_layout);
 
     build_fingerprint = qjsjit_hash_u64(UINT64_C(0xcbf29ce484222325),
@@ -2869,7 +2945,9 @@ int JS_GetJitABIInfo(JSJitABIInfo *out)
                                         info.exit_layout_fingerprint);
     build_fingerprint = qjsjit_hash_u64(
         build_fingerprint, info.runtime_api_layout_fingerprint);
-    info.build_fingerprint = qjsjit_hash_u64(
+    build_fingerprint = qjsjit_hash_u64(
         build_fingerprint, info.helper_table_fingerprint);
+    info.build_fingerprint = qjsjit_hash_u64(
+        build_fingerprint, info.element_layout_fingerprint);
 
     copy_size = caller_size;