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;
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ TRI_v8_global_s::TRI_v8_global_s(v8::Isolate* isolate)
|
|||
VocbaseTempl(),
|
||||
|
||||
BufferTempl(),
|
||||
FastBufferConstructor(),
|
||||
|
||||
BufferConstant(),
|
||||
DeleteConstant(),
|
||||
|
|
|
@ -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
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue