Skip to content

Commit 4cd869d

Browse files
triniwizrigor789edusperoni
authored
feat: JSI support for BigInt, Initial TypedArrays & ArrayBuffer creation (#204)
* feat: JSI support for BigInt, Initial TypedArrays & ArrayBuffer creation * chore(release): 8.5.1-dev.0 --------- Co-authored-by: Igor Randjelovic <rigor789@gmail.com> Co-authored-by: Eduardo Speroni <edusperoni@users.noreply.github.com>
1 parent 5088f5f commit 4cd869d

File tree

10 files changed

+498
-1
lines changed

10 files changed

+498
-1
lines changed

NativeScript/JSIRuntime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// Copyright © 2022 Progress. All rights reserved.
77
//
88

9+
#pragma once
910
#import <Foundation/Foundation.h>
1011
#import "v8runtime/V8Runtime.h"
1112
#include "runtime/Runtime.h"

NativeScript/jsi/decorator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
272272
Array createArray(size_t length) override {
273273
return plain_.createArray(length);
274274
};
275+
ArrayBuffer createArrayBuffer(
276+
std::shared_ptr<MutableBuffer> buffer) override {
277+
return plain_.createArrayBuffer(std::move(buffer));
278+
};
275279
size_t size(const Array& a) override {
276280
return plain_.size(a);
277281
};
@@ -671,6 +675,10 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
671675
Around around{with_};
672676
return RD::createArray(length);
673677
};
678+
ArrayBuffer createArrayBuffer(
679+
std::shared_ptr<MutableBuffer> buffer) override {
680+
return RD::createArrayBuffer(std::move(buffer));
681+
};
674682
size_t size(const Array& a) override {
675683
Around around{with_};
676684
return RD::size(a);

NativeScript/jsi/jsi-inl.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,22 @@ inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) && {
156156
return ArrayBuffer(value);
157157
}
158158

