1
0
Fork 0

make buffers somewhat usable

This commit is contained in:
jsteemann 2016-03-17 22:47:22 +01:00
parent a9ab4eaace
commit e0ce1cef5a
5 changed files with 50 additions and 89 deletions

View File

@ -18,8 +18,6 @@ const exports = {};
var SlowBuffer = require('internal').SlowBuffer;
require('internal').setFastBufferConstructor(Buffer);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
@ -246,7 +244,8 @@ function Buffer(subject, encoding, offset) {
}
}
SlowBuffer.makeFastBuffer(this.parent, this, this.offset, this.length);
// SlowBuffer.makeFastBuffer(this.parent, this, this.offset, this.length);
}
function isArrayIsh(subject) {

View File

@ -760,11 +760,6 @@ bool V8Buffer::hasInstance(v8::Isolate* isolate, v8::Handle<v8::Value> val) {
return true;
}
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
TRI_GET_GLOBAL(FastBufferConstructor, v8::Function);
TRI_ASSERT(!FastBufferConstructor.IsEmpty());
#endif
return strcmp(*v8::String::Utf8Value(obj->GetConstructorName()), "Buffer") ==
0;
}
@ -1549,63 +1544,10 @@ static void JS_ByteLength(v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::Integer::New(isolate, (int32_t)ByteLengthString(isolate, s, e)));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief makeFastBuffer
////////////////////////////////////////////////////////////////////////////////
static void JS_MakeFastBuffer(v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
if (!V8Buffer::hasInstance(isolate, args[0])) {
TRI_V8_THROW_EXCEPTION_USAGE(
"makeFastBuffer(<buffer>, <fastBuffer>, <offset>, <length>");
}
V8Buffer* buffer = V8Buffer::unwrap(args[0]->ToObject());
v8::Local<v8::Object> fast_buffer = args[1]->ToObject();
;
uint32_t offset = args[2]->Uint32Value();
uint32_t length = args[3]->Uint32Value();
if (offset > buffer->_length) {
TRI_V8_THROW_RANGE_ERROR("<offset> out of range");
}
if (offset + length > buffer->_length) {
TRI_V8_THROW_RANGE_ERROR("<length> out of range");
}
// Check for wraparound. Safe because offset and length are unsigned.
if (offset + length < offset) {
TRI_V8_THROW_RANGE_ERROR("<offset> or <length> out of range");
}
fast_buffer->SetIndexedPropertiesToExternalArrayData(
buffer->_data + offset, v8::kExternalUnsignedByteArray, length);
TRI_V8_RETURN_UNDEFINED();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief setFastBufferConstructor
////////////////////////////////////////////////////////////////////////////////
static void JS_SetFastBufferConstructor(
v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::Isolate* isolate = args.GetIsolate();
TRI_V8_CURRENT_GLOBALS_AND_SCOPE;
if (args[0]->IsFunction()) {
v8::Handle<v8::Function> fn = args[0].As<v8::Function>();
v8g->FastBufferConstructor.Reset(isolate, fn);
}
TRI_V8_RETURN_UNDEFINED();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief selects an indexed attribute from the buffer
////////////////////////////////////////////////////////////////////////////////
/*
static void MapGetIndexedBuffer(
uint32_t idx, const v8::PropertyCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
@ -1646,7 +1588,7 @@ static void MapSetIndexedBuffer(
TRI_V8_RETURN(
v8::Integer::NewFromUnsigned(isolate, ((uint8_t)buffer->_data[idx])));
}
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes the buffer module
////////////////////////////////////////////////////////////////////////////////
@ -1678,7 +1620,7 @@ void TRI_InitV8Buffer(v8::Isolate* isolate, v8::Handle<v8::Context> context) {
rt->SetInternalFieldCount(1);
// accessor for indexed properties (e.g. buffer[1])
rt->SetIndexedPropertyHandler(MapGetIndexedBuffer, MapSetIndexedBuffer);
// rt->SetIndexedPropertyHandler(MapGetIndexedBuffer, MapSetIndexedBuffer);
v8g->BufferTempl.Reset(isolate, ft);
@ -1729,16 +1671,11 @@ void TRI_InitV8Buffer(v8::Isolate* isolate, v8::Handle<v8::Context> context) {
TRI_V8_AddMethod(isolate, ft, TRI_V8_ASCII_STRING("byteLength"),
JS_ByteLength);
TRI_V8_AddMethod(isolate, ft, TRI_V8_ASCII_STRING("makeFastBuffer"),
JS_MakeFastBuffer);
// create the exports
v8::Handle<v8::Object> exports = v8::Object::New(isolate);
TRI_V8_AddMethod(isolate, exports, TRI_V8_ASCII_STRING("SlowBuffer"), ft);
TRI_V8_AddMethod(isolate, exports,
TRI_V8_ASCII_STRING("setFastBufferConstructor"),
JS_SetFastBufferConstructor);
TRI_AddGlobalVariableVocbase(
isolate, context, TRI_V8_ASCII_STRING("EXPORTS_SLOW_BUFFER"), exports);

View File

@ -51,6 +51,7 @@
#include "Basics/Common.h"
#include "V8/v8-globals.h"
#include "V8/v8-wrapper.h"
////////////////////////////////////////////////////////////////////////////////
@ -102,24 +103,40 @@ class V8Buffer : public V8Wrapper<V8Buffer, TRI_V8_BUFFER_CID> {
static inline char* data(v8::Handle<v8::Value> val) {
TRI_ASSERT(val->IsObject());
auto o = val->ToObject();
int32_t offsetValue = 0;
if (o->InternalFieldCount() == 0) {
// seems object has become a FastBuffer already
if (!o->HasIndexedPropertiesInExternalArrayData()) {
// probably not...
return nullptr;
ISOLATE;
if (o->Has(TRI_V8_ASCII_STRING("offset"))) {
v8::Handle<v8::Value> offset = o->Get(TRI_V8_ASCII_STRING("offset"));
if (offset->IsNumber()) {
offsetValue = offset->Int32Value();
}
}
void* data = o->GetIndexedPropertiesExternalArrayData();
return static_cast<char*>(data);
if (o->Has(TRI_V8_ASCII_STRING("parent"))) {
v8::Handle<v8::Value> parent = o->Get(TRI_V8_ASCII_STRING("parent"));
if (!parent->IsObject()) {
return nullptr;
}
o = parent->ToObject();
// fallthrough intentional
}
}
V8Buffer* buffer = unwrap(o);
if (buffer == nullptr) {
if (buffer == nullptr || offsetValue < 0) {
return nullptr;
}
size_t length = buffer->_length;
if (static_cast<size_t>(offsetValue) >= length) {
return nullptr; //OOB
}
return buffer->_data;
return buffer->_data + offsetValue;
}
//////////////////////////////////////////////////////////////////////////////
@ -138,23 +155,38 @@ class V8Buffer : public V8Wrapper<V8Buffer, TRI_V8_BUFFER_CID> {
static inline size_t length(v8::Handle<v8::Value> val) {
TRI_ASSERT(val->IsObject());
auto o = val->ToObject();
int32_t lengthValue = -1;
if (o->InternalFieldCount() == 0) {
// seems object has become a FastBuffer already
if (!o->HasIndexedPropertiesInExternalArrayData()) {
// probably not...
return 0;
ISOLATE;
if (o->Has(TRI_V8_ASCII_STRING("length"))) {
v8::Handle<v8::Value> length = o->Get(TRI_V8_ASCII_STRING("length"));
if (length->IsNumber()) {
lengthValue = length->Int32Value();
}
}
int len = o->GetIndexedPropertiesExternalArrayDataLength();
return static_cast<size_t>(len);
if (o->Has(TRI_V8_ASCII_STRING("parent"))) {
v8::Handle<v8::Value> parent = o->Get(TRI_V8_ASCII_STRING("parent"));
if (!parent->IsObject()) {
return 0;
}
o = parent->ToObject();
// fallthrough intentional
}
}
V8Buffer* buffer = unwrap(o);
if (buffer == nullptr) {
return 0;
}
if (lengthValue >= 0) {
return static_cast<size_t>(lengthValue);
}
return buffer->_length;
}

View File

@ -38,7 +38,6 @@ TRI_v8_global_s::TRI_v8_global_s(v8::Isolate* isolate)
VocbaseTempl(),
BufferTempl(),
FastBufferConstructor(),
BufferConstant(),
DeleteConstant(),

View File

@ -541,12 +541,6 @@ typedef struct TRI_v8_global_s {
v8::Persistent<v8::FunctionTemplate> BufferTempl;
//////////////////////////////////////////////////////////////////////////////
/// @brief fast Buffer constructor
//////////////////////////////////////////////////////////////////////////////
v8::Persistent<v8::Function> FastBufferConstructor;
//////////////////////////////////////////////////////////////////////////////
/// @brief "Buffer" constant
//////////////////////////////////////////////////////////////////////////////