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