Skip to content

Commit 23be6ca

Browse files
trevnorrisrvagg
authored andcommitted
buffer: allow ARGS_THIS to accept a name
Allowing the name to be passed to the ARGS_THIS macro will make it easier to share code with the Uint8Array implementation. PR-URL: #1825 Reviewed-By: Ben Noordhuis <[email protected]>
1 parent deb7ee9 commit 23be6ca

File tree

1 file changed

+77
-61
lines changed

1 file changed

+77
-61
lines changed

src/node_buffer.cc

+77-61
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@
2424
return env->ThrowTypeError("argument should be a Buffer"); \
2525
} while (0)
2626

27-
#define ARGS_THIS(argT) \
28-
Local<Object> obj = argT; \
29-
size_t obj_length = obj->GetIndexedPropertiesExternalArrayDataLength(); \
30-
char* obj_data = static_cast<char*>( \
31-
obj->GetIndexedPropertiesExternalArrayData()); \
32-
if (obj_length > 0) \
33-
CHECK_NE(obj_data, nullptr);
27+
#define ARGS_THIS_DEC(name) \
28+
size_t name##_length; \
29+
char* name##_data;
30+
31+
#define ARGS_THIS(argT, name) \
32+
Local<Object> name = argT; \
33+
name##_length = name->GetIndexedPropertiesExternalArrayDataLength(); \
34+
name##_data = static_cast<char*>( \
35+
name->GetIndexedPropertiesExternalArrayData()); \
36+
if (name##_length > 0) \
37+
CHECK_NE(name##_data, nullptr);
3438

3539
#define SLICE_START_END(start_arg, end_arg, end_max) \
3640
size_t start; \
@@ -228,34 +232,38 @@ Local<Object> Use(Environment* env, char* data, uint32_t length) {
228232
template <encoding encoding>
229233
void StringSlice(const FunctionCallbackInfo<Value>& args) {
230234
Environment* env = Environment::GetCurrent(args);
235+
Isolate* isolate = env->isolate();
231236

232237
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
233-
ARGS_THIS(args.This())
234238

235-
if (obj_length == 0)
239+
ARGS_THIS_DEC(ts_obj);
240+
ARGS_THIS(args.This(), ts_obj);
241+
242+
if (ts_obj_length == 0)
236243
return args.GetReturnValue().SetEmptyString();
237244

238-
SLICE_START_END(args[0], args[1], obj_length)
245+
SLICE_START_END(args[0], args[1], ts_obj_length)
239246

240247
args.GetReturnValue().Set(
241-
StringBytes::Encode(env->isolate(), obj_data + start, length, encoding));
248+
StringBytes::Encode(isolate, ts_obj_data + start, length, encoding));
242249
}
243250

244251

245252
template <>
246253
void StringSlice<UCS2>(const FunctionCallbackInfo<Value>& args) {
247254
Environment* env = Environment::GetCurrent(args);
255+
ARGS_THIS_DEC(ts_obj);
248256

249257
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
250-
ARGS_THIS(args.This())
258+
ARGS_THIS(args.This(), ts_obj);
251259

252-
if (obj_length == 0)
260+
if (ts_obj_length == 0)
253261
return args.GetReturnValue().SetEmptyString();
254262

255-
SLICE_START_END(args[0], args[1], obj_length)
263+
SLICE_START_END(args[0], args[1], ts_obj_length)
256264
length /= 2;
257265

258-
const char* data = obj_data + start;
266+
const char* data = ts_obj_data + start;
259267
const uint16_t* buf;
260268
bool release = false;
261269

@@ -319,13 +327,10 @@ void Base64Slice(const FunctionCallbackInfo<Value>& args) {
319327
void Copy(const FunctionCallbackInfo<Value> &args) {
320328
Environment* env = Environment::GetCurrent(args);
321329

322-
if (!HasInstance(args[0]))
323-
return env->ThrowTypeError("first arg should be a Buffer");
324-
325-
Local<Object> target = args[0].As<Object>();
326-
327330
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
328-
ARGS_THIS(args.This())
331+
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
332+
Local<Object> target_obj = args[0].As<Object>();
333+
329334
size_t target_length = target->GetIndexedPropertiesExternalArrayDataLength();
330335
char* target_data = static_cast<char*>(
331336
target->GetIndexedPropertiesExternalArrayData());
@@ -335,63 +340,64 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
335340

336341
CHECK_NOT_OOB(ParseArrayIndex(args[1], 0, &target_start));
337342
CHECK_NOT_OOB(ParseArrayIndex(args[2], 0, &source_start));
338-
CHECK_NOT_OOB(ParseArrayIndex(args[3], obj_length, &source_end));
343+
CHECK_NOT_OOB(ParseArrayIndex(args[3], ts_obj_length, &source_end));
339344

340345
// Copy 0 bytes; we're done
341346
if (target_start >= target_length || source_start >= source_end)
342347
return args.GetReturnValue().Set(0);
343348

344-
if (source_start > obj_length)
349+
if (source_start > ts_obj_length)
345350
return env->ThrowRangeError("out of range index");
346351

347352
if (source_end - source_start > target_length - target_start)
348353
source_end = source_start + target_length - target_start;
349354

350355
uint32_t to_copy = MIN(MIN(source_end - source_start,
351356
target_length - target_start),
352-
obj_length - source_start);
357+
ts_obj_length - source_start);
353358

354-
memmove(target_data + target_start, obj_data + source_start, to_copy);
359+
memmove(target_data + target_start, ts_obj_data + source_start, to_copy);
355360
args.GetReturnValue().Set(to_copy);
356361
}
357362

358363

359364
void Fill(const FunctionCallbackInfo<Value>& args) {
360365
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
361-
ARGS_THIS(args[0].As<Object>())
366+
ARGS_THIS_DEC(ts_obj);
367+
ARGS_THIS(args[0].As<Object>(), ts_obj);
362368

363369
size_t start = args[2]->Uint32Value();
364370
size_t end = args[3]->Uint32Value();
365371
size_t length = end - start;
366-
CHECK(length + start <= obj_length);
372+
CHECK(length + start <= ts_obj_length);
367373

368374
if (args[1]->IsNumber()) {
369375
int value = args[1]->Uint32Value() & 255;
370-
memset(obj_data + start, value, length);
376+
memset(ts_obj_data + start, value, length);
371377
return;
372378
}
373379

374380
node::Utf8Value str(args.GetIsolate(), args[1]);
375381
size_t str_length = str.length();
376382
size_t in_there = str_length;
377-
char* ptr = obj_data + start + str_length;
383+
char* ptr = ts_obj_data + start + str_length;
378384

379385
if (str_length == 0)
380386
return;
381387

382-
memcpy(obj_data + start, *str, MIN(str_length, length));
388+
memcpy(ts_obj_data + start, *str, MIN(str_length, length));
383389

384390
if (str_length >= length)
385391
return;
386392

387393
while (in_there < length - in_there) {
388-
memcpy(ptr, obj_data + start, in_there);
394+
memcpy(ptr, ts_obj_data + start, in_there);
389395
ptr += in_there;
390396
in_there *= 2;
391397
}
392398

393399
if (in_there < length) {
394-
memcpy(ptr, obj_data + start, length - in_there);
400+
memcpy(ptr, ts_obj_data + start, length - in_there);
395401
in_there = length;
396402
}
397403
}
@@ -400,9 +406,10 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
400406
template <encoding encoding>
401407
void StringWrite(const FunctionCallbackInfo<Value>& args) {
402408
Environment* env = Environment::GetCurrent(args);
409+
ARGS_THIS_DEC(ts_obj);
403410

404411
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
405-
ARGS_THIS(args.This())
412+
ARGS_THIS(args.This(), ts_obj);
406413

407414
if (!args[0]->IsString())
408415
return env->ThrowTypeError("Argument must be a string");
@@ -416,18 +423,18 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
416423
size_t max_length;
417424

418425
CHECK_NOT_OOB(ParseArrayIndex(args[1], 0, &offset));
419-
CHECK_NOT_OOB(ParseArrayIndex(args[2], obj_length - offset, &max_length));
426+
CHECK_NOT_OOB(ParseArrayIndex(args[2], ts_obj_length - offset, &max_length));
420427

421-
max_length = MIN(obj_length - offset, max_length);
428+
max_length = MIN(ts_obj_length - offset, max_length);
422429

423430
if (max_length == 0)
424431
return args.GetReturnValue().Set(0);
425432

426-
if (offset >= obj_length)
433+
if (offset >= ts_obj_length)
427434
return env->ThrowRangeError("Offset is out of bounds");
428435

429436
uint32_t written = StringBytes::Write(env->isolate(),
430-
obj_data + offset,
437+
ts_obj_data + offset,
431438
max_length,
432439
str,
433440
encoding,
@@ -479,18 +486,19 @@ static inline void Swizzle(char* start, unsigned int len) {
479486
template <typename T, enum Endianness endianness>
480487
void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) {
481488
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
482-
ARGS_THIS(args[0].As<Object>());
489+
ARGS_THIS_DEC(ts_obj);
490+
ARGS_THIS(args[0].As<Object>(), ts_obj);
483491

484492
uint32_t offset = args[1]->Uint32Value();
485-
CHECK_LE(offset + sizeof(T), obj_length);
493+
CHECK_LE(offset + sizeof(T), ts_obj_length);
486494

487495
union NoAlias {
488496
T val;
489497
char bytes[sizeof(T)];
490498
};
491499

492500
union NoAlias na;
493-
const char* ptr = static_cast<const char*>(obj_data) + offset;
501+
const char* ptr = static_cast<const char*>(ts_obj_data) + offset;
494502
memcpy(na.bytes, ptr, sizeof(na.bytes));
495503
if (endianness != GetEndianness())
496504
Swizzle(na.bytes, sizeof(na.bytes));
@@ -521,19 +529,20 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {
521529

522530
template <typename T, enum Endianness endianness>
523531
uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
524-
ARGS_THIS(args[0].As<Object>())
532+
ARGS_THIS_DEC(ts_obj);
533+
ARGS_THIS(args[0].As<Object>(), ts_obj);
525534

526535
T val = args[1]->NumberValue();
527536
uint32_t offset = args[2]->Uint32Value();
528-
CHECK_LE(offset + sizeof(T), obj_length);
537+
CHECK_LE(offset + sizeof(T), ts_obj_length);
529538

530539
union NoAlias {
531540
T val;
532541
char bytes[sizeof(T)];
533542
};
534543

535544
union NoAlias na = { val };
536-
char* ptr = static_cast<char*>(obj_data) + offset;
545+
char* ptr = static_cast<char*>(ts_obj_data) + offset;
537546
if (endianness != GetEndianness())
538547
Swizzle(na.bytes, sizeof(na.bytes));
539548
memcpy(ptr, na.bytes, sizeof(na.bytes));
@@ -575,6 +584,7 @@ void ByteLengthUtf8(const FunctionCallbackInfo<Value> &args) {
575584

576585
void Compare(const FunctionCallbackInfo<Value> &args) {
577586
Environment* env = Environment::GetCurrent(args);
587+
578588
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
579589
THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
580590

@@ -631,28 +641,30 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
631641
ASSERT(args[2]->IsNumber());
632642

633643
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
634-
ARGS_THIS(args[0].As<Object>());
644+
ARGS_THIS_DEC(ts_obj);
645+
ARGS_THIS(args[0].As<Object>(), ts_obj);
646+
635647
node::Utf8Value str(args.GetIsolate(), args[1]);
636648
int32_t offset_i32 = args[2]->Int32Value();
637649
uint32_t offset;
638650

639651
if (offset_i32 < 0) {
640-
if (offset_i32 + static_cast<int32_t>(obj_length) < 0)
652+
if (offset_i32 + static_cast<int32_t>(ts_obj_length) < 0)
641653
offset = 0;
642654
else
643-
offset = static_cast<uint32_t>(obj_length + offset_i32);
655+
offset = static_cast<uint32_t>(ts_obj_length + offset_i32);
644656
} else {
645657
offset = static_cast<uint32_t>(offset_i32);
646658
}
647659

648660
if (str.length() == 0 ||
649-
obj_length == 0 ||
661+
ts_obj_length == 0 ||
650662
(offset != 0 && str.length() + offset <= str.length()) ||
651-
str.length() + offset > obj_length)
663+
str.length() + offset > ts_obj_length)
652664
return args.GetReturnValue().Set(-1);
653665

654666
int32_t r =
655-
IndexOf(obj_data + offset, obj_length - offset, *str, str.length());
667+
IndexOf(ts_obj_data + offset, ts_obj_length - offset, *str, str.length());
656668
args.GetReturnValue().Set(r == -1 ? -1 : static_cast<int32_t>(r + offset));
657669
}
658670

@@ -662,7 +674,9 @@ void IndexOfBuffer(const FunctionCallbackInfo<Value>& args) {
662674
ASSERT(args[2]->IsNumber());
663675

664676
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
665-
ARGS_THIS(args[0].As<Object>());
677+
ARGS_THIS_DEC(ts_obj);
678+
ARGS_THIS(args[0].As<Object>(), ts_obj);
679+
666680
Local<Object> buf = args[1].As<Object>();
667681
int32_t offset_i32 = args[2]->Int32Value();
668682
size_t buf_length = buf->GetIndexedPropertiesExternalArrayDataLength();
@@ -674,22 +688,22 @@ void IndexOfBuffer(const FunctionCallbackInfo<Value>& args) {
674688
CHECK_NE(buf_data, nullptr);
675689

676690
if (offset_i32 < 0) {
677-
if (offset_i32 + static_cast<int32_t>(obj_length) < 0)
691+
if (offset_i32 + static_cast<int32_t>(ts_obj_length) < 0)
678692
offset = 0;
679693
else
680-
offset = static_cast<uint32_t>(obj_length + offset_i32);
694+
offset = static_cast<uint32_t>(ts_obj_length + offset_i32);
681695
} else {
682696
offset = static_cast<uint32_t>(offset_i32);
683697
}
684698

685699
if (buf_length == 0 ||
686-
obj_length == 0 ||
700+
ts_obj_length == 0 ||
687701
(offset != 0 && buf_length + offset <= buf_length) ||
688-
buf_length + offset > obj_length)
702+
buf_length + offset > ts_obj_length)
689703
return args.GetReturnValue().Set(-1);
690704

691705
int32_t r =
692-
IndexOf(obj_data + offset, obj_length - offset, buf_data, buf_length);
706+
IndexOf(ts_obj_data + offset, ts_obj_length - offset, buf_data, buf_length);
693707
args.GetReturnValue().Set(r == -1 ? -1 : static_cast<int32_t>(r + offset));
694708
}
695709

@@ -699,27 +713,29 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
699713
ASSERT(args[2]->IsNumber());
700714

701715
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
702-
ARGS_THIS(args[0].As<Object>());
716+
ARGS_THIS_DEC(ts_obj);
717+
ARGS_THIS(args[0].As<Object>(), ts_obj);
718+
703719
uint32_t needle = args[1]->Uint32Value();
704720
int32_t offset_i32 = args[2]->Int32Value();
705721
uint32_t offset;
706722

707723
if (offset_i32 < 0) {
708-
if (offset_i32 + static_cast<int32_t>(obj_length) < 0)
724+
if (offset_i32 + static_cast<int32_t>(ts_obj_length) < 0)
709725
offset = 0;
710726
else
711-
offset = static_cast<uint32_t>(obj_length + offset_i32);
727+
offset = static_cast<uint32_t>(ts_obj_length + offset_i32);
712728
} else {
713729
offset = static_cast<uint32_t>(offset_i32);
714730
}
715731

716-
if (obj_length == 0 || offset + 1 > obj_length)
732+
if (ts_obj_length == 0 || offset + 1 > ts_obj_length)
717733
return args.GetReturnValue().Set(-1);
718734

719-
void* ptr = memchr(obj_data + offset, needle, obj_length - offset);
735+
void* ptr = memchr(ts_obj_data + offset, needle, ts_obj_length - offset);
720736
char* ptr_char = static_cast<char*>(ptr);
721737
args.GetReturnValue().Set(
722-
ptr ? static_cast<int32_t>(ptr_char - obj_data) : -1);
738+
ptr ? static_cast<int32_t>(ptr_char - ts_obj_data) : -1);
723739
}
724740

725741

0 commit comments

Comments
 (0)