mirror of https://gitee.com/bigwinds/arangodb
make buffers somewhat usable
This commit is contained in:
parent
a9ab4eaace
commit
e0ce1cef5a
|
@ -18,8 +18,6 @@ const exports = {};
|
||||||
|
|
||||||
var SlowBuffer = require('internal').SlowBuffer;
|
var SlowBuffer = require('internal').SlowBuffer;
|
||||||
|
|
||||||
require('internal').setFastBufferConstructor(Buffer);
|
|
||||||
|
|
||||||
// Copyright Joyent, Inc. and other Node contributors.
|
// Copyright Joyent, Inc. and other Node contributors.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// 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) {
|
function isArrayIsh(subject) {
|
||||||
|
|
|
@ -760,11 +760,6 @@ bool V8Buffer::hasInstance(v8::Isolate* isolate, v8::Handle<v8::Value> val) {
|
||||||
return true;
|
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") ==
|
return strcmp(*v8::String::Utf8Value(obj->GetConstructorName()), "Buffer") ==
|
||||||
0;
|
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)));
|
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
|
/// @brief selects an indexed attribute from the buffer
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
static void MapGetIndexedBuffer(
|
static void MapGetIndexedBuffer(
|
||||||
uint32_t idx, const v8::PropertyCallbackInfo<v8::Value>& args) {
|
uint32_t idx, const v8::PropertyCallbackInfo<v8::Value>& args) {
|
||||||
v8::Isolate* isolate = args.GetIsolate();
|
v8::Isolate* isolate = args.GetIsolate();
|
||||||
|
@ -1646,7 +1588,7 @@ static void MapSetIndexedBuffer(
|
||||||
TRI_V8_RETURN(
|
TRI_V8_RETURN(
|
||||||
v8::Integer::NewFromUnsigned(isolate, ((uint8_t)buffer->_data[idx])));
|
v8::Integer::NewFromUnsigned(isolate, ((uint8_t)buffer->_data[idx])));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief initializes the buffer module
|
/// @brief initializes the buffer module
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1678,7 +1620,7 @@ void TRI_InitV8Buffer(v8::Isolate* isolate, v8::Handle<v8::Context> context) {
|
||||||
rt->SetInternalFieldCount(1);
|
rt->SetInternalFieldCount(1);
|
||||||
|
|
||||||
// accessor for indexed properties (e.g. buffer[1])
|
// accessor for indexed properties (e.g. buffer[1])
|
||||||
rt->SetIndexedPropertyHandler(MapGetIndexedBuffer, MapSetIndexedBuffer);
|
// rt->SetIndexedPropertyHandler(MapGetIndexedBuffer, MapSetIndexedBuffer);
|
||||||
|
|
||||||
v8g->BufferTempl.Reset(isolate, ft);
|
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"),
|
TRI_V8_AddMethod(isolate, ft, TRI_V8_ASCII_STRING("byteLength"),
|
||||||
JS_ByteLength);
|
JS_ByteLength);
|
||||||
TRI_V8_AddMethod(isolate, ft, TRI_V8_ASCII_STRING("makeFastBuffer"),
|
|
||||||
JS_MakeFastBuffer);
|
|
||||||
|
|
||||||
// create the exports
|
// create the exports
|
||||||
v8::Handle<v8::Object> exports = v8::Object::New(isolate);
|
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("SlowBuffer"), ft);
|
||||||
TRI_V8_AddMethod(isolate, exports,
|
|
||||||
TRI_V8_ASCII_STRING("setFastBufferConstructor"),
|
|
||||||
JS_SetFastBufferConstructor);
|
|
||||||
TRI_AddGlobalVariableVocbase(
|
TRI_AddGlobalVariableVocbase(
|
||||||
isolate, context, TRI_V8_ASCII_STRING("EXPORTS_SLOW_BUFFER"), exports);
|
isolate, context, TRI_V8_ASCII_STRING("EXPORTS_SLOW_BUFFER"), exports);
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
|
|
||||||
|
#include "V8/v8-globals.h"
|
||||||
#include "V8/v8-wrapper.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) {
|
static inline char* data(v8::Handle<v8::Value> val) {
|
||||||
TRI_ASSERT(val->IsObject());
|
TRI_ASSERT(val->IsObject());
|
||||||
auto o = val->ToObject();
|
auto o = val->ToObject();
|
||||||
|
int32_t offsetValue = 0;
|
||||||
|
|
||||||
if (o->InternalFieldCount() == 0) {
|
if (o->InternalFieldCount() == 0) {
|
||||||
// seems object has become a FastBuffer already
|
// seems object has become a FastBuffer already
|
||||||
if (!o->HasIndexedPropertiesInExternalArrayData()) {
|
ISOLATE;
|
||||||
// probably not...
|
|
||||||
return nullptr;
|
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();
|
if (o->Has(TRI_V8_ASCII_STRING("parent"))) {
|
||||||
return static_cast<char*>(data);
|
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);
|
V8Buffer* buffer = unwrap(o);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr || offsetValue < 0) {
|
||||||
return nullptr;
|
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) {
|
static inline size_t length(v8::Handle<v8::Value> val) {
|
||||||
TRI_ASSERT(val->IsObject());
|
TRI_ASSERT(val->IsObject());
|
||||||
auto o = val->ToObject();
|
auto o = val->ToObject();
|
||||||
|
int32_t lengthValue = -1;
|
||||||
|
|
||||||
if (o->InternalFieldCount() == 0) {
|
if (o->InternalFieldCount() == 0) {
|
||||||
// seems object has become a FastBuffer already
|
// seems object has become a FastBuffer already
|
||||||
if (!o->HasIndexedPropertiesInExternalArrayData()) {
|
ISOLATE;
|
||||||
// probably not...
|
|
||||||
return 0;
|
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();
|
if (o->Has(TRI_V8_ASCII_STRING("parent"))) {
|
||||||
return static_cast<size_t>(len);
|
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);
|
V8Buffer* buffer = unwrap(o);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lengthValue >= 0) {
|
||||||
|
return static_cast<size_t>(lengthValue);
|
||||||
|
}
|
||||||
|
|
||||||
return buffer->_length;
|
return buffer->_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ TRI_v8_global_s::TRI_v8_global_s(v8::Isolate* isolate)
|
||||||
VocbaseTempl(),
|
VocbaseTempl(),
|
||||||
|
|
||||||
BufferTempl(),
|
BufferTempl(),
|
||||||
FastBufferConstructor(),
|
|
||||||
|
|
||||||
BufferConstant(),
|
BufferConstant(),
|
||||||
DeleteConstant(),
|
DeleteConstant(),
|
||||||
|
|
|
@ -541,12 +541,6 @@ typedef struct TRI_v8_global_s {
|
||||||
|
|
||||||
v8::Persistent<v8::FunctionTemplate> BufferTempl;
|
v8::Persistent<v8::FunctionTemplate> BufferTempl;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief fast Buffer constructor
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
v8::Persistent<v8::Function> FastBufferConstructor;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief "Buffer" constant
|
/// @brief "Buffer" constant
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue