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

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

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

Powered by Google App Engine
This is Rietveld 408576698