13
13
#include < string.h>
14
14
#include < limits.h>
15
15
16
+ #define BUFFER_ID 0xB0E4
17
+
16
18
#define MIN (a, b ) ((a) < (b) ? (a) : (b))
17
19
18
20
#define CHECK_NOT_OOB (r ) \
@@ -73,12 +75,103 @@ using v8::Isolate;
73
75
using v8::Local;
74
76
using v8::Number;
75
77
using v8::Object;
78
+ using v8::Persistent;
76
79
using v8::String;
77
80
using v8::Uint32;
78
81
using v8::Uint8Array;
79
82
using v8::Value;
83
+ using v8::WeakCallbackData;
84
+
85
+
86
+ class CallbackInfo {
87
+ public:
88
+ static inline void Free (char * data, void * hint);
89
+ static inline CallbackInfo* New (Isolate* isolate,
90
+ Handle <Object> object,
91
+ FreeCallback callback,
92
+ void * hint = 0 );
93
+ inline void Dispose (Isolate* isolate);
94
+ inline Persistent<Object>* persistent ();
95
+ private:
96
+ static void WeakCallback (const WeakCallbackData<Object, CallbackInfo>&);
97
+ inline void WeakCallback (Isolate* isolate, Local<Object> object);
98
+ inline CallbackInfo (Isolate* isolate,
99
+ Handle <Object> object,
100
+ FreeCallback callback,
101
+ void * hint);
102
+ ~CallbackInfo ();
103
+ Persistent<Object> persistent_;
104
+ FreeCallback const callback_;
105
+ void * const hint_;
106
+ DISALLOW_COPY_AND_ASSIGN (CallbackInfo);
107
+ };
108
+
109
+
110
+ void CallbackInfo::Free (char * data, void *) {
111
+ ::free (data);
112
+ }
113
+
114
+
115
+ CallbackInfo* CallbackInfo::New (Isolate* isolate,
116
+ Handle <Object> object,
117
+ FreeCallback callback,
118
+ void * hint) {
119
+ return new CallbackInfo (isolate, object, callback, hint);
120
+ }
121
+
122
+
123
+ void CallbackInfo::Dispose (Isolate* isolate) {
124
+ WeakCallback (isolate, PersistentToLocal (isolate, persistent_));
125
+ }
126
+
127
+
128
+ Persistent<Object>* CallbackInfo::persistent () {
129
+ return &persistent_;
130
+ }
131
+
132
+
133
+ CallbackInfo::CallbackInfo (Isolate* isolate,
134
+ Handle <Object> object,
135
+ FreeCallback callback,
136
+ void * hint)
137
+ : persistent_(isolate, object),
138
+ callback_ (callback),
139
+ hint_(hint) {
140
+ persistent_.SetWeak (this , WeakCallback);
141
+ persistent_.SetWrapperClassId (BUFFER_ID);
142
+ persistent_.MarkIndependent ();
143
+ isolate->AdjustAmountOfExternalAllocatedMemory (sizeof (*this ));
144
+ }
145
+
146
+
147
+ CallbackInfo::~CallbackInfo () {
148
+ persistent_.Reset ();
149
+ }
150
+
151
+
152
+ void CallbackInfo::WeakCallback (
153
+ const WeakCallbackData<Object, CallbackInfo>& data) {
154
+ data.GetParameter ()->WeakCallback (data.GetIsolate (), data.GetValue ());
155
+ }
80
156
81
157
158
+ void CallbackInfo::WeakCallback (Isolate* isolate, Local<Object> object) {
159
+ ARGS_THIS_DEC (obj);
160
+ SPREAD_ARG (object, obj);
161
+ CHECK_EQ (obj_offset, 0 );
162
+ CHECK_EQ (obj_c.ByteLength (), obj_length);
163
+
164
+ obj->Buffer ()->Neuter ();
165
+ callback_ (obj_data, hint_);
166
+ int64_t change_in_bytes = -static_cast <int64_t >(sizeof (*this ));
167
+ isolate->AdjustAmountOfExternalAllocatedMemory (change_in_bytes);
168
+
169
+ delete this ;
170
+ }
171
+
172
+
173
+ // Buffer methods
174
+
82
175
bool HasInstance (Handle <Value> val) {
83
176
return val->IsObject () && HasInstance (val.As <Object>());
84
177
}
@@ -277,7 +370,7 @@ Local<Object> New(Environment* env, const char* data, size_t length) {
277
370
Local<Object> New (Isolate* isolate,
278
371
char * data,
279
372
size_t length,
280
- smalloc:: FreeCallback callback,
373
+ FreeCallback callback,
281
374
void * hint) {
282
375
Environment* env = Environment::GetCurrent (isolate);
283
376
EscapableHandleScope handle_scope (env->isolate ());
@@ -289,19 +382,28 @@ Local<Object> New(Isolate* isolate,
289
382
Local<Object> New (Environment* env,
290
383
char * data,
291
384
size_t length,
292
- smalloc:: FreeCallback callback,
385
+ FreeCallback callback,
293
386
void * hint) {
294
387
EscapableHandleScope scope (env->isolate ());
295
388
296
- // TODO(trevnorris): IMPLEMENT
297
- CHECK_LE (length, kMaxLength );
298
-
299
- Local<Value> arg = Uint32::NewFromUnsigned (env->isolate (), length);
300
- Local<Object> obj = env->buffer_constructor_function ()->NewInstance (1 , &arg);
389
+ if (using_old_buffer) {
390
+ CHECK_LE (length, kMaxLength );
391
+ Local<Value> arg = Uint32::NewFromUnsigned (env->isolate (), length);
392
+ Local<Object> obj =
393
+ env->buffer_constructor_function ()->NewInstance (1 , &arg);
394
+ smalloc::Alloc (env, obj, data, length, callback, hint);
395
+ return scope.Escape (obj);
396
+ }
301
397
302
- smalloc::Alloc (env, obj, data, length, callback, hint);
398
+ if (!IsValidSmi (length)) {
399
+ return Local<Object>();
400
+ }
303
401
304
- return scope.Escape (obj);
402
+ Local<ArrayBuffer> ab = ArrayBuffer::New (env->isolate (), data, length);
403
+ Local<Uint8Array> ui = Uint8Array::New (ab, 0 , length);
404
+ ui->SetPrototype (env->buffer_prototype_object ());
405
+ CallbackInfo::New (env->isolate (), ui, callback, hint);
406
+ return scope.Escape (ui);
305
407
}
306
408
307
409
0 commit comments