159+
160+
inline TypedArray Object::getTypedArray(Runtime &runtime) const &{
161+
assert(runtime.isTypedArray(*this));
162+
(void) runtime; // when assert is disabled we need to mark this as used
163+
return TypedArray(runtime.cloneObject(ptr_));
164+
}
165+
166+
inline TypedArray Object::getTypedArray(Runtime &runtime) &&{
167+
assert(runtime.isTypedArray(*this));
168+
(void) runtime; // when assert is disabled we need to mark this as used
169+
Runtime::PointerValue *value = ptr_;
170+
ptr_ = nullptr;
171+
return TypedArray(value);
172+
}
173+
174+
159175
inline Function Object::getFunction(Runtime& runtime) const& {
160176
assert(runtime.isFunction(*this));
161177
return Function(runtime.cloneObject(ptr_));

NativeScript/jsi/jsi.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ Value callGlobalFunction(Runtime& runtime, const char* name, const Value& arg) {
6666

6767
Buffer::~Buffer() = default;
6868

69+
MutableBuffer::~MutableBuffer() = default;
70+
6971
PreparedJavaScript::~PreparedJavaScript() = default;
7072

7173
Value HostObject::get(Runtime&, const PropNameID&) {

NativeScript/jsi/jsi.h

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ class JSI_EXPORT Buffer {
3838
virtual const uint8_t* data() const = 0;
3939
};
4040

41+
/// Base class for buffers of data that need to be passed to the runtime. The
42+
/// result of size() and data() must not change after construction. However, the
43+
/// region pointed to by data() may be modified by the user or the runtime. The
44+
/// user must ensure that access to the contents of the buffer is properly
45+
/// synchronised.
46+
class JSI_EXPORT MutableBuffer {
47+
public:
48+
virtual ~MutableBuffer();
49+
virtual size_t size() const = 0;
50+
virtual uint8_t* data() = 0;
51+
};
52+
4153
class JSI_EXPORT StringBuffer : public Buffer {
4254
public:
4355
StringBuffer(std::string s) : s_(std::move(s)) {}
@@ -80,6 +92,7 @@ class Instrumentation;
8092
class Scope;
8193
class JSIException;
8294
class JSError;
95+
class TypedArray;
8396

8497
/// A function which has this type can be registered as a function
8598
/// callable from JavaScript using Function::createFromHostFunction().
@@ -251,6 +264,8 @@ class JSI_EXPORT Runtime {
251264
friend class Value;
252265
friend class Scope;
253266
friend class JSError;
267+
friend class TypedArray;
268+
254269

255270
// Potential optimization: avoid the cloneFoo() virtual dispatch,
256271
// and instead just fix the number of fields, and copy them, since
@@ -307,18 +322,40 @@ class JSI_EXPORT Runtime {
307322

308323
virtual bool isArray(const Object&) const = 0;
309324
virtual bool isArrayBuffer(const Object&) const = 0;
325+
virtual bool isArrayBufferView(const Object&) const = 0;
326+
virtual bool isTypedArray(const Object&) const = 0;
327+
virtual bool isInt8Array(const Object&) const = 0;
328+
virtual bool isUint8Array(const Object&) const = 0;
329+
virtual bool isUint8ClampedArray(const Object&) const = 0;
330+
virtual bool isInt16Array(const Object&) const = 0;
331+
virtual bool isUint16Array(const Object&) const = 0;
332+
virtual bool isInt32Array(const Object&) const = 0;
333+
virtual bool isUint32Array(const Object&) const = 0;
334+
virtual bool isFloat32Array(const Object&) const = 0;
335+
virtual bool isBigInt64Array(const Object&) const = 0;
336+
virtual bool isBigUint64Array(const Object&) const = 0;
337+
virtual bool isFloat64Array(const Object&) const = 0;
310338
virtual bool isFunction(const Object&) const = 0;
311339
virtual bool isHostObject(const jsi::Object&) const = 0;
312340
virtual bool isHostFunction(const jsi::Function&) const = 0;
313341
virtual Array getPropertyNames(const Object&) = 0;
314342

315343
virtual WeakObject createWeakObject(const Object&) = 0;
316344
virtual Value lockWeakObject(WeakObject&) = 0;
345+
346+
virtual uint64_t uint64Value(const BigInt&, bool *lossless) const = 0;
347+
virtual int64_t int64Value(const BigInt&, bool *lossless) const = 0;
348+
317349

318350
virtual Array createArray(size_t length) = 0;
351+
virtual ArrayBuffer createArrayBuffer(
352+
std::shared_ptr<MutableBuffer> buffer) = 0;
319353
virtual size_t size(const Array&) = 0;
320354
virtual size_t size(const ArrayBuffer&) = 0;
355+
virtual size_t size(const TypedArray&) = 0;
321356
virtual uint8_t* data(const ArrayBuffer&) = 0;
357+
virtual uint8_t* data(const TypedArray&) = 0;
358+
virtual size_t offset(const TypedArray&) = 0;
322359
virtual Value getValueAtIndex(const Array&, size_t i) = 0;
323360
virtual void setValueAtIndexImpl(Array&, size_t i, const Value& value) = 0;
324361

@@ -493,6 +530,26 @@ class JSI_EXPORT BigInt : public Pointer {
493530

494531
BigInt(BigInt&& other) = default;
495532
BigInt& operator=(BigInt&& other) = default;
533+
534+
535+
/**
536+
* Returns the value of this BigInt as an unsigned 64-bit integer.
537+
* If `lossless` is provided, it will reflect whether the return value was
538+
* truncated or wrapped around. In particular, it is set to `false` if this
539+
* BigInt is negative.
540+
*/
541+
uint64_t Uint64Value(Runtime& runtime, bool* lossless = nullptr) const {
542+
return runtime.uint64Value(*this, lossless);
543+
}
544+
545+
/**
546+
* Returns the value of this BigInt as a signed 64-bit integer.
547+
* If `lossless` is provided, it will reflect whether this BigInt was
548+
* truncated or not.
549+
*/
550+
int64_t Int64Value(Runtime& runtime, bool* lossless = nullptr) const {
551+
return runtime.int64Value(*this, lossless);
552+
}
496553

497554
friend class Runtime;
498555
friend class Value;
@@ -641,6 +698,86 @@ class JSI_EXPORT Object : public Pointer {
641698
bool isArrayBuffer(Runtime& runtime) const {
642699
return runtime.isArrayBuffer(*this);
643700
}
701+
702+
703+
/// \return true iff the Object is an isArrayBufferView. If so, then \c
704+
/// getArrayBuffer() will succeed.
705+
bool isArrayBufferView(Runtime& runtime) const {
706+
return runtime.isArrayBufferView(*this);
707+
}
708+
709+
/// \return true iff the Object is an isTypedArray. If so, then \c
710+
/// getArrayBuffer() will succeed.
711+
bool isTypedArray(Runtime& runtime) const {
712+
return runtime.isTypedArray(*this);
713+
}
714+
715+
716+
/// \return true iff the Object is an isInt8Array. If so, then \c
717+
/// getArrayBuffer() will succeed.
718+
bool isInt8Array(Runtime& runtime) const {
719+
return runtime.isInt8Array(*this);
720+
}
721+
722+
/// \return true iff the Object is an isUint8Array. If so, then \c
723+
/// getArrayBuffer() will succeed.
724+
bool isUint8Array(Runtime& runtime) const {
725+
return runtime.isUint8Array(*this);
726+
}
727+
728+
/// \return true iff the Object is an isUint8ClampedArray. If so, then \c
729+
/// getArrayBuffer() will succeed.
730+
bool isUint8ClampedArray(Runtime& runtime) const {
731+
return runtime.isUint8ClampedArray(*this);
732+
}
733+
734+
/// \return true iff the Object is an isInt16Array. If so, then \c
735+
/// getArrayBuffer() will succeed.
736+
bool isInt16Array(Runtime& runtime) const {
737+
return runtime.isInt16Array(*this);
738+
}
739+
740+
/// \return true iff the Object is an isUint16Array. If so, then \c
741+
/// getArrayBuffer() will succeed.
742+
bool isUint16Array(Runtime& runtime) const {
743+
return runtime.isUint16Array(*this);
744+
}
745+
746+
/// \return true iff the Object is an isInt32Array. If so, then \c
747+
/// getArrayBuffer() will succeed.
748+
bool isInt32Array(Runtime& runtime) const {
749+
return runtime.isInt32Array(*this);
750+
}
751+
752+
/// \return true iff the Object is an isUint32Array. If so, then \c
753+
/// getArrayBuffer() will succeed.
754+
bool isUint32Array(Runtime& runtime) const {
755+
return runtime.isUint32Array(*this);
756+
}
757+
758+
/// \return true iff the Object is an isFloat32Array. If so, then \c
759+
/// getArrayBuffer() will succeed.
760+
bool isFloat32Array(Runtime& runtime) const {
761+
return runtime.isFloat32Array(*this);
762+
}
763+
764+
/// \return true iff the Object is an isBigInt64Array. If so, then \c
765+
/// getArrayBuffer() will succeed.
766+
bool isBigInt64Array(Runtime& runtime) const {
767+
return runtime.isBigInt64Array(*this);
768+
}
769+
770+
/// \return true iff the Object is an isBigUint64Array. If so, then \c
771+
/// getArrayBuffer() will succeed.
772+
bool isBigUint64Array(Runtime& runtime) const {
773+
return runtime.isBigUint64Array(*this);
774+
}
775+
776+
/// \return true iff the Object is an isFloat64Array. If so, then \c
777+
/// getArrayBuffer() will succeed.
778+
bool isFloat64Array(Runtime& runtime) const {
779+
return runtime.isFloat64Array(*this);
780+
}
644781

645782
/// \return true iff the Object is callable. If so, then \c
646783
/// getFunction will succeed.
@@ -679,6 +816,16 @@ class JSI_EXPORT Object : public Pointer {
679816
/// \return an ArrayBuffer instance which refers to the same underlying
680817
/// object. If \c isArrayBuffer() would return false, this will assert.
681818
ArrayBuffer getArrayBuffer(Runtime& runtime) &&;
819+
820+
821+
/// \return an TypedArray instance which refers to the same underlying
822+
/// object. If \c isTypedArray() would return false, this will assert.
823+
TypedArray getTypedArray(Runtime& runtime) const&;
824+
825+
/// \return an TypedArray instance which refers to the same underlying
826+
/// object. If \c isTypedArray() would return false, this will assert.
827+
TypedArray getTypedArray(Runtime& runtime) &&;
828+
682829

683830
/// \return a Function instance which refers to the same underlying
684831
/// object. If \c isFunction() would return false, this will assert.
@@ -828,6 +975,8 @@ class JSI_EXPORT ArrayBuffer : public Object {
828975
public:
829976
ArrayBuffer(ArrayBuffer&&) = default;
830977
ArrayBuffer& operator=(ArrayBuffer&&) = default;
978+
ArrayBuffer(Runtime& runtime, std::shared_ptr<MutableBuffer> buffer)
979+
: ArrayBuffer(runtime.createArrayBuffer(std::move(buffer))) {}
831980

832981
/// \return the size of the ArrayBuffer, according to its byteLength property.
833982
/// (C++ naming convention)
@@ -850,6 +999,41 @@ class JSI_EXPORT ArrayBuffer : public Object {
850999
ArrayBuffer(Runtime::PointerValue* value) : Object(value) {}
8511000
};
8521001

1002+
1003+
/// Represents a TypedArray
1004+
class JSI_EXPORT TypedArray : public Object {
1005+
public:
1006+
TypedArray(TypedArray &&) = default;
1007+
1008+
TypedArray &operator=(TypedArray &&) = default;
1009+
1010+
/// \return the size of the TypedArray ArrayBuffer, according to its byteLength property.
1011+
/// (C++ naming convention)
1012+
size_t size(Runtime &runtime) {
1013+
return runtime.size(*this);
1014+
}
1015+
1016+
size_t offset(Runtime &runtime) const {
1017+
return runtime.offset(*this);
1018+
}
1019+
1020+
size_t length(Runtime &runtime) const {
1021+
return runtime.size(*this);
1022+
}
1023+
1024+
uint8_t *data(Runtime &runtime) {
1025+
return runtime.data(*this);
1026+
}
1027+
1028+
private:
1029+
friend class Object;
1030+
1031+
friend class Value;
1032+
1033+
TypedArray(Runtime::PointerValue *value) : Object(value) {}
1034+
};
1035+
1036+
8531037
/// Represents a JS Object which is guaranteed to be Callable.
8541038
class JSI_EXPORT Function : public Object {
8551039
public:

NativeScript/v8runtime/JSIV8ValueConverter.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ jsi::Value JSIV8ValueConverter::ToJSIValue(
3939
if (value->IsObject()) {
4040
return V8Runtime::make<jsi::Object>(new V8PointerValue(isolate, value));
4141
}
42+
43+
if (value->IsBigInt()) {
44+
return V8Runtime::make<jsi::BigInt>(new V8PointerValue(isolate, value));
45+
}
4246

4347
return jsi::Value::undefined();
4448
}
@@ -65,6 +69,9 @@ v8::Local<v8::Value> JSIV8ValueConverter::ToV8Value(
6569
} else if (value.isObject()) {
6670
return scopedHandle.Escape(ToV8Object(
6771
runtime, std::move(value.getObject(const_cast<V8Runtime &>(runtime)))));
72+
}else if(value.isBigInt()){
73+
return scopedHandle.Escape(ToV8BigInt(
74+
runtime, std::move(value.getBigInt(const_cast<V8Runtime &>(runtime)))));
6875
} else {
6976
// What are you?
7077
std::abort();
@@ -132,6 +139,19 @@ v8::Local<v8::Object> JSIV8ValueConverter::ToV8Object(
132139
v8::Local<v8::Object>::Cast(v8PointerValue->Get(runtime.isolate_)));
133140
}
134141

142+
// static
143+
v8::Local<v8::BigInt> JSIV8ValueConverter::ToV8BigInt(
144+
const V8Runtime &runtime,
145+
const jsi::BigInt &bigInt) {
146+
v8::EscapableHandleScope scopedHandle(runtime.isolate_);
147+
const auto *v8PointerValue =
148+
static_cast<const V8PointerValue *>(runtime.getPointerValue(bigInt));
149+
assert(v8PointerValue->Get(runtime.isolate_)->IsBigInt());
150+
return scopedHandle.Escape(
151+
v8::Local<v8::BigInt>::Cast(v8PointerValue->Get(runtime.isolate_)));
152+
}
153+
154+
135155
// static
136156
v8::Local<v8::Array> JSIV8ValueConverter::ToV8Array(
137157
const V8Runtime &runtime,

NativeScript/v8runtime/JSIV8ValueConverter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class JSIV8ValueConverter {
4747
static v8::Local<v8::Object> ToV8Object(
4848
const V8Runtime &runtime,
4949
const facebook::jsi::Object &object);
50+
51+
static v8::Local<v8::BigInt> ToV8BigInt(
52+
const V8Runtime &runtime,
53+
const facebook::jsi::BigInt &bigInt);
5054

5155
static v8::Local<v8::Array> ToV8Array(
5256
const V8Runtime &runtime,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy