@@ -2184,41 +2184,8 @@ static term nif_erlang_atom_to_list_1(Context *ctx, int argc, term argv[])
2184
2184
return ret ;
2185
2185
}
2186
2186
2187
- static size_t lltoa (avm_int64_t int_value , unsigned base , char * integer_string )
2188
- {
2189
- int integer_string_len = 0 ;
2190
- bool neg = int_value < 0 ;
2191
- if (neg ) {
2192
- integer_string_len ++ ;
2193
- if (integer_string ) {
2194
- integer_string [0 ] = '-' ;
2195
- }
2196
- }
2197
- avm_int64_t v = int_value ;
2198
- do {
2199
- v = v / base ;
2200
- integer_string_len ++ ;
2201
- } while (v != 0 );
2202
- if (integer_string ) {
2203
- int ix = 1 ;
2204
- do {
2205
- avm_int_t digit = int_value % base ;
2206
- if (digit < 0 ) {
2207
- digit = - digit ;
2208
- }
2209
- if (digit < 10 ) {
2210
- integer_string [integer_string_len - ix ] = '0' + digit ;
2211
- } else {
2212
- integer_string [integer_string_len - ix ] = 'A' + digit - 10 ;
2213
- }
2214
- int_value = int_value / base ;
2215
- ix ++ ;
2216
- } while (int_value != 0 );
2217
- }
2218
- return integer_string_len ;
2219
- }
2220
-
2221
- static term nif_erlang_integer_to_binary_2 (Context * ctx , int argc , term argv [])
2187
+ static term integer_to_buf (Context * ctx , int argc , term argv [], char * tmp_buf , size_t tmp_buf_size ,
2188
+ char * * int_buf , size_t * int_len )
2222
2189
{
2223
2190
term value = argv [0 ];
2224
2191
avm_int_t base = 10 ;
@@ -2231,36 +2198,84 @@ static term nif_erlang_integer_to_binary_2(Context *ctx, int argc, term argv[])
2231
2198
}
2232
2199
}
2233
2200
2234
- avm_int64_t int_value = term_maybe_unbox_int64 (value );
2235
- size_t len = lltoa (int_value , base , NULL );
2201
+ _Static_assert (sizeof (intptr_t ) >= sizeof (avm_int_t ), "Cast to intptr_t is not safe" );
2236
2202
2237
- if (UNLIKELY (memory_ensure_free_opt (ctx , term_binary_heap_size (len ), MEMORY_CAN_SHRINK ) != MEMORY_GC_OK )) {
2203
+ if (term_is_integer (value )) {
2204
+ avm_int_t int_val = term_to_int (value );
2205
+ size_t wlen = intptr_write_to_ascii_buf (int_val , base , tmp_buf + tmp_buf_size );
2206
+ * int_len = wlen ;
2207
+ * int_buf = tmp_buf + tmp_buf_size - wlen ;
2208
+ } else {
2209
+ switch (term_boxed_size (value )) {
2210
+ case 0 :
2211
+ UNREACHABLE ();
2212
+ case 1 : {
2213
+ avm_int_t int_val = term_unbox_int (value );
2214
+ size_t wlen = intptr_write_to_ascii_buf (int_val , base , tmp_buf + tmp_buf_size );
2215
+ * int_len = wlen ;
2216
+ * int_buf = tmp_buf + tmp_buf_size - wlen ;
2217
+ break ;
2218
+ }
2219
+ #if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
2220
+ case 2 : {
2221
+ avm_int64_t int64_val = term_unbox_int64 (value );
2222
+ size_t wlen = int64_write_to_ascii_buf (int64_val , base , tmp_buf + tmp_buf_size );
2223
+ * int_len = wlen ;
2224
+ * int_buf = tmp_buf + tmp_buf_size - wlen ;
2225
+ break ;
2226
+ }
2227
+ #endif
2228
+ default :
2229
+ abort ();
2230
+ }
2231
+ }
2232
+
2233
+ return term_nil ();
2234
+ }
2235
+
2236
+ static term nif_erlang_integer_to_binary_2 (Context * ctx , int argc , term argv [])
2237
+ {
2238
+ #ifdef INT64_TO_A_BUF_LEN
2239
+ size_t tmp_buf_size = INT64_WRITE_TO_ASCII_BUF_LEN ;
2240
+ #else
2241
+ size_t tmp_buf_size = INTPTR_WRITE_TO_ASCII_BUF_LEN ;
2242
+ #endif
2243
+ char tmp_buf [tmp_buf_size ];
2244
+
2245
+ char * int_buf ;
2246
+ size_t int_len ;
2247
+ term maybe_fail_ret
2248
+ = integer_to_buf (ctx , argc , argv , tmp_buf , tmp_buf_size , & int_buf , & int_len );
2249
+ if (UNLIKELY (term_is_invalid_term (maybe_fail_ret ))) {
2250
+ return maybe_fail_ret ;
2251
+ }
2252
+
2253
+ if (UNLIKELY (memory_ensure_free_opt (ctx , term_binary_heap_size (int_len ), MEMORY_CAN_SHRINK )
2254
+ != MEMORY_GC_OK )) {
2238
2255
RAISE_ERROR (OUT_OF_MEMORY_ATOM );
2239
2256
}
2240
- term result = term_create_empty_binary (len , & ctx -> heap , ctx -> global );
2241
- lltoa (int_value , base , (char * ) term_binary_data (result ));
2242
- return result ;
2257
+
2258
+ return term_from_literal_binary (int_buf , int_len , & ctx -> heap , ctx -> global );
2243
2259
}
2244
2260
2245
2261
static term nif_erlang_integer_to_list_2 (Context * ctx , int argc , term argv [])
2246
2262
{
2247
- term value = argv [0 ];
2248
- unsigned base = 10 ;
2249
- VALIDATE_VALUE (value , term_is_any_integer );
2250
- if (argc > 1 ) {
2251
- VALIDATE_VALUE (argv [1 ], term_is_integer );
2252
- base = term_to_int (argv [1 ]);
2253
- if (UNLIKELY (base < 2 || base > 36 )) {
2254
- RAISE_ERROR (BADARG_ATOM );
2255
- }
2256
- }
2263
+ #ifdef INT64_TO_A_BUF_LEN
2264
+ size_t tmp_buf_size = INT64_WRITE_TO_ASCII_BUF_LEN ;
2265
+ #else
2266
+ size_t tmp_buf_size = INTPTR_WRITE_TO_ASCII_BUF_LEN ;
2267
+ #endif
2268
+ char tmp_buf [tmp_buf_size ];
2257
2269
2258
- avm_int64_t int_value = term_maybe_unbox_int64 (value );
2259
- size_t integer_string_len = lltoa (int_value , base , NULL );
2260
- char integer_string [integer_string_len ];
2261
- lltoa (int_value , base , integer_string );
2270
+ char * int_buf ;
2271
+ size_t int_len ;
2272
+ term maybe_fail_ret
2273
+ = integer_to_buf (ctx , argc , argv , tmp_buf , tmp_buf_size , & int_buf , & int_len );
2274
+ if (UNLIKELY (term_is_invalid_term (maybe_fail_ret ))) {
2275
+ return maybe_fail_ret ;
2276
+ }
2262
2277
2263
- return make_list_from_ascii_buf ((uint8_t * ) integer_string , integer_string_len , ctx );
2278
+ return make_list_from_ascii_buf ((uint8_t * ) int_buf , int_len , ctx );
2264
2279
}
2265
2280
2266
2281
static int format_float (term value , int scientific , int decimals , int compact , char * out_buf , int outbuf_len )
0 commit comments