diff --git a/js/common/bootstrap/modules/buffer.js b/js/common/bootstrap/modules/buffer.js index 6cf8f22018..90087f7b4d 100644 --- a/js/common/bootstrap/modules/buffer.js +++ b/js/common/bootstrap/modules/buffer.js @@ -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) { diff --git a/lib/V8/v8-buffer.cpp b/lib/V8/v8-buffer.cpp index f2faea9db0..137573c449 100644 --- a/lib/V8/v8-buffer.cpp +++ b/lib/V8/v8-buffer.cpp @@ -760,11 +760,6 @@ bool V8Buffer::hasInstance(v8::Isolate* isolate, v8::Handle 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 const& args) { v8::Integer::New(isolate, (int32_t)ByteLengthString(isolate, s, e))); } -//////////////////////////////////////////////////////////////////////////////// -/// @brief makeFastBuffer -//////////////////////////////////////////////////////////////////////////////// - -static void JS_MakeFastBuffer(v8::FunctionCallbackInfo const& args) { - v8::Isolate* isolate = args.GetIsolate(); - v8::HandleScope scope(isolate); - - if (!V8Buffer::hasInstance(isolate, args[0])) { - TRI_V8_THROW_EXCEPTION_USAGE( - "makeFastBuffer(, , , "); - } - - V8Buffer* buffer = V8Buffer::unwrap(args[0]->ToObject()); - v8::Local 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(" out of range"); - } - - if (offset + length > buffer->_length) { - TRI_V8_THROW_RANGE_ERROR(" out of range"); - } - - // Check for wraparound. Safe because offset and length are unsigned. - if (offset + length < offset) { - TRI_V8_THROW_RANGE_ERROR(" or out of range"); - } - - fast_buffer->SetIndexedPropertiesToExternalArrayData( - buffer->_data + offset, v8::kExternalUnsignedByteArray, length); - - TRI_V8_RETURN_UNDEFINED(); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief setFastBufferConstructor -//////////////////////////////////////////////////////////////////////////////// - -static void JS_SetFastBufferConstructor( - v8::FunctionCallbackInfo const& args) { - v8::Isolate* isolate = args.GetIsolate(); - TRI_V8_CURRENT_GLOBALS_AND_SCOPE; - if (args[0]->IsFunction()) { - v8::Handle fn = args[0].As(); - 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& 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 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 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 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); diff --git a/lib/V8/v8-buffer.h b/lib/V8/v8-buffer.h index da8f7f6afc..6cbeb45bce 100644 --- a/lib/V8/v8-buffer.h +++ b/lib/V8/v8-buffer.h @@ -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 { static inline char* data(v8::Handle 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 offset = o->Get(TRI_V8_ASCII_STRING("offset")); + if (offset->IsNumber()) { + offsetValue = offset->Int32Value(); + } } - void* data = o->GetIndexedPropertiesExternalArrayData(); - return static_cast(data); + if (o->Has(TRI_V8_ASCII_STRING("parent"))) { + v8::Handle 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(offsetValue) >= length) { + return nullptr; //OOB + } - return buffer->_data; + return buffer->_data + offsetValue; } ////////////////////////////////////////////////////////////////////////////// @@ -138,23 +155,38 @@ class V8Buffer : public V8Wrapper { static inline size_t length(v8::Handle 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 length = o->Get(TRI_V8_ASCII_STRING("length")); + if (length->IsNumber()) { + lengthValue = length->Int32Value(); + } } - int len = o->GetIndexedPropertiesExternalArrayDataLength(); - return static_cast(len); + if (o->Has(TRI_V8_ASCII_STRING("parent"))) { + v8::Handle 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(lengthValue); + } + return buffer->_length; } diff --git a/lib/V8/v8-globals.cpp b/lib/V8/v8-globals.cpp index 75322e5717..b2ddacbb79 100644 --- a/lib/V8/v8-globals.cpp +++ b/lib/V8/v8-globals.cpp @@ -38,7 +38,6 @@ TRI_v8_global_s::TRI_v8_global_s(v8::Isolate* isolate) VocbaseTempl(), BufferTempl(), - FastBufferConstructor(), BufferConstant(), DeleteConstant(), diff --git a/lib/V8/v8-globals.h b/lib/V8/v8-globals.h index 7b63e90f23..1134fbfd84 100644 --- a/lib/V8/v8-globals.h +++ b/lib/V8/v8-globals.h @@ -541,12 +541,6 @@ typedef struct TRI_v8_global_s { v8::Persistent BufferTempl; - ////////////////////////////////////////////////////////////////////////////// - /// @brief fast Buffer constructor - ////////////////////////////////////////////////////////////////////////////// - - v8::Persistent FastBufferConstructor; - ////////////////////////////////////////////////////////////////////////////// /// @brief "Buffer" constant //////////////////////////////////////////////////////////////////////////////