OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/bigint_operations.h" | |
6 #include "vm/dart_api_message.h" | 5 #include "vm/dart_api_message.h" |
7 #include "vm/object.h" | 6 #include "vm/object.h" |
8 #include "vm/snapshot_ids.h" | 7 #include "vm/snapshot_ids.h" |
9 #include "vm/symbols.h" | 8 #include "vm/symbols.h" |
10 #include "vm/unicode.h" | 9 #include "vm/unicode.h" |
11 | 10 |
12 namespace dart { | 11 namespace dart { |
13 | 12 |
14 static const int kNumInitialReferences = 4; | 13 static const int kNumInitialReferences = 4; |
15 | 14 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 } | 84 } |
86 | 85 |
87 | 86 |
88 Dart_CObject* ApiMessageReader::AllocateDartCObjectInt64(int64_t val) { | 87 Dart_CObject* ApiMessageReader::AllocateDartCObjectInt64(int64_t val) { |
89 Dart_CObject* value = AllocateDartCObject(Dart_CObject_kInt64); | 88 Dart_CObject* value = AllocateDartCObject(Dart_CObject_kInt64); |
90 value->value.as_int64 = val; | 89 value->value.as_int64 = val; |
91 return value; | 90 return value; |
92 } | 91 } |
93 | 92 |
94 | 93 |
95 Dart_CObject* ApiMessageReader::AllocateDartCObjectBigint(intptr_t length) { | 94 Dart_CObject* ApiMessageReader::AllocateDartCObjectBigint() { |
96 // Allocate a Dart_CObject structure followed by an array of chars | 95 Dart_CObject* value = AllocateDartCObject(Dart_CObject_kBigint); |
97 // for the bigint hex string content. The pointer to the bigint | 96 value->value.as_bigint.neg = false; |
98 // content is set up to this area. | 97 value->value.as_bigint.used = 0; |
99 Dart_CObject* value = | 98 value->value.as_bigint.digits = NULL; |
100 reinterpret_cast<Dart_CObject*>( | |
101 alloc_(NULL, 0, sizeof(Dart_CObject) + length + 1)); | |
102 value->value.as_bigint = reinterpret_cast<char*>(value) + sizeof(*value); | |
103 value->type = Dart_CObject_kBigint; | 99 value->type = Dart_CObject_kBigint; |
104 return value; | 100 return value; |
105 } | 101 } |
106 | 102 |
107 | 103 |
108 Dart_CObject* ApiMessageReader::AllocateDartCObjectDouble(double val) { | 104 Dart_CObject* ApiMessageReader::AllocateDartCObjectDouble(double val) { |
109 Dart_CObject* value = AllocateDartCObject(Dart_CObject_kDouble); | 105 Dart_CObject* value = AllocateDartCObject(Dart_CObject_kDouble); |
110 value->value.as_double = val; | 106 value->value.as_double = val; |
111 return value; | 107 return value; |
112 } | 108 } |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 Dart_CObject* object; | 511 Dart_CObject* object; |
516 if ((kMinInt32 <= value64) && (value64 <= kMaxInt32)) { | 512 if ((kMinInt32 <= value64) && (value64 <= kMaxInt32)) { |
517 object = AllocateDartCObjectInt32(static_cast<int32_t>(value64)); | 513 object = AllocateDartCObjectInt32(static_cast<int32_t>(value64)); |
518 } else { | 514 } else { |
519 object = AllocateDartCObjectInt64(value64); | 515 object = AllocateDartCObjectInt64(value64); |
520 } | 516 } |
521 AddBackRef(object_id, object, kIsDeserialized); | 517 AddBackRef(object_id, object, kIsDeserialized); |
522 return object; | 518 return object; |
523 } | 519 } |
524 case kBigintCid: { | 520 case kBigintCid: { |
525 // Read in the hex string representation of the bigint. | 521 // Allocate an empty bigint which will be updated when its contents |
526 intptr_t len = ReadIntptrValue(); | 522 // has been deserialized. |
527 Dart_CObject* object = AllocateDartCObjectBigint(len); | 523 Dart_CObject* object = AllocateDartCObjectBigint(); |
528 AddBackRef(object_id, object, kIsDeserialized); | 524 AddBackRef(object_id, object, kIsDeserialized); |
529 char* p = object->value.as_bigint; | 525 Dart_CObject* neg_obj = ReadObjectImpl(); |
530 for (intptr_t i = 0; i < len; i++) { | 526 ASSERT(neg_obj->type == Dart_CObject_kBool); |
531 p[i] = Read<uint8_t>(); | 527 const bool neg = neg_obj->value.as_bool; |
532 } | 528 Dart_CObject* used_obj = ReadObjectImpl(); |
533 p[len] = '\0'; | 529 ASSERT(used_obj->type == Dart_CObject_kInt32); |
| 530 const intptr_t used = used_obj->value.as_int32; |
| 531 Dart_CObject* digits = ReadObjectImpl(); |
| 532 ASSERT(digits->type == Dart_CObject_kTypedData); |
| 533 ASSERT(digits->value.as_typed_data.type == Dart_TypedData_kUint32); |
| 534 ASSERT(digits->value.as_typed_data.length >= 4*used); |
| 535 // Update the bigint object. |
| 536 object->value.as_bigint.neg = neg; |
| 537 object->value.as_bigint.used = used; |
| 538 object->value.as_bigint.digits = digits; |
534 return object; | 539 return object; |
535 } | 540 } |
536 case kDoubleCid: { | 541 case kDoubleCid: { |
537 // Doubles are handled specially when being sent as part of message | 542 // Doubles are handled specially when being sent as part of message |
538 // snapshots. | 543 // snapshots. |
539 UNREACHABLE(); | 544 UNREACHABLE(); |
540 } | 545 } |
541 case kOneByteStringCid: { | 546 case kOneByteStringCid: { |
542 intptr_t len = ReadSmiValue(); | 547 intptr_t len = ReadSmiValue(); |
543 intptr_t hash = ReadSmiValue(); | 548 intptr_t hash = ReadSmiValue(); |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 WriteVMIsolateObject(kFalseValue); | 1038 WriteVMIsolateObject(kFalseValue); |
1034 } | 1039 } |
1035 break; | 1040 break; |
1036 case Dart_CObject_kInt32: | 1041 case Dart_CObject_kInt32: |
1037 WriteInt32(object); | 1042 WriteInt32(object); |
1038 break; | 1043 break; |
1039 case Dart_CObject_kInt64: | 1044 case Dart_CObject_kInt64: |
1040 WriteInt64(object); | 1045 WriteInt64(object); |
1041 break; | 1046 break; |
1042 case Dart_CObject_kBigint: { | 1047 case Dart_CObject_kBigint: { |
1043 char* hex_string = object->value.as_bigint; | |
1044 const intptr_t chunk_len = | |
1045 BigintOperations::ComputeChunkLength(hex_string); | |
1046 if (chunk_len < 0 || | |
1047 chunk_len > Bigint::kMaxElements) { | |
1048 return false; | |
1049 } | |
1050 // Write out the serialization header value for this object. | 1048 // Write out the serialization header value for this object. |
1051 WriteInlinedHeader(object); | 1049 WriteInlinedHeader(object); |
1052 // Write out the class and tags information. | 1050 // Write out the class and tags information. |
1053 WriteIndexedObject(kBigintCid); | 1051 WriteIndexedObject(kBigintCid); |
1054 WriteTags(0); | 1052 WriteTags(0); |
1055 // Write hex string length and content | 1053 // Write neg field. |
1056 intptr_t len = strlen(hex_string); | 1054 if (object->value.as_bigint.neg) { |
1057 WriteIntptrValue(len); | 1055 WriteVMIsolateObject(kTrueValue); |
1058 for (intptr_t i = 0; i < len; i++) { | 1056 } else { |
1059 Write<uint8_t>(hex_string[i]); | 1057 WriteVMIsolateObject(kFalseValue); |
1060 } | 1058 } |
| 1059 // Write used field. |
| 1060 WriteSmi(object->value.as_bigint.used); |
| 1061 // Write digits as TypedData (or NullObject). |
| 1062 WriteCObject(object->value.as_bigint.digits); |
1061 break; | 1063 break; |
1062 } | 1064 } |
1063 case Dart_CObject_kDouble: | 1065 case Dart_CObject_kDouble: |
1064 WriteVMIsolateObject(kDoubleObject); | 1066 WriteVMIsolateObject(kDoubleObject); |
1065 WriteDouble(object->value.as_double); | 1067 WriteDouble(object->value.as_double); |
1066 break; | 1068 break; |
1067 case Dart_CObject_kString: { | 1069 case Dart_CObject_kString: { |
1068 const uint8_t* utf8_str = | 1070 const uint8_t* utf8_str = |
1069 reinterpret_cast<const uint8_t*>(object->value.as_string); | 1071 reinterpret_cast<const uint8_t*>(object->value.as_string); |
1070 intptr_t utf8_len = strlen(object->value.as_string); | 1072 intptr_t utf8_len = strlen(object->value.as_string); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 WriteInlinedHeader(object); | 1119 WriteInlinedHeader(object); |
1118 // Write out the class and tags information. | 1120 // Write out the class and tags information. |
1119 intptr_t class_id; | 1121 intptr_t class_id; |
1120 switch (object->value.as_typed_data.type) { | 1122 switch (object->value.as_typed_data.type) { |
1121 case Dart_TypedData_kInt8: | 1123 case Dart_TypedData_kInt8: |
1122 class_id = kTypedDataInt8ArrayCid; | 1124 class_id = kTypedDataInt8ArrayCid; |
1123 break; | 1125 break; |
1124 case Dart_TypedData_kUint8: | 1126 case Dart_TypedData_kUint8: |
1125 class_id = kTypedDataUint8ArrayCid; | 1127 class_id = kTypedDataUint8ArrayCid; |
1126 break; | 1128 break; |
| 1129 case Dart_TypedData_kUint32: |
| 1130 class_id = kTypedDataUint32ArrayCid; |
| 1131 break; |
1127 default: | 1132 default: |
1128 class_id = kTypedDataUint8ArrayCid; | 1133 class_id = kTypedDataUint8ArrayCid; |
1129 UNIMPLEMENTED(); | 1134 UNIMPLEMENTED(); |
1130 } | 1135 } |
1131 | 1136 |
1132 intptr_t len = object->value.as_typed_data.length; | 1137 intptr_t len = object->value.as_typed_data.length; |
1133 if (len < 0 || | 1138 if (len < 0 || |
1134 len > TypedData::MaxElements(class_id)) { | 1139 len > TypedData::MaxElements(class_id)) { |
1135 return false; | 1140 return false; |
1136 } | 1141 } |
1137 | 1142 |
1138 WriteIndexedObject(class_id); | 1143 WriteIndexedObject(class_id); |
1139 WriteTags(RawObject::ClassIdTag::update(class_id, 0)); | 1144 WriteTags(RawObject::ClassIdTag::update(class_id, 0)); |
1140 WriteSmi(len); | 1145 WriteSmi(len); |
1141 uint8_t* bytes = object->value.as_typed_data.values; | 1146 switch (class_id) { |
1142 for (intptr_t i = 0; i < len; i++) { | 1147 case kTypedDataInt8ArrayCid: |
1143 Write<uint8_t>(bytes[i]); | 1148 case kTypedDataUint8ArrayCid: { |
| 1149 uint8_t* bytes = object->value.as_typed_data.values; |
| 1150 for (intptr_t i = 0; i < len; i++) { |
| 1151 Write<uint8_t>(bytes[i]); |
| 1152 } |
| 1153 break; |
| 1154 } |
| 1155 case kTypedDataUint32ArrayCid: { |
| 1156 uint32_t* words = |
| 1157 reinterpret_cast<uint32_t*>(object->value.as_typed_data.values); |
| 1158 for (intptr_t i = 0; i < len; i++) { |
| 1159 Write<uint32_t>(words[i]); |
| 1160 } |
| 1161 break; |
| 1162 } |
| 1163 default: |
| 1164 UNIMPLEMENTED(); |
1144 } | 1165 } |
1145 break; | 1166 break; |
1146 } | 1167 } |
1147 case Dart_CObject_kExternalTypedData: { | 1168 case Dart_CObject_kExternalTypedData: { |
1148 // TODO(ager): we are writing C pointers into the message in | 1169 // TODO(ager): we are writing C pointers into the message in |
1149 // order to post external arrays through ports. We need to make | 1170 // order to post external arrays through ports. We need to make |
1150 // sure that messages containing pointers can never be posted | 1171 // sure that messages containing pointers can never be posted |
1151 // to other processes. | 1172 // to other processes. |
1152 | 1173 |
1153 // Write out serialization header value for this object. | 1174 // Write out serialization header value for this object. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 if (!success) { | 1215 if (!success) { |
1195 UnmarkAllCObjects(object); | 1216 UnmarkAllCObjects(object); |
1196 return false; | 1217 return false; |
1197 } | 1218 } |
1198 } | 1219 } |
1199 UnmarkAllCObjects(object); | 1220 UnmarkAllCObjects(object); |
1200 return true; | 1221 return true; |
1201 } | 1222 } |
1202 | 1223 |
1203 } // namespace dart | 1224 } // namespace dart |
OLD | NEW |