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

Side by Side Diff: runtime/bin/dartutils.cc

Issue 509153003: New bigint implementation in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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
OLDNEW
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 "bin/dartutils.h" 5 #include "bin/dartutils.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "include/dart_native_api.h" 8 #include "include/dart_native_api.h"
9 9
10 #include "platform/assert.h" 10 #include "platform/assert.h"
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 862
863 863
864 Dart_CObject* CObject::NewIntptr(intptr_t value) { 864 Dart_CObject* CObject::NewIntptr(intptr_t value) {
865 // Pointer values passed as intptr_t are always send as int64_t. 865 // Pointer values passed as intptr_t are always send as int64_t.
866 Dart_CObject* cobject = New(Dart_CObject_kInt64); 866 Dart_CObject* cobject = New(Dart_CObject_kInt64);
867 cobject->value.as_int64 = value; 867 cobject->value.as_int64 = value;
868 return cobject; 868 return cobject;
869 } 869 }
870 870
871 871
872 static bool IsHexDigit(char c) {
873 return (('0' <= c) && (c <= '9'))
874 || (('A' <= c) && (c <= 'F'))
875 || (('a' <= c) && (c <= 'f'));
876 }
877
srdjan 2014/09/08 19:19:49 two lines
regis 2014/09/09 19:18:14 Done.
878 static int HexDigitToInt(char c) {
879 if (('0' <= c) && (c <= '9')) return c - '0';
880 if (('A' <= c) && (c <= 'F')) return 10 + (c - 'A');
881 return 10 + (c - 'a');
882 }
883
884
885 Dart_CObject* CObject::NewBigint(const char* hex_value) {
886 if (hex_value == NULL) {
887 return NULL;
888 }
889 bool neg = false;
890 if (hex_value[0] == '-') {
891 neg = true;
892 hex_value++;
893 }
894 if ((hex_value[0] != '0') ||
895 ((hex_value[1] != 'x') && (hex_value[1] != 'X'))) {
896 return NULL;
897 }
898 hex_value += 2;
899 intptr_t hex_i = strlen(hex_value); // Terminating byte excluded.
900 if (hex_i == 0) {
901 return NULL;
902 }
903 const int kBitsPerHexDigit = 4;
904 const int kHexDigitsPerDigit = 8;
905 const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit;
906 const intptr_t len = (hex_i + kHexDigitsPerDigit - 1) / kHexDigitsPerDigit;
907 Dart_CObject* cobject = New(Dart_CObject_kBigint);
908 cobject->value.as_bigint.digits = NewUint32Array(len);
909 uint32_t* digits = reinterpret_cast<uint32_t*>(
910 cobject->value.as_bigint.digits->value.as_typed_data.values);
911 intptr_t used = 0;
912 uint32_t digit = 0;
913 intptr_t bit_i = 0;
914 while (--hex_i >= 0) {
915 if (!IsHexDigit(hex_value[hex_i])) {
916 return NULL;
917 }
918 digit += HexDigitToInt(hex_value[hex_i]) << bit_i;
919 bit_i += kBitsPerHexDigit;
920 if (bit_i == kBitsPerDigit) {
921 bit_i = 0;
922 digits[used++] = digit;
923 digit = 0;
924 }
925 }
926 if (bit_i != 0) {
927 digits[used++] = digit;
928 }
929 while ((used > 0) && (digits[used - 1] == 0)) {
930 used--;
931 }
932 cobject->value.as_bigint.used = used;
933 if (used == 0) {
934 neg = false;
935 }
936 cobject->value.as_bigint.neg = neg;
937 return cobject;
938 }
939
940
941 static char IntToHexDigit(int i) {
942 ASSERT(0 <= i && i < 16);
943 if (i < 10) return static_cast<char>('0' + i);
944 return static_cast<char>('A' + (i - 10));
945 }
946
947
948 char* CObject::BigintToHexValue(Dart_CObject* bigint) {
949 ASSERT(bigint->type == Dart_CObject_kBigint);
950 const intptr_t used = bigint->value.as_bigint.used;
951 if (used == 0) {
952 const char* zero = "0x0";
953 const size_t len = strlen(zero) + 1;
954 char* hex_value = reinterpret_cast<char*>(malloc(len));
955 strncpy(hex_value, zero, len);
956 return hex_value;
957 }
958 const int kBitsPerHexDigit = 4;
959 const int kHexDigitsPerDigit = 8;
960 const intptr_t kMaxUsed = (kIntptrMax - 4) / kHexDigitsPerDigit;
961 if (used > kMaxUsed) {
962 return NULL;
963 }
964 intptr_t hex_len = (used - 1) * kHexDigitsPerDigit;
965 const uint32_t* digits = reinterpret_cast<uint32_t*>(
966 bigint->value.as_bigint.digits->value.as_typed_data.values);
967 // The most significant digit may use fewer than kHexDigitsPerDigit digits.
968 uint32_t digit = digits[used - 1];
969 ASSERT(digit != 0); // Value must be clamped.
970 while (digit != 0) {
971 hex_len++;
972 digit >>= kBitsPerHexDigit;
973 }
974 const bool neg = bigint->value.as_bigint.neg;
975 // Add bytes for '0x', for the minus sign, and for the trailing \0 character.
976 const int32_t len = (neg ? 1 : 0) + 2 + hex_len + 1;
977 char* hex_value = reinterpret_cast<char*>(malloc(len));
978 intptr_t pos = len;
979 hex_value[--pos] = '\0';
980 for (intptr_t i = 0; i < (used - 1); i++) {
981 digit = digits[i];
982 for (intptr_t j = 0; j < kHexDigitsPerDigit; j++) {
983 hex_value[--pos] = IntToHexDigit(digit & 0xf);
984 digit >>= kBitsPerHexDigit;
985 }
986 }
987 digit = digits[used - 1];
988 while (digit != 0) {
989 hex_value[--pos] = IntToHexDigit(digit & 0xf);
990 digit >>= kBitsPerHexDigit;
991 }
992 hex_value[--pos] = 'x';
993 hex_value[--pos] = '0';
994 if (neg) {
995 hex_value[--pos] = '-';
996 }
997 ASSERT(pos == 0);
998 return hex_value;
999 }
1000
1001
872 Dart_CObject* CObject::NewDouble(double value) { 1002 Dart_CObject* CObject::NewDouble(double value) {
873 Dart_CObject* cobject = New(Dart_CObject_kDouble); 1003 Dart_CObject* cobject = New(Dart_CObject_kDouble);
874 cobject->value.as_double = value; 1004 cobject->value.as_double = value;
875 return cobject; 1005 return cobject;
876 } 1006 }
877 1007
878 1008
879 Dart_CObject* CObject::NewString(intptr_t length) { 1009 Dart_CObject* CObject::NewString(intptr_t length) {
880 Dart_CObject* cobject = New(Dart_CObject_kString, length + 1); 1010 Dart_CObject* cobject = New(Dart_CObject_kString, length + 1);
881 cobject->value.as_string = reinterpret_cast<char*>(cobject + 1); 1011 cobject->value.as_string = reinterpret_cast<char*>(cobject + 1);
(...skipping 21 matching lines...) Expand all
903 1033
904 Dart_CObject* CObject::NewUint8Array(intptr_t length) { 1034 Dart_CObject* CObject::NewUint8Array(intptr_t length) {
905 Dart_CObject* cobject = New(Dart_CObject_kTypedData, length); 1035 Dart_CObject* cobject = New(Dart_CObject_kTypedData, length);
906 cobject->value.as_typed_data.type = Dart_TypedData_kUint8; 1036 cobject->value.as_typed_data.type = Dart_TypedData_kUint8;
907 cobject->value.as_typed_data.length = length; 1037 cobject->value.as_typed_data.length = length;
908 cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1); 1038 cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
909 return cobject; 1039 return cobject;
910 } 1040 }
911 1041
912 1042
1043 Dart_CObject* CObject::NewUint32Array(intptr_t length) {
1044 Dart_CObject* cobject = New(Dart_CObject_kTypedData, 4*length);
1045 cobject->value.as_typed_data.type = Dart_TypedData_kUint32;
1046 cobject->value.as_typed_data.length = length;
1047 cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
1048 return cobject;
1049 }
1050
1051
913 Dart_CObject* CObject::NewExternalUint8Array( 1052 Dart_CObject* CObject::NewExternalUint8Array(
914 intptr_t length, uint8_t* data, void* peer, 1053 intptr_t length, uint8_t* data, void* peer,
915 Dart_WeakPersistentHandleFinalizer callback) { 1054 Dart_WeakPersistentHandleFinalizer callback) {
916 Dart_CObject* cobject = New(Dart_CObject_kExternalTypedData); 1055 Dart_CObject* cobject = New(Dart_CObject_kExternalTypedData);
917 cobject->value.as_external_typed_data.type = Dart_TypedData_kUint8; 1056 cobject->value.as_external_typed_data.type = Dart_TypedData_kUint8;
918 cobject->value.as_external_typed_data.length = length; 1057 cobject->value.as_external_typed_data.length = length;
919 cobject->value.as_external_typed_data.data = data; 1058 cobject->value.as_external_typed_data.data = data;
920 cobject->value.as_external_typed_data.peer = peer; 1059 cobject->value.as_external_typed_data.peer = peer;
921 cobject->value.as_external_typed_data.callback = callback; 1060 cobject->value.as_external_typed_data.callback = callback;
922 return cobject; 1061 return cobject;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 new CObjectString(CObject::NewString(os_error->message())); 1110 new CObjectString(CObject::NewString(os_error->message()));
972 CObjectArray* result = new CObjectArray(CObject::NewArray(3)); 1111 CObjectArray* result = new CObjectArray(CObject::NewArray(3));
973 result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError))); 1112 result->SetAt(0, new CObjectInt32(CObject::NewInt32(kOSError)));
974 result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code()))); 1113 result->SetAt(1, new CObjectInt32(CObject::NewInt32(os_error->code())));
975 result->SetAt(2, error_message); 1114 result->SetAt(2, error_message);
976 return result; 1115 return result;
977 } 1116 }
978 1117
979 } // namespace bin 1118 } // namespace bin
980 } // namespace dart 1119 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698