| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent fdcd775 commit faaccfb
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -25,6 +25,7 @@ using v8::MaybeLocal; | |||
| 25 | 25 | using v8::NewStringType; | |
| 26 | 26 | using v8::Number; | |
| 27 | 27 | using v8::Object; | |
| 28 | + using v8::SharedArrayBuffer; | ||
| 28 | 29 | using v8::String; | |
| 29 | 30 | using v8::Value; | |
| 30 | 31 | ||
@@ -675,26 +676,17 @@ void ExportBytes(const FunctionCallbackInfo<Value>& args) { | |||
| 675 | 676 | return; | |
| 676 | 677 | } | |
| 677 | 678 | ||
| 678 | - const uint8_t* source_data = nullptr; | ||
| 679 | - size_t source_len = 0; | ||
| 679 | + // This needs to be kept alive until the data | ||
| 680 | + // is actually copied. | ||
| 681 | + ArrayBufferViewContents<uint8_t> view; | ||
| 680 | 682 | ||
| 681 | - if (args[0]->IsArrayBuffer()) { | ||
| 682 | - Local<ArrayBuffer> array_buffer = args[0].As<ArrayBuffer>(); | ||
| 683 | - std::shared_ptr<BackingStore> store = array_buffer->GetBackingStore(); | ||
| 684 | - if (!store) { | ||
| 685 | - THROW_ERR_INVALID_ARG_VALUE(env, "Invalid ArrayBuffer backing store"); | ||
| 686 | - return; | ||
| 687 | - } | ||
| 688 | - source_data = static_cast<const uint8_t*>(store->Data()); | ||
| 689 | - source_len = array_buffer->ByteLength(); | ||
| 690 | - } else if (args[0]->IsArrayBufferView()) { | ||
| 691 | - ArrayBufferViewContents<uint8_t> view(args[0]); | ||
| 683 | + if (args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer() || | ||
| 684 | + args[0]->IsArrayBufferView()) { | ||
| 685 | + view.ReadValue(args[0]); | ||
| 692 | 686 | if (view.WasDetached()) { | |
| 693 | 687 | THROW_ERR_INVALID_ARG_VALUE(env, "Invalid ArrayBufferView backing store"); | |
| 694 | 688 | return; | |
| 695 | 689 | } | |
| 696 | - source_data = view.data(); | ||
| 697 | - source_len = view.length(); | ||
| 698 | 690 | } else { | |
| 699 | 691 | THROW_ERR_INVALID_ARG_TYPE( | |
| 700 | 692 | env, | |
@@ -713,12 +705,12 @@ void ExportBytes(const FunctionCallbackInfo<Value>& args) { | |||
| 713 | 705 | return; | |
| 714 | 706 | } | |
| 715 | 707 | ||
| 716 | - if (len < source_len) { | ||
| 708 | + if (len < view.length()) { | ||
| 717 | 709 | THROW_ERR_OUT_OF_RANGE(env, "The length must be >= source byte length"); | |
| 718 | 710 | return; | |
| 719 | 711 | } | |
| 720 | 712 | ||
| 721 | - if (ptr == 0 && source_len > 0) { | ||
| 713 | + if (ptr == 0 && view.length() > 0) { | ||
| 722 | 714 | THROW_ERR_FFI_INVALID_POINTER(env, | |
| 723 | 715 | "Cannot create a buffer from a null pointer"); | |
| 724 | 716 | return; | |
@@ -733,9 +725,7 @@ void ExportBytes(const FunctionCallbackInfo<Value>& args) { | |||
| 733 | 725 | return; | |
| 734 | 726 | } | |
| 735 | 727 | ||
| 736 | - if (source_len > 0) { | ||
| 737 | - std::memcpy(reinterpret_cast<void*>(ptr), source_data, source_len); | ||
| 738 | - } | ||
| 728 | + std::memcpy(reinterpret_cast<void*>(ptr), view.data(), view.length()); | ||
| 739 | 729 | } | |
| 740 | 730 | ||
| 741 | 731 | void GetRawPointer(const FunctionCallbackInfo<Value>& args) { | |
@@ -752,28 +742,34 @@ void GetRawPointer(const FunctionCallbackInfo<Value>& args) { | |||
| 752 | 742 | } | |
| 753 | 743 | ||
| 754 | 744 | uintptr_t ptr = 0; | |
| 745 | + size_t offset = 0; | ||
| 746 | + std::shared_ptr<BackingStore> store; | ||
| 755 | 747 | ||
| 756 | 748 | if (args[0]->IsArrayBuffer()) { | |
| 757 | - Local<ArrayBuffer> array_buffer = args[0].As<ArrayBuffer>(); | ||
| 758 | - std::shared_ptr<BackingStore> store = array_buffer->GetBackingStore(); | ||
| 759 | - if (!store) { | ||
| 760 | - THROW_ERR_INVALID_ARG_VALUE(env, "Invalid ArrayBuffer backing store"); | ||
| 761 | - return; | ||
| 762 | - } | ||
| 763 | - ptr = reinterpret_cast<uintptr_t>(store->Data()); | ||
| 749 | + store = args[0].As<ArrayBuffer>()->GetBackingStore(); | ||
| 750 | + } else if (args[0]->IsSharedArrayBuffer()) { | ||
| 751 | + store = args[0].As<SharedArrayBuffer>()->GetBackingStore(); | ||
| 764 | 752 | } else if (args[0]->IsArrayBufferView()) { | |
| 765 | - ArrayBufferViewContents<uint8_t> view(args[0]); | ||
| 766 | - if (view.WasDetached()) { | ||
| 767 | - THROW_ERR_INVALID_ARG_VALUE(env, "Invalid ArrayBufferView backing store"); | ||
| 768 | - return; | ||
| 769 | - } | ||
| 770 | - ptr = reinterpret_cast<uintptr_t>(view.data()); | ||
| 753 | + // Access the store here to ensure that it exists. Small typed arrays | ||
| 754 | + // may not have a store until this point and can instead be stored | ||
| 755 | + // entirely in-heap. | ||
| 756 | + store = args[0].As<ArrayBufferView>()->Buffer()->GetBackingStore(); | ||
| 757 | + offset = args[0].As<ArrayBufferView>()->ByteOffset(); | ||
| 771 | 758 | } else { | |
| 772 | - THROW_ERR_INVALID_ARG_TYPE( | ||
| 773 | - env, | ||
| 774 | - "The first argument must be a Buffer, ArrayBuffer, or ArrayBufferView"); | ||
| 759 | + THROW_ERR_INVALID_ARG_TYPE(env, | ||
| 760 | + "The first argument must be a Buffer, " | ||
| 761 | + "ArrayBuffer, or ArrayBufferView"); | ||
| 762 | + return; | ||
| 763 | + } | ||
| 764 | + | ||
| 765 | + // WARNING: There is no inherent guarantee that the pointer returned | ||
| 766 | + // from this function will be valid beyond the lifetime of the BackingStore | ||
| 767 | + // instance! | ||
| 768 | + if (!store) { | ||
| 769 | + THROW_ERR_INVALID_ARG_VALUE(env, "Invalid ArrayBuffer backing store"); | ||
| 775 | 770 | return; | |
| 776 | 771 | } | |
| 772 | + ptr = reinterpret_cast<uintptr_t>(store->Data()) + offset; | ||
| 777 | 773 | ||
| 778 | 774 | args.GetReturnValue().Set( | |
| 779 | 775 | BigInt::NewFromUnsigned(isolate, static_cast<uint64_t>(ptr))); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments