#define V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT 2
#endif
+
+enum class ArrayBufferCreationMode { kInternalized, kExternalized };
+
+
/**
* An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5).
* This API is experimental and may change significantly.
/**
* Create a new ArrayBuffer over an existing memory block.
- * The created array buffer is immediately in externalized state.
+ * The created array buffer is by default immediately in externalized state.
* The memory block will not be reclaimed when a created ArrayBuffer
* is garbage-collected.
*/
- static Local<ArrayBuffer> New(Isolate* isolate, void* data,
- size_t byte_length);
+ static Local<ArrayBuffer> New(
+ Isolate* isolate, void* data, size_t byte_length,
+ ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized);
/**
* Returns true if ArrayBuffer is extrenalized, that is, does not
*/
Contents Externalize();
+ /**
+ * Get a pointer to the ArrayBuffer's underlying memory block without
+ * externalizing it. If the ArrayBuffer is not externalized, this pointer
+ * will become invalid as soon as the ArrayBuffer became garbage collected.
+ *
+ * The embedder should make sure to hold a strong reference to the
+ * ArrayBuffer while accessing this pointer.
+ *
+ * The memory block is guaranteed to be allocated with |Allocator::Allocate|.
+ */
+ Contents GetContents();
+
V8_INLINE static ArrayBuffer* Cast(Value* obj);
static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT;
v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
- i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
- Utils::ApiCheck(!obj->is_external(),
- "v8::ArrayBuffer::Externalize",
+ i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
+ Utils::ApiCheck(!self->is_external(), "v8::ArrayBuffer::Externalize",
"ArrayBuffer already externalized");
- obj->set_is_external(true);
- size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
+ self->set_is_external(true);
+ return GetContents();
+}
+
+
+v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
+ i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
+ size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
Contents contents;
- contents.data_ = obj->backing_store();
+ contents.data_ = self->backing_store();
contents.byte_length_ = byte_length;
return contents;
}
Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
- size_t byte_length) {
+ size_t byte_length,
+ ArrayBufferCreationMode mode) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
i_isolate->factory()->NewJSArrayBuffer();
- i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
+ i::Runtime::SetupArrayBuffer(i_isolate, obj,
+ mode == ArrayBufferCreationMode::kExternalized,
+ data, byte_length);
return Utils::ToLocal(obj);
}
#include "src/api.h"
#include "src/heap/heap.h"
#include "src/objects.h"
+#include "src/v8.h"
using namespace v8::internal;
"var a = new DataView(b, 2);");
TestArrayBufferViewContents(env, true);
}
+
+
+TEST(AllocateNotExternal) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ void* memory = V8::ArrayBufferAllocator()->Allocate(1024);
+ v8::Local<v8::ArrayBuffer> buffer =
+ v8::ArrayBuffer::New(env->GetIsolate(), memory, 1024,
+ v8::ArrayBufferCreationMode::kInternalized);
+ CHECK(!buffer->IsExternal());
+ CHECK_EQ(memory, buffer->GetContents().Data());
+}