2
2
//!
3
3
//!
4
4
//! See https://tc39.github.io/ecma262/#sec-literals-numeric-literals
5
- use std:: { borrow:: Cow , fmt :: Write } ;
5
+ use std:: borrow:: Cow ;
6
6
7
7
use either:: Either ;
8
8
use num_bigint:: BigInt as BigIntValue ;
9
9
use num_traits:: { Num as NumTrait , ToPrimitive } ;
10
- use smartstring:: LazyCompact ;
11
10
use swc_common:: SyntaxContext ;
12
11
use tracing:: trace;
13
12
@@ -46,7 +45,6 @@ impl<'a> Lexer<'a> {
46
45
}
47
46
48
47
let start = self . cur_pos ( ) ;
49
- let mut raw_val = SmartString :: < LazyCompact > :: new ( ) ;
50
48
51
49
let val = if starts_with_dot {
52
50
// first char is '.'
@@ -70,8 +68,6 @@ impl<'a> Lexer<'a> {
70
68
) ) ) ;
71
69
}
72
70
73
- write ! ( raw_val, "{}" , & s. value) . unwrap ( ) ;
74
-
75
71
if starts_with_zero {
76
72
// TODO: I guess it would be okay if I don't use -ffast-math
77
73
// (or something like that), but needs review.
@@ -146,29 +142,28 @@ impl<'a> Lexer<'a> {
146
142
//
147
143
// `.1.a`, `.1e-4.a` are valid,
148
144
if self . cur ( ) == Some ( '.' ) {
149
- raw_val. push ( '.' ) ;
150
-
151
145
self . bump ( ) ;
152
146
153
147
if starts_with_dot {
154
148
debug_assert ! ( self . cur( ) . is_some( ) ) ;
155
149
debug_assert ! ( self . cur( ) . unwrap( ) . is_ascii_digit( ) ) ;
156
150
}
157
151
158
- let mut raw = Raw ( Some ( Default :: default ( ) ) ) ;
159
152
// Read numbers after dot
160
- let dec_val = self . read_int :: < 10 > ( 0 , & mut raw ) ?;
153
+ self . read_int :: < 10 > ( 0 ) ?;
161
154
162
155
val = {
163
- if dec_val. is_some ( ) {
164
- raw_val. push_str ( raw. 0 . as_ref ( ) . unwrap ( ) ) ;
165
- }
156
+ let end = self . cur_pos ( ) ;
157
+ let raw = unsafe {
158
+ // Safety: We got both start and end position from `self.input`
159
+ self . input . slice ( start, end)
160
+ } ;
166
161
167
162
// Remove number separator from number
168
- if raw_val . contains ( '_' ) {
169
- Cow :: Owned ( raw_val . replace ( '_' , "" ) )
163
+ if raw . contains ( '_' ) {
164
+ Cow :: Owned ( raw . replace ( '_' , "" ) )
170
165
} else {
171
- Cow :: Borrowed ( & * raw_val )
166
+ Cow :: Borrowed ( raw )
172
167
}
173
168
. parse ( )
174
169
. expect ( "failed to parse float using rust's impl" )
@@ -193,8 +188,6 @@ impl<'a> Lexer<'a> {
193
188
}
194
189
} ;
195
190
196
- raw_val. push ( 'e' ) ;
197
-
198
191
let positive = if next == '+' || next == '-' {
199
192
self . bump ( ) ; // remove '+', '-'
200
193
@@ -203,8 +196,7 @@ impl<'a> Lexer<'a> {
203
196
true
204
197
} ;
205
198
206
- let mut raw = Raw ( Some ( Default :: default ( ) ) ) ;
207
- let exp = self . read_number_no_dot :: < 10 > ( & mut raw) ?;
199
+ let exp = self . read_number_no_dot :: < 10 > ( ) ?;
208
200
209
201
val = if exp == f64:: INFINITY {
210
202
if positive && val != 0.0 {
@@ -213,16 +205,16 @@ impl<'a> Lexer<'a> {
213
205
0.0
214
206
}
215
207
} else {
216
- let flag = if positive { '+' } else { '-' } ;
217
-
218
- raw_val . push ( flag ) ;
219
-
220
- write ! ( raw_val , "{}" , exp ) . unwrap ( ) ;
221
-
222
- if raw_val . contains ( '_' ) {
223
- Cow :: Owned ( raw_val . replace ( '_' , "" ) )
208
+ let end = self . cur_pos ( ) ;
209
+ let raw = unsafe {
210
+ // Safety: We got both start and end position from `self.input`
211
+ self . input . slice ( start , end )
212
+ } ;
213
+
214
+ if raw . contains ( '_' ) {
215
+ Cow :: Owned ( raw . replace ( '_' , "" ) )
224
216
} else {
225
- Cow :: Borrowed ( & * raw_val )
217
+ Cow :: Borrowed ( raw )
226
218
}
227
219
. parse ( )
228
220
. expect ( "failed to parse float literal" )
@@ -293,7 +285,7 @@ impl<'a> Lexer<'a> {
293
285
294
286
/// This can read long integers like
295
287
/// "13612536612375123612312312312312312312312".
296
- fn read_number_no_dot < const RADIX : u8 > ( & mut self , raw : & mut Raw ) -> LexResult < f64 > {
288
+ fn read_number_no_dot < const RADIX : u8 > ( & mut self ) -> LexResult < f64 > {
297
289
debug_assert ! (
298
290
RADIX == 2 || RADIX == 8 || RADIX == 10 || RADIX == 16 ,
299
291
"radix for read_number_no_dot should be one of 2, 8, 10, 16, but got {}" ,
@@ -309,7 +301,6 @@ impl<'a> Lexer<'a> {
309
301
310
302
Ok ( ( f64:: mul_add ( total, radix as f64 , v as f64 ) , true ) )
311
303
} ,
312
- raw,
313
304
true ,
314
305
) ;
315
306
@@ -336,8 +327,6 @@ impl<'a> Lexer<'a> {
336
327
let mut non_octal = false ;
337
328
let mut read_any = false ;
338
329
339
- let mut raw = Raw ( Some ( Default :: default ( ) ) ) ;
340
-
341
330
self . read_digits :: < _ , f64 , RADIX > (
342
331
|total, radix, v| {
343
332
read_any = true ;
@@ -348,17 +337,20 @@ impl<'a> Lexer<'a> {
348
337
349
338
Ok ( ( f64:: mul_add ( total, radix as f64 , v as f64 ) , true ) )
350
339
} ,
351
- & mut raw,
352
340
true ,
353
341
) ?;
354
342
355
343
if !read_any {
356
344
self . error ( start, SyntaxError :: ExpectedDigit { radix : RADIX } ) ?;
357
345
}
358
346
359
- let raw_str = raw. 0 . take ( ) . unwrap ( ) ;
347
+ let end = self . cur_pos ( ) ;
348
+ let raw = unsafe {
349
+ // Safety: We got both start and end position from `self.input`
350
+ self . input . slice ( start, end)
351
+ } ;
360
352
// Remove number separator from number
361
- let raw_number_str = raw_str . replace ( '_' , "" ) ;
353
+ let raw_number_str = raw . replace ( '_' , "" ) ;
362
354
let parsed_float = BigIntValue :: from_str_radix ( & raw_number_str, RADIX as u32 )
363
355
. expect ( "failed to parse float using BigInt" )
364
356
. to_f64 ( )
@@ -381,11 +373,7 @@ impl<'a> Lexer<'a> {
381
373
/// were read, the integer value otherwise.
382
374
/// When `len` is not zero, this
383
375
/// will return `None` unless the integer has exactly `len` digits.
384
- pub ( super ) fn read_int < const RADIX : u8 > (
385
- & mut self ,
386
- len : u8 ,
387
- raw : & mut Raw ,
388
- ) -> LexResult < Option < f64 > > {
376
+ pub ( super ) fn read_int < const RADIX : u8 > ( & mut self , len : u8 ) -> LexResult < Option < f64 > > {
389
377
let mut count = 0u16 ;
390
378
let v = self . read_digits :: < _ , Option < f64 > , RADIX > (
391
379
|opt : Option < f64 > , radix, val| {
@@ -394,7 +382,6 @@ impl<'a> Lexer<'a> {
394
382
395
383
Ok ( ( Some ( total) , count != len as u16 ) )
396
384
} ,
397
- raw,
398
385
true ,
399
386
) ?;
400
387
if len != 0 && count != len as u16 {
@@ -404,11 +391,7 @@ impl<'a> Lexer<'a> {
404
391
}
405
392
}
406
393
407
- pub ( super ) fn read_int_u32 < const RADIX : u8 > (
408
- & mut self ,
409
- len : u8 ,
410
- raw : & mut Raw ,
411
- ) -> LexResult < Option < u32 > > {
394
+ pub ( super ) fn read_int_u32 < const RADIX : u8 > ( & mut self , len : u8 ) -> LexResult < Option < u32 > > {
412
395
let start = self . state . start ;
413
396
414
397
let mut count = 0 ;
@@ -427,7 +410,6 @@ impl<'a> Lexer<'a> {
427
410
428
411
Ok ( ( Some ( total) , count != len) )
429
412
} ,
430
- raw,
431
413
true ,
432
414
) ?;
433
415
if len != 0 && count != len {
@@ -441,7 +423,6 @@ impl<'a> Lexer<'a> {
441
423
fn read_digits < F , Ret , const RADIX : u8 > (
442
424
& mut self ,
443
425
mut op : F ,
444
- raw : & mut Raw ,
445
426
allow_num_separator : bool ,
446
427
) -> LexResult < Ret >
447
428
where
@@ -499,7 +480,6 @@ impl<'a> Lexer<'a> {
499
480
// Safety: cur() returns Some(c) where c is a valid char
500
481
self . input . bump ( ) ;
501
482
}
502
- raw. push ( c) ;
503
483
504
484
continue ;
505
485
}
@@ -511,8 +491,6 @@ impl<'a> Lexer<'a> {
511
491
return Ok ( total) ;
512
492
} ;
513
493
514
- raw. push ( c) ;
515
-
516
494
self . bump ( ) ;
517
495
518
496
let ( t, cont) = op ( total, RADIX , val) ?;
@@ -574,7 +552,7 @@ mod tests {
574
552
575
553
fn int < const RADIX : u8 > ( s : & ' static str ) -> u32 {
576
554
lex ( s, |l| {
577
- l. read_int_u32 :: < RADIX > ( 0 , & mut Raw ( None ) )
555
+ l. read_int_u32 :: < RADIX > ( 0 )
578
556
. unwrap ( )
579
557
. expect ( "read_int returned None" )
580
558
} )
0 commit comments