diff --git a/NativeScript/JSIRuntime.h b/NativeScript/JSIRuntime.h index 110d565e..8cfb636a 100644 --- a/NativeScript/JSIRuntime.h +++ b/NativeScript/JSIRuntime.h @@ -6,6 +6,7 @@ // Copyright © 2022 Progress. All rights reserved. // +#pragma once #import #import "v8runtime/V8Runtime.h" #include "runtime/Runtime.h" diff --git a/NativeScript/jsi/decorator.h b/NativeScript/jsi/decorator.h index 30dd98b3..2fab930a 100644 --- a/NativeScript/jsi/decorator.h +++ b/NativeScript/jsi/decorator.h @@ -272,6 +272,10 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation { Array createArray(size_t length) override { return plain_.createArray(length); }; + ArrayBuffer createArrayBuffer( + std::shared_ptr buffer) override { + return plain_.createArrayBuffer(std::move(buffer)); + }; size_t size(const Array& a) override { return plain_.size(a); }; @@ -671,6 +675,10 @@ class WithRuntimeDecorator : public RuntimeDecorator { Around around{with_}; return RD::createArray(length); }; + ArrayBuffer createArrayBuffer( + std::shared_ptr buffer) override { + return RD::createArrayBuffer(std::move(buffer)); + }; size_t size(const Array& a) override { Around around{with_}; return RD::size(a); diff --git a/NativeScript/jsi/jsi-inl.h b/NativeScript/jsi/jsi-inl.h index 3823e8b2..3f78e629 100644 --- a/NativeScript/jsi/jsi-inl.h +++ b/NativeScript/jsi/jsi-inl.h @@ -156,6 +156,22 @@ inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) && { return ArrayBuffer(value); } + +inline TypedArray Object::getTypedArray(Runtime &runtime) const &{ + assert(runtime.isTypedArray(*this)); + (void) runtime; // when assert is disabled we need to mark this as used + return TypedArray(runtime.cloneObject(ptr_)); +} + +inline TypedArray Object::getTypedArray(Runtime &runtime) &&{ + assert(runtime.isTypedArray(*this)); + (void) runtime; // when assert is disabled we need to mark this as used + Runtime::PointerValue *value = ptr_; + ptr_ = nullptr; + return TypedArray(value); +} + + inline Function Object::getFunction(Runtime& runtime) const& { assert(runtime.isFunction(*this)); return Function(runtime.cloneObject(ptr_)); diff --git a/NativeScript/jsi/jsi.cpp b/NativeScript/jsi/jsi.cpp index 11d74b02..480a2109 100644 --- a/NativeScript/jsi/jsi.cpp +++ b/NativeScript/jsi/jsi.cpp @@ -66,6 +66,8 @@ Value callGlobalFunction(Runtime& runtime, const char* name, const Value& arg) { Buffer::~Buffer() = default; +MutableBuffer::~MutableBuffer() = default; + PreparedJavaScript::~PreparedJavaScript() = default; Value HostObject::get(Runtime&, const PropNameID&) { diff --git a/NativeScript/jsi/jsi.h b/NativeScript/jsi/jsi.h index cc6c98aa..cf8ac5b0 100644 --- a/NativeScript/jsi/jsi.h +++ b/NativeScript/jsi/jsi.h @@ -38,6 +38,18 @@ class JSI_EXPORT Buffer { virtual const uint8_t* data() const = 0; }; +/// Base class for buffers of data that need to be passed to the runtime. The +/// result of size() and data() must not change after construction. However, the +/// region pointed to by data() may be modified by the user or the runtime. The +/// user must ensure that access to the contents of the buffer is properly +/// synchronised. +class JSI_EXPORT MutableBuffer { + public: + virtual ~MutableBuffer(); + virtual size_t size() const = 0; + virtual uint8_t* data() = 0; +}; + class JSI_EXPORT StringBuffer : public Buffer { public: StringBuffer(std::string s) : s_(std::move(s)) {} @@ -80,6 +92,7 @@ class Instrumentation; class Scope; class JSIException; class JSError; +class TypedArray; /// A function which has this type can be registered as a function /// callable from JavaScript using Function::createFromHostFunction(). @@ -251,6 +264,8 @@ class JSI_EXPORT Runtime { friend class Value; friend class Scope; friend class JSError; + friend class TypedArray; + // Potential optimization: avoid the cloneFoo() virtual dispatch, // and instead just fix the number of fields, and copy them, since @@ -307,6 +322,19 @@ class JSI_EXPORT Runtime { virtual bool isArray(const Object&) const = 0; virtual bool isArrayBuffer(const Object&) const = 0; + virtual bool isArrayBufferView(const Object&) const = 0; + virtual bool isTypedArray(const Object&) const = 0; + virtual bool isInt8Array(const Object&) const = 0; + virtual bool isUint8Array(const Object&) const = 0; + virtual bool isUint8ClampedArray(const Object&) const = 0; + virtual bool isInt16Array(const Object&) const = 0; + virtual bool isUint16Array(const Object&) const = 0; + virtual bool isInt32Array(const Object&) const = 0; + virtual bool isUint32Array(const Object&) const = 0; + virtual bool isFloat32Array(const Object&) const = 0; + virtual bool isBigInt64Array(const Object&) const = 0; + virtual bool isBigUint64Array(const Object&) const = 0; + virtual bool isFloat64Array(const Object&) const = 0; virtual bool isFunction(const Object&) const = 0; virtual bool isHostObject(const jsi::Object&) const = 0; virtual bool isHostFunction(const jsi::Function&) const = 0; @@ -314,11 +342,20 @@ class JSI_EXPORT Runtime { virtual WeakObject createWeakObject(const Object&) = 0; virtual Value lockWeakObject(WeakObject&) = 0; + + virtual uint64_t uint64Value(const BigInt&, bool *lossless) const = 0; + virtual int64_t int64Value(const BigInt&, bool *lossless) const = 0; + virtual Array createArray(size_t length) = 0; + virtual ArrayBuffer createArrayBuffer( + std::shared_ptr buffer) = 0; virtual size_t size(const Array&) = 0; virtual size_t size(const ArrayBuffer&) = 0; + virtual size_t size(const TypedArray&) = 0; virtual uint8_t* data(const ArrayBuffer&) = 0; + virtual uint8_t* data(const TypedArray&) = 0; + virtual size_t offset(const TypedArray&) = 0; virtual Value getValueAtIndex(const Array&, size_t i) = 0; virtual void setValueAtIndexImpl(Array&, size_t i, const Value& value) = 0; @@ -493,6 +530,26 @@ class JSI_EXPORT BigInt : public Pointer { BigInt(BigInt&& other) = default; BigInt& operator=(BigInt&& other) = default; + + + /** + * Returns the value of this BigInt as an unsigned 64-bit integer. + * If `lossless` is provided, it will reflect whether the return value was + * truncated or wrapped around. In particular, it is set to `false` if this + * BigInt is negative. + */ + uint64_t Uint64Value(Runtime& runtime, bool* lossless = nullptr) const { + return runtime.uint64Value(*this, lossless); + } + + /** + * Returns the value of this BigInt as a signed 64-bit integer. + * If `lossless` is provided, it will reflect whether this BigInt was + * truncated or not. + */ + int64_t Int64Value(Runtime& runtime, bool* lossless = nullptr) const { + return runtime.int64Value(*this, lossless); + } friend class Runtime; friend class Value; @@ -641,6 +698,86 @@ class JSI_EXPORT Object : public Pointer { bool isArrayBuffer(Runtime& runtime) const { return runtime.isArrayBuffer(*this); } + + + /// \return true iff the Object is an isArrayBufferView. If so, then \c + /// getArrayBuffer() will succeed. + bool isArrayBufferView(Runtime& runtime) const { + return runtime.isArrayBufferView(*this); + } + + /// \return true iff the Object is an isTypedArray. If so, then \c + /// getArrayBuffer() will succeed. + bool isTypedArray(Runtime& runtime) const { + return runtime.isTypedArray(*this); + } + + + /// \return true iff the Object is an isInt8Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isInt8Array(Runtime& runtime) const { + return runtime.isInt8Array(*this); + } + + /// \return true iff the Object is an isUint8Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isUint8Array(Runtime& runtime) const { + return runtime.isUint8Array(*this); + } + + /// \return true iff the Object is an isUint8ClampedArray. If so, then \c + /// getArrayBuffer() will succeed. + bool isUint8ClampedArray(Runtime& runtime) const { + return runtime.isUint8ClampedArray(*this); + } + + /// \return true iff the Object is an isInt16Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isInt16Array(Runtime& runtime) const { + return runtime.isInt16Array(*this); + } + + /// \return true iff the Object is an isUint16Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isUint16Array(Runtime& runtime) const { + return runtime.isUint16Array(*this); + } + + /// \return true iff the Object is an isInt32Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isInt32Array(Runtime& runtime) const { + return runtime.isInt32Array(*this); + } + + /// \return true iff the Object is an isUint32Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isUint32Array(Runtime& runtime) const { + return runtime.isUint32Array(*this); + } + + /// \return true iff the Object is an isFloat32Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isFloat32Array(Runtime& runtime) const { + return runtime.isFloat32Array(*this); + } + + /// \return true iff the Object is an isBigInt64Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isBigInt64Array(Runtime& runtime) const { + return runtime.isBigInt64Array(*this); + } + + /// \return true iff the Object is an isBigUint64Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isBigUint64Array(Runtime& runtime) const { + return runtime.isBigUint64Array(*this); + } + + /// \return true iff the Object is an isFloat64Array. If so, then \c + /// getArrayBuffer() will succeed. + bool isFloat64Array(Runtime& runtime) const { + return runtime.isFloat64Array(*this); + } /// \return true iff the Object is callable. If so, then \c /// getFunction will succeed. @@ -679,6 +816,16 @@ class JSI_EXPORT Object : public Pointer { /// \return an ArrayBuffer instance which refers to the same underlying /// object. If \c isArrayBuffer() would return false, this will assert. ArrayBuffer getArrayBuffer(Runtime& runtime) &&; + + + /// \return an TypedArray instance which refers to the same underlying + /// object. If \c isTypedArray() would return false, this will assert. + TypedArray getTypedArray(Runtime& runtime) const&; + + /// \return an TypedArray instance which refers to the same underlying + /// object. If \c isTypedArray() would return false, this will assert. + TypedArray getTypedArray(Runtime& runtime) &&; + /// \return a Function instance which refers to the same underlying /// object. If \c isFunction() would return false, this will assert. @@ -828,6 +975,8 @@ class JSI_EXPORT ArrayBuffer : public Object { public: ArrayBuffer(ArrayBuffer&&) = default; ArrayBuffer& operator=(ArrayBuffer&&) = default; + ArrayBuffer(Runtime& runtime, std::shared_ptr buffer) + : ArrayBuffer(runtime.createArrayBuffer(std::move(buffer))) {} /// \return the size of the ArrayBuffer, according to its byteLength property. /// (C++ naming convention) @@ -850,6 +999,41 @@ class JSI_EXPORT ArrayBuffer : public Object { ArrayBuffer(Runtime::PointerValue* value) : Object(value) {} }; + +/// Represents a TypedArray +class JSI_EXPORT TypedArray : public Object { +public: + TypedArray(TypedArray &&) = default; + + TypedArray &operator=(TypedArray &&) = default; + + /// \return the size of the TypedArray ArrayBuffer, according to its byteLength property. + /// (C++ naming convention) + size_t size(Runtime &runtime) { + return runtime.size(*this); + } + + size_t offset(Runtime &runtime) const { + return runtime.offset(*this); + } + + size_t length(Runtime &runtime) const { + return runtime.size(*this); + } + + uint8_t *data(Runtime &runtime) { + return runtime.data(*this); + } + +private: + friend class Object; + + friend class Value; + + TypedArray(Runtime::PointerValue *value) : Object(value) {} +}; + + /// Represents a JS Object which is guaranteed to be Callable. class JSI_EXPORT Function : public Object { public: diff --git a/NativeScript/v8runtime/JSIV8ValueConverter.cpp b/NativeScript/v8runtime/JSIV8ValueConverter.cpp index 920d9c7c..3d9f0c91 100644 --- a/NativeScript/v8runtime/JSIV8ValueConverter.cpp +++ b/NativeScript/v8runtime/JSIV8ValueConverter.cpp @@ -39,6 +39,10 @@ jsi::Value JSIV8ValueConverter::ToJSIValue( if (value->IsObject()) { return V8Runtime::make(new V8PointerValue(isolate, value)); } + + if (value->IsBigInt()) { + return V8Runtime::make(new V8PointerValue(isolate, value)); + } return jsi::Value::undefined(); } @@ -65,6 +69,9 @@ v8::Local JSIV8ValueConverter::ToV8Value( } else if (value.isObject()) { return scopedHandle.Escape(ToV8Object( runtime, std::move(value.getObject(const_cast(runtime))))); + }else if(value.isBigInt()){ + return scopedHandle.Escape(ToV8BigInt( + runtime, std::move(value.getBigInt(const_cast(runtime))))); } else { // What are you? std::abort(); @@ -132,6 +139,19 @@ v8::Local JSIV8ValueConverter::ToV8Object( v8::Local::Cast(v8PointerValue->Get(runtime.isolate_))); } +// static +v8::Local JSIV8ValueConverter::ToV8BigInt( + const V8Runtime &runtime, + const jsi::BigInt &bigInt) { + v8::EscapableHandleScope scopedHandle(runtime.isolate_); + const auto *v8PointerValue = + static_cast(runtime.getPointerValue(bigInt)); + assert(v8PointerValue->Get(runtime.isolate_)->IsBigInt()); + return scopedHandle.Escape( + v8::Local::Cast(v8PointerValue->Get(runtime.isolate_))); +} + + // static v8::Local JSIV8ValueConverter::ToV8Array( const V8Runtime &runtime, diff --git a/NativeScript/v8runtime/JSIV8ValueConverter.h b/NativeScript/v8runtime/JSIV8ValueConverter.h index ddfdefb4..fd6983da 100644 --- a/NativeScript/v8runtime/JSIV8ValueConverter.h +++ b/NativeScript/v8runtime/JSIV8ValueConverter.h @@ -47,6 +47,10 @@ class JSIV8ValueConverter { static v8::Local ToV8Object( const V8Runtime &runtime, const facebook::jsi::Object &object); + + static v8::Local ToV8BigInt( + const V8Runtime &runtime, + const facebook::jsi::BigInt &bigInt); static v8::Local ToV8Array( const V8Runtime &runtime, diff --git a/NativeScript/v8runtime/V8Runtime.cpp b/NativeScript/v8runtime/V8Runtime.cpp index c20f8cf0..ffc27de6 100644 --- a/NativeScript/v8runtime/V8Runtime.cpp +++ b/NativeScript/v8runtime/V8Runtime.cpp @@ -634,6 +634,57 @@ void V8Runtime::setPropertyValue( } } + + +facebook::jsi::ArrayBuffer V8Runtime::createArrayBuffer( + std::shared_ptr buffer) { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + auto size = buffer->size(); + auto *data = buffer->data(); + auto *ctx = new std::shared_ptr(std::move(buffer)); + auto finalize = [](void *, size_t, void *ctx) { + delete static_cast *>(ctx); + }; + + std::unique_ptr store = v8::ArrayBuffer::NewBackingStore(data, size, + finalize, ctx); + auto arrayBuffer = v8::ArrayBuffer::New(isolate_, std::move(store)); + + + return make(new V8PointerValue(isolate_, arrayBuffer)) + .getArrayBuffer(*this); +} + + +uint64_t V8Runtime::uint64Value(const jsi::BigInt &bigInt, bool *lossless) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::TryCatch tryCatch(isolate_); + auto v8ObjectA = JSIV8ValueConverter::ToV8BigInt(*this, bigInt); + + return v8ObjectA->Uint64Value(lossless); +} + +int64_t V8Runtime::int64Value(const jsi::BigInt &bigInt, bool *lossless) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::TryCatch tryCatch(isolate_); + auto v8ObjectA = JSIV8ValueConverter::ToV8BigInt(*this, bigInt); + + return v8ObjectA->Int64Value(lossless); +} + + bool V8Runtime::isArray(const jsi::Object &object) const { v8::Locker locker(isolate_); v8::Isolate::Scope scopedIsolate(isolate_); @@ -656,6 +707,152 @@ bool V8Runtime::isArrayBuffer(const jsi::Object &object) const { return v8Object->IsArrayBuffer(); } + +bool V8Runtime::isArrayBufferView(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsArrayBufferView(); +} + +bool V8Runtime::isTypedArray(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + + return v8Object->IsTypedArray(); +} + +bool V8Runtime::isUint8Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsUint8Array(); +} + +bool V8Runtime::isUint8ClampedArray(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsUint8ClampedArray(); +} + +bool V8Runtime::isInt8Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsInt8Array(); +} + +bool V8Runtime::isUint16Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsUint16Array(); +} + +bool V8Runtime::isInt16Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsInt16Array(); +} + +bool V8Runtime::isUint32Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsUint32Array(); +} + +bool V8Runtime::isInt32Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsInt32Array(); +} + +bool V8Runtime::isFloat32Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsFloat32Array(); +} + +bool V8Runtime::isBigUint64Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsBigUint64Array(); +} + +bool V8Runtime::isBigInt64Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsBigInt64Array(); +} + +bool V8Runtime::isFloat64Array(const jsi::Object &object) const { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, object); + return v8Object->IsFloat64Array(); +} + + bool V8Runtime::isFunction(const jsi::Object &object) const { v8::Locker locker(isolate_); v8::Isolate::Scope scopedIsolate(isolate_); @@ -783,6 +980,33 @@ size_t V8Runtime::size(const jsi::ArrayBuffer &arrayBuffer) { return v8ArrayBuffer->ByteLength(); } + +size_t V8Runtime::size(const jsi::TypedArray &typedArray) { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, typedArray); + assert(v8Object->IsTypedArray()); + v8::TypedArray *array = v8::TypedArray::Cast(*v8Object); + return array->ByteLength(); +} + +size_t V8Runtime::offset(const jsi::TypedArray &typedArray) { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, typedArray); + assert(v8Object->IsTypedArray()); + auto array = v8Object.As(); + return array->ByteOffset(); +} + uint8_t *V8Runtime::data(const jsi::ArrayBuffer &arrayBuffer) { v8::Locker locker(isolate_); v8::Isolate::Scope scopedIsolate(isolate_); @@ -796,6 +1020,19 @@ uint8_t *V8Runtime::data(const jsi::ArrayBuffer &arrayBuffer) { return reinterpret_cast(v8ArrayBuffer->GetBackingStore()->Data()); } +uint8_t *V8Runtime::data(const jsi::TypedArray &typedArray) { + v8::Locker locker(isolate_); + v8::Isolate::Scope scopedIsolate(isolate_); + v8::HandleScope scopedHandle(isolate_); + v8::Context::Scope scopedContext(context_.Get(isolate_)); + + v8::Local v8Object = + JSIV8ValueConverter::ToV8Object(*this, typedArray); + assert(v8Object->IsTypedArray()); + auto array = v8Object.As(); + return reinterpret_cast(array->Buffer()->GetBackingStore()->Data()); +} + jsi::Value V8Runtime::getValueAtIndex(const jsi::Array &array, size_t i) { v8::Locker locker(isolate_); v8::Isolate::Scope scopedIsolate(isolate_); diff --git a/NativeScript/v8runtime/V8Runtime.h b/NativeScript/v8runtime/V8Runtime.h index 50a708a0..96b11e9a 100644 --- a/NativeScript/v8runtime/V8Runtime.h +++ b/NativeScript/v8runtime/V8Runtime.h @@ -104,6 +104,10 @@ class V8Runtime : public facebook::jsi::Runtime { facebook::jsi::Object createObject() override; facebook::jsi::Object createObject( std::shared_ptr hostObject) override; + + facebook::jsi::ArrayBuffer createArrayBuffer( + std::shared_ptr buffer) override; + std::shared_ptr getHostObject( const facebook::jsi::Object &) override; facebook::jsi::HostFunctionType &getHostFunction( @@ -132,6 +136,20 @@ class V8Runtime : public facebook::jsi::Runtime { bool isArray(const facebook::jsi::Object &) const override; bool isArrayBuffer(const facebook::jsi::Object &) const override; + bool isArrayBufferView(const facebook::jsi::Object &) const override; + bool isTypedArray(const facebook::jsi::Object &) const override; + bool isInt8Array(const facebook::jsi::Object &) const override; + bool isUint8Array(const facebook::jsi::Object &) const override; + bool isUint8ClampedArray(const facebook::jsi::Object &) const override; + bool isInt16Array(const facebook::jsi::Object &) const override; + bool isUint16Array(const facebook::jsi::Object &) const override; + bool isInt32Array(const facebook::jsi::Object &) const override; + bool isUint32Array(const facebook::jsi::Object &) const override; + bool isFloat32Array(const facebook::jsi::Object &) const override; + bool isBigInt64Array(const facebook::jsi::Object &) const override; + bool isBigUint64Array(const facebook::jsi::Object &) const override; + bool isFloat64Array(const facebook::jsi::Object &) const override; + bool isFunction(const facebook::jsi::Object &) const override; bool isHostObject(const facebook::jsi::Object &) const override; bool isHostFunction(const facebook::jsi::Function &) const override; @@ -144,7 +162,10 @@ class V8Runtime : public facebook::jsi::Runtime { facebook::jsi::Array createArray(size_t length) override; size_t size(const facebook::jsi::Array &) override; size_t size(const facebook::jsi::ArrayBuffer &) override; + size_t size(const facebook::jsi::TypedArray &) override; + size_t offset(const facebook::jsi::TypedArray &) override; uint8_t *data(const facebook::jsi::ArrayBuffer &) override; + uint8_t *data(const facebook::jsi::TypedArray &) override; facebook::jsi::Value getValueAtIndex(const facebook::jsi::Array &, size_t i) override; void setValueAtIndexImpl( @@ -184,6 +205,10 @@ class V8Runtime : public facebook::jsi::Runtime { bool instanceOf( const facebook::jsi::Object &o, const facebook::jsi::Function &f) override; + + uint64_t uint64Value(const facebook::jsi::BigInt&, bool* lossless = nullptr) const override; + + int64_t int64Value(const facebook::jsi::BigInt&, bool* lossless = nullptr) const override; private: friend class V8PointerValue; diff --git a/v8ios.xcodeproj/project.pbxproj b/v8ios.xcodeproj/project.pbxproj index 08e55e54..42caa33e 100644 --- a/v8ios.xcodeproj/project.pbxproj +++ b/v8ios.xcodeproj/project.pbxproj @@ -34,7 +34,7 @@ 6573B9E2291FE2A700B0ED7C /* jsi-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 6573B9D9291FE2A700B0ED7C /* jsi-inl.h */; }; 6573B9E3291FE2A700B0ED7C /* jsilib-posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6573B9DA291FE2A700B0ED7C /* jsilib-posix.cpp */; }; 6573B9E4291FE2A700B0ED7C /* jsilib-windows.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6573B9DB291FE2A700B0ED7C /* jsilib-windows.cpp */; }; - 6573B9E5291FE2A700B0ED7C /* jsi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6573B9DC291FE2A700B0ED7C /* jsi.cpp */; }; + 6573B9E5291FE2A700B0ED7C /* jsi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6573B9DC291FE2A700B0ED7C /* jsi.cpp */; settings = {COMPILER_FLAGS = "-frtti"; }; }; 6573B9E6291FE2A700B0ED7C /* instrumentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6573B9DD291FE2A700B0ED7C /* instrumentation.h */; }; 6573B9E7291FE2A700B0ED7C /* jsi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6573B9DE291FE2A700B0ED7C /* jsi.h */; }; 6573B9E8291FE2A700B0ED7C /* decorator.h in Headers */ = {isa = PBXBuildFile; fileRef = 6573B9DF291FE2A700B0ED7C /* decorator.h */; };