浏览代码

LibJS: Allow ArrayBuffer to not own its backing data buffer as well

This is implemented as a ByteBuffer* in a variant, so its size should
only be increased by an index.
Ali Mohammad Pur 4 年之前
父节点
当前提交
4fd43a8f96
共有 2 个文件被更改,包括 27 次插入4 次删除
  1. 11 0
      Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp
  2. 16 4
      Userland/Libraries/LibJS/Runtime/ArrayBuffer.h

+ 11 - 0
Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp

@@ -19,6 +19,11 @@ ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer& buffer
     return global_object.heap().allocate<ArrayBuffer>(global_object, buffer, *global_object.array_buffer_prototype());
     return global_object.heap().allocate<ArrayBuffer>(global_object, buffer, *global_object.array_buffer_prototype());
 }
 }
 
 
+ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer* buffer)
+{
+    return global_object.heap().allocate<ArrayBuffer>(global_object, buffer, *global_object.array_buffer_prototype());
+}
+
 ArrayBuffer::ArrayBuffer(size_t byte_size, Object& prototype)
 ArrayBuffer::ArrayBuffer(size_t byte_size, Object& prototype)
     : Object(prototype)
     : Object(prototype)
     , m_buffer(ByteBuffer::create_zeroed(byte_size))
     , m_buffer(ByteBuffer::create_zeroed(byte_size))
@@ -31,6 +36,12 @@ ArrayBuffer::ArrayBuffer(ByteBuffer& buffer, Object& prototype)
 {
 {
 }
 }
 
 
+ArrayBuffer::ArrayBuffer(ByteBuffer* buffer, Object& prototype)
+    : Object(prototype)
+    , m_buffer(buffer)
+{
+}
+
 ArrayBuffer::~ArrayBuffer()
 ArrayBuffer::~ArrayBuffer()
 {
 {
 }
 }

+ 16 - 4
Userland/Libraries/LibJS/Runtime/ArrayBuffer.h

@@ -7,6 +7,7 @@
 #pragma once
 #pragma once
 
 
 #include <AK/ByteBuffer.h>
 #include <AK/ByteBuffer.h>
+#include <AK/Variant.h>
 #include <LibJS/Runtime/Object.h>
 #include <LibJS/Runtime/Object.h>
 
 
 namespace JS {
 namespace JS {
@@ -17,17 +18,28 @@ class ArrayBuffer : public Object {
 public:
 public:
     static ArrayBuffer* create(GlobalObject&, size_t);
     static ArrayBuffer* create(GlobalObject&, size_t);
     static ArrayBuffer* create(GlobalObject&, ByteBuffer&);
     static ArrayBuffer* create(GlobalObject&, ByteBuffer&);
+    static ArrayBuffer* create(GlobalObject&, ByteBuffer*);
 
 
     ArrayBuffer(size_t, Object& prototype);
     ArrayBuffer(size_t, Object& prototype);
     ArrayBuffer(ByteBuffer& buffer, Object& prototype);
     ArrayBuffer(ByteBuffer& buffer, Object& prototype);
+    ArrayBuffer(ByteBuffer* buffer, Object& prototype);
     virtual ~ArrayBuffer() override;
     virtual ~ArrayBuffer() override;
 
 
-    size_t byte_length() const { return m_buffer.size(); }
-    ByteBuffer& buffer() { return m_buffer; }
-    const ByteBuffer& buffer() const { return m_buffer; }
+    size_t byte_length() const { return buffer_impl().size(); }
+    ByteBuffer& buffer() { return buffer_impl(); }
+    const ByteBuffer& buffer() const { return buffer_impl(); }
 
 
 private:
 private:
-    ByteBuffer m_buffer;
+    ByteBuffer& buffer_impl()
+    {
+        ByteBuffer* ptr { nullptr };
+        m_buffer.visit([&](auto* pointer) { ptr = pointer; }, [&](auto& value) { ptr = &value; });
+        return *ptr;
+    }
+
+    const ByteBuffer& buffer_impl() const { return const_cast<ArrayBuffer*>(this)->buffer_impl(); }
+
+    Variant<ByteBuffer, ByteBuffer*> m_buffer;
 };
 };
 
 
 }
 }