mirror of
https://github.com/openharmony/ark_js_runtime.git
synced 2026-07-22 07:35:27 -04:00
ebad65a675
Merge pull request !138 from yingguofeng/nativepointer
891 lines
25 KiB
C++
891 lines
25 KiB
C++
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
|
|
#define ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
|
|
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "ecmascript/common.h"
|
|
#include "libpandabase/macros.h"
|
|
|
|
namespace panda {
|
|
class JSNApiHelper;
|
|
class EscapeLocalScope;
|
|
template<typename T>
|
|
class Global;
|
|
class JSNApi;
|
|
class PrimitiveRef;
|
|
class ArrayRef;
|
|
class StringRef;
|
|
class ObjectRef;
|
|
class FunctionRef;
|
|
class NumberRef;
|
|
class BooleanRef;
|
|
class NativePointerRef;
|
|
namespace test {
|
|
class JSNApiTests;
|
|
} // namespace test
|
|
|
|
namespace ecmascript {
|
|
class EcmaVM;
|
|
} // namespace ecmascript
|
|
|
|
using Deleter = void (*)(void *buffer, void *data);
|
|
using EcmaVM = ecmascript::EcmaVM;
|
|
using JSTaggedType = uint64_t;
|
|
static constexpr uint32_t DEFAULT_GC_POOL_SIZE = 256 * 1024 * 1024;
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
#define DISALLOW_COPY(className) \
|
|
className(const className &) = delete; \
|
|
className &operator=(const className &) = delete
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
|
#define DISALLOW_MOVE(className) \
|
|
className(className &&) = delete; \
|
|
className &operator=(className &&) = delete
|
|
|
|
template<typename T>
|
|
class PUBLIC_API Local { // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
|
|
public:
|
|
inline Local() = default;
|
|
|
|
template<typename S>
|
|
inline Local(const Local<S> ¤t) : address_(reinterpret_cast<uintptr_t>(*current))
|
|
{
|
|
// Check
|
|
}
|
|
|
|
Local(const EcmaVM *vm, const Global<T> ¤t);
|
|
|
|
~Local() = default;
|
|
|
|
inline T *operator*() const
|
|
{
|
|
return GetAddress();
|
|
}
|
|
|
|
inline T *operator->() const
|
|
{
|
|
return GetAddress();
|
|
}
|
|
|
|
inline bool IsEmpty() const
|
|
{
|
|
return GetAddress() == nullptr;
|
|
}
|
|
|
|
inline bool CheckException() const
|
|
{
|
|
return IsEmpty() || GetAddress()->IsException();
|
|
}
|
|
|
|
inline bool IsException() const
|
|
{
|
|
return !IsEmpty() && GetAddress()->IsException();
|
|
}
|
|
|
|
inline bool IsNull() const
|
|
{
|
|
return IsEmpty() || GetAddress()->IsHole();
|
|
}
|
|
|
|
private:
|
|
explicit inline Local(uintptr_t addr) : address_(addr) {}
|
|
inline T *GetAddress() const
|
|
{
|
|
return reinterpret_cast<T *>(address_);
|
|
};
|
|
uintptr_t address_ = 0U;
|
|
friend JSNApiHelper;
|
|
friend EscapeLocalScope;
|
|
};
|
|
|
|
template<typename T>
|
|
class PUBLIC_API Global { // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions
|
|
public:
|
|
inline Global() = default;
|
|
|
|
inline Global(const Global &that) {
|
|
address_ = that.address_;
|
|
vm_ = that.vm_;
|
|
}
|
|
|
|
inline Global &operator=(const Global &that)
|
|
{
|
|
Update(that);
|
|
return *this;
|
|
}
|
|
|
|
inline Global(Global &&that) {
|
|
address_ = that.address_;
|
|
vm_ = that.vm_;
|
|
}
|
|
|
|
inline Global &operator=(Global &&that)
|
|
{
|
|
Update(that);
|
|
return *this;
|
|
}
|
|
// Non-empty initial value.
|
|
explicit Global(const EcmaVM *vm);
|
|
|
|
template<typename S>
|
|
Global(const EcmaVM *vm, const Local<S> ¤t);
|
|
~Global() = default;
|
|
|
|
Local<T> ToLocal(const EcmaVM *vm) const
|
|
{
|
|
return Local<T>(vm, *this);
|
|
}
|
|
|
|
void Empty()
|
|
{
|
|
address_ = 0;
|
|
}
|
|
|
|
// This method must be called before Global is released.
|
|
void FreeGlobalHandleAddr();
|
|
|
|
inline T *operator*() const
|
|
{
|
|
return GetAddress();
|
|
}
|
|
|
|
inline T *operator->() const
|
|
{
|
|
return GetAddress();
|
|
}
|
|
|
|
inline bool IsEmpty() const
|
|
{
|
|
return GetAddress() == nullptr;
|
|
}
|
|
|
|
inline bool CheckException() const
|
|
{
|
|
return IsEmpty() || GetAddress()->IsException();
|
|
}
|
|
|
|
void SetWeak();
|
|
|
|
bool IsWeak() const;
|
|
|
|
private:
|
|
inline T *GetAddress() const
|
|
{
|
|
return reinterpret_cast<T *>(address_);
|
|
};
|
|
inline void Update(const Global &that);
|
|
uintptr_t address_ = 0U;
|
|
const EcmaVM *vm_{nullptr};
|
|
};
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
|
|
class PUBLIC_API LocalScope {
|
|
public:
|
|
explicit LocalScope(const EcmaVM *vm);
|
|
virtual ~LocalScope();
|
|
|
|
protected:
|
|
inline LocalScope(const EcmaVM *vm, JSTaggedType value);
|
|
|
|
private:
|
|
void *prevNext_ = nullptr;
|
|
void *prevEnd_ = nullptr;
|
|
int prevHandleStorageIndex_{-1};
|
|
void *thread_ = nullptr;
|
|
};
|
|
|
|
class PUBLIC_API EscapeLocalScope final : public LocalScope {
|
|
public:
|
|
explicit EscapeLocalScope(const EcmaVM *vm);
|
|
~EscapeLocalScope() override = default;
|
|
|
|
DISALLOW_COPY(EscapeLocalScope);
|
|
DISALLOW_MOVE(EscapeLocalScope);
|
|
|
|
template<typename T>
|
|
inline Local<T> Escape(Local<T> current)
|
|
{
|
|
ASSERT(!alreadyEscape_);
|
|
alreadyEscape_ = true;
|
|
*(reinterpret_cast<T *>(escapeHandle_)) = **current;
|
|
return Local<T>(escapeHandle_);
|
|
}
|
|
|
|
private:
|
|
bool alreadyEscape_ = false;
|
|
uintptr_t escapeHandle_ = 0U;
|
|
};
|
|
|
|
class PUBLIC_API JSExecutionScope {
|
|
public:
|
|
explicit JSExecutionScope(const EcmaVM *vm);
|
|
~JSExecutionScope();
|
|
DISALLOW_COPY(JSExecutionScope);
|
|
DISALLOW_MOVE(JSExecutionScope);
|
|
|
|
private:
|
|
void *last_current_thread_ = nullptr;
|
|
bool is_revert_ = false;
|
|
};
|
|
|
|
class PUBLIC_API JSValueRef {
|
|
public:
|
|
static Local<PrimitiveRef> Undefined(const EcmaVM *vm);
|
|
static Local<PrimitiveRef> Null(const EcmaVM *vm);
|
|
static Local<PrimitiveRef> True(const EcmaVM *vm);
|
|
static Local<PrimitiveRef> False(const EcmaVM *vm);
|
|
static Local<JSValueRef> Exception(const EcmaVM *vm);
|
|
|
|
bool BooleaValue();
|
|
int64_t IntegerValue(const EcmaVM *vm);
|
|
uint32_t Uint32Value(const EcmaVM *vm);
|
|
int32_t Int32Value(const EcmaVM *vm);
|
|
|
|
Local<NumberRef> ToNumber(const EcmaVM *vm);
|
|
Local<BooleanRef> ToBoolean(const EcmaVM *vm);
|
|
Local<StringRef> ToString(const EcmaVM *vm);
|
|
Local<ObjectRef> ToObject(const EcmaVM *vm);
|
|
Local<NativePointerRef> ToNativePointer(const EcmaVM *vm);
|
|
|
|
bool IsUndefined();
|
|
bool IsNull();
|
|
bool IsHole();
|
|
bool IsTrue();
|
|
bool IsFalse();
|
|
bool IsNumber();
|
|
bool IsInt();
|
|
bool WithinInt32();
|
|
bool IsBoolean();
|
|
bool IsString();
|
|
bool IsSymbol();
|
|
bool IsObject();
|
|
bool IsArray(const EcmaVM *vm);
|
|
bool IsConstructor();
|
|
bool IsFunction();
|
|
bool IsProxy();
|
|
bool IsException();
|
|
bool IsPromise();
|
|
bool IsDataView();
|
|
bool IsTypedArray();
|
|
bool IsNativePointer();
|
|
bool IsDate();
|
|
bool IsError();
|
|
bool IsMap();
|
|
bool IsSet();
|
|
bool IsWeakMap();
|
|
bool IsWeakSet();
|
|
bool IsRegExp();
|
|
bool IsArrayIterator();
|
|
bool IsStringIterator();
|
|
bool IsSetIterator();
|
|
bool IsMapIterator();
|
|
bool IsArrayBuffer();
|
|
bool IsUint8Array();
|
|
bool IsInt8Array();
|
|
bool IsUint8ClampedArray();
|
|
bool IsInt16Array();
|
|
bool IsUint16Array();
|
|
bool IsInt32Array();
|
|
bool IsUint32Array();
|
|
bool IsFloat32Array();
|
|
bool IsFloat64Array();
|
|
bool IsJSPrimitiveRef();
|
|
bool IsJSPrimitiveNumber();
|
|
bool IsJSPrimitiveInt();
|
|
bool IsJSPrimitiveBoolean();
|
|
bool IsJSPrimitiveString();
|
|
|
|
bool IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value);
|
|
Local<StringRef> Typeof(const EcmaVM *vm);
|
|
bool InstanceOf(const EcmaVM *vm, Local<JSValueRef> value);
|
|
|
|
private:
|
|
JSTaggedType value_;
|
|
friend JSNApi;
|
|
template<typename T>
|
|
friend class Global;
|
|
template<typename T>
|
|
friend class Local;
|
|
};
|
|
|
|
class PUBLIC_API PrimitiveRef : public JSValueRef {
|
|
};
|
|
|
|
class PUBLIC_API IntegerRef : public PrimitiveRef {
|
|
public:
|
|
static Local<IntegerRef> New(const EcmaVM *vm, int input);
|
|
static Local<IntegerRef> NewFromUnsigned(const EcmaVM *vm, unsigned int input);
|
|
int Value();
|
|
};
|
|
|
|
class PUBLIC_API NumberRef : public PrimitiveRef {
|
|
public:
|
|
static Local<NumberRef> New(const EcmaVM *vm, double input);
|
|
double Value();
|
|
};
|
|
|
|
class PUBLIC_API BooleanRef : public PrimitiveRef {
|
|
public:
|
|
static Local<BooleanRef> New(const EcmaVM *vm, bool input);
|
|
bool Value();
|
|
};
|
|
|
|
class PUBLIC_API StringRef : public PrimitiveRef {
|
|
public:
|
|
static inline StringRef *Cast(JSValueRef *value)
|
|
{
|
|
// check
|
|
return static_cast<StringRef *>(value);
|
|
}
|
|
static Local<StringRef> NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1);
|
|
std::string ToString();
|
|
int32_t Length();
|
|
int32_t Utf8Length();
|
|
int WriteUtf8(char *buffer, int length);
|
|
};
|
|
|
|
class PUBLIC_API SymbolRef : public PrimitiveRef {
|
|
public:
|
|
static Local<SymbolRef> New(const EcmaVM *vm, Local<StringRef> description);
|
|
Local<StringRef> GetDescription(const EcmaVM *vm);
|
|
};
|
|
|
|
using NativePointerCallback = void (*)(void* value, void* hint);
|
|
class PUBLIC_API NativePointerRef : public JSValueRef {
|
|
public:
|
|
static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer);
|
|
static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack,
|
|
void *data);
|
|
void *Value();
|
|
};
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
|
|
class PUBLIC_API PropertyAttribute {
|
|
public:
|
|
static PropertyAttribute Default()
|
|
{
|
|
return PropertyAttribute();
|
|
}
|
|
PropertyAttribute() = default;
|
|
PropertyAttribute(Local<JSValueRef> value, bool w, bool e, bool c)
|
|
: value_(value),
|
|
writable_(w),
|
|
enumerable_(e),
|
|
configurable_(c),
|
|
hasWritable_(true),
|
|
hasEnumerable_(true),
|
|
hasConfigurable_(true)
|
|
{}
|
|
~PropertyAttribute() = default;
|
|
|
|
bool IsWritable() const
|
|
{
|
|
return writable_;
|
|
}
|
|
void SetWritable(bool flag)
|
|
{
|
|
writable_ = flag;
|
|
hasWritable_ = true;
|
|
}
|
|
bool IsEnumerable() const
|
|
{
|
|
return enumerable_;
|
|
}
|
|
void SetEnumerable(bool flag)
|
|
{
|
|
enumerable_ = flag;
|
|
hasEnumerable_ = true;
|
|
}
|
|
bool IsConfigurable() const
|
|
{
|
|
return configurable_;
|
|
}
|
|
void SetConfigurable(bool flag)
|
|
{
|
|
configurable_ = flag;
|
|
hasConfigurable_ = true;
|
|
}
|
|
bool HasWritable() const
|
|
{
|
|
return hasWritable_;
|
|
}
|
|
bool HasConfigurable() const
|
|
{
|
|
return hasConfigurable_;
|
|
}
|
|
bool HasEnumerable() const
|
|
{
|
|
return hasEnumerable_;
|
|
}
|
|
Local<JSValueRef> GetValue(const EcmaVM *vm) const
|
|
{
|
|
if (value_.IsEmpty()) {
|
|
return JSValueRef::Undefined(vm);
|
|
}
|
|
return value_;
|
|
}
|
|
void SetValue(Local<JSValueRef> value)
|
|
{
|
|
value_ = value;
|
|
}
|
|
inline bool HasValue() const
|
|
{
|
|
return !value_.IsEmpty();
|
|
}
|
|
Local<JSValueRef> GetGetter(const EcmaVM *vm) const
|
|
{
|
|
if (getter_.IsEmpty()) {
|
|
return JSValueRef::Undefined(vm);
|
|
}
|
|
return getter_;
|
|
}
|
|
void SetGetter(Local<JSValueRef> value)
|
|
{
|
|
getter_ = value;
|
|
}
|
|
bool HasGetter() const
|
|
{
|
|
return !getter_.IsEmpty();
|
|
}
|
|
Local<JSValueRef> GetSetter(const EcmaVM *vm) const
|
|
{
|
|
if (setter_.IsEmpty()) {
|
|
return JSValueRef::Undefined(vm);
|
|
}
|
|
return setter_;
|
|
}
|
|
void SetSetter(Local<JSValueRef> value)
|
|
{
|
|
setter_ = value;
|
|
}
|
|
bool HasSetter() const
|
|
{
|
|
return !setter_.IsEmpty();
|
|
}
|
|
|
|
private:
|
|
Local<JSValueRef> value_;
|
|
Local<JSValueRef> getter_;
|
|
Local<JSValueRef> setter_;
|
|
bool writable_ = false;
|
|
bool enumerable_ = false;
|
|
bool configurable_ = false;
|
|
bool hasWritable_ = false;
|
|
bool hasEnumerable_ = false;
|
|
bool hasConfigurable_ = false;
|
|
};
|
|
|
|
class PUBLIC_API ObjectRef : public JSValueRef {
|
|
public:
|
|
static inline ObjectRef *Cast(JSValueRef *value)
|
|
{
|
|
// check
|
|
return static_cast<ObjectRef *>(value);
|
|
}
|
|
static Local<ObjectRef> New(const EcmaVM *vm);
|
|
bool Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
|
|
bool Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value);
|
|
bool SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
|
|
Local<FunctionRef> setter, PropertyAttribute attribute = PropertyAttribute::Default());
|
|
Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
|
|
Local<JSValueRef> Get(const EcmaVM *vm, int32_t key);
|
|
|
|
bool GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property);
|
|
Local<ArrayRef> GetOwnPropertyNames(const EcmaVM *vm);
|
|
Local<ArrayRef> GetOwnEnumerablePropertyNames(const EcmaVM *vm);
|
|
Local<JSValueRef> GetPrototype(const EcmaVM *vm);
|
|
|
|
bool DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute);
|
|
|
|
bool Has(const EcmaVM *vm, Local<JSValueRef> key);
|
|
bool Has(const EcmaVM *vm, uint32_t key);
|
|
|
|
bool Delete(const EcmaVM *vm, Local<JSValueRef> key);
|
|
bool Delete(const EcmaVM *vm, uint32_t key);
|
|
|
|
void SetNativePointerFieldCount(int32_t count);
|
|
int32_t GetNativePointerFieldCount();
|
|
void *GetNativePointerField(int32_t index);
|
|
void SetNativePointerField(int32_t index,
|
|
void *nativePointer = nullptr,
|
|
NativePointerCallback callBack = nullptr,
|
|
void *data = nullptr);
|
|
};
|
|
|
|
using FunctionCallback = Local<JSValueRef> (*)(EcmaVM *, Local<JSValueRef>,
|
|
const Local<JSValueRef>[], // NOLINTNEXTLINE(modernize-avoid-c-arrays)
|
|
int32_t, void *);
|
|
using FunctionCallbackWithNewTarget =
|
|
Local<JSValueRef> (*)(EcmaVM *, Local<JSValueRef>, Local<JSValueRef>, const Local<JSValueRef>[], int32_t, void *);
|
|
class PUBLIC_API FunctionRef : public ObjectRef {
|
|
public:
|
|
static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, void *data);
|
|
static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter, void *data);
|
|
static Local<FunctionRef> NewWithProperty(EcmaVM *vm, FunctionCallback nativeFunc, void *data);
|
|
static Local<FunctionRef> NewClassFunction(EcmaVM *vm, FunctionCallbackWithNewTarget nativeFunc, Deleter deleter,
|
|
void *data);
|
|
Local<JSValueRef> Call(const EcmaVM *vm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[],
|
|
int32_t length);
|
|
Local<JSValueRef> Constructor(const EcmaVM *vm, const Local<JSValueRef> argv[], int32_t length);
|
|
Local<JSValueRef> GetFunctionPrototype(const EcmaVM *vm);
|
|
void SetName(const EcmaVM *vm, Local<StringRef> name);
|
|
Local<StringRef> GetName(const EcmaVM *vm);
|
|
bool IsNative(const EcmaVM *vm);
|
|
};
|
|
|
|
class PUBLIC_API ArrayRef : public ObjectRef {
|
|
public:
|
|
static Local<ArrayRef> New(const EcmaVM *vm, int32_t length = 0);
|
|
int32_t Length(const EcmaVM *vm);
|
|
static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
|
|
static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
|
|
};
|
|
|
|
class PUBLIC_API PromiseRef : public ObjectRef {
|
|
public:
|
|
Local<PromiseRef> Catch(const EcmaVM *vm, Local<FunctionRef> handler);
|
|
Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> handler);
|
|
Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected);
|
|
};
|
|
|
|
class PUBLIC_API PromiseCapabilityRef : public ObjectRef {
|
|
public:
|
|
static Local<PromiseCapabilityRef> New(const EcmaVM *vm);
|
|
bool Resolve(const EcmaVM *vm, Local<JSValueRef> value);
|
|
bool Reject(const EcmaVM *vm, Local<JSValueRef> reason);
|
|
Local<PromiseRef> GetPromise(const EcmaVM *vm);
|
|
};
|
|
|
|
class PUBLIC_API ArrayBufferRef : public ObjectRef {
|
|
public:
|
|
static Local<ArrayBufferRef> New(const EcmaVM *vm, int32_t length);
|
|
static Local<ArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter,
|
|
void *data);
|
|
|
|
int32_t ByteLength(const EcmaVM *vm);
|
|
void *GetBuffer();
|
|
};
|
|
|
|
class PUBLIC_API DataViewRef : public ObjectRef {
|
|
public:
|
|
static Local<DataViewRef> New(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, int32_t byteOffset,
|
|
int32_t byteLength);
|
|
int32_t ByteLength();
|
|
int32_t ByteOffset();
|
|
Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
|
|
};
|
|
|
|
class PUBLIC_API TypedArrayRef : public ObjectRef {
|
|
public:
|
|
int32_t ByteLength(const EcmaVM *vm);
|
|
int32_t ByteOffset(const EcmaVM *vm);
|
|
int32_t ArrayLength(const EcmaVM *vm);
|
|
Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
|
|
};
|
|
|
|
class PUBLIC_API Int8ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Uint8ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Uint8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Uint8ClampedArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
|
|
int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Int16ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Int16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Uint16ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Uint16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
|
|
int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Int32ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Int32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Uint32ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Uint32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
|
|
int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Float32ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Float32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
|
|
int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API Float64ArrayRef : public TypedArrayRef {
|
|
public:
|
|
static Local<Float64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
|
|
int32_t length);
|
|
};
|
|
|
|
class PUBLIC_API RegExpRef : public ObjectRef {
|
|
public:
|
|
Local<StringRef> GetOriginalSource(const EcmaVM *vm);
|
|
};
|
|
|
|
class PUBLIC_API DateRef : public ObjectRef {
|
|
public:
|
|
Local<StringRef> ToString(const EcmaVM *vm);
|
|
};
|
|
|
|
class PUBLIC_API MapRef : public ObjectRef {
|
|
public:
|
|
int32_t GetSize();
|
|
};
|
|
|
|
class PUBLIC_API SetRef : public ObjectRef {
|
|
public:
|
|
int32_t GetSize();
|
|
};
|
|
|
|
class PUBLIC_API JSON {
|
|
public:
|
|
static Local<JSValueRef> Parse(const EcmaVM *vm, Local<StringRef> string);
|
|
static Local<JSValueRef> Stringify(const EcmaVM *vm, Local<JSValueRef> json);
|
|
};
|
|
|
|
class PUBLIC_API Exception {
|
|
public:
|
|
static Local<JSValueRef> Error(const EcmaVM *vm, Local<StringRef> message);
|
|
static Local<JSValueRef> RangeError(const EcmaVM *vm, Local<StringRef> message);
|
|
static Local<JSValueRef> ReferenceError(const EcmaVM *vm, Local<StringRef> message);
|
|
static Local<JSValueRef> SyntaxError(const EcmaVM *vm, Local<StringRef> message);
|
|
static Local<JSValueRef> TypeError(const EcmaVM *vm, Local<StringRef> message);
|
|
static Local<JSValueRef> EvalError(const EcmaVM *vm, Local<StringRef> message);
|
|
};
|
|
|
|
using LOG_PRINT = int (*)(int id, int level, const char *tag, const char *fmt, const char *message);
|
|
|
|
class PUBLIC_API RuntimeOption {
|
|
public:
|
|
enum class PUBLIC_API GC_TYPE : uint8_t { EPSILON, GEN_GC, STW };
|
|
enum class PUBLIC_API LOG_LEVEL : uint8_t {
|
|
DEBUG = 3,
|
|
INFO = 4,
|
|
WARN = 5,
|
|
ERROR = 6,
|
|
FATAL = 7,
|
|
};
|
|
|
|
void SetGcType(GC_TYPE type)
|
|
{
|
|
gcType_ = type;
|
|
}
|
|
|
|
void SetGcPoolSize(uint32_t size)
|
|
{
|
|
gcPoolSize_ = size;
|
|
}
|
|
|
|
void SetLogLevel(LOG_LEVEL logLevel)
|
|
{
|
|
logLevel_ = logLevel;
|
|
}
|
|
|
|
void SetLogBufPrint(LOG_PRINT out)
|
|
{
|
|
logBufPrint_ = out;
|
|
}
|
|
|
|
void SetDebuggerLibraryPath(const std::string &path)
|
|
{
|
|
debuggerLibraryPath_ = path;
|
|
}
|
|
|
|
private:
|
|
std::string GetGcType() const
|
|
{
|
|
std::string gcType;
|
|
switch (gcType_) {
|
|
case GC_TYPE::GEN_GC:
|
|
gcType = "gen-gc";
|
|
break;
|
|
case GC_TYPE::STW:
|
|
gcType = "stw";
|
|
break;
|
|
case GC_TYPE::EPSILON:
|
|
gcType = "epsilon";
|
|
break;
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
return gcType;
|
|
}
|
|
|
|
std::string GetLogLevel() const
|
|
{
|
|
std::string logLevel;
|
|
switch (logLevel_) {
|
|
case LOG_LEVEL::INFO:
|
|
case LOG_LEVEL::WARN:
|
|
logLevel = "info";
|
|
break;
|
|
case LOG_LEVEL::ERROR:
|
|
logLevel = "error";
|
|
break;
|
|
case LOG_LEVEL::FATAL:
|
|
logLevel = "fatal";
|
|
break;
|
|
case LOG_LEVEL::DEBUG:
|
|
default:
|
|
logLevel = "debug";
|
|
break;
|
|
}
|
|
|
|
return logLevel;
|
|
}
|
|
|
|
uint32_t GetGcPoolSize() const
|
|
{
|
|
return gcPoolSize_;
|
|
}
|
|
|
|
LOG_PRINT GetLogBufPrint() const
|
|
{
|
|
return logBufPrint_;
|
|
}
|
|
|
|
std::string GetDebuggerLibraryPath() const
|
|
{
|
|
return debuggerLibraryPath_;
|
|
}
|
|
|
|
GC_TYPE gcType_ = GC_TYPE::EPSILON;
|
|
LOG_LEVEL logLevel_ = LOG_LEVEL::DEBUG;
|
|
uint32_t gcPoolSize_ = DEFAULT_GC_POOL_SIZE;
|
|
LOG_PRINT logBufPrint_{nullptr};
|
|
std::string debuggerLibraryPath_{};
|
|
friend JSNApi;
|
|
};
|
|
|
|
class PUBLIC_API JSNApi {
|
|
public:
|
|
// JSVM
|
|
enum class PUBLIC_API TRIGGER_GC_TYPE : uint8_t { SEMI_GC, OLD_GC, COMPRESS_FULL_GC };
|
|
static EcmaVM *CreateJSVM(const RuntimeOption &option);
|
|
static void DestoryJSVM(EcmaVM *ecmaVm);
|
|
|
|
// JS code
|
|
static bool Execute(EcmaVM *vm, Local<StringRef> fileName, Local<StringRef> entry);
|
|
static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, Local<StringRef> entry);
|
|
static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file);
|
|
static Local<ObjectRef> GetExportObject(EcmaVM *vm, const std::string &file, const std::string &itemName);
|
|
|
|
// ObjectRef Operation
|
|
static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm);
|
|
static void ExecutePendingJob(const EcmaVM *vm);
|
|
|
|
// Memory
|
|
static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC);
|
|
// Exception
|
|
static void ThrowException(const EcmaVM *vm, Local<JSValueRef> error);
|
|
static Local<ObjectRef> GetUncaughtException(const EcmaVM *vm);
|
|
static void EnableUserUncaughtErrorHandler(EcmaVM *vm);
|
|
|
|
static bool StartDebugger(const char *library_path, EcmaVM *vm);
|
|
// Serialize & Deserialize.
|
|
static void* SerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer);
|
|
static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void* recoder);
|
|
static void DeleteSerializationData(void *data);
|
|
|
|
private:
|
|
static bool CreateRuntime(const RuntimeOption &option);
|
|
static bool DestoryRuntime();
|
|
|
|
static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
|
|
static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
|
|
static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress);
|
|
static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress);
|
|
static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr);
|
|
template<typename T>
|
|
friend class Global;
|
|
template<typename T>
|
|
friend class Local;
|
|
friend class test::JSNApiTests;
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
template<typename S>
|
|
Global<T>::Global(const EcmaVM *vm, const Local<S> ¤t) : vm_(vm)
|
|
{
|
|
if (!current.IsEmpty()) {
|
|
address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
void Global<T>::Update(const Global &that)
|
|
{
|
|
if (address_ != 0) {
|
|
JSNApi::DisposeGlobalHandleAddr(vm_, address_);
|
|
}
|
|
address_ = that.address_;
|
|
vm_ = that.vm_;
|
|
}
|
|
|
|
template<typename T>
|
|
void Global<T>::FreeGlobalHandleAddr()
|
|
{
|
|
if (address_ == 0) {
|
|
return;
|
|
}
|
|
JSNApi::DisposeGlobalHandleAddr(vm_, address_);
|
|
address_ = 0;
|
|
}
|
|
|
|
template<typename T>
|
|
void Global<T>::SetWeak()
|
|
{
|
|
address_ = JSNApi::SetWeak(vm_, address_);
|
|
}
|
|
|
|
template<typename T>
|
|
bool Global<T>::IsWeak() const
|
|
{
|
|
return JSNApi::IsWeak(vm_, address_);
|
|
}
|
|
|
|
// ---------------------------------- Local --------------------------------------------
|
|
template<typename T>
|
|
Local<T>::Local(const EcmaVM *vm, const Global<T> ¤t)
|
|
{
|
|
address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
|
|
}
|
|
} // namespace panda
|
|
#endif // ECMASCRIPT_NAPI_INCLUDE_JSNAPI_H
|