| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9cedaa6 commit dc3d70c
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -825,6 +825,58 @@ void Reference::WeakCallback(const v8::WeakCallbackInfo<Reference>& data) { | |||
| 825 | 825 | reference->env_->InvokeFinalizerFromGC(reference); | |
| 826 | 826 | } | |
| 827 | 827 | ||
| 828 | + /** | ||
| 829 | + * A wrapper for `v8::External` to support type-tagging. `v8::External` doesn't | ||
| 830 | + * support defining any properties and private properties on it, even though it | ||
| 831 | + * is an object. This wrapper is used to store the type tag and the data of the | ||
| 832 | + * external value. | ||
| 833 | + */ | ||
| 834 | + class ExternalWrapper { | ||
| 835 | + private: | ||
| 836 | + explicit ExternalWrapper(void* data) : data_(data) {} | ||
| 837 | + | ||
| 838 | + static void WeakCallback(const v8::WeakCallbackInfo<ExternalWrapper>& data) { | ||
| 839 | + ExternalWrapper* wrapper = data.GetParameter(); | ||
| 840 | + delete wrapper; | ||
| 841 | + } | ||
| 842 | + | ||
| 843 | + public: | ||
| 844 | + static v8::Local<v8::External> New(napi_env env, void* data) { | ||
| 845 | + ExternalWrapper* wrapper = new ExternalWrapper(data); | ||
| 846 | + v8::Local<v8::External> external = v8::External::New(env->isolate, wrapper); | ||
| 847 | + wrapper->persistent_.Reset(env->isolate, external); | ||
| 848 | + wrapper->persistent_.SetWeak( | ||
| 849 | + wrapper, WeakCallback, v8::WeakCallbackType::kParameter); | ||
| 850 | + | ||
| 851 | + return external; | ||
| 852 | + } | ||
| 853 | + | ||
| 854 | + static ExternalWrapper* From(v8::Local<v8::External> external) { | ||
| 855 | + return static_cast<ExternalWrapper*>(external->Value()); | ||
| 856 | + } | ||
| 857 | + | ||
| 858 | + void* Data() { return data_; } | ||
| 859 | + | ||
| 860 | + bool TypeTag(const napi_type_tag* type_tag) { | ||
| 861 | + if (type_tag_ != nullptr) { | ||
| 862 | + return false; | ||
| 863 | + } | ||
| 864 | + type_tag_ = type_tag; | ||
| 865 | + return true; | ||
| 866 | + } | ||
| 867 | + | ||
| 868 | + bool CheckTypeTag(const napi_type_tag* type_tag) { | ||
| 869 | + return type_tag == type_tag_ || | ||
| 870 | + (type_tag_ && type_tag->lower == type_tag_->lower && | ||
| 871 | + type_tag->upper == type_tag_->upper); | ||
| 872 | + } | ||
| 873 | + | ||
| 874 | + private: | ||
| 875 | + v8impl::Persistent<v8::Value> persistent_; | ||
| 876 | + void* data_; | ||
| 877 | + const napi_type_tag* type_tag_ = nullptr; | ||
| 878 | + }; | ||
| 879 | + | ||
| 828 | 880 | } // end of namespace v8impl | |
| 829 | 881 | ||
| 830 | 882 | // Warning: Keep in-sync with napi_status enum | |
@@ -2532,9 +2584,8 @@ napi_create_external(napi_env env, | |||
| 2532 | 2584 | NAPI_PREAMBLE(env); | |
| 2533 | 2585 | CHECK_ARG(env, result); | |
| 2534 | 2586 | ||
| 2535 | - v8::Isolate* isolate = env->isolate; | ||
| 2536 | - | ||
| 2537 | - v8::Local<v8::Value> external_value = v8::External::New(isolate, data); | ||
| 2587 | + v8::Local<v8::External> external_value = | ||
| 2588 | + v8impl::ExternalWrapper::New(env, data); | ||
| 2538 | 2589 | ||
| 2539 | 2590 | if (finalize_cb) { | |
| 2540 | 2591 | // The Reference object will delete itself after invoking the finalizer | |
@@ -2554,12 +2605,24 @@ napi_create_external(napi_env env, | |||
| 2554 | 2605 | } | |
| 2555 | 2606 | ||
| 2556 | 2607 | napi_status NAPI_CDECL napi_type_tag_object(napi_env env, | |
| 2557 | - napi_value object, | ||
| 2608 | + napi_value object_or_external, | ||
| 2558 | 2609 | const napi_type_tag* type_tag) { | |
| 2559 | 2610 | NAPI_PREAMBLE(env); | |
| 2560 | 2611 | v8::Local<v8::Context> context = env->context(); | |
| 2612 | + | ||
| 2613 | + CHECK_ARG(env, object_or_external); | ||
| 2614 | + v8::Local<v8::Value> val = | ||
| 2615 | + v8impl::V8LocalValueFromJsValue(object_or_external); | ||
| 2616 | + if (val->IsExternal()) { | ||
| 2617 | + v8impl::ExternalWrapper* wrapper = | ||
| 2618 | + v8impl::ExternalWrapper::From(val.As<v8::External>()); | ||
| 2619 | + RETURN_STATUS_IF_FALSE_WITH_PREAMBLE( | ||
| 2620 | + env, wrapper->TypeTag(type_tag), napi_invalid_arg); | ||
| 2621 | + return GET_RETURN_STATUS(env); | ||
| 2622 | + } | ||
| 2623 | + | ||
| 2561 | 2624 | v8::Local<v8::Object> obj; | |
| 2562 | - CHECK_TO_OBJECT_WITH_PREAMBLE(env, context, obj, object); | ||
| 2625 | + CHECK_TO_OBJECT_WITH_PREAMBLE(env, context, obj, object_or_external); | ||
| 2563 | 2626 | CHECK_ARG_WITH_PREAMBLE(env, type_tag); | |
| 2564 | 2627 | ||
| 2565 | 2628 | auto key = NAPI_PRIVATE_KEY(context, type_tag); | |
@@ -2581,13 +2644,24 @@ napi_status NAPI_CDECL napi_type_tag_object(napi_env env, | |||
| 2581 | 2644 | } | |
| 2582 | 2645 | ||
| 2583 | 2646 | napi_status NAPI_CDECL napi_check_object_type_tag(napi_env env, | |
| 2584 | - napi_value object, | ||
| 2647 | + napi_value object_or_external, | ||
| 2585 | 2648 | const napi_type_tag* type_tag, | |
| 2586 | 2649 | bool* result) { | |
| 2587 | 2650 | NAPI_PREAMBLE(env); | |
| 2588 | 2651 | v8::Local<v8::Context> context = env->context(); | |
| 2652 | + | ||
| 2653 | + CHECK_ARG(env, object_or_external); | ||
| 2654 | + v8::Local<v8::Value> obj_val = | ||
| 2655 | + v8impl::V8LocalValueFromJsValue(object_or_external); | ||
| 2656 | + if (obj_val->IsExternal()) { | ||
| 2657 | + v8impl::ExternalWrapper* wrapper = | ||
| 2658 | + v8impl::ExternalWrapper::From(obj_val.As<v8::External>()); | ||
| 2659 | + *result = wrapper->CheckTypeTag(type_tag); | ||
| 2660 | + return GET_RETURN_STATUS(env); | ||
| 2661 | + } | ||
| 2662 | + | ||
| 2589 | 2663 | v8::Local<v8::Object> obj; | |
| 2590 | - CHECK_TO_OBJECT_WITH_PREAMBLE(env, context, obj, object); | ||
| 2664 | + CHECK_TO_OBJECT_WITH_PREAMBLE(env, context, obj, object_or_external); | ||
| 2591 | 2665 | CHECK_ARG_WITH_PREAMBLE(env, type_tag); | |
| 2592 | 2666 | CHECK_ARG_WITH_PREAMBLE(env, result); | |
| 2593 | 2667 | ||
@@ -2632,7 +2706,7 @@ napi_status NAPI_CDECL napi_get_value_external(napi_env env, | |||
| 2632 | 2706 | RETURN_STATUS_IF_FALSE(env, val->IsExternal(), napi_invalid_arg); | |
| 2633 | 2707 | ||
| 2634 | 2708 | v8::Local<v8::External> external_value = val.As<v8::External>(); | |
| 2635 | - *result = external_value->Value(); | ||
| 2709 | + *result = v8impl::ExternalWrapper::From(external_value)->Data(); | ||
| 2636 | 2710 | ||
| 2637 | 2711 | return napi_clear_last_error(env); | |
| 2638 | 2712 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -250,7 +250,8 @@ napi_value NapiLinkedWithInstanceData(napi_env env, napi_value exports) { | |||
| 250 | 250 | napi_value key, value; | |
| 251 | 251 | CHECK_EQ(napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &key), | |
| 252 | 252 | napi_ok); | |
| 253 | - CHECK_EQ(napi_create_external(env, instance_data, nullptr, nullptr, &value), | ||
| 253 | + CHECK_EQ(napi_create_external_arraybuffer( | ||
| 254 | + env, instance_data, 1, nullptr, nullptr, &value), | ||
| 254 | 255 | napi_ok); | |
| 255 | 256 | CHECK_EQ(napi_set_property(env, exports, key, value), napi_ok); | |
| 256 | 257 | return nullptr; | |
@@ -289,9 +290,9 @@ TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingNapiInstanceDataTest) { | |||
| 289 | 290 | .ToLocalChecked(); | |
| 290 | 291 | v8::Local<v8::Value> completion_value = | |
| 291 | 292 | script->Run(context).ToLocalChecked(); | |
| 292 | - CHECK(completion_value->IsExternal()); | ||
| 293 | + CHECK(completion_value->IsArrayBuffer()); | ||
| 293 | 294 | instance_data = | |
| 294 | - static_cast<int*>(completion_value.As<v8::External>()->Value()); | ||
| 295 | + static_cast<int*>(completion_value.As<v8::ArrayBuffer>()->Data()); | ||
| 295 | 296 | CHECK_NE(instance_data, nullptr); | |
| 296 | 297 | CHECK_EQ(*instance_data, 0); | |
| 297 | 298 | } | |
@@ -327,9 +328,9 @@ TEST_F(LinkedBindingTest, | |||
| 327 | 328 | .ToLocalChecked(); | |
| 328 | 329 | v8::Local<v8::Value> completion_value = | |
| 329 | 330 | script->Run(context).ToLocalChecked(); | |
| 330 | - CHECK(completion_value->IsExternal()); | ||
| 331 | + CHECK(completion_value->IsArrayBuffer()); | ||
| 331 | 332 | instance_data = | |
| 332 | - static_cast<int*>(completion_value.As<v8::External>()->Value()); | ||
| 333 | + static_cast<int*>(completion_value.As<v8::ArrayBuffer>()->Data()); | ||
| 333 | 334 | CHECK_NE(instance_data, nullptr); | |
| 334 | 335 | CHECK_EQ(*instance_data, 0); | |
| 335 | 336 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments