forked from mirrors/gecko-dev
		
	 68119ed2dd
			
		
	
	
		68119ed2dd
		
	
	
	
	
		
			
			- There's no need for the i32 bounds check, since the field is now a u64. - It's simpler to clone the pointer outside of the ProcessData call and not have to do any GC shenanigans. - Use newer C++ constructor code so that static-analysis doesn't complain. Differential Revision: https://phabricator.services.mozilla.com/D208517
		
			
				
	
	
		
			96 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim:set ts=2 sw=2 sts=2 et cindent: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "nsString.h"
 | |
| #include "mozilla/dom/OwnedRustBuffer.h"
 | |
| 
 | |
| namespace mozilla::uniffi {
 | |
| 
 | |
| using dom::ArrayBuffer;
 | |
| 
 | |
| OwnedRustBuffer::OwnedRustBuffer(const RustBuffer& aBuf) : mBuf(aBuf) {
 | |
|   MOZ_ASSERT(IsValid());
 | |
| }
 | |
| 
 | |
| Result<OwnedRustBuffer, nsCString> OwnedRustBuffer::FromArrayBuffer(
 | |
|     const ArrayBuffer& aArrayBuffer) {
 | |
|   return aArrayBuffer.ProcessData(
 | |
|       [](const Span<uint8_t>& aData,
 | |
|          JS::AutoCheckCannotGC&&) -> Result<OwnedRustBuffer, nsCString> {
 | |
|         uint64_t bufLen = aData.Length();
 | |
|         RustCallStatus status{};
 | |
|         RustBuffer buf =
 | |
|             uniffi_rustbuffer_alloc(static_cast<uint64_t>(bufLen), &status);
 | |
|         buf.len = bufLen;
 | |
|         if (status.code != 0) {
 | |
|           if (status.error_buf.data) {
 | |
|             auto message = nsCString("uniffi_rustbuffer_alloc: ");
 | |
|             message.Append(nsDependentCSubstring(
 | |
|                 reinterpret_cast<char*>(status.error_buf.data),
 | |
|                 status.error_buf.len));
 | |
|             RustCallStatus status2{};
 | |
|             uniffi_rustbuffer_free(status.error_buf, &status2);
 | |
|             MOZ_RELEASE_ASSERT(status2.code == 0,
 | |
|                                "Freeing a rustbuffer should never fail");
 | |
|             return Err(message);
 | |
|           }
 | |
| 
 | |
|           return Err("Unknown error allocating rust buffer"_ns);
 | |
|         }
 | |
| 
 | |
|         memcpy(buf.data, aData.Elements(), bufLen);
 | |
|         return OwnedRustBuffer(buf);
 | |
|       });
 | |
| }
 | |
| 
 | |
| OwnedRustBuffer::OwnedRustBuffer(OwnedRustBuffer&& aOther) : mBuf(aOther.mBuf) {
 | |
|   aOther.mBuf = RustBuffer{0};
 | |
| }
 | |
| 
 | |
| OwnedRustBuffer& OwnedRustBuffer::operator=(OwnedRustBuffer&& aOther) {
 | |
|   if (&aOther != this) {
 | |
|     FreeData();
 | |
|   }
 | |
|   mBuf = aOther.mBuf;
 | |
|   aOther.mBuf = RustBuffer{0};
 | |
|   return *this;
 | |
| }
 | |
| 
 | |
| void OwnedRustBuffer::FreeData() {
 | |
|   if (IsValid()) {
 | |
|     RustCallStatus status{};
 | |
|     uniffi_rustbuffer_free(mBuf, &status);
 | |
|     MOZ_RELEASE_ASSERT(status.code == 0,
 | |
|                        "Freeing a rustbuffer should never fail");
 | |
|     mBuf = {0};
 | |
|   }
 | |
| }
 | |
| 
 | |
| OwnedRustBuffer::~OwnedRustBuffer() { FreeData(); }
 | |
| 
 | |
| RustBuffer OwnedRustBuffer::IntoRustBuffer() {
 | |
|   RustBuffer rv = mBuf;
 | |
|   mBuf = {};
 | |
|   return rv;
 | |
| }
 | |
| 
 | |
| JSObject* OwnedRustBuffer::IntoArrayBuffer(JSContext* cx) {
 | |
|   JS::Rooted<JSObject*> obj(cx);
 | |
|   {
 | |
|     auto len = mBuf.len;
 | |
|     void* data = mBuf.data;
 | |
|     auto userData = MakeUnique<OwnedRustBuffer>(std::move(*this));
 | |
|     UniquePtr<void, JS::BufferContentsDeleter> dataPtr{
 | |
|         data, {&ArrayBufferFreeFunc, userData.release()}};
 | |
|     obj = JS::NewExternalArrayBuffer(cx, len, std::move(dataPtr));
 | |
|   }
 | |
|   return obj;
 | |
| }
 | |
| 
 | |
| void OwnedRustBuffer::ArrayBufferFreeFunc(void* contents, void* userData) {
 | |
|   UniquePtr<OwnedRustBuffer> buf{reinterpret_cast<OwnedRustBuffer*>(userData)};
 | |
| }
 | |
| }  // namespace mozilla::uniffi
 |