Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: src/value-serializer.cc

Issue 2643723010: [d8] Use ValueSerializer for postMessage (instead of ad-hoc serializer) (Closed)
Patch Set: forgot hash_combine Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/value-serializer.h" 5 #include "src/value-serializer.h"
6 6
7 #include <type_traits> 7 #include <type_traits>
8 8
9 #include "src/base/logging.h" 9 #include "src/base/logging.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 WriteRawBytes(chars.begin(), chars.length() * sizeof(uint8_t)); 210 WriteRawBytes(chars.begin(), chars.length() * sizeof(uint8_t));
211 } 211 }
212 212
213 void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) { 213 void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) {
214 // Warning: this uses host endianness. 214 // Warning: this uses host endianness.
215 WriteVarint<uint32_t>(chars.length() * sizeof(uc16)); 215 WriteVarint<uint32_t>(chars.length() * sizeof(uc16));
216 WriteRawBytes(chars.begin(), chars.length() * sizeof(uc16)); 216 WriteRawBytes(chars.begin(), chars.length() * sizeof(uc16));
217 } 217 }
218 218
219 void ValueSerializer::WriteRawBytes(const void* source, size_t length) { 219 void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
220 memcpy(ReserveRawBytes(length), source, length); 220 uint8_t* dest;
221 if (ReserveRawBytes(length).To(&dest)) {
222 memcpy(dest, source, length);
223 }
221 } 224 }
222 225
223 uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) { 226 Maybe<uint8_t*> ValueSerializer::ReserveRawBytes(size_t bytes) {
224 size_t old_size = buffer_size_; 227 size_t old_size = buffer_size_;
225 size_t new_size = old_size + bytes; 228 size_t new_size = old_size + bytes;
226 if (new_size > buffer_capacity_) ExpandBuffer(new_size); 229 if (new_size > buffer_capacity_) {
230 bool ok;
231 if (!ExpandBuffer(new_size).To(&ok)) {
232 return Nothing<uint8_t*>();
233 }
234 }
227 buffer_size_ = new_size; 235 buffer_size_ = new_size;
228 return &buffer_[old_size]; 236 return Just(&buffer_[old_size]);
229 } 237 }
230 238
231 void ValueSerializer::ExpandBuffer(size_t required_capacity) { 239 Maybe<bool> ValueSerializer::ExpandBuffer(size_t required_capacity) {
232 DCHECK_GT(required_capacity, buffer_capacity_); 240 DCHECK_GT(required_capacity, buffer_capacity_);
233 size_t requested_capacity = 241 size_t requested_capacity =
234 std::max(required_capacity, buffer_capacity_ * 2) + 64; 242 std::max(required_capacity, buffer_capacity_ * 2) + 64;
235 size_t provided_capacity = 0; 243 size_t provided_capacity = 0;
236 void* new_buffer = nullptr; 244 void* new_buffer = nullptr;
237 if (delegate_) { 245 if (delegate_) {
238 new_buffer = delegate_->ReallocateBufferMemory(buffer_, requested_capacity, 246 new_buffer = delegate_->ReallocateBufferMemory(buffer_, requested_capacity,
239 &provided_capacity); 247 &provided_capacity);
240 } else { 248 } else {
241 new_buffer = realloc(buffer_, requested_capacity); 249 new_buffer = realloc(buffer_, requested_capacity);
242 provided_capacity = requested_capacity; 250 provided_capacity = requested_capacity;
243 } 251 }
244 DCHECK_GE(provided_capacity, requested_capacity); 252 if (new_buffer) {
245 buffer_ = reinterpret_cast<uint8_t*>(new_buffer); 253 DCHECK(provided_capacity >= requested_capacity);
246 buffer_capacity_ = provided_capacity; 254 buffer_ = reinterpret_cast<uint8_t*>(new_buffer);
255 buffer_capacity_ = provided_capacity;
256 return Just(true);
257 } else {
258 out_of_memory_ = true;
259 return Nothing<bool>();
260 }
247 } 261 }
248 262
249 void ValueSerializer::WriteUint32(uint32_t value) { 263 void ValueSerializer::WriteUint32(uint32_t value) {
250 WriteVarint<uint32_t>(value); 264 WriteVarint<uint32_t>(value);
251 } 265 }
252 266
253 void ValueSerializer::WriteUint64(uint64_t value) { 267 void ValueSerializer::WriteUint64(uint64_t value) {
254 WriteVarint<uint64_t>(value); 268 WriteVarint<uint64_t>(value);
255 } 269 }
256 270
(...skipping 10 matching lines...) Expand all
267 } 281 }
268 282
269 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id, 283 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
270 Handle<JSArrayBuffer> array_buffer) { 284 Handle<JSArrayBuffer> array_buffer) {
271 DCHECK(!array_buffer_transfer_map_.Find(array_buffer)); 285 DCHECK(!array_buffer_transfer_map_.Find(array_buffer));
272 DCHECK(!array_buffer->is_shared()); 286 DCHECK(!array_buffer->is_shared());
273 array_buffer_transfer_map_.Set(array_buffer, transfer_id); 287 array_buffer_transfer_map_.Set(array_buffer, transfer_id);
274 } 288 }
275 289
276 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) { 290 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {
291 out_of_memory_ = false;
277 if (object->IsSmi()) { 292 if (object->IsSmi()) {
278 WriteSmi(Smi::cast(*object)); 293 WriteSmi(Smi::cast(*object));
279 return Just(true); 294 return ThrowIfOutOfMemory();
280 } 295 }
281 296
282 DCHECK(object->IsHeapObject()); 297 DCHECK(object->IsHeapObject());
283 switch (HeapObject::cast(*object)->map()->instance_type()) { 298 switch (HeapObject::cast(*object)->map()->instance_type()) {
284 case ODDBALL_TYPE: 299 case ODDBALL_TYPE:
285 WriteOddball(Oddball::cast(*object)); 300 WriteOddball(Oddball::cast(*object));
286 return Just(true); 301 return ThrowIfOutOfMemory();
287 case HEAP_NUMBER_TYPE: 302 case HEAP_NUMBER_TYPE:
288 case MUTABLE_HEAP_NUMBER_TYPE: 303 case MUTABLE_HEAP_NUMBER_TYPE:
289 WriteHeapNumber(HeapNumber::cast(*object)); 304 WriteHeapNumber(HeapNumber::cast(*object));
290 return Just(true); 305 return ThrowIfOutOfMemory();
291 case JS_TYPED_ARRAY_TYPE: 306 case JS_TYPED_ARRAY_TYPE:
292 case JS_DATA_VIEW_TYPE: { 307 case JS_DATA_VIEW_TYPE: {
293 // Despite being JSReceivers, these have their wrapped buffer serialized 308 // Despite being JSReceivers, these have their wrapped buffer serialized
294 // first. That makes this logic a little quirky, because it needs to 309 // first. That makes this logic a little quirky, because it needs to
295 // happen before we assign object IDs. 310 // happen before we assign object IDs.
296 // TODO(jbroman): It may be possible to avoid materializing a typed 311 // TODO(jbroman): It may be possible to avoid materializing a typed
297 // array's buffer here. 312 // array's buffer here.
298 Handle<JSArrayBufferView> view = Handle<JSArrayBufferView>::cast(object); 313 Handle<JSArrayBufferView> view = Handle<JSArrayBufferView>::cast(object);
299 if (!id_map_.Find(view)) { 314 if (!id_map_.Find(view)) {
300 Handle<JSArrayBuffer> buffer( 315 Handle<JSArrayBuffer> buffer(
301 view->IsJSTypedArray() 316 view->IsJSTypedArray()
302 ? Handle<JSTypedArray>::cast(view)->GetBuffer() 317 ? Handle<JSTypedArray>::cast(view)->GetBuffer()
303 : handle(JSArrayBuffer::cast(view->buffer()), isolate_)); 318 : handle(JSArrayBuffer::cast(view->buffer()), isolate_));
304 if (!WriteJSReceiver(buffer).FromMaybe(false)) return Nothing<bool>(); 319 if (!WriteJSReceiver(buffer).FromMaybe(false)) return Nothing<bool>();
305 } 320 }
306 return WriteJSReceiver(view); 321 return WriteJSReceiver(view);
307 } 322 }
308 default: 323 default:
309 if (object->IsString()) { 324 if (object->IsString()) {
310 WriteString(Handle<String>::cast(object)); 325 WriteString(Handle<String>::cast(object));
311 return Just(true); 326 return ThrowIfOutOfMemory();
312 } else if (object->IsJSReceiver()) { 327 } else if (object->IsJSReceiver()) {
313 return WriteJSReceiver(Handle<JSReceiver>::cast(object)); 328 return WriteJSReceiver(Handle<JSReceiver>::cast(object));
314 } else { 329 } else {
315 ThrowDataCloneError(MessageTemplate::kDataCloneError, object); 330 ThrowDataCloneError(MessageTemplate::kDataCloneError, object);
316 return Nothing<bool>(); 331 return Nothing<bool>();
317 } 332 }
318 } 333 }
319 } 334 }
320 335
321 void ValueSerializer::WriteOddball(Oddball* oddball) { 336 void ValueSerializer::WriteOddball(Oddball* oddball) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 // TODO(jbroman): In a future format version, consider adding a tag for 377 // TODO(jbroman): In a future format version, consider adding a tag for
363 // Latin-1 strings, so that this can be skipped. 378 // Latin-1 strings, so that this can be skipped.
364 WriteTag(SerializationTag::kUtf8String); 379 WriteTag(SerializationTag::kUtf8String);
365 Vector<const uint8_t> chars = flat.ToOneByteVector(); 380 Vector<const uint8_t> chars = flat.ToOneByteVector();
366 if (String::IsAscii(chars.begin(), chars.length())) { 381 if (String::IsAscii(chars.begin(), chars.length())) {
367 WriteOneByteString(chars); 382 WriteOneByteString(chars);
368 } else { 383 } else {
369 v8::Local<v8::String> api_string = Utils::ToLocal(string); 384 v8::Local<v8::String> api_string = Utils::ToLocal(string);
370 uint32_t utf8_length = api_string->Utf8Length(); 385 uint32_t utf8_length = api_string->Utf8Length();
371 WriteVarint(utf8_length); 386 WriteVarint(utf8_length);
372 api_string->WriteUtf8( 387 uint8_t* dest;
373 reinterpret_cast<char*>(ReserveRawBytes(utf8_length)), utf8_length, 388 if (ReserveRawBytes(utf8_length).To(&dest)) {
374 nullptr, v8::String::NO_NULL_TERMINATION); 389 api_string->WriteUtf8(reinterpret_cast<char*>(dest), utf8_length,
390 nullptr, v8::String::NO_NULL_TERMINATION);
391 }
375 } 392 }
376 } else if (flat.IsTwoByte()) { 393 } else if (flat.IsTwoByte()) {
377 Vector<const uc16> chars = flat.ToUC16Vector(); 394 Vector<const uc16> chars = flat.ToUC16Vector();
378 uint32_t byte_length = chars.length() * sizeof(uc16); 395 uint32_t byte_length = chars.length() * sizeof(uc16);
379 // The existing reading code expects 16-byte strings to be aligned. 396 // The existing reading code expects 16-byte strings to be aligned.
380 if ((buffer_size_ + 1 + BytesNeededForVarint(byte_length)) & 1) 397 if ((buffer_size_ + 1 + BytesNeededForVarint(byte_length)) & 1)
381 WriteTag(SerializationTag::kPadding); 398 WriteTag(SerializationTag::kPadding);
382 WriteTag(SerializationTag::kTwoByteString); 399 WriteTag(SerializationTag::kTwoByteString);
383 WriteTwoByteString(chars); 400 WriteTwoByteString(chars);
384 } else { 401 } else {
385 UNREACHABLE(); 402 UNREACHABLE();
386 } 403 }
387 } 404 }
388 405
389 Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { 406 Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {
390 // If the object has already been serialized, just write its ID. 407 // If the object has already been serialized, just write its ID.
391 uint32_t* id_map_entry = id_map_.Get(receiver); 408 uint32_t* id_map_entry = id_map_.Get(receiver);
392 if (uint32_t id = *id_map_entry) { 409 if (uint32_t id = *id_map_entry) {
393 WriteTag(SerializationTag::kObjectReference); 410 WriteTag(SerializationTag::kObjectReference);
394 WriteVarint(id - 1); 411 WriteVarint(id - 1);
395 return Just(true); 412 return ThrowIfOutOfMemory();
396 } 413 }
397 414
398 // Otherwise, allocate an ID for it. 415 // Otherwise, allocate an ID for it.
399 uint32_t id = next_id_++; 416 uint32_t id = next_id_++;
400 *id_map_entry = id + 1; 417 *id_map_entry = id + 1;
401 418
402 // Eliminate callable and exotic objects, which should not be serialized. 419 // Eliminate callable and exotic objects, which should not be serialized.
403 InstanceType instance_type = receiver->map()->instance_type(); 420 InstanceType instance_type = receiver->map()->instance_type();
404 if (receiver->IsCallable() || (IsSpecialReceiverInstanceType(instance_type) && 421 if (receiver->IsCallable() || (IsSpecialReceiverInstanceType(instance_type) &&
405 instance_type != JS_SPECIAL_API_OBJECT_TYPE)) { 422 instance_type != JS_SPECIAL_API_OBJECT_TYPE)) {
(...skipping 19 matching lines...) Expand all
425 } else if (JSObject::GetInternalFieldCount(map)) { 442 } else if (JSObject::GetInternalFieldCount(map)) {
426 return WriteHostObject(js_object); 443 return WriteHostObject(js_object);
427 } else { 444 } else {
428 return WriteJSObject(js_object); 445 return WriteJSObject(js_object);
429 } 446 }
430 } 447 }
431 case JS_SPECIAL_API_OBJECT_TYPE: 448 case JS_SPECIAL_API_OBJECT_TYPE:
432 return WriteHostObject(Handle<JSObject>::cast(receiver)); 449 return WriteHostObject(Handle<JSObject>::cast(receiver));
433 case JS_DATE_TYPE: 450 case JS_DATE_TYPE:
434 WriteJSDate(JSDate::cast(*receiver)); 451 WriteJSDate(JSDate::cast(*receiver));
435 return Just(true); 452 return ThrowIfOutOfMemory();
436 case JS_VALUE_TYPE: 453 case JS_VALUE_TYPE:
437 return WriteJSValue(Handle<JSValue>::cast(receiver)); 454 return WriteJSValue(Handle<JSValue>::cast(receiver));
438 case JS_REGEXP_TYPE: 455 case JS_REGEXP_TYPE:
439 WriteJSRegExp(JSRegExp::cast(*receiver)); 456 WriteJSRegExp(JSRegExp::cast(*receiver));
440 return Just(true); 457 return ThrowIfOutOfMemory();
441 case JS_MAP_TYPE: 458 case JS_MAP_TYPE:
442 return WriteJSMap(Handle<JSMap>::cast(receiver)); 459 return WriteJSMap(Handle<JSMap>::cast(receiver));
443 case JS_SET_TYPE: 460 case JS_SET_TYPE:
444 return WriteJSSet(Handle<JSSet>::cast(receiver)); 461 return WriteJSSet(Handle<JSSet>::cast(receiver));
445 case JS_ARRAY_BUFFER_TYPE: 462 case JS_ARRAY_BUFFER_TYPE:
446 return WriteJSArrayBuffer(Handle<JSArrayBuffer>::cast(receiver)); 463 return WriteJSArrayBuffer(Handle<JSArrayBuffer>::cast(receiver));
447 case JS_TYPED_ARRAY_TYPE: 464 case JS_TYPED_ARRAY_TYPE:
448 case JS_DATA_VIEW_TYPE: 465 case JS_DATA_VIEW_TYPE:
449 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver)); 466 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver));
450 default: 467 default:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 508
492 if (!WriteObject(key).FromMaybe(false) || 509 if (!WriteObject(key).FromMaybe(false) ||
493 !WriteObject(value).FromMaybe(false)) { 510 !WriteObject(value).FromMaybe(false)) {
494 return Nothing<bool>(); 511 return Nothing<bool>();
495 } 512 }
496 properties_written++; 513 properties_written++;
497 } 514 }
498 515
499 WriteTag(SerializationTag::kEndJSObject); 516 WriteTag(SerializationTag::kEndJSObject);
500 WriteVarint<uint32_t>(properties_written); 517 WriteVarint<uint32_t>(properties_written);
501 return Just(true); 518 return ThrowIfOutOfMemory();
502 } 519 }
503 520
504 Maybe<bool> ValueSerializer::WriteJSObjectSlow(Handle<JSObject> object) { 521 Maybe<bool> ValueSerializer::WriteJSObjectSlow(Handle<JSObject> object) {
505 WriteTag(SerializationTag::kBeginJSObject); 522 WriteTag(SerializationTag::kBeginJSObject);
506 Handle<FixedArray> keys; 523 Handle<FixedArray> keys;
507 uint32_t properties_written; 524 uint32_t properties_written;
508 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, 525 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly,
509 ENUMERABLE_STRINGS) 526 ENUMERABLE_STRINGS)
510 .ToHandle(&keys) || 527 .ToHandle(&keys) ||
511 !WriteJSObjectPropertiesSlow(object, keys).To(&properties_written)) { 528 !WriteJSObjectPropertiesSlow(object, keys).To(&properties_written)) {
512 return Nothing<bool>(); 529 return Nothing<bool>();
513 } 530 }
514 WriteTag(SerializationTag::kEndJSObject); 531 WriteTag(SerializationTag::kEndJSObject);
515 WriteVarint<uint32_t>(properties_written); 532 WriteVarint<uint32_t>(properties_written);
516 return Just(true); 533 return ThrowIfOutOfMemory();
517 } 534 }
518 535
519 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) { 536 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
520 uint32_t length = 0; 537 uint32_t length = 0;
521 bool valid_length = array->length()->ToArrayLength(&length); 538 bool valid_length = array->length()->ToArrayLength(&length);
522 DCHECK(valid_length); 539 DCHECK(valid_length);
523 USE(valid_length); 540 USE(valid_length);
524 541
525 // To keep things simple, for now we decide between dense and sparse 542 // To keep things simple, for now we decide between dense and sparse
526 // serialization based on elements kind. A more principled heuristic could 543 // serialization based on elements kind. A more principled heuristic could
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly, 628 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly,
612 ENUMERABLE_STRINGS) 629 ENUMERABLE_STRINGS)
613 .ToHandle(&keys) || 630 .ToHandle(&keys) ||
614 !WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) { 631 !WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
615 return Nothing<bool>(); 632 return Nothing<bool>();
616 } 633 }
617 WriteTag(SerializationTag::kEndSparseJSArray); 634 WriteTag(SerializationTag::kEndSparseJSArray);
618 WriteVarint<uint32_t>(properties_written); 635 WriteVarint<uint32_t>(properties_written);
619 WriteVarint<uint32_t>(length); 636 WriteVarint<uint32_t>(length);
620 } 637 }
621 return Just(true); 638 return ThrowIfOutOfMemory();
622 } 639 }
623 640
624 void ValueSerializer::WriteJSDate(JSDate* date) { 641 void ValueSerializer::WriteJSDate(JSDate* date) {
625 WriteTag(SerializationTag::kDate); 642 WriteTag(SerializationTag::kDate);
626 WriteDouble(date->value()->Number()); 643 WriteDouble(date->value()->Number());
627 } 644 }
628 645
629 Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) { 646 Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) {
630 Object* inner_value = value->value(); 647 Object* inner_value = value->value();
631 if (inner_value->IsTrue(isolate_)) { 648 if (inner_value->IsTrue(isolate_)) {
632 WriteTag(SerializationTag::kTrueObject); 649 WriteTag(SerializationTag::kTrueObject);
633 } else if (inner_value->IsFalse(isolate_)) { 650 } else if (inner_value->IsFalse(isolate_)) {
634 WriteTag(SerializationTag::kFalseObject); 651 WriteTag(SerializationTag::kFalseObject);
635 } else if (inner_value->IsNumber()) { 652 } else if (inner_value->IsNumber()) {
636 WriteTag(SerializationTag::kNumberObject); 653 WriteTag(SerializationTag::kNumberObject);
637 WriteDouble(inner_value->Number()); 654 WriteDouble(inner_value->Number());
638 } else if (inner_value->IsString()) { 655 } else if (inner_value->IsString()) {
639 // TODO(jbroman): Replace UTF-8 encoding with the same options available for 656 // TODO(jbroman): Replace UTF-8 encoding with the same options available for
640 // ordinary strings. 657 // ordinary strings.
641 WriteTag(SerializationTag::kStringObject); 658 WriteTag(SerializationTag::kStringObject);
642 v8::Local<v8::String> api_string = 659 v8::Local<v8::String> api_string =
643 Utils::ToLocal(handle(String::cast(inner_value), isolate_)); 660 Utils::ToLocal(handle(String::cast(inner_value), isolate_));
644 uint32_t utf8_length = api_string->Utf8Length(); 661 uint32_t utf8_length = api_string->Utf8Length();
645 WriteVarint(utf8_length); 662 WriteVarint(utf8_length);
646 api_string->WriteUtf8(reinterpret_cast<char*>(ReserveRawBytes(utf8_length)), 663 uint8_t* dest;
647 utf8_length, nullptr, 664 if (ReserveRawBytes(utf8_length).To(&dest)) {
648 v8::String::NO_NULL_TERMINATION); 665 api_string->WriteUtf8(reinterpret_cast<char*>(dest), utf8_length, nullptr,
666 v8::String::NO_NULL_TERMINATION);
667 }
649 } else { 668 } else {
650 DCHECK(inner_value->IsSymbol()); 669 DCHECK(inner_value->IsSymbol());
651 ThrowDataCloneError(MessageTemplate::kDataCloneError, value); 670 ThrowDataCloneError(MessageTemplate::kDataCloneError, value);
652 return Nothing<bool>(); 671 return Nothing<bool>();
653 } 672 }
654 return Just(true); 673 return ThrowIfOutOfMemory();
655 } 674 }
656 675
657 void ValueSerializer::WriteJSRegExp(JSRegExp* regexp) { 676 void ValueSerializer::WriteJSRegExp(JSRegExp* regexp) {
658 WriteTag(SerializationTag::kRegExp); 677 WriteTag(SerializationTag::kRegExp);
659 v8::Local<v8::String> api_string = 678 v8::Local<v8::String> api_string =
660 Utils::ToLocal(handle(regexp->Pattern(), isolate_)); 679 Utils::ToLocal(handle(regexp->Pattern(), isolate_));
661 uint32_t utf8_length = api_string->Utf8Length(); 680 uint32_t utf8_length = api_string->Utf8Length();
662 WriteVarint(utf8_length); 681 WriteVarint(utf8_length);
663 api_string->WriteUtf8(reinterpret_cast<char*>(ReserveRawBytes(utf8_length)), 682 uint8_t* dest;
664 utf8_length, nullptr, v8::String::NO_NULL_TERMINATION); 683 if (ReserveRawBytes(utf8_length).To(&dest)) {
684 api_string->WriteUtf8(reinterpret_cast<char*>(dest), utf8_length, nullptr,
685 v8::String::NO_NULL_TERMINATION);
686 }
665 WriteVarint(static_cast<uint32_t>(regexp->GetFlags())); 687 WriteVarint(static_cast<uint32_t>(regexp->GetFlags()));
666 } 688 }
667 689
668 Maybe<bool> ValueSerializer::WriteJSMap(Handle<JSMap> map) { 690 Maybe<bool> ValueSerializer::WriteJSMap(Handle<JSMap> map) {
669 // First copy the key-value pairs, since getters could mutate them. 691 // First copy the key-value pairs, since getters could mutate them.
670 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table())); 692 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
671 int length = table->NumberOfElements() * 2; 693 int length = table->NumberOfElements() * 2;
672 Handle<FixedArray> entries = isolate_->factory()->NewFixedArray(length); 694 Handle<FixedArray> entries = isolate_->factory()->NewFixedArray(length);
673 { 695 {
674 DisallowHeapAllocation no_gc; 696 DisallowHeapAllocation no_gc;
(...skipping 11 matching lines...) Expand all
686 708
687 // Then write it out. 709 // Then write it out.
688 WriteTag(SerializationTag::kBeginJSMap); 710 WriteTag(SerializationTag::kBeginJSMap);
689 for (int i = 0; i < length; i++) { 711 for (int i = 0; i < length; i++) {
690 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) { 712 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) {
691 return Nothing<bool>(); 713 return Nothing<bool>();
692 } 714 }
693 } 715 }
694 WriteTag(SerializationTag::kEndJSMap); 716 WriteTag(SerializationTag::kEndJSMap);
695 WriteVarint<uint32_t>(length); 717 WriteVarint<uint32_t>(length);
696 return Just(true); 718 return ThrowIfOutOfMemory();
697 } 719 }
698 720
699 Maybe<bool> ValueSerializer::WriteJSSet(Handle<JSSet> set) { 721 Maybe<bool> ValueSerializer::WriteJSSet(Handle<JSSet> set) {
700 // First copy the element pointers, since getters could mutate them. 722 // First copy the element pointers, since getters could mutate them.
701 Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table())); 723 Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
702 int length = table->NumberOfElements(); 724 int length = table->NumberOfElements();
703 Handle<FixedArray> entries = isolate_->factory()->NewFixedArray(length); 725 Handle<FixedArray> entries = isolate_->factory()->NewFixedArray(length);
704 { 726 {
705 DisallowHeapAllocation no_gc; 727 DisallowHeapAllocation no_gc;
706 Oddball* the_hole = isolate_->heap()->the_hole_value(); 728 Oddball* the_hole = isolate_->heap()->the_hole_value();
707 int capacity = table->UsedCapacity(); 729 int capacity = table->UsedCapacity();
708 int result_index = 0; 730 int result_index = 0;
709 for (int i = 0; i < capacity; i++) { 731 for (int i = 0; i < capacity; i++) {
710 Object* key = table->KeyAt(i); 732 Object* key = table->KeyAt(i);
711 if (key == the_hole) continue; 733 if (key == the_hole) continue;
712 entries->set(result_index++, key); 734 entries->set(result_index++, key);
713 } 735 }
714 DCHECK_EQ(result_index, length); 736 DCHECK_EQ(result_index, length);
715 } 737 }
716 738
717 // Then write it out. 739 // Then write it out.
718 WriteTag(SerializationTag::kBeginJSSet); 740 WriteTag(SerializationTag::kBeginJSSet);
719 for (int i = 0; i < length; i++) { 741 for (int i = 0; i < length; i++) {
720 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) { 742 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) {
721 return Nothing<bool>(); 743 return Nothing<bool>();
722 } 744 }
723 } 745 }
724 WriteTag(SerializationTag::kEndJSSet); 746 WriteTag(SerializationTag::kEndJSSet);
725 WriteVarint<uint32_t>(length); 747 WriteVarint<uint32_t>(length);
726 return Just(true); 748 return ThrowIfOutOfMemory();
727 } 749 }
728 750
729 Maybe<bool> ValueSerializer::WriteJSArrayBuffer( 751 Maybe<bool> ValueSerializer::WriteJSArrayBuffer(
730 Handle<JSArrayBuffer> array_buffer) { 752 Handle<JSArrayBuffer> array_buffer) {
731 if (array_buffer->is_shared()) { 753 if (array_buffer->is_shared()) {
732 if (!delegate_) { 754 if (!delegate_) {
733 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer); 755 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer);
734 return Nothing<bool>(); 756 return Nothing<bool>();
735 } 757 }
736 758
737 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_); 759 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
738 Maybe<uint32_t> index = delegate_->GetSharedArrayBufferId( 760 Maybe<uint32_t> index = delegate_->GetSharedArrayBufferId(
739 v8_isolate, Utils::ToLocalShared(array_buffer)); 761 v8_isolate, Utils::ToLocalShared(array_buffer));
740 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate_, Nothing<bool>()); 762 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate_, Nothing<bool>());
741 763
742 WriteTag(SerializationTag::kSharedArrayBuffer); 764 WriteTag(SerializationTag::kSharedArrayBuffer);
743 WriteVarint(index.FromJust()); 765 WriteVarint(index.FromJust());
744 return Just(true); 766 return ThrowIfOutOfMemory();
745 } 767 }
746 768
747 uint32_t* transfer_entry = array_buffer_transfer_map_.Find(array_buffer); 769 uint32_t* transfer_entry = array_buffer_transfer_map_.Find(array_buffer);
748 if (transfer_entry) { 770 if (transfer_entry) {
749 WriteTag(SerializationTag::kArrayBufferTransfer); 771 WriteTag(SerializationTag::kArrayBufferTransfer);
750 WriteVarint(*transfer_entry); 772 WriteVarint(*transfer_entry);
751 return Just(true); 773 return ThrowIfOutOfMemory();
752 } 774 }
753 if (array_buffer->was_neutered()) { 775 if (array_buffer->was_neutered()) {
754 ThrowDataCloneError(MessageTemplate::kDataCloneErrorNeuteredArrayBuffer); 776 ThrowDataCloneError(MessageTemplate::kDataCloneErrorNeuteredArrayBuffer);
755 return Nothing<bool>(); 777 return Nothing<bool>();
756 } 778 }
757 double byte_length = array_buffer->byte_length()->Number(); 779 double byte_length = array_buffer->byte_length()->Number();
758 if (byte_length > std::numeric_limits<uint32_t>::max()) { 780 if (byte_length > std::numeric_limits<uint32_t>::max()) {
759 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer); 781 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer);
760 return Nothing<bool>(); 782 return Nothing<bool>();
761 } 783 }
762 WriteTag(SerializationTag::kArrayBuffer); 784 WriteTag(SerializationTag::kArrayBuffer);
763 WriteVarint<uint32_t>(byte_length); 785 WriteVarint<uint32_t>(byte_length);
764 WriteRawBytes(array_buffer->backing_store(), byte_length); 786 WriteRawBytes(array_buffer->backing_store(), byte_length);
765 return Just(true); 787 return ThrowIfOutOfMemory();
766 } 788 }
767 789
768 Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) { 790 Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) {
769 WriteTag(SerializationTag::kArrayBufferView); 791 WriteTag(SerializationTag::kArrayBufferView);
770 ArrayBufferViewTag tag = ArrayBufferViewTag::kInt8Array; 792 ArrayBufferViewTag tag = ArrayBufferViewTag::kInt8Array;
771 if (view->IsJSTypedArray()) { 793 if (view->IsJSTypedArray()) {
772 switch (JSTypedArray::cast(view)->type()) { 794 switch (JSTypedArray::cast(view)->type()) {
773 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 795 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
774 case kExternal##Type##Array: \ 796 case kExternal##Type##Array: \
775 tag = ArrayBufferViewTag::k##Type##Array; \ 797 tag = ArrayBufferViewTag::k##Type##Array; \
776 break; 798 break;
777 TYPED_ARRAYS(TYPED_ARRAY_CASE) 799 TYPED_ARRAYS(TYPED_ARRAY_CASE)
778 #undef TYPED_ARRAY_CASE 800 #undef TYPED_ARRAY_CASE
779 } 801 }
780 } else { 802 } else {
781 DCHECK(view->IsJSDataView()); 803 DCHECK(view->IsJSDataView());
782 tag = ArrayBufferViewTag::kDataView; 804 tag = ArrayBufferViewTag::kDataView;
783 } 805 }
784 WriteVarint(static_cast<uint8_t>(tag)); 806 WriteVarint(static_cast<uint8_t>(tag));
785 WriteVarint(NumberToUint32(view->byte_offset())); 807 WriteVarint(NumberToUint32(view->byte_offset()));
786 WriteVarint(NumberToUint32(view->byte_length())); 808 WriteVarint(NumberToUint32(view->byte_length()));
787 return Just(true); 809 return ThrowIfOutOfMemory();
788 } 810 }
789 811
790 Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) { 812 Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) {
791 Handle<WasmCompiledModule> compiled_part( 813 Handle<WasmCompiledModule> compiled_part(
792 WasmCompiledModule::cast(object->GetInternalField(0)), isolate_); 814 WasmCompiledModule::cast(object->GetInternalField(0)), isolate_);
793 WasmEncodingTag encoding_tag = WasmEncodingTag::kRawBytes; 815 WasmEncodingTag encoding_tag = WasmEncodingTag::kRawBytes;
794 WriteTag(SerializationTag::kWasmModule); 816 WriteTag(SerializationTag::kWasmModule);
795 WriteRawBytes(&encoding_tag, sizeof(encoding_tag)); 817 WriteRawBytes(&encoding_tag, sizeof(encoding_tag));
796 818
797 Handle<String> wire_bytes(compiled_part->module_bytes(), isolate_); 819 Handle<String> wire_bytes(compiled_part->module_bytes(), isolate_);
798 int wire_bytes_length = wire_bytes->length(); 820 int wire_bytes_length = wire_bytes->length();
799 WriteVarint<uint32_t>(wire_bytes_length); 821 WriteVarint<uint32_t>(wire_bytes_length);
800 uint8_t* destination = ReserveRawBytes(wire_bytes_length); 822 uint8_t* destination;
801 String::WriteToFlat(*wire_bytes, destination, 0, wire_bytes_length); 823 if (ReserveRawBytes(wire_bytes_length).To(&destination)) {
824 String::WriteToFlat(*wire_bytes, destination, 0, wire_bytes_length);
825 }
802 826
803 std::unique_ptr<ScriptData> script_data = 827 std::unique_ptr<ScriptData> script_data =
804 WasmCompiledModuleSerializer::SerializeWasmModule(isolate_, 828 WasmCompiledModuleSerializer::SerializeWasmModule(isolate_,
805 compiled_part); 829 compiled_part);
806 int script_data_length = script_data->length(); 830 int script_data_length = script_data->length();
807 WriteVarint<uint32_t>(script_data_length); 831 WriteVarint<uint32_t>(script_data_length);
808 WriteRawBytes(script_data->data(), script_data_length); 832 WriteRawBytes(script_data->data(), script_data_length);
809 833
810 return Just(true); 834 return ThrowIfOutOfMemory();
811 } 835 }
812 836
813 Maybe<bool> ValueSerializer::WriteHostObject(Handle<JSObject> object) { 837 Maybe<bool> ValueSerializer::WriteHostObject(Handle<JSObject> object) {
814 if (!delegate_) { 838 if (!delegate_) {
815 isolate_->Throw(*isolate_->factory()->NewError( 839 isolate_->Throw(*isolate_->factory()->NewError(
816 isolate_->error_function(), MessageTemplate::kDataCloneError, object)); 840 isolate_->error_function(), MessageTemplate::kDataCloneError, object));
817 return Nothing<bool>(); 841 return Nothing<bool>();
818 } 842 }
819 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_); 843 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
820 Maybe<bool> result = 844 Maybe<bool> result =
(...skipping 30 matching lines...) Expand all
851 } 875 }
852 return Just(properties_written); 876 return Just(properties_written);
853 } 877 }
854 878
855 void ValueSerializer::ThrowDataCloneError( 879 void ValueSerializer::ThrowDataCloneError(
856 MessageTemplate::Template template_index) { 880 MessageTemplate::Template template_index) {
857 return ThrowDataCloneError(template_index, 881 return ThrowDataCloneError(template_index,
858 isolate_->factory()->empty_string()); 882 isolate_->factory()->empty_string());
859 } 883 }
860 884
885 Maybe<bool> ValueSerializer::ThrowIfOutOfMemory() {
886 if (out_of_memory_) {
887 ThrowDataCloneError(MessageTemplate::kDataCloneErrorOutOfMemory);
888 return Nothing<bool>();
889 }
890 return Just(true);
891 }
892
861 void ValueSerializer::ThrowDataCloneError( 893 void ValueSerializer::ThrowDataCloneError(
862 MessageTemplate::Template template_index, Handle<Object> arg0) { 894 MessageTemplate::Template template_index, Handle<Object> arg0) {
863 Handle<String> message = 895 Handle<String> message =
864 MessageTemplate::FormatMessage(isolate_, template_index, arg0); 896 MessageTemplate::FormatMessage(isolate_, template_index, arg0);
865 if (delegate_) { 897 if (delegate_) {
866 delegate_->ThrowDataCloneError(Utils::ToLocal(message)); 898 delegate_->ThrowDataCloneError(Utils::ToLocal(message));
867 } else { 899 } else {
868 isolate_->Throw( 900 isolate_->Throw(
869 *isolate_->factory()->NewError(isolate_->error_function(), message)); 901 *isolate_->factory()->NewError(isolate_->error_function(), message));
870 } 902 }
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
1884 if (stack.size() != 1) { 1916 if (stack.size() != 1) {
1885 isolate_->Throw(*isolate_->factory()->NewError( 1917 isolate_->Throw(*isolate_->factory()->NewError(
1886 MessageTemplate::kDataCloneDeserializationError)); 1918 MessageTemplate::kDataCloneDeserializationError));
1887 return MaybeHandle<Object>(); 1919 return MaybeHandle<Object>();
1888 } 1920 }
1889 return scope.CloseAndEscape(stack[0]); 1921 return scope.CloseAndEscape(stack[0]);
1890 } 1922 }
1891 1923
1892 } // namespace internal 1924 } // namespace internal
1893 } // namespace v8 1925 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698