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

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

Powered by Google App Engine
This is Rietveld 408576698