Skip to content

Commit 6fe70c8

Browse files
committed
fix(interop): Correctly initialize pointers from numbers on 64-bit archs
JavaScript represents 64-bit integers as floating point `double` values. This means that the conversion from JSValue to pointer is done by extracting the `double` value and then converting it to integer. **Caution:** This means that pointers with more than 54 significant bits are likely to be rounded and misrepresented! However, current OS and hardware implementations are using 48 bits, so we're safe at the time being. See https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details and https://en.wikipedia.org/wiki/ARM_architecture#ARMv8-A
1 parent 4dde0e4 commit 6fe70c8

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

src/NativeScript/Marshalling/Pointer/PointerConstructor.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,19 @@ void PointerConstructor::finishCreation(VM& vm, PointerPrototype* pointerPrototy
3333
EncodedJSValue JSC_HOST_CALL PointerConstructor::constructPointerInstance(ExecState* execState) {
3434
void* value = nullptr;
3535
if (execState->argumentCount() == 1) {
36-
value = reinterpret_cast<void*>(execState->argument(0).toUInt32(execState));
36+
auto arg0 = execState->argument(0);
37+
#if __SIZEOF_POINTER__ == 8
38+
// JSC stores 64-bit integers as doubles in JSValue.
39+
// Caution: This means that pointers with more than 54 significant bits
40+
// are likely to be rounded and misrepresented!
41+
// However, current OS and hardware implementations are using 48 bits,
42+
// so we're safe at the time being.
43+
// See https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details
44+
// and https://en.wikipedia.org/wiki/ARM_architecture#ARMv8-A
45+
value = reinterpret_cast<void*>(static_cast<int64_t>(arg0.toIntegerPreserveNaN(execState)));
46+
#else
47+
value = reinterpret_cast<void*>(arg0.toInt32(execState));
48+
#endif
3749
}
3850

3951
JSValue result = jsCast<GlobalObject*>(execState->lexicalGlobalObject())->interop()->pointerInstanceForPointer(execState, value);

0 commit comments

Comments
 (0)