Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03k
1#ifndef SRC_NAPI_INL_H_2#define SRC_NAPI_INL_H_3 4////////////////////////////////////////////////////////////////////////////////5// Node-API C++ Wrapper Classes6//7// Inline header-only implementations for "Node-API" ABI-stable C APIs for8// Node.js.9////////////////////////////////////////////////////////////////////////////////10 11// Note: Do not include this file directly! Include "napi.h" instead.12 13#include <algorithm>14#include <cstring>15#if NAPI_HAS_THREADS16#include <mutex>17#endif // NAPI_HAS_THREADS18#include <type_traits>19#include <utility>20 21namespace Napi {22 23#ifdef NAPI_CPP_CUSTOM_NAMESPACE24namespace NAPI_CPP_CUSTOM_NAMESPACE {25#endif26 27// Helpers to handle functions exposed from C++ and internal constants.28namespace details {29 30// New napi_status constants not yet available in all supported versions of31// Node.js releases. Only necessary when they are used in napi.h and napi-inl.h.32constexpr int napi_no_external_buffers_allowed = 22;33 34template <typename FreeType>35inline void default_finalizer(napi_env /*env*/, void* data, void* /*hint*/) {36 delete static_cast<FreeType*>(data);37}38 39// Attach a data item to an object and delete it when the object gets40// garbage-collected.41// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes42// available on all supported versions of Node.js.43template <typename FreeType,44 napi_finalize finalizer = default_finalizer<FreeType>>45inline napi_status AttachData(napi_env env,46 napi_value obj,47 FreeType* data,48 void* hint = nullptr) {49 napi_status status;50#if (NAPI_VERSION < 5)51 napi_value symbol, external;52 status = napi_create_symbol(env, nullptr, &symbol);53 if (status == napi_ok) {54 status = napi_create_external(env, data, finalizer, hint, &external);55 if (status == napi_ok) {56 napi_property_descriptor desc = {nullptr,57 symbol,58 nullptr,59 nullptr,60 nullptr,61 external,62 napi_default,63 nullptr};64 status = napi_define_properties(env, obj, 1, &desc);65 }66 }67#else // NAPI_VERSION >= 568 status = napi_add_finalizer(env, obj, data, finalizer, hint, nullptr);69#endif70 return status;71}72 73// For use in JS to C++ callback wrappers to catch any Napi::Error exceptions74// and rethrow them as JavaScript exceptions before returning from the callback.75template <typename Callable>76inline napi_value WrapCallback(Callable callback) {77#ifdef NAPI_CPP_EXCEPTIONS78 try {79 return callback();80 } catch (const Error& e) {81 e.ThrowAsJavaScriptException();82 return nullptr;83 }84#else // NAPI_CPP_EXCEPTIONS85 // When C++ exceptions are disabled, errors are immediately thrown as JS86 // exceptions, so there is no need to catch and rethrow them here.87 return callback();88#endif // NAPI_CPP_EXCEPTIONS89}90 91// For use in JS to C++ void callback wrappers to catch any Napi::Error92// exceptions and rethrow them as JavaScript exceptions before returning from93// the callback.94template <typename Callable>95inline void WrapVoidCallback(Callable callback) {96#ifdef NAPI_CPP_EXCEPTIONS97 try {98 callback();99 } catch (const Error& e) {100 e.ThrowAsJavaScriptException();101 }102#else // NAPI_CPP_EXCEPTIONS103 // When C++ exceptions are disabled, errors are immediately thrown as JS104 // exceptions, so there is no need to catch and rethrow them here.105 callback();106#endif // NAPI_CPP_EXCEPTIONS107}108 109template <typename Callable, typename Return>110struct CallbackData {111 static inline napi_value Wrapper(napi_env env, napi_callback_info info) {112 return details::WrapCallback([&] {113 CallbackInfo callbackInfo(env, info);114 CallbackData* callbackData =115 static_cast<CallbackData*>(callbackInfo.Data());116 callbackInfo.SetData(callbackData->data);117 return callbackData->callback(callbackInfo);118 });119 }120 121 Callable callback;122 void* data;123};124 125template <typename Callable>126struct CallbackData<Callable, void> {127 static inline napi_value Wrapper(napi_env env, napi_callback_info info) {128 return details::WrapCallback([&] {129 CallbackInfo callbackInfo(env, info);130 CallbackData* callbackData =131 static_cast<CallbackData*>(callbackInfo.Data());132 callbackInfo.SetData(callbackData->data);133 callbackData->callback(callbackInfo);134 return nullptr;135 });136 }137 138 Callable callback;139 void* data;140};141 142template <void (*Callback)(const CallbackInfo& info)>143napi_value TemplatedVoidCallback(napi_env env,144 napi_callback_info info) NAPI_NOEXCEPT {145 return details::WrapCallback([&] {146 CallbackInfo cbInfo(env, info);147 Callback(cbInfo);148 return nullptr;149 });150}151 152template <Napi::Value (*Callback)(const CallbackInfo& info)>153napi_value TemplatedCallback(napi_env env,154 napi_callback_info info) NAPI_NOEXCEPT {155 return details::WrapCallback([&] {156 CallbackInfo cbInfo(env, info);157 return Callback(cbInfo);158 });159}160 161template <typename T,162 Napi::Value (T::*UnwrapCallback)(const CallbackInfo& info)>163napi_value TemplatedInstanceCallback(napi_env env,164 napi_callback_info info) NAPI_NOEXCEPT {165 return details::WrapCallback([&] {166 CallbackInfo cbInfo(env, info);167 T* instance = T::Unwrap(cbInfo.This().As<Object>());168 return instance ? (instance->*UnwrapCallback)(cbInfo) : Napi::Value();169 });170}171 172template <typename T, void (T::*UnwrapCallback)(const CallbackInfo& info)>173napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info)174 NAPI_NOEXCEPT {175 return details::WrapCallback([&] {176 CallbackInfo cbInfo(env, info);177 T* instance = T::Unwrap(cbInfo.This().As<Object>());178 if (instance) (instance->*UnwrapCallback)(cbInfo);179 return nullptr;180 });181}182 183template <typename T, typename Finalizer, typename Hint = void>184struct FinalizeData {185 static inline void Wrapper(napi_env env,186 void* data,187 void* finalizeHint) NAPI_NOEXCEPT {188 WrapVoidCallback([&] {189 FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);190 finalizeData->callback(Env(env), static_cast<T*>(data));191 delete finalizeData;192 });193 }194 195 static inline void WrapperWithHint(napi_env env,196 void* data,197 void* finalizeHint) NAPI_NOEXCEPT {198 WrapVoidCallback([&] {199 FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);200 finalizeData->callback(201 Env(env), static_cast<T*>(data), finalizeData->hint);202 delete finalizeData;203 });204 }205 206 Finalizer callback;207 Hint* hint;208};209 210#if (NAPI_VERSION > 3 && NAPI_HAS_THREADS)211template <typename ContextType = void,212 typename Finalizer = std::function<void(Env, void*, ContextType*)>,213 typename FinalizerDataType = void>214struct ThreadSafeFinalize {215 static inline void Wrapper(napi_env env,216 void* rawFinalizeData,217 void* /* rawContext */) {218 if (rawFinalizeData == nullptr) return;219 220 ThreadSafeFinalize* finalizeData =221 static_cast<ThreadSafeFinalize*>(rawFinalizeData);222 finalizeData->callback(Env(env));223 delete finalizeData;224 }225 226 static inline void FinalizeWrapperWithData(napi_env env,227 void* rawFinalizeData,228 void* /* rawContext */) {229 if (rawFinalizeData == nullptr) return;230 231 ThreadSafeFinalize* finalizeData =232 static_cast<ThreadSafeFinalize*>(rawFinalizeData);233 finalizeData->callback(Env(env), finalizeData->data);234 delete finalizeData;235 }236 237 static inline void FinalizeWrapperWithContext(napi_env env,238 void* rawFinalizeData,239 void* rawContext) {240 if (rawFinalizeData == nullptr) return;241 242 ThreadSafeFinalize* finalizeData =243 static_cast<ThreadSafeFinalize*>(rawFinalizeData);244 finalizeData->callback(Env(env), static_cast<ContextType*>(rawContext));245 delete finalizeData;246 }247 248 static inline void FinalizeFinalizeWrapperWithDataAndContext(249 napi_env env, void* rawFinalizeData, void* rawContext) {250 if (rawFinalizeData == nullptr) return;251 252 ThreadSafeFinalize* finalizeData =253 static_cast<ThreadSafeFinalize*>(rawFinalizeData);254 finalizeData->callback(255 Env(env), finalizeData->data, static_cast<ContextType*>(rawContext));256 delete finalizeData;257 }258 259 FinalizerDataType* data;260 Finalizer callback;261};262 263template <typename ContextType, typename DataType, typename CallJs, CallJs call>264inline typename std::enable_if<call != static_cast<CallJs>(nullptr)>::type265CallJsWrapper(napi_env env, napi_value jsCallback, void* context, void* data) {266 details::WrapVoidCallback([&]() {267 call(env,268 Function(env, jsCallback),269 static_cast<ContextType*>(context),270 static_cast<DataType*>(data));271 });272}273 274template <typename ContextType, typename DataType, typename CallJs, CallJs call>275inline typename std::enable_if<call == static_cast<CallJs>(nullptr)>::type276CallJsWrapper(napi_env env,277 napi_value jsCallback,278 void* /*context*/,279 void* /*data*/) {280 details::WrapVoidCallback([&]() {281 if (jsCallback != nullptr) {282 Function(env, jsCallback).Call(0, nullptr);283 }284 });285}286 287#if NAPI_VERSION > 4288 289template <typename CallbackType, typename TSFN>290napi_value DefaultCallbackWrapper(napi_env /*env*/, std::nullptr_t /*cb*/) {291 return nullptr;292}293 294template <typename CallbackType, typename TSFN>295napi_value DefaultCallbackWrapper(napi_env /*env*/, Napi::Function cb) {296 return cb;297}298 299#else300template <typename CallbackType, typename TSFN>301napi_value DefaultCallbackWrapper(napi_env env, Napi::Function cb) {302 if (cb.IsEmpty()) {303 return TSFN::EmptyFunctionFactory(env);304 }305 return cb;306}307#endif // NAPI_VERSION > 4308#endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS309 310template <typename Getter, typename Setter>311struct AccessorCallbackData {312 static inline napi_value GetterWrapper(napi_env env,313 napi_callback_info info) {314 return details::WrapCallback([&] {315 CallbackInfo callbackInfo(env, info);316 AccessorCallbackData* callbackData =317 static_cast<AccessorCallbackData*>(callbackInfo.Data());318 callbackInfo.SetData(callbackData->data);319 return callbackData->getterCallback(callbackInfo);320 });321 }322 323 static inline napi_value SetterWrapper(napi_env env,324 napi_callback_info info) {325 return details::WrapCallback([&] {326 CallbackInfo callbackInfo(env, info);327 AccessorCallbackData* callbackData =328 static_cast<AccessorCallbackData*>(callbackInfo.Data());329 callbackInfo.SetData(callbackData->data);330 callbackData->setterCallback(callbackInfo);331 return nullptr;332 });333 }334 335 Getter getterCallback;336 Setter setterCallback;337 void* data;338};339 340} // namespace details341 342#ifndef NODE_ADDON_API_DISABLE_DEPRECATED343#include "napi-inl.deprecated.h"344#endif // !NODE_ADDON_API_DISABLE_DEPRECATED345 346////////////////////////////////////////////////////////////////////////////////347// Module registration348////////////////////////////////////////////////////////////////////////////////349 350// Register an add-on based on an initializer function.351#define NODE_API_MODULE(modname, regfunc) \352 static napi_value __napi_##regfunc(napi_env env, napi_value exports) { \353 return Napi::RegisterModule(env, exports, regfunc); \354 } \355 NAPI_MODULE(modname, __napi_##regfunc)356 357// Register an add-on based on a subclass of `Addon<T>` with a custom Node.js358// module name.359#define NODE_API_NAMED_ADDON(modname, classname) \360 static napi_value __napi_##classname(napi_env env, napi_value exports) { \361 return Napi::RegisterModule(env, exports, &classname::Init); \362 } \363 NAPI_MODULE(modname, __napi_##classname)364 365// Register an add-on based on a subclass of `Addon<T>` with the Node.js module366// name given by node-gyp from the `target_name` in binding.gyp.367#define NODE_API_ADDON(classname) \368 NODE_API_NAMED_ADDON(NODE_GYP_MODULE_NAME, classname)369 370// Adapt the NAPI_MODULE registration function:371// - Wrap the arguments in NAPI wrappers.372// - Catch any NAPI errors and rethrow as JS exceptions.373inline napi_value RegisterModule(napi_env env,374 napi_value exports,375 ModuleRegisterCallback registerCallback) {376 return details::WrapCallback([&] {377 return napi_value(378 registerCallback(Napi::Env(env), Napi::Object(env, exports)));379 });380}381 382////////////////////////////////////////////////////////////////////////////////383// Maybe class384////////////////////////////////////////////////////////////////////////////////385 386template <class T>387bool Maybe<T>::IsNothing() const {388 return !_has_value;389}390 391template <class T>392bool Maybe<T>::IsJust() const {393 return _has_value;394}395 396template <class T>397void Maybe<T>::Check() const {398 NAPI_CHECK(IsJust(), "Napi::Maybe::Check", "Maybe value is Nothing.");399}400 401template <class T>402T Maybe<T>::Unwrap() const {403 NAPI_CHECK(IsJust(), "Napi::Maybe::Unwrap", "Maybe value is Nothing.");404 return _value;405}406 407template <class T>408T Maybe<T>::UnwrapOr(const T& default_value) const {409 return _has_value ? _value : default_value;410}411 412template <class T>413bool Maybe<T>::UnwrapTo(T* out) const {414 if (IsJust()) {415 *out = _value;416 return true;417 };418 return false;419}420 421template <class T>422bool Maybe<T>::operator==(const Maybe& other) const {423 return (IsJust() == other.IsJust()) &&424 (!IsJust() || Unwrap() == other.Unwrap());425}426 427template <class T>428bool Maybe<T>::operator!=(const Maybe& other) const {429 return !operator==(other);430}431 432template <class T>433Maybe<T>::Maybe() : _has_value(false) {}434 435template <class T>436Maybe<T>::Maybe(const T& t) : _has_value(true), _value(t) {}437 438template <class T>439inline Maybe<T> Nothing() {440 return Maybe<T>();441}442 443template <class T>444inline Maybe<T> Just(const T& t) {445 return Maybe<T>(t);446}447 448////////////////////////////////////////////////////////////////////////////////449// Env class450////////////////////////////////////////////////////////////////////////////////451 452inline Env::Env(napi_env env) : _env(env) {}453 454inline Env::operator napi_env() const {455 return _env;456}457 458inline Object Env::Global() const {459 napi_value value;460 napi_status status = napi_get_global(*this, &value);461 NAPI_THROW_IF_FAILED(*this, status, Object());462 return Object(*this, value);463}464 465inline Value Env::Undefined() const {466 napi_value value;467 napi_status status = napi_get_undefined(*this, &value);468 NAPI_THROW_IF_FAILED(*this, status, Value());469 return Value(*this, value);470}471 472inline Value Env::Null() const {473 napi_value value;474 napi_status status = napi_get_null(*this, &value);475 NAPI_THROW_IF_FAILED(*this, status, Value());476 return Value(*this, value);477}478 479inline bool Env::IsExceptionPending() const {480 bool result;481 napi_status status = napi_is_exception_pending(_env, &result);482 if (status != napi_ok)483 result = false; // Checking for a pending exception shouldn't throw.484 return result;485}486 487inline Error Env::GetAndClearPendingException() const {488 napi_value value;489 napi_status status = napi_get_and_clear_last_exception(_env, &value);490 if (status != napi_ok) {491 // Don't throw another exception when failing to get the exception!492 return Error();493 }494 return Error(_env, value);495}496 497inline MaybeOrValue<Value> Env::RunScript(const char* utf8script) const {498 String script = String::New(_env, utf8script);499 return RunScript(script);500}501 502inline MaybeOrValue<Value> Env::RunScript(const std::string& utf8script) const {503 return RunScript(utf8script.c_str());504}505 506inline MaybeOrValue<Value> Env::RunScript(String script) const {507 napi_value result;508 napi_status status = napi_run_script(_env, script, &result);509 NAPI_RETURN_OR_THROW_IF_FAILED(510 _env, status, Napi::Value(_env, result), Napi::Value);511}512 513#if NAPI_VERSION > 2514template <typename Hook, typename Arg>515void Env::CleanupHook<Hook, Arg>::Wrapper(void* data) NAPI_NOEXCEPT {516 auto* cleanupData =517 static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(518 data);519 cleanupData->hook();520 delete cleanupData;521}522 523template <typename Hook, typename Arg>524void Env::CleanupHook<Hook, Arg>::WrapperWithArg(void* data) NAPI_NOEXCEPT {525 auto* cleanupData =526 static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(527 data);528 cleanupData->hook(static_cast<Arg*>(cleanupData->arg));529 delete cleanupData;530}531#endif // NAPI_VERSION > 2532 533#if NAPI_VERSION > 5534template <typename T, Env::Finalizer<T> fini>535inline void Env::SetInstanceData(T* data) const {536 napi_status status = napi_set_instance_data(537 _env,538 data,539 [](napi_env env, void* data, void*) { fini(env, static_cast<T*>(data)); },540 nullptr);541 NAPI_THROW_IF_FAILED_VOID(_env, status);542}543 544template <typename DataType,545 typename HintType,546 Napi::Env::FinalizerWithHint<DataType, HintType> fini>547inline void Env::SetInstanceData(DataType* data, HintType* hint) const {548 napi_status status = napi_set_instance_data(549 _env,550 data,551 [](napi_env env, void* data, void* hint) {552 fini(env, static_cast<DataType*>(data), static_cast<HintType*>(hint));553 },554 hint);555 NAPI_THROW_IF_FAILED_VOID(_env, status);556}557 558template <typename T>559inline T* Env::GetInstanceData() const {560 void* data = nullptr;561 562 napi_status status = napi_get_instance_data(_env, &data);563 NAPI_THROW_IF_FAILED(_env, status, nullptr);564 565 return static_cast<T*>(data);566}567 568template <typename T>569void Env::DefaultFini(Env, T* data) {570 delete data;571}572 573template <typename DataType, typename HintType>574void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) {575 delete data;576}577#endif // NAPI_VERSION > 5578 579#if NAPI_VERSION > 8580inline const char* Env::GetModuleFileName() const {581 const char* result;582 napi_status status = node_api_get_module_file_name(_env, &result);583 NAPI_THROW_IF_FAILED(*this, status, nullptr);584 return result;585}586#endif // NAPI_VERSION > 8587////////////////////////////////////////////////////////////////////////////////588// Value class589////////////////////////////////////////////////////////////////////////////////590 591inline Value::Value() : _env(nullptr), _value(nullptr) {}592 593inline Value::Value(napi_env env, napi_value value)594 : _env(env), _value(value) {}595 596inline Value::operator napi_value() const {597 return _value;598}599 600inline bool Value::operator==(const Value& other) const {601 return StrictEquals(other);602}603 604inline bool Value::operator!=(const Value& other) const {605 return !this->operator==(other);606}607 608inline bool Value::StrictEquals(const Value& other) const {609 bool result;610 napi_status status = napi_strict_equals(_env, *this, other, &result);611 NAPI_THROW_IF_FAILED(_env, status, false);612 return result;613}614 615inline Napi::Env Value::Env() const {616 return Napi::Env(_env);617}618 619inline bool Value::IsEmpty() const {620 return _value == nullptr;621}622 623inline napi_valuetype Value::Type() const {624 if (IsEmpty()) {625 return napi_undefined;626 }627 628 napi_valuetype type;629 napi_status status = napi_typeof(_env, _value, &type);630 NAPI_THROW_IF_FAILED(_env, status, napi_undefined);631 return type;632}633 634inline bool Value::IsUndefined() const {635 return Type() == napi_undefined;636}637 638inline bool Value::IsNull() const {639 return Type() == napi_null;640}641 642inline bool Value::IsBoolean() const {643 return Type() == napi_boolean;644}645 646inline bool Value::IsNumber() const {647 return Type() == napi_number;648}649 650#if NAPI_VERSION > 5651inline bool Value::IsBigInt() const {652 return Type() == napi_bigint;653}654#endif // NAPI_VERSION > 5655 656#if (NAPI_VERSION > 4)657inline bool Value::IsDate() const {658 if (IsEmpty()) {659 return false;660 }661 662 bool result;663 napi_status status = napi_is_date(_env, _value, &result);664 NAPI_THROW_IF_FAILED(_env, status, false);665 return result;666}667#endif668 669inline bool Value::IsString() const {670 return Type() == napi_string;671}672 673inline bool Value::IsSymbol() const {674 return Type() == napi_symbol;675}676 677inline bool Value::IsArray() const {678 if (IsEmpty()) {679 return false;680 }681 682 bool result;683 napi_status status = napi_is_array(_env, _value, &result);684 NAPI_THROW_IF_FAILED(_env, status, false);685 return result;686}687 688inline bool Value::IsArrayBuffer() const {689 if (IsEmpty()) {690 return false;691 }692 693 bool result;694 napi_status status = napi_is_arraybuffer(_env, _value, &result);695 NAPI_THROW_IF_FAILED(_env, status, false);696 return result;697}698 699inline bool Value::IsTypedArray() const {700 if (IsEmpty()) {701 return false;702 }703 704 bool result;705 napi_status status = napi_is_typedarray(_env, _value, &result);706 NAPI_THROW_IF_FAILED(_env, status, false);707 return result;708}709 710inline bool Value::IsObject() const {711 return Type() == napi_object || IsFunction();712}713 714inline bool Value::IsFunction() const {715 return Type() == napi_function;716}717 718inline bool Value::IsPromise() const {719 if (IsEmpty()) {720 return false;721 }722 723 bool result;724 napi_status status = napi_is_promise(_env, _value, &result);725 NAPI_THROW_IF_FAILED(_env, status, false);726 return result;727}728 729inline bool Value::IsDataView() const {730 if (IsEmpty()) {731 return false;732 }733 734 bool result;735 napi_status status = napi_is_dataview(_env, _value, &result);736 NAPI_THROW_IF_FAILED(_env, status, false);737 return result;738}739 740inline bool Value::IsBuffer() const {741 if (IsEmpty()) {742 return false;743 }744 745 bool result;746 napi_status status = napi_is_buffer(_env, _value, &result);747 NAPI_THROW_IF_FAILED(_env, status, false);748 return result;749}750 751inline bool Value::IsExternal() const {752 return Type() == napi_external;753}754 755template <typename T>756inline T Value::As() const {757#ifdef NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS758 T::CheckCast(_env, _value);759#endif760 return T(_env, _value);761}762 763inline MaybeOrValue<Boolean> Value::ToBoolean() const {764 napi_value result;765 napi_status status = napi_coerce_to_bool(_env, _value, &result);766 NAPI_RETURN_OR_THROW_IF_FAILED(767 _env, status, Napi::Boolean(_env, result), Napi::Boolean);768}769 770inline MaybeOrValue<Number> Value::ToNumber() const {771 napi_value result;772 napi_status status = napi_coerce_to_number(_env, _value, &result);773 NAPI_RETURN_OR_THROW_IF_FAILED(774 _env, status, Napi::Number(_env, result), Napi::Number);775}776 777inline MaybeOrValue<String> Value::ToString() const {778 napi_value result;779 napi_status status = napi_coerce_to_string(_env, _value, &result);780 NAPI_RETURN_OR_THROW_IF_FAILED(781 _env, status, Napi::String(_env, result), Napi::String);782}783 784inline MaybeOrValue<Object> Value::ToObject() const {785 napi_value result;786 napi_status status = napi_coerce_to_object(_env, _value, &result);787 NAPI_RETURN_OR_THROW_IF_FAILED(788 _env, status, Napi::Object(_env, result), Napi::Object);789}790 791////////////////////////////////////////////////////////////////////////////////792// Boolean class793////////////////////////////////////////////////////////////////////////////////794 795inline Boolean Boolean::New(napi_env env, bool val) {796 napi_value value;797 napi_status status = napi_get_boolean(env, val, &value);798 NAPI_THROW_IF_FAILED(env, status, Boolean());799 return Boolean(env, value);800}801 802inline void Boolean::CheckCast(napi_env env, napi_value value) {803 NAPI_CHECK(value != nullptr, "Boolean::CheckCast", "empty value");804 805 napi_valuetype type;806 napi_status status = napi_typeof(env, value, &type);807 NAPI_CHECK(status == napi_ok, "Boolean::CheckCast", "napi_typeof failed");808 NAPI_CHECK(809 type == napi_boolean, "Boolean::CheckCast", "value is not napi_boolean");810}811 812inline Boolean::Boolean() : Napi::Value() {}813 814inline Boolean::Boolean(napi_env env, napi_value value)815 : Napi::Value(env, value) {}816 817inline Boolean::operator bool() const {818 return Value();819}820 821inline bool Boolean::Value() const {822 bool result;823 napi_status status = napi_get_value_bool(_env, _value, &result);824 NAPI_THROW_IF_FAILED(_env, status, false);825 return result;826}827 828////////////////////////////////////////////////////////////////////////////////829// Number class830////////////////////////////////////////////////////////////////////////////////831 832inline Number Number::New(napi_env env, double val) {833 napi_value value;834 napi_status status = napi_create_double(env, val, &value);835 NAPI_THROW_IF_FAILED(env, status, Number());836 return Number(env, value);837}838 839inline void Number::CheckCast(napi_env env, napi_value value) {840 NAPI_CHECK(value != nullptr, "Number::CheckCast", "empty value");841 842 napi_valuetype type;843 napi_status status = napi_typeof(env, value, &type);844 NAPI_CHECK(status == napi_ok, "Number::CheckCast", "napi_typeof failed");845 NAPI_CHECK(846 type == napi_number, "Number::CheckCast", "value is not napi_number");847}848 849inline Number::Number() : Value() {}850 851inline Number::Number(napi_env env, napi_value value) : Value(env, value) {}852 853inline Number::operator int32_t() const {854 return Int32Value();855}856 857inline Number::operator uint32_t() const {858 return Uint32Value();859}860 861inline Number::operator int64_t() const {862 return Int64Value();863}864 865inline Number::operator float() const {866 return FloatValue();867}868 869inline Number::operator double() const {870 return DoubleValue();871}872 873inline int32_t Number::Int32Value() const {874 int32_t result;875 napi_status status = napi_get_value_int32(_env, _value, &result);876 NAPI_THROW_IF_FAILED(_env, status, 0);877 return result;878}879 880inline uint32_t Number::Uint32Value() const {881 uint32_t result;882 napi_status status = napi_get_value_uint32(_env, _value, &result);883 NAPI_THROW_IF_FAILED(_env, status, 0);884 return result;885}886 887inline int64_t Number::Int64Value() const {888 int64_t result;889 napi_status status = napi_get_value_int64(_env, _value, &result);890 NAPI_THROW_IF_FAILED(_env, status, 0);891 return result;892}893 894inline float Number::FloatValue() const {895 return static_cast<float>(DoubleValue());896}897 898inline double Number::DoubleValue() const {899 double result;900 napi_status status = napi_get_value_double(_env, _value, &result);901 NAPI_THROW_IF_FAILED(_env, status, 0);902 return result;903}904 905#if NAPI_VERSION > 5906////////////////////////////////////////////////////////////////////////////////907// BigInt Class908////////////////////////////////////////////////////////////////////////////////909 910inline BigInt BigInt::New(napi_env env, int64_t val) {911 napi_value value;912 napi_status status = napi_create_bigint_int64(env, val, &value);913 NAPI_THROW_IF_FAILED(env, status, BigInt());914 return BigInt(env, value);915}916 917inline BigInt BigInt::New(napi_env env, uint64_t val) {918 napi_value value;919 napi_status status = napi_create_bigint_uint64(env, val, &value);920 NAPI_THROW_IF_FAILED(env, status, BigInt());921 return BigInt(env, value);922}923 924inline BigInt BigInt::New(napi_env env,925 int sign_bit,926 size_t word_count,927 const uint64_t* words) {928 napi_value value;929 napi_status status =930 napi_create_bigint_words(env, sign_bit, word_count, words, &value);931 NAPI_THROW_IF_FAILED(env, status, BigInt());932 return BigInt(env, value);933}934 935inline void BigInt::CheckCast(napi_env env, napi_value value) {936 NAPI_CHECK(value != nullptr, "BigInt::CheckCast", "empty value");937 938 napi_valuetype type;939 napi_status status = napi_typeof(env, value, &type);940 NAPI_CHECK(status == napi_ok, "BigInt::CheckCast", "napi_typeof failed");941 NAPI_CHECK(942 type == napi_bigint, "BigInt::CheckCast", "value is not napi_bigint");943}944 945inline BigInt::BigInt() : Value() {}946 947inline BigInt::BigInt(napi_env env, napi_value value) : Value(env, value) {}948 949inline int64_t BigInt::Int64Value(bool* lossless) const {950 int64_t result;951 napi_status status =952 napi_get_value_bigint_int64(_env, _value, &result, lossless);953 NAPI_THROW_IF_FAILED(_env, status, 0);954 return result;955}956 957inline uint64_t BigInt::Uint64Value(bool* lossless) const {958 uint64_t result;959 napi_status status =960 napi_get_value_bigint_uint64(_env, _value, &result, lossless);961 NAPI_THROW_IF_FAILED(_env, status, 0);962 return result;963}964 965inline size_t BigInt::WordCount() const {966 size_t word_count;967 napi_status status =968 napi_get_value_bigint_words(_env, _value, nullptr, &word_count, nullptr);969 NAPI_THROW_IF_FAILED(_env, status, 0);970 return word_count;971}972 973inline void BigInt::ToWords(int* sign_bit,974 size_t* word_count,975 uint64_t* words) {976 napi_status status =977 napi_get_value_bigint_words(_env, _value, sign_bit, word_count, words);978 NAPI_THROW_IF_FAILED_VOID(_env, status);979}980#endif // NAPI_VERSION > 5981 982#if (NAPI_VERSION > 4)983////////////////////////////////////////////////////////////////////////////////984// Date Class985////////////////////////////////////////////////////////////////////////////////986 987inline Date Date::New(napi_env env, double val) {988 napi_value value;989 napi_status status = napi_create_date(env, val, &value);990 NAPI_THROW_IF_FAILED(env, status, Date());991 return Date(env, value);992}993 994inline void Date::CheckCast(napi_env env, napi_value value) {995 NAPI_CHECK(value != nullptr, "Date::CheckCast", "empty value");996 997 bool result;998 napi_status status = napi_is_date(env, value, &result);999 NAPI_CHECK(status == napi_ok, "Date::CheckCast", "napi_is_date failed");1000 NAPI_CHECK(result, "Date::CheckCast", "value is not date");1001}1002 1003inline Date::Date() : Value() {}1004 1005inline Date::Date(napi_env env, napi_value value) : Value(env, value) {}1006 1007inline Date::operator double() const {1008 return ValueOf();1009}1010 1011inline double Date::ValueOf() const {1012 double result;1013 napi_status status = napi_get_date_value(_env, _value, &result);1014 NAPI_THROW_IF_FAILED(_env, status, 0);1015 return result;1016}1017#endif1018 1019////////////////////////////////////////////////////////////////////////////////1020// Name class1021////////////////////////////////////////////////////////////////////////////////1022inline void Name::CheckCast(napi_env env, napi_value value) {1023 NAPI_CHECK(value != nullptr, "Name::CheckCast", "empty value");1024 1025 napi_valuetype type;1026 napi_status status = napi_typeof(env, value, &type);1027 NAPI_CHECK(status == napi_ok, "Name::CheckCast", "napi_typeof failed");1028 NAPI_CHECK(type == napi_string || type == napi_symbol,1029 "Name::CheckCast",1030 "value is not napi_string or napi_symbol");1031}1032 1033inline Name::Name() : Value() {}1034 1035inline Name::Name(napi_env env, napi_value value) : Value(env, value) {}1036 1037////////////////////////////////////////////////////////////////////////////////1038// String class1039////////////////////////////////////////////////////////////////////////////////1040 1041inline String String::New(napi_env env, const std::string& val) {1042 return String::New(env, val.c_str(), val.size());1043}1044 1045inline String String::New(napi_env env, const std::u16string& val) {1046 return String::New(env, val.c_str(), val.size());1047}1048 1049inline String String::New(napi_env env, const char* val) {1050 // TODO(@gabrielschulhof) Remove if-statement when core's error handling is1051 // available in all supported versions.1052 if (val == nullptr) {1053 // Throw an error that looks like it came from core.1054 NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());1055 }1056 napi_value value;1057 napi_status status =1058 napi_create_string_utf8(env, val, std::strlen(val), &value);1059 NAPI_THROW_IF_FAILED(env, status, String());1060 return String(env, value);1061}1062 1063inline String String::New(napi_env env, const char16_t* val) {1064 napi_value value;1065 // TODO(@gabrielschulhof) Remove if-statement when core's error handling is1066 // available in all supported versions.1067 if (val == nullptr) {1068 // Throw an error that looks like it came from core.1069 NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());1070 }1071 napi_status status =1072 napi_create_string_utf16(env, val, std::u16string(val).size(), &value);1073 NAPI_THROW_IF_FAILED(env, status, String());1074 return String(env, value);1075}1076 1077inline String String::New(napi_env env, const char* val, size_t length) {1078 napi_value value;1079 napi_status status = napi_create_string_utf8(env, val, length, &value);1080 NAPI_THROW_IF_FAILED(env, status, String());1081 return String(env, value);1082}1083 1084inline String String::New(napi_env env, const char16_t* val, size_t length) {1085 napi_value value;1086 napi_status status = napi_create_string_utf16(env, val, length, &value);1087 NAPI_THROW_IF_FAILED(env, status, String());1088 return String(env, value);1089}1090 1091inline void String::CheckCast(napi_env env, napi_value value) {1092 NAPI_CHECK(value != nullptr, "String::CheckCast", "empty value");1093 1094 napi_valuetype type;1095 napi_status status = napi_typeof(env, value, &type);1096 NAPI_CHECK(status == napi_ok, "String::CheckCast", "napi_typeof failed");1097 NAPI_CHECK(1098 type == napi_string, "String::CheckCast", "value is not napi_string");1099}1100 1101inline String::String() : Name() {}1102 1103inline String::String(napi_env env, napi_value value) : Name(env, value) {}1104 1105inline String::operator std::string() const {1106 return Utf8Value();1107}1108 1109inline String::operator std::u16string() const {1110 return Utf16Value();1111}1112 1113inline std::string String::Utf8Value() const {1114 size_t length;1115 napi_status status =1116 napi_get_value_string_utf8(_env, _value, nullptr, 0, &length);1117 NAPI_THROW_IF_FAILED(_env, status, "");1118 1119 std::string value;1120 value.reserve(length + 1);1121 value.resize(length);1122 status = napi_get_value_string_utf8(1123 _env, _value, &value[0], value.capacity(), nullptr);1124 NAPI_THROW_IF_FAILED(_env, status, "");1125 return value;1126}1127 1128inline std::u16string String::Utf16Value() const {1129 size_t length;1130 napi_status status =1131 napi_get_value_string_utf16(_env, _value, nullptr, 0, &length);1132 NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT(""));1133 1134 std::u16string value;1135 value.reserve(length + 1);1136 value.resize(length);1137 status = napi_get_value_string_utf16(1138 _env, _value, &value[0], value.capacity(), nullptr);1139 NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT(""));1140 return value;1141}1142 1143////////////////////////////////////////////////////////////////////////////////1144// Symbol class1145////////////////////////////////////////////////////////////////////////////////1146 1147inline Symbol Symbol::New(napi_env env, const char* description) {1148 napi_value descriptionValue = description != nullptr1149 ? String::New(env, description)1150 : static_cast<napi_value>(nullptr);1151 return Symbol::New(env, descriptionValue);1152}1153 1154inline Symbol Symbol::New(napi_env env, const std::string& description) {1155 napi_value descriptionValue = String::New(env, description);1156 return Symbol::New(env, descriptionValue);1157}1158 1159inline Symbol Symbol::New(napi_env env, String description) {1160 napi_value descriptionValue = description;1161 return Symbol::New(env, descriptionValue);1162}1163 1164inline Symbol Symbol::New(napi_env env, napi_value description) {1165 napi_value value;1166 napi_status status = napi_create_symbol(env, description, &value);1167 NAPI_THROW_IF_FAILED(env, status, Symbol());1168 return Symbol(env, value);1169}1170 1171inline MaybeOrValue<Symbol> Symbol::WellKnown(napi_env env,1172 const std::string& name) {1173#if defined(NODE_ADDON_API_ENABLE_MAYBE)1174 Value symbol_obj;1175 Value symbol_value;1176 if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&1177 symbol_obj.As<Object>().Get(name).UnwrapTo(&symbol_value)) {1178 return Just<Symbol>(symbol_value.As<Symbol>());1179 }1180 return Nothing<Symbol>();1181#else1182 return Napi::Env(env)1183 .Global()1184 .Get("Symbol")1185 .As<Object>()1186 .Get(name)1187 .As<Symbol>();1188#endif1189}1190 1191inline MaybeOrValue<Symbol> Symbol::For(napi_env env,1192 const std::string& description) {1193 napi_value descriptionValue = String::New(env, description);1194 return Symbol::For(env, descriptionValue);1195}1196 1197inline MaybeOrValue<Symbol> Symbol::For(napi_env env, const char* description) {1198 napi_value descriptionValue = String::New(env, description);1199 return Symbol::For(env, descriptionValue);1200}