1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use luaur_vm::macros::lua_extra_size::LUA_EXTRA_SIZE;
use luaur_vm::macros::lua_use_longjmp::LUA_USE_LONGJMP;
use luaur_vm::records::lua_node::LuaNode;
use luaur_vm::records::lua_t_value::TValue;
use crate::functions::is_unwind_supported::is_unwind_supported;
use crate::macros::codegen_target_a_64::CODEGEN_TARGET_A64;
use crate::macros::codegen_target_x_64::CODEGEN_TARGET_X64;
// NOTE: This function is native-only in the original codegen. It depends on
// platform ABI assumptions (TValue/LuaNode layout) and CPU feature detection.
pub fn is_supported() -> bool {
if LUA_EXTRA_SIZE != 1 {
return false;
}
// The JIT emits machine code with hardcoded structure sizes/offsets, so the
// runtime ABI layout must match what the code generator assumes. C++
// (CodeGen/src/CodeGen.cpp) bails out of native codegen if these don't hold:
// if (sizeof(TValue) != 16) return false;
// if (sizeof(LuaNode) != 32) return false;
if core::mem::size_of::<TValue>() != 16 {
return false;
}
if core::mem::size_of::<LuaNode>() != 32 {
return false;
}
#[cfg(not(windows))]
{
if LUA_USE_LONGJMP == 0 && !is_unwind_supported() {
return false;
}
}
#[cfg(windows)]
{
if !is_unwind_supported() {
return false;
}
}
#[cfg(CODEGEN_TARGET_X64)]
{
// CPU feature check for AVX1/VEX encoded XMM ops and ROUNDSD via SSE4.1.
// Use the same CPUID leaf as the C++ code: EAX=1.
//
// We use is_x86_feature_detected! which is supported on wasm32 for
// non-native targets behind cfg; this function is native-only so it is
// fine to rely on x86 intrinsics when compiling for x86.
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
{
use core::arch::x86::__cpuid;
let cpuinfo = unsafe { __cpuid(1) };
// https://en.wikipedia.org/wiki/CPUID#EAX=1:_Processor_Info_and_Feature_Bits
// cpuinfo.ecx holds feature bits. Bit 28 == AVX1.
if (cpuinfo.ecx & (1 << 28)) == 0 {
return false;
}
}
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
{
return false;
}
return true;
}
#[cfg(CODEGEN_TARGET_A64)]
{
return true;
}
false
}