@@ -19,7 +19,7 @@ Local<Value> Pointer::NewInstance(Local<Context> context, void* handle) {
1919 Isolate* isolate = context->GetIsolate ();
2020 intptr_t ptr = static_cast <intptr_t >(reinterpret_cast <size_t >(handle));
2121
22- Local<Value> arg = Number::New (isolate, ptr);
22+ Local<Value> arg = BigInt::NewFromUnsigned (isolate, ptr);
2323 Local<Value> args[1 ] { arg };
2424 Local<Value> result;
2525 Local<v8::Function> ctorFunc = Pointer::GetPointerCtorFunc (context);
@@ -60,6 +60,7 @@ Local<v8::Function> Pointer::GetPointerCtorFunc(Local<Context> context) {
6060 Pointer::RegisterToHexStringMethod (context, prototype);
6161 Pointer::RegisterToDecimalStringMethod (context, prototype);
6262 Pointer::RegisterToNumberMethod (context, prototype);
63+ Pointer::RegisterToBigIntMethod (context, prototype);
6364
6465 cache->PointerCtorFunc = std::make_unique<Persistent<v8::Function>>(isolate, ctorFunc);
6566
@@ -73,12 +74,12 @@ void Pointer::PointerConstructorCallback(const FunctionCallbackInfo<Value>& info
7374 void * ptr = nullptr ;
7475
7576 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) {
7780 throw NativeScriptException (" Pointer constructor's first arg must be an integer." );
7881 }
7982
80- Local<Number> arg = info[0 ].As <Number>();
81-
8283 #if __SIZEOF_POINTER__ == 8
8384 // JSC stores 64-bit integers as doubles in JSValue.
8485 // Caution: This means that pointers with more than 54 significant bits
@@ -87,12 +88,28 @@ void Pointer::PointerConstructorCallback(const FunctionCallbackInfo<Value>& info
8788 // so we're safe at the time being.
8889 // See https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details
8990 // 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,
9094 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+
92105 ptr = reinterpret_cast <void *>(value);
93106 #else
94107 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+ }
96113 ptr = reinterpret_cast <void *>(value);
97114 #endif
98115 }
@@ -253,4 +270,22 @@ void Pointer::RegisterToNumberMethod(Local<Context> context, Local<Object> proto
253270 tns::Assert (success, isolate);
254271}
255272
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+
256291}
0 commit comments