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 "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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |