Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTrevor Norris <trev.norris@gmail.com>2015-06-01 21:29:17 +0300
committerRod Vagg <rod@vagg.org>2015-08-04 21:56:10 +0300
commitd75f5c8d0ecdf400933b601ed07b064dbfe27bf6 (patch)
treedf5c51cda5e900e89993926aeb79161e2d3c3eee /src
parent63da0dfd3a4460e117240e84b57af2137469497e (diff)
buffer: finish implementing FreeCallback
Passing a FreeCallback to Buffer::New() now uses externalized ArrayBuffer's. PR-URL: https://github.com/nodejs/io.js/pull/1825 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src')
-rw-r--r--src/node_buffer.cc120
-rw-r--r--src/node_buffer.h8
2 files changed, 116 insertions, 12 deletions
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index d3398075d06..57268e749da 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -13,6 +13,8 @@
#include <string.h>
#include <limits.h>
+#define BUFFER_ID 0xB0E4
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define CHECK_NOT_OOB(r) \
@@ -73,12 +75,103 @@ using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
+using v8::Persistent;
using v8::String;
using v8::Uint32;
using v8::Uint8Array;
using v8::Value;
+using v8::WeakCallbackData;
+
+
+class CallbackInfo {
+ public:
+ static inline void Free(char* data, void* hint);
+ static inline CallbackInfo* New(Isolate* isolate,
+ Handle<Object> object,
+ FreeCallback callback,
+ void* hint = 0);
+ inline void Dispose(Isolate* isolate);
+ inline Persistent<Object>* persistent();
+ private:
+ static void WeakCallback(const WeakCallbackData<Object, CallbackInfo>&);
+ inline void WeakCallback(Isolate* isolate, Local<Object> object);
+ inline CallbackInfo(Isolate* isolate,
+ Handle<Object> object,
+ FreeCallback callback,
+ void* hint);
+ ~CallbackInfo();
+ Persistent<Object> persistent_;
+ FreeCallback const callback_;
+ void* const hint_;
+ DISALLOW_COPY_AND_ASSIGN(CallbackInfo);
+};
+
+
+void CallbackInfo::Free(char* data, void*) {
+ ::free(data);
+}
+
+
+CallbackInfo* CallbackInfo::New(Isolate* isolate,
+ Handle<Object> object,
+ FreeCallback callback,
+ void* hint) {
+ return new CallbackInfo(isolate, object, callback, hint);
+}
+
+
+void CallbackInfo::Dispose(Isolate* isolate) {
+ WeakCallback(isolate, PersistentToLocal(isolate, persistent_));
+}
+
+
+Persistent<Object>* CallbackInfo::persistent() {
+ return &persistent_;
+}
+
+
+CallbackInfo::CallbackInfo(Isolate* isolate,
+ Handle<Object> object,
+ FreeCallback callback,
+ void* hint)
+ : persistent_(isolate, object),
+ callback_(callback),
+ hint_(hint) {
+ persistent_.SetWeak(this, WeakCallback);
+ persistent_.SetWrapperClassId(BUFFER_ID);
+ persistent_.MarkIndependent();
+ isolate->AdjustAmountOfExternalAllocatedMemory(sizeof(*this));
+}
+
+
+CallbackInfo::~CallbackInfo() {
+ persistent_.Reset();
+}
+
+
+void CallbackInfo::WeakCallback(
+ const WeakCallbackData<Object, CallbackInfo>& data) {
+ data.GetParameter()->WeakCallback(data.GetIsolate(), data.GetValue());
+}
+void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) {
+ ARGS_THIS_DEC(obj);
+ SPREAD_ARG(object, obj);
+ CHECK_EQ(obj_offset, 0);
+ CHECK_EQ(obj_c.ByteLength(), obj_length);
+
+ obj->Buffer()->Neuter();
+ callback_(obj_data, hint_);
+ int64_t change_in_bytes = -static_cast<int64_t>(sizeof(*this));
+ isolate->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
+
+ delete this;
+}
+
+
+// Buffer methods
+
bool HasInstance(Handle<Value> val) {
return val->IsObject() && HasInstance(val.As<Object>());
}
@@ -277,7 +370,7 @@ Local<Object> New(Environment* env, const char* data, size_t length) {
Local<Object> New(Isolate* isolate,
char* data,
size_t length,
- smalloc::FreeCallback callback,
+ FreeCallback callback,
void* hint) {
Environment* env = Environment::GetCurrent(isolate);
EscapableHandleScope handle_scope(env->isolate());
@@ -289,19 +382,28 @@ Local<Object> New(Isolate* isolate,
Local<Object> New(Environment* env,
char* data,
size_t length,
- smalloc::FreeCallback callback,
+ FreeCallback callback,
void* hint) {
EscapableHandleScope scope(env->isolate());
- // TODO(trevnorris): IMPLEMENT
- CHECK_LE(length, kMaxLength);
-
- Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
- Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
+ if (using_old_buffer) {
+ CHECK_LE(length, kMaxLength);
+ Local<Value> arg = Uint32::NewFromUnsigned(env->isolate(), length);
+ Local<Object> obj =
+ env->buffer_constructor_function()->NewInstance(1, &arg);
+ smalloc::Alloc(env, obj, data, length, callback, hint);
+ return scope.Escape(obj);
+ }
- smalloc::Alloc(env, obj, data, length, callback, hint);
+ if (!IsValidSmi(length)) {
+ return Local<Object>();
+ }
- return scope.Escape(obj);
+ Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), data, length);
+ Local<Uint8Array> ui = Uint8Array::New(ab, 0, length);
+ ui->SetPrototype(env->buffer_prototype_object());
+ CallbackInfo::New(env->isolate(), ui, callback, hint);
+ return scope.Escape(ui);
}
diff --git a/src/node_buffer.h b/src/node_buffer.h
index 4b1b2cd8591..568b68f83db 100644
--- a/src/node_buffer.h
+++ b/src/node_buffer.h
@@ -14,6 +14,8 @@ namespace Buffer {
static const unsigned int kMaxLength = smalloc::kMaxLength;
+NODE_EXTERN typedef void (*FreeCallback)(char* data, void* hint);
+
NODE_EXTERN bool HasInstance(v8::Handle<v8::Value> val);
NODE_EXTERN bool HasInstance(v8::Handle<v8::Object> val);
NODE_EXTERN char* Data(v8::Handle<v8::Value> val);
@@ -49,12 +51,12 @@ NODE_DEPRECATED("Use New(isolate, ...)",
NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate,
char* data,
size_t length,
- smalloc::FreeCallback callback,
+ FreeCallback callback,
void* hint);
NODE_DEPRECATED("Use New(isolate, ...)",
inline v8::Local<v8::Object> New(char* data,
size_t length,
- smalloc::FreeCallback callback,
+ FreeCallback callback,
void* hint) {
return New(v8::Isolate::GetCurrent(), data, length, callback, hint);
})
@@ -93,7 +95,7 @@ v8::Local<v8::Object> New(Environment* env, const char* data, size_t len);
v8::Local<v8::Object> New(Environment* env,
char* data,
size_t length,
- smalloc::FreeCallback callback,
+ FreeCallback callback,
void* hint);
v8::Local<v8::Object> Use(Environment* env, char* data, size_t length);
#endif // defined(NODE_WANT_INTERNALS)