@@ -19,7 +19,7 @@ Local<Value> Pointer::NewInstance(Local<Context> context, void* handle) {
19
19
Isolate* isolate = context->GetIsolate ();
20
20
intptr_t ptr = static_cast <intptr_t >(reinterpret_cast <size_t >(handle));
21
21
22
- Local<Value> arg = Number::New (isolate, ptr);
22
+ Local<Value> arg = BigInt::NewFromUnsigned (isolate, ptr);
23
23
Local<Value> args[1 ] { arg };
24
24
Local<Value> result;
25
25
Local<v8::Function> ctorFunc = Pointer::GetPointerCtorFunc (context);
@@ -60,6 +60,7 @@ Local<v8::Function> Pointer::GetPointerCtorFunc(Local<Context> context) {
60
60
Pointer::RegisterToHexStringMethod (context, prototype);
61
61
Pointer::RegisterToDecimalStringMethod (context, prototype);
62
62
Pointer::RegisterToNumberMethod (context, prototype);
63
+ Pointer::RegisterToBigIntMethod (context, prototype);
63
64
64
65
cache->PointerCtorFunc = std::make_unique<Persistent<v8::Function>>(isolate, ctorFunc);
65
66
@@ -73,12 +74,12 @@ void Pointer::PointerConstructorCallback(const FunctionCallbackInfo<Value>& info
73
74
void * ptr = nullptr ;
74
75
75
76
if (info.Length () == 1 ) {
76
- if (!tns::IsNumber (info[0 ])) {
77
+ bool isBigInt = tns::IsBigInt (info[0 ]);
78
+ bool isNumber = !isBigInt && tns::IsNumber (info[0 ]);
79
+ if (!isBigInt && !isNumber) {
77
80
throw NativeScriptException (" Pointer constructor's first arg must be an integer." );
78
81
}
79
82
80
- Local<Number> arg = info[0 ].As <Number>();
81
-
82
83
#if __SIZEOF_POINTER__ == 8
83
84
// JSC stores 64-bit integers as doubles in JSValue.
84
85
// Caution: This means that pointers with more than 54 significant bits
@@ -87,12 +88,28 @@ void Pointer::PointerConstructorCallback(const FunctionCallbackInfo<Value>& info
87
88
// so we're safe at the time being.
88
89
// See https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details
89
90
// and https://en.wikipedia.org/wiki/ARM_architecture#ARMv8-A
91
+
92
+ // The future is here, and turns out the OS is using more than 54 bits.
93
+ // as a result,
90
94
int64_t value;
91
- tns::Assert (arg->IntegerValue (context).To (&value), isolate);
95
+ if (isBigInt) {
96
+ value = info[0 ].As <BigInt>()->Int64Value ();
97
+ } else {
98
+ // TODO: Maybe log this?
99
+ // #ifdef DEBUG
100
+ // syslog(LOG_WARNING, "Using JS Number to represent a pointer. Result might be wrong.");
101
+ // #endif
102
+ tns::Assert (info[0 ].As <Number>()->IntegerValue (context).To (&value), isolate);
103
+ }
104
+
92
105
ptr = reinterpret_cast <void *>(value);
93
106
#else
94
107
int32_t value;
95
- tns::Assert (arg->Int32Value (context).To (&value), isolate);
108
+ if (isBigInt) {
109
+ value = (int32_t )info[0 ].As <BigInt>()->Int64Value ();
110
+ } else {
111
+ tns::Assert (info[0 ].As <Number>()->Int32Value (context).To (&value), isolate);
112
+ }
96
113
ptr = reinterpret_cast <void *>(value);
97
114
#endif
98
115
}
@@ -253,4 +270,22 @@ void Pointer::RegisterToNumberMethod(Local<Context> context, Local<Object> proto
253
270
tns::Assert (success, isolate);
254
271
}
255
272
273
+ void Pointer::RegisterToBigIntMethod (Local<Context> context, Local<Object> prototype) {
274
+ Isolate* isolate = context->GetIsolate ();
275
+ Local<FunctionTemplate> funcTemplate = FunctionTemplate::New (isolate, [](const FunctionCallbackInfo<Value>& info) {
276
+ Isolate* isolate = info.GetIsolate ();
277
+ PointerWrapper* wrapper = static_cast <PointerWrapper*>(info.This ()->GetInternalField (0 ).As <External>()->Value ());
278
+ const void * value = wrapper->Data ();
279
+ size_t number = reinterpret_cast <size_t >(value);
280
+ Local<BigInt> result = BigInt::NewFromUnsigned (isolate, number);
281
+ info.GetReturnValue ().Set (result);
282
+ });
283
+
284
+ Local<v8::Function> func;
285
+ tns::Assert (funcTemplate->GetFunction (context).ToLocal (&func), isolate);
286
+
287
+ bool success = prototype->Set (context, tns::ToV8String (isolate, " toBigInt" ), func).FromMaybe (false );
288
+ tns::Assert (success, isolate);
289
+ }
290
+
256
291
}
0 commit comments