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

Side by Side Diff: src/d8.cc

Issue 14654011: Remove d8 implementation of ArrayBuffer and typed arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 #endif 82 #endif
83 83
84 namespace v8 { 84 namespace v8 {
85 85
86 86
87 static Handle<Value> Throw(const char* message) { 87 static Handle<Value> Throw(const char* message) {
88 return ThrowException(String::New(message)); 88 return ThrowException(String::New(message));
89 } 89 }
90 90
91 91
92 // TODO(rossberg): should replace these by proper uses of HasInstance,
93 // once we figure out a good way to make the templates global.
94 const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_";
95 const char kArrayMarkerPropName[] = "d8::_is_typed_array_";
96
97
98 #define FOR_EACH_STRING(V) \
99 V(ArrayBuffer, "ArrayBuffer") \
100 V(ArrayBufferMarkerPropName, kArrayBufferMarkerPropName) \
101 V(ArrayMarkerPropName, kArrayMarkerPropName) \
102 V(buffer, "buffer") \
103 V(byteLength, "byteLength") \
104 V(byteOffset, "byteOffset") \
105 V(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT") \
106 V(length, "length")
107
108 92
109 class PerIsolateData { 93 class PerIsolateData {
110 public: 94 public:
111 explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) { 95 explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) {
112 HandleScope scope(isolate); 96 HandleScope scope(isolate);
113 #define INIT_STRING(name, value) \
114 name##_string_ = Persistent<String>::New(isolate, String::NewSymbol(value));
115 FOR_EACH_STRING(INIT_STRING)
116 #undef INIT_STRING
117 isolate->SetData(this); 97 isolate->SetData(this);
118 } 98 }
119 99
120 ~PerIsolateData() { 100 ~PerIsolateData() {
121 #define DISPOSE_STRING(name, value) name##_string_.Dispose(isolate_);
122 FOR_EACH_STRING(DISPOSE_STRING)
123 #undef DISPOSE_STRING
124 isolate_->SetData(NULL); // Not really needed, just to be sure... 101 isolate_->SetData(NULL); // Not really needed, just to be sure...
125 } 102 }
126 103
127 inline static PerIsolateData* Get(Isolate* isolate) { 104 inline static PerIsolateData* Get(Isolate* isolate) {
128 return reinterpret_cast<PerIsolateData*>(isolate->GetData()); 105 return reinterpret_cast<PerIsolateData*>(isolate->GetData());
129 } 106 }
130 107
131 #define DEFINE_STRING_GETTER(name, value) \
132 static Handle<String> name##_string(Isolate* isolate) { \
133 return Handle<String>(*Get(isolate)->name##_string_); \
134 }
135 FOR_EACH_STRING(DEFINE_STRING_GETTER)
136 #undef DEFINE_STRING_GETTER
137
138 class RealmScope { 108 class RealmScope {
139 public: 109 public:
140 explicit RealmScope(PerIsolateData* data); 110 explicit RealmScope(PerIsolateData* data);
141 ~RealmScope(); 111 ~RealmScope();
142 private: 112 private:
143 PerIsolateData* data_; 113 PerIsolateData* data_;
144 }; 114 };
145 115
146 private: 116 private:
147 friend class Shell; 117 friend class Shell;
148 friend class RealmScope; 118 friend class RealmScope;
149 Isolate* isolate_; 119 Isolate* isolate_;
150 int realm_count_; 120 int realm_count_;
151 int realm_current_; 121 int realm_current_;
152 int realm_switch_; 122 int realm_switch_;
153 Persistent<Context>* realms_; 123 Persistent<Context>* realms_;
154 Persistent<Value> realm_shared_; 124 Persistent<Value> realm_shared_;
155 125
156 #define DEFINE_MEMBER(name, value) Persistent<String> name##_string_;
157 FOR_EACH_STRING(DEFINE_MEMBER)
158 #undef DEFINE_MEMBER
159
160 int RealmFind(Handle<Context> context); 126 int RealmFind(Handle<Context> context);
161 }; 127 };
162 128
163 129
164 LineEditor *LineEditor::current_ = NULL; 130 LineEditor *LineEditor::current_ = NULL;
165 131
166 132
167 LineEditor::LineEditor(Type type, const char* name) 133 LineEditor::LineEditor(Type type, const char* name)
168 : type_(type), name_(name) { 134 : type_(type), name_(name) {
169 if (current_ == NULL || current_->type_ < type) current_ = this; 135 if (current_ == NULL || current_->type_ < type) current_ = this;
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 source, 520 source,
555 String::New(*file), 521 String::New(*file),
556 false, 522 false,
557 true)) { 523 true)) {
558 return Throw("Error executing file"); 524 return Throw("Error executing file");
559 } 525 }
560 } 526 }
561 return Undefined(args.GetIsolate()); 527 return Undefined(args.GetIsolate());
562 } 528 }
563 529
564 static int32_t convertToInt(Local<Value> value_in, TryCatch* try_catch) {
565 if (value_in->IsInt32()) {
566 return value_in->Int32Value();
567 }
568
569 Local<Value> number = value_in->ToNumber();
570 if (try_catch->HasCaught()) return 0;
571
572 ASSERT(number->IsNumber());
573 Local<Int32> int32 = number->ToInt32();
574 if (try_catch->HasCaught() || int32.IsEmpty()) return 0;
575
576 int32_t value = int32->Int32Value();
577 if (try_catch->HasCaught()) return 0;
578
579 return value;
580 }
581
582
583 static int32_t convertToUint(Local<Value> value_in, TryCatch* try_catch) {
584 int32_t raw_value = convertToInt(value_in, try_catch);
585 if (try_catch->HasCaught()) return 0;
586
587 if (raw_value < 0) {
588 Throw("Array length must not be negative.");
589 return 0;
590 }
591
592 static const int kMaxLength = 0x3fffffff;
593 #ifndef V8_SHARED
594 ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
595 #endif // V8_SHARED
596 if (raw_value > static_cast<int32_t>(kMaxLength)) {
597 Throw("Array length exceeds maximum length.");
598 }
599 return raw_value;
600 }
601
602
603 Handle<Value> Shell::CreateExternalArrayBuffer(Isolate* isolate,
604 Handle<Object> buffer,
605 int32_t length) {
606 static const int32_t kMaxSize = 0x7fffffff;
607 // Make sure the total size fits into a (signed) int.
608 if (length < 0 || length > kMaxSize) {
609 return Throw("ArrayBuffer exceeds maximum size (2G)");
610 }
611 uint8_t* data = new uint8_t[length];
612 if (data == NULL) {
613 return Throw("Memory allocation failed");
614 }
615 memset(data, 0, length);
616
617 buffer->SetHiddenValue(
618 PerIsolateData::ArrayBufferMarkerPropName_string(isolate), True());
619 Persistent<Object> persistent_array =
620 Persistent<Object>::New(isolate, buffer);
621 persistent_array.MakeWeak(isolate, data, ExternalArrayWeakCallback);
622 persistent_array.MarkIndependent(isolate);
623 isolate->AdjustAmountOfExternalAllocatedMemory(length);
624
625 buffer->SetIndexedPropertiesToExternalArrayData(
626 data, v8::kExternalByteArray, length);
627 buffer->Set(PerIsolateData::byteLength_string(isolate),
628 Int32::New(length, isolate),
629 ReadOnly);
630
631 return buffer;
632 }
633
634
635 Handle<Value> Shell::ArrayBuffer(const Arguments& args) {
636 if (!args.IsConstructCall()) {
637 Handle<Value>* rec_args = new Handle<Value>[args.Length()];
638 for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
639 Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
640 delete[] rec_args;
641 return result;
642 }
643
644 if (args.Length() == 0) {
645 return Throw("ArrayBuffer constructor must have one argument");
646 }
647 TryCatch try_catch;
648 int32_t length = convertToUint(args[0], &try_catch);
649 if (try_catch.HasCaught()) return try_catch.ReThrow();
650
651 return CreateExternalArrayBuffer(args.GetIsolate(), args.This(), length);
652 }
653
654
655 Handle<Object> Shell::CreateExternalArray(Isolate* isolate,
656 Handle<Object> array,
657 Handle<Object> buffer,
658 ExternalArrayType type,
659 int32_t length,
660 int32_t byteLength,
661 int32_t byteOffset,
662 int32_t element_size) {
663 ASSERT(element_size == 1 || element_size == 2 ||
664 element_size == 4 || element_size == 8);
665 ASSERT(byteLength == length * element_size);
666
667 void* data = buffer->GetIndexedPropertiesExternalArrayData();
668 ASSERT(data != NULL);
669
670 array->SetIndexedPropertiesToExternalArrayData(
671 static_cast<uint8_t*>(data) + byteOffset, type, length);
672 array->SetHiddenValue(PerIsolateData::ArrayMarkerPropName_string(isolate),
673 Int32::New(type, isolate));
674 array->Set(PerIsolateData::byteLength_string(isolate),
675 Int32::New(byteLength, isolate),
676 ReadOnly);
677 array->Set(PerIsolateData::byteOffset_string(isolate),
678 Int32::New(byteOffset, isolate),
679 ReadOnly);
680 array->Set(PerIsolateData::length_string(isolate),
681 Int32::New(length, isolate),
682 ReadOnly);
683 array->Set(PerIsolateData::BYTES_PER_ELEMENT_string(isolate),
684 Int32::New(element_size, isolate));
685 array->Set(PerIsolateData::buffer_string(isolate),
686 buffer,
687 ReadOnly);
688
689 return array;
690 }
691
692
693 Handle<Value> Shell::CreateExternalArray(const Arguments& args,
694 ExternalArrayType type,
695 int32_t element_size) {
696 Isolate* isolate = args.GetIsolate();
697 if (!args.IsConstructCall()) {
698 Handle<Value>* rec_args = new Handle<Value>[args.Length()];
699 for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i];
700 Handle<Value> result = args.Callee()->NewInstance(args.Length(), rec_args);
701 delete[] rec_args;
702 return result;
703 }
704
705 TryCatch try_catch;
706 ASSERT(element_size == 1 || element_size == 2 ||
707 element_size == 4 || element_size == 8);
708
709 // All of the following constructors are supported:
710 // TypedArray(unsigned long length)
711 // TypedArray(type[] array)
712 // TypedArray(TypedArray array)
713 // TypedArray(ArrayBuffer buffer,
714 // optional unsigned long byteOffset,
715 // optional unsigned long length)
716 Handle<Object> buffer;
717 int32_t length;
718 int32_t byteLength;
719 int32_t byteOffset;
720 bool init_from_array = false;
721 if (args.Length() == 0) {
722 return Throw("Array constructor must have at least one argument");
723 }
724 if (args[0]->IsObject() &&
725 !args[0]->ToObject()->GetHiddenValue(
726 PerIsolateData::ArrayBufferMarkerPropName_string(isolate)).IsEmpty()) {
727 // Construct from ArrayBuffer.
728 buffer = args[0]->ToObject();
729 int32_t bufferLength = convertToUint(
730 buffer->Get(PerIsolateData::byteLength_string(isolate)), &try_catch);
731 if (try_catch.HasCaught()) return try_catch.ReThrow();
732
733 if (args.Length() < 2 || args[1]->IsUndefined()) {
734 byteOffset = 0;
735 } else {
736 byteOffset = convertToUint(args[1], &try_catch);
737 if (try_catch.HasCaught()) return try_catch.ReThrow();
738 if (byteOffset > bufferLength) {
739 return Throw("byteOffset out of bounds");
740 }
741 if (byteOffset % element_size != 0) {
742 return Throw("byteOffset must be multiple of element size");
743 }
744 }
745
746 if (args.Length() < 3 || args[2]->IsUndefined()) {
747 byteLength = bufferLength - byteOffset;
748 length = byteLength / element_size;
749 if (byteLength % element_size != 0) {
750 return Throw("buffer size must be multiple of element size");
751 }
752 } else {
753 length = convertToUint(args[2], &try_catch);
754 if (try_catch.HasCaught()) return try_catch.ReThrow();
755 byteLength = length * element_size;
756 if (byteOffset + byteLength > bufferLength) {
757 return Throw("length out of bounds");
758 }
759 }
760 } else {
761 if (args[0]->IsObject() &&
762 args[0]->ToObject()->Has(PerIsolateData::length_string(isolate))) {
763 // Construct from array.
764 Local<Value> value =
765 args[0]->ToObject()->Get(PerIsolateData::length_string(isolate));
766 if (try_catch.HasCaught()) return try_catch.ReThrow();
767 length = convertToUint(value, &try_catch);
768 if (try_catch.HasCaught()) return try_catch.ReThrow();
769 init_from_array = true;
770 } else {
771 // Construct from size.
772 length = convertToUint(args[0], &try_catch);
773 if (try_catch.HasCaught()) return try_catch.ReThrow();
774 }
775 byteLength = length * element_size;
776 byteOffset = 0;
777
778 Handle<Object> global = Context::GetCurrent()->Global();
779 Handle<Value> array_buffer =
780 global->Get(PerIsolateData::ArrayBuffer_string(isolate));
781 ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction());
782 Handle<Value> buffer_args[] = { Uint32::New(byteLength, isolate) };
783 Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance(
784 1, buffer_args);
785 if (try_catch.HasCaught()) return result;
786 buffer = result->ToObject();
787 }
788
789 Handle<Object> array =
790 CreateExternalArray(isolate, args.This(), buffer, type, length,
791 byteLength, byteOffset, element_size);
792
793 if (init_from_array) {
794 Handle<Object> init = args[0]->ToObject();
795 for (int i = 0; i < length; ++i) {
796 Local<Value> value = init->Get(i);
797 if (try_catch.HasCaught()) return try_catch.ReThrow();
798 array->Set(i, value);
799 }
800 }
801
802 return array;
803 }
804
805
806 Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) {
807 TryCatch try_catch;
808
809 if (!args.This()->IsObject()) {
810 return Throw("'slice' invoked on non-object receiver");
811 }
812
813 Isolate* isolate = args.GetIsolate();
814 Local<Object> self = args.This();
815 Local<Value> marker = self->GetHiddenValue(
816 PerIsolateData::ArrayBufferMarkerPropName_string(isolate));
817 if (marker.IsEmpty()) {
818 return Throw("'slice' invoked on wrong receiver type");
819 }
820
821 int32_t length = convertToUint(
822 self->Get(PerIsolateData::byteLength_string(isolate)), &try_catch);
823 if (try_catch.HasCaught()) return try_catch.ReThrow();
824
825 if (args.Length() == 0) {
826 return Throw("'slice' must have at least one argument");
827 }
828 int32_t begin = convertToInt(args[0], &try_catch);
829 if (try_catch.HasCaught()) return try_catch.ReThrow();
830 if (begin < 0) begin += length;
831 if (begin < 0) begin = 0;
832 if (begin > length) begin = length;
833
834 int32_t end;
835 if (args.Length() < 2 || args[1]->IsUndefined()) {
836 end = length;
837 } else {
838 end = convertToInt(args[1], &try_catch);
839 if (try_catch.HasCaught()) return try_catch.ReThrow();
840 if (end < 0) end += length;
841 if (end < 0) end = 0;
842 if (end > length) end = length;
843 if (end < begin) end = begin;
844 }
845
846 Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
847 Handle<Value> new_args[] = { Uint32::New(end - begin, isolate) };
848 Handle<Value> result = constructor->NewInstance(1, new_args);
849 if (try_catch.HasCaught()) return result;
850 Handle<Object> buffer = result->ToObject();
851 uint8_t* dest =
852 static_cast<uint8_t*>(buffer->GetIndexedPropertiesExternalArrayData());
853 uint8_t* src = begin + static_cast<uint8_t*>(
854 self->GetIndexedPropertiesExternalArrayData());
855 memcpy(dest, src, end - begin);
856
857 return buffer;
858 }
859
860
861 Handle<Value> Shell::ArraySubArray(const Arguments& args) {
862 TryCatch try_catch;
863
864 if (!args.This()->IsObject()) {
865 return Throw("'subarray' invoked on non-object receiver");
866 }
867
868 Isolate* isolate = args.GetIsolate();
869 Local<Object> self = args.This();
870 Local<Value> marker =
871 self->GetHiddenValue(PerIsolateData::ArrayMarkerPropName_string(isolate));
872 if (marker.IsEmpty()) {
873 return Throw("'subarray' invoked on wrong receiver type");
874 }
875
876 Handle<Object> buffer =
877 self->Get(PerIsolateData::buffer_string(isolate))->ToObject();
878 if (try_catch.HasCaught()) return try_catch.ReThrow();
879 int32_t length = convertToUint(
880 self->Get(PerIsolateData::length_string(isolate)), &try_catch);
881 if (try_catch.HasCaught()) return try_catch.ReThrow();
882 int32_t byteOffset = convertToUint(
883 self->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch);
884 if (try_catch.HasCaught()) return try_catch.ReThrow();
885 int32_t element_size = convertToUint(
886 self->Get(PerIsolateData::BYTES_PER_ELEMENT_string(isolate)), &try_catch);
887 if (try_catch.HasCaught()) return try_catch.ReThrow();
888
889 if (args.Length() == 0) {
890 return Throw("'subarray' must have at least one argument");
891 }
892 int32_t begin = convertToInt(args[0], &try_catch);
893 if (try_catch.HasCaught()) return try_catch.ReThrow();
894 if (begin < 0) begin += length;
895 if (begin < 0) begin = 0;
896 if (begin > length) begin = length;
897
898 int32_t end;
899 if (args.Length() < 2 || args[1]->IsUndefined()) {
900 end = length;
901 } else {
902 end = convertToInt(args[1], &try_catch);
903 if (try_catch.HasCaught()) return try_catch.ReThrow();
904 if (end < 0) end += length;
905 if (end < 0) end = 0;
906 if (end > length) end = length;
907 if (end < begin) end = begin;
908 }
909
910 length = end - begin;
911 byteOffset += begin * element_size;
912
913 Local<Function> constructor = Local<Function>::Cast(self->GetConstructor());
914 Handle<Value> construct_args[] = {
915 buffer, Uint32::New(byteOffset, isolate), Uint32::New(length, isolate)
916 };
917 return constructor->NewInstance(3, construct_args);
918 }
919
920
921 Handle<Value> Shell::ArraySet(const Arguments& args) {
922 TryCatch try_catch;
923
924 if (!args.This()->IsObject()) {
925 return Throw("'set' invoked on non-object receiver");
926 }
927
928 Isolate* isolate = args.GetIsolate();
929 Local<Object> self = args.This();
930 Local<Value> marker =
931 self->GetHiddenValue(PerIsolateData::ArrayMarkerPropName_string(isolate));
932 if (marker.IsEmpty()) {
933 return Throw("'set' invoked on wrong receiver type");
934 }
935 int32_t length = convertToUint(
936 self->Get(PerIsolateData::length_string(isolate)), &try_catch);
937 if (try_catch.HasCaught()) return try_catch.ReThrow();
938 int32_t element_size = convertToUint(
939 self->Get(PerIsolateData::BYTES_PER_ELEMENT_string(isolate)), &try_catch);
940 if (try_catch.HasCaught()) return try_catch.ReThrow();
941
942 if (args.Length() == 0) {
943 return Throw("'set' must have at least one argument");
944 }
945 if (!args[0]->IsObject() ||
946 !args[0]->ToObject()->Has(PerIsolateData::length_string(isolate))) {
947 return Throw("'set' invoked with non-array argument");
948 }
949 Handle<Object> source = args[0]->ToObject();
950 int32_t source_length = convertToUint(
951 source->Get(PerIsolateData::length_string(isolate)), &try_catch);
952 if (try_catch.HasCaught()) return try_catch.ReThrow();
953
954 int32_t offset;
955 if (args.Length() < 2 || args[1]->IsUndefined()) {
956 offset = 0;
957 } else {
958 offset = convertToUint(args[1], &try_catch);
959 if (try_catch.HasCaught()) return try_catch.ReThrow();
960 }
961 if (offset + source_length > length) {
962 return Throw("offset or source length out of bounds");
963 }
964
965 int32_t source_element_size;
966 if (source->GetHiddenValue(
967 PerIsolateData::ArrayMarkerPropName_string(isolate)).IsEmpty()) {
968 source_element_size = 0;
969 } else {
970 source_element_size = convertToUint(
971 source->Get(PerIsolateData::BYTES_PER_ELEMENT_string(isolate)),
972 &try_catch);
973 if (try_catch.HasCaught()) return try_catch.ReThrow();
974 }
975
976 if (element_size == source_element_size &&
977 self->GetConstructor()->StrictEquals(source->GetConstructor())) {
978 // Use memmove on the array buffers.
979 Handle<Object> buffer =
980 self->Get(PerIsolateData::buffer_string(isolate))->ToObject();
981 if (try_catch.HasCaught()) return try_catch.ReThrow();
982 Handle<Object> source_buffer =
983 source->Get(PerIsolateData::buffer_string(isolate))->ToObject();
984 if (try_catch.HasCaught()) return try_catch.ReThrow();
985 int32_t byteOffset = convertToUint(
986 self->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch);
987 if (try_catch.HasCaught()) return try_catch.ReThrow();
988 int32_t source_byteOffset = convertToUint(
989 source->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch);
990 if (try_catch.HasCaught()) return try_catch.ReThrow();
991
992 uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>(
993 buffer->GetIndexedPropertiesExternalArrayData());
994 uint8_t* src = source_byteOffset + static_cast<uint8_t*>(
995 source_buffer->GetIndexedPropertiesExternalArrayData());
996 memmove(dest, src, source_length * element_size);
997 } else if (source_element_size == 0) {
998 // Source is not a typed array, copy element-wise sequentially.
999 for (int i = 0; i < source_length; ++i) {
1000 self->Set(offset + i, source->Get(i));
1001 if (try_catch.HasCaught()) return try_catch.ReThrow();
1002 }
1003 } else {
1004 // Need to copy element-wise to make the right conversions.
1005 Handle<Object> buffer =
1006 self->Get(PerIsolateData::buffer_string(isolate))->ToObject();
1007 if (try_catch.HasCaught()) return try_catch.ReThrow();
1008 Handle<Object> source_buffer =
1009 source->Get(PerIsolateData::buffer_string(isolate))->ToObject();
1010 if (try_catch.HasCaught()) return try_catch.ReThrow();
1011
1012 if (buffer->StrictEquals(source_buffer)) {
1013 // Same backing store, need to handle overlap correctly.
1014 // This gets a bit tricky in the case of different element sizes
1015 // (which, of course, is extremely unlikely to ever occur in practice).
1016 int32_t byteOffset = convertToUint(
1017 self->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch);
1018 if (try_catch.HasCaught()) return try_catch.ReThrow();
1019 int32_t source_byteOffset = convertToUint(
1020 source->Get(PerIsolateData::byteOffset_string(isolate)), &try_catch);
1021 if (try_catch.HasCaught()) return try_catch.ReThrow();
1022
1023 // Copy as much as we can from left to right.
1024 int i = 0;
1025 int32_t next_dest_offset = byteOffset + (offset + 1) * element_size;
1026 int32_t next_src_offset = source_byteOffset + source_element_size;
1027 while (i < length && next_dest_offset <= next_src_offset) {
1028 self->Set(offset + i, source->Get(i));
1029 ++i;
1030 next_dest_offset += element_size;
1031 next_src_offset += source_element_size;
1032 }
1033 // Of what's left, copy as much as we can from right to left.
1034 int j = length - 1;
1035 int32_t dest_offset = byteOffset + (offset + j) * element_size;
1036 int32_t src_offset = source_byteOffset + j * source_element_size;
1037 while (j >= i && dest_offset >= src_offset) {
1038 self->Set(offset + j, source->Get(j));
1039 --j;
1040 dest_offset -= element_size;
1041 src_offset -= source_element_size;
1042 }
1043 // There can be at most 8 entries left in the middle that need buffering
1044 // (because the largest element_size is 8 times the smallest).
1045 ASSERT(j+1 - i <= 8);
1046 Handle<Value> temp[8];
1047 for (int k = i; k <= j; ++k) {
1048 temp[k - i] = source->Get(k);
1049 }
1050 for (int k = i; k <= j; ++k) {
1051 self->Set(offset + k, temp[k - i]);
1052 }
1053 } else {
1054 // Different backing stores, safe to copy element-wise sequentially.
1055 for (int i = 0; i < source_length; ++i)
1056 self->Set(offset + i, source->Get(i));
1057 }
1058 }
1059
1060 return Undefined(args.GetIsolate());
1061 }
1062
1063
1064 void Shell::ExternalArrayWeakCallback(v8::Isolate* isolate,
1065 Persistent<Object>* object,
1066 uint8_t* data) {
1067 HandleScope scope(isolate);
1068 int32_t length = (*object)->Get(
1069 PerIsolateData::byteLength_string(isolate))->Uint32Value();
1070 isolate->AdjustAmountOfExternalAllocatedMemory(-length);
1071 delete[] data;
1072 object->Dispose(isolate);
1073 }
1074
1075
1076 Handle<Value> Shell::Int8Array(const Arguments& args) {
1077 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
1078 }
1079
1080
1081 Handle<Value> Shell::Uint8Array(const Arguments& args) {
1082 return CreateExternalArray(args, kExternalUnsignedByteArray, sizeof(uint8_t));
1083 }
1084
1085
1086 Handle<Value> Shell::Int16Array(const Arguments& args) {
1087 return CreateExternalArray(args, kExternalShortArray, sizeof(int16_t));
1088 }
1089
1090
1091 Handle<Value> Shell::Uint16Array(const Arguments& args) {
1092 return CreateExternalArray(
1093 args, kExternalUnsignedShortArray, sizeof(uint16_t));
1094 }
1095
1096
1097 Handle<Value> Shell::Int32Array(const Arguments& args) {
1098 return CreateExternalArray(args, kExternalIntArray, sizeof(int32_t));
1099 }
1100
1101
1102 Handle<Value> Shell::Uint32Array(const Arguments& args) {
1103 return CreateExternalArray(args, kExternalUnsignedIntArray, sizeof(uint32_t));
1104 }
1105
1106
1107 Handle<Value> Shell::Float32Array(const Arguments& args) {
1108 return CreateExternalArray(
1109 args, kExternalFloatArray, sizeof(float)); // NOLINT
1110 }
1111
1112
1113 Handle<Value> Shell::Float64Array(const Arguments& args) {
1114 return CreateExternalArray(
1115 args, kExternalDoubleArray, sizeof(double)); // NOLINT
1116 }
1117
1118
1119 Handle<Value> Shell::Uint8ClampedArray(const Arguments& args) {
1120 return CreateExternalArray(args, kExternalPixelArray, sizeof(uint8_t));
1121 }
1122
1123 530
1124 Handle<Value> Shell::Quit(const Arguments& args) { 531 Handle<Value> Shell::Quit(const Arguments& args) {
1125 int exit_code = args[0]->Int32Value(); 532 int exit_code = args[0]->Int32Value();
1126 OnExit(); 533 OnExit();
1127 exit(exit_code); 534 exit(exit_code);
1128 return Undefined(args.GetIsolate()); 535 return Undefined(args.GetIsolate());
1129 } 536 }
1130 537
1131 538
1132 Handle<Value> Shell::Version(const Arguments& args) { 539 Handle<Value> Shell::Version(const Arguments& args) {
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 0, 1); 812 0, 1);
1406 if (result == BZ_OK) { 813 if (result == BZ_OK) {
1407 *raw_data_size = decompressed_size; 814 *raw_data_size = decompressed_size;
1408 } 815 }
1409 return result; 816 return result;
1410 } 817 }
1411 }; 818 };
1412 #endif 819 #endif
1413 820
1414 821
1415 Handle<FunctionTemplate> Shell::CreateArrayBufferTemplate(
1416 InvocationCallback fun) {
1417 Handle<FunctionTemplate> buffer_template = FunctionTemplate::New(fun);
1418 Local<Template> proto_template = buffer_template->PrototypeTemplate();
1419 proto_template->Set(String::New("slice"),
1420 FunctionTemplate::New(ArrayBufferSlice));
1421 return buffer_template;
1422 }
1423
1424
1425 Handle<FunctionTemplate> Shell::CreateArrayTemplate(InvocationCallback fun) {
1426 Handle<FunctionTemplate> array_template = FunctionTemplate::New(fun);
1427 Local<Template> proto_template = array_template->PrototypeTemplate();
1428 proto_template->Set(String::New("set"), FunctionTemplate::New(ArraySet));
1429 proto_template->Set(String::New("subarray"),
1430 FunctionTemplate::New(ArraySubArray));
1431 return array_template;
1432 }
1433
1434
1435 Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) { 822 Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
1436 Handle<ObjectTemplate> global_template = ObjectTemplate::New(); 823 Handle<ObjectTemplate> global_template = ObjectTemplate::New();
1437 global_template->Set(String::New("print"), FunctionTemplate::New(Print)); 824 global_template->Set(String::New("print"), FunctionTemplate::New(Print));
1438 global_template->Set(String::New("write"), FunctionTemplate::New(Write)); 825 global_template->Set(String::New("write"), FunctionTemplate::New(Write));
1439 global_template->Set(String::New("read"), FunctionTemplate::New(Read)); 826 global_template->Set(String::New("read"), FunctionTemplate::New(Read));
1440 global_template->Set(String::New("readbuffer"), 827 global_template->Set(String::New("readbuffer"),
1441 FunctionTemplate::New(ReadBuffer)); 828 FunctionTemplate::New(ReadBuffer));
1442 global_template->Set(String::New("readline"), 829 global_template->Set(String::New("readline"),
1443 FunctionTemplate::New(ReadLine)); 830 FunctionTemplate::New(ReadLine));
1444 global_template->Set(String::New("load"), FunctionTemplate::New(Load)); 831 global_template->Set(String::New("load"), FunctionTemplate::New(Load));
(...skipping 17 matching lines...) Expand all
1462 realm_template->Set(String::New("dispose"), 849 realm_template->Set(String::New("dispose"),
1463 FunctionTemplate::New(RealmDispose)); 850 FunctionTemplate::New(RealmDispose));
1464 realm_template->Set(String::New("switch"), 851 realm_template->Set(String::New("switch"),
1465 FunctionTemplate::New(RealmSwitch)); 852 FunctionTemplate::New(RealmSwitch));
1466 realm_template->Set(String::New("eval"), 853 realm_template->Set(String::New("eval"),
1467 FunctionTemplate::New(RealmEval)); 854 FunctionTemplate::New(RealmEval));
1468 realm_template->SetAccessor(String::New("shared"), 855 realm_template->SetAccessor(String::New("shared"),
1469 RealmSharedGet, RealmSharedSet); 856 RealmSharedGet, RealmSharedSet);
1470 global_template->Set(String::New("Realm"), realm_template); 857 global_template->Set(String::New("Realm"), realm_template);
1471 858
1472 // Bind the handlers for external arrays.
1473 #ifndef V8_SHARED
1474 if (!i::FLAG_harmony_typed_arrays) {
1475 #endif // V8_SHARED
1476 PropertyAttribute attr =
1477 static_cast<PropertyAttribute>(ReadOnly | DontDelete);
1478 global_template->Set(PerIsolateData::ArrayBuffer_string(isolate),
1479 CreateArrayBufferTemplate(ArrayBuffer), attr);
1480 global_template->Set(String::New("Int8Array"),
1481 CreateArrayTemplate(Int8Array), attr);
1482 global_template->Set(String::New("Uint8Array"),
1483 CreateArrayTemplate(Uint8Array), attr);
1484 global_template->Set(String::New("Int16Array"),
1485 CreateArrayTemplate(Int16Array), attr);
1486 global_template->Set(String::New("Uint16Array"),
1487 CreateArrayTemplate(Uint16Array), attr);
1488 global_template->Set(String::New("Int32Array"),
1489 CreateArrayTemplate(Int32Array), attr);
1490 global_template->Set(String::New("Uint32Array"),
1491 CreateArrayTemplate(Uint32Array), attr);
1492 global_template->Set(String::New("Float32Array"),
1493 CreateArrayTemplate(Float32Array), attr);
1494 global_template->Set(String::New("Float64Array"),
1495 CreateArrayTemplate(Float64Array), attr);
1496 global_template->Set(String::New("Uint8ClampedArray"),
1497 CreateArrayTemplate(Uint8ClampedArray), attr);
1498 #ifndef V8_SHARED
1499 }
1500 #endif // V8_SHARED
1501
1502 #if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64) 859 #if !defined(V8_SHARED) && !defined(_WIN32) && !defined(_WIN64)
1503 Handle<ObjectTemplate> os_templ = ObjectTemplate::New(); 860 Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
1504 AddOSMethods(os_templ); 861 AddOSMethods(os_templ);
1505 global_template->Set(String::New("os"), os_templ); 862 global_template->Set(String::New("os"), os_templ);
1506 #endif // V8_SHARED 863 #endif // V8_SHARED
1507 864
1508 return global_template; 865 return global_template;
1509 } 866 }
1510 867
1511 868
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 int length; 1055 int length;
1699 if (*filename == NULL) { 1056 if (*filename == NULL) {
1700 return Throw("Error loading file"); 1057 return Throw("Error loading file");
1701 } 1058 }
1702 1059
1703 uint8_t* data = reinterpret_cast<uint8_t*>( 1060 uint8_t* data = reinterpret_cast<uint8_t*>(
1704 ReadChars(args.GetIsolate(), *filename, &length)); 1061 ReadChars(args.GetIsolate(), *filename, &length));
1705 if (data == NULL) { 1062 if (data == NULL) {
1706 return Throw("Error reading file"); 1063 return Throw("Error reading file");
1707 } 1064 }
1708 Isolate* isolate = args.GetIsolate(); 1065 Handle<v8::ArrayBuffer> buffer = ArrayBuffer::New(length);
1709 Handle<Object> buffer = Object::New(); 1066 memcpy(buffer->Data(), data, length);
1710 buffer->SetHiddenValue( 1067 delete[] data;
1711 PerIsolateData::ArrayBufferMarkerPropName_string(isolate), True());
1712 Persistent<Object> persistent_buffer =
1713 Persistent<Object>::New(isolate, buffer);
1714 persistent_buffer.MakeWeak(isolate, data, ExternalArrayWeakCallback);
1715 persistent_buffer.MarkIndependent(isolate);
1716 isolate->AdjustAmountOfExternalAllocatedMemory(length);
1717
1718 buffer->SetIndexedPropertiesToExternalArrayData(
1719 data, kExternalUnsignedByteArray, length);
1720 buffer->Set(PerIsolateData::byteLength_string(isolate),
1721 Int32::New(static_cast<int32_t>(length), isolate), ReadOnly);
1722 return buffer; 1068 return buffer;
1723 } 1069 }
1724 1070
1725 1071
1726 #ifndef V8_SHARED 1072 #ifndef V8_SHARED
1727 static char* ReadToken(char* data, char token) { 1073 static char* ReadToken(char* data, char token) {
1728 char* next = i::OS::StrChr(data, token); 1074 char* next = i::OS::StrChr(data, token);
1729 if (next != NULL) { 1075 if (next != NULL) {
1730 *next = '\0'; 1076 *next = '\0';
1731 return (next + 1); 1077 return (next + 1);
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
2256 } 1602 }
2257 1603
2258 } // namespace v8 1604 } // namespace v8
2259 1605
2260 1606
2261 #ifndef GOOGLE3 1607 #ifndef GOOGLE3
2262 int main(int argc, char* argv[]) { 1608 int main(int argc, char* argv[]) {
2263 return v8::Shell::Main(argc, argv); 1609 return v8::Shell::Main(argc, argv);
2264 } 1610 }
2265 #endif 1611 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698