11
22import {
33 CharCode ,
4- allocate ,
4+ allocate as allocateString ,
55 HEADER_SIZE as STRING_HEADER_SIZE
66} from "./string" ;
77
8- import { loadUnsafe } from "./arraybuffer" ;
8+ import {
9+ loadUnsafe
10+ } from "./arraybuffer" ;
911
1012@inline
11- function getPowers10Table ( ) : u32 [ ] {
12- return < u32 [ ] > [
13+ function POWERS10 ( ) : u32 [ ] {
14+ const table : u32 [ ] = [
1315 1 ,
1416 10 ,
1517 100 ,
@@ -21,6 +23,7 @@ function getPowers10Table(): u32[] {
2123 100000000 ,
2224 1000000000
2325 ] ;
26+ return table ; // inlines to a constant memory offset
2427}
2528
2629/*
@@ -38,8 +41,8 @@ function getPowers10Table(): u32[] {
3841 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"
3942*/
4043@inline
41- function getDigitsTable ( ) : u32 [ ] {
42- return < u32 [ ] > [
44+ function DIGITS ( ) : u32 [ ] {
45+ const table : u32 [ ] = [
4346 0x00300030 , 0x00310030 , 0x00320030 , 0x00330030 , 0x00340030 ,
4447 0x00350030 , 0x00360030 , 0x00370030 , 0x00380030 , 0x00390030 ,
4548 0x00300031 , 0x00310031 , 0x00320031 , 0x00330031 , 0x00340031 ,
@@ -61,42 +64,40 @@ function getDigitsTable(): u32[] {
6164 0x00300039 , 0x00310039 , 0x00320039 , 0x00330039 , 0x00340039 ,
6265 0x00350039 , 0x00360039 , 0x00370039 , 0x00380039 , 0x00390039
6366 ] ;
67+ return table ; // inlines to a constant memory offset
6468}
6569
6670// Count number of decimals in value
67- function decimalCount < T > ( value : T ) : i32 {
68- // make value abs
69- var sign = value >> ( 8 * sizeof < T > ( ) - 1 ) ;
70- var v = ( value ^ sign ) - sign ;
71- var l = 8 * sizeof < T > ( ) - < i32 > clz < T > ( v | 10 ) ; // log2
72- var t = l * 1233 >>> 12 ; // log10
73-
74- var lutbuf = changetype < ArrayBuffer > ( getPowers10Table ( ) . buffer_ ) ;
71+ export function decimalCount < T > ( value : T ) : i32 {
72+ var v = abs < T > ( value ) ; // NOP if value is unsigned anyway
73+ var l : usize = 8 * sizeof < T > ( ) - < usize > clz < T > ( v | 10 ) ; // log2
74+ var t = l * 1233 >>> 12 ; // log10
75+
76+ var lutbuf = < ArrayBuffer > POWERS10 ( ) . buffer_ ;
7577 if ( sizeof < T > ( ) <= 4 ) {
7678 let power = loadUnsafe < u32 , T > ( lutbuf , t ) ;
77- t -= < i32 > ( v < power ) ;
79+ t -= < usize > ( v < power ) ;
7880 } else { // sizeof<T>() == 8
7981 let le10 = t <= 10 ;
80- let offset = select < i32 > ( 0 , 10 , le10 ) ; // offset = t <= 10 ? 0 : 10
82+ let offset = select < usize > ( 0 , 10 , le10 ) ; // offset = t <= 10 ? 0 : 10
8183 let factor = select < T > ( 1 , 10000000000 , le10 ) ; // factor = t <= 10 ? 1 : 10 ^ 10
8284 let power = loadUnsafe < u32 , T > ( lutbuf , t - offset ) ;
83- t -= < i32 > ( v < factor * power ) ;
85+ t -= < usize > ( v < factor * power ) ;
8486 }
8587 return t + 1 ;
8688}
8789
88- function utoa32_lut ( buffer : usize , num : u32 , offset : u32 ) : void {
89- var r : u32 , t : u32 , d1 : u32 , d2 : u32 ;
90- var lutbuf = changetype < ArrayBuffer > ( getDigitsTable ( ) . buffer_ ) ;
90+ function utoa32_lut ( buffer : usize , num : u32 , offset : usize ) : void {
91+ var lutbuf = < ArrayBuffer > DIGITS ( ) . buffer_ ;
9192
9293 while ( num >= 10000 ) {
9394 // in most VMs i32/u32 div and modulo by constant can be shared and simplificate
94- t = num / 10000 ;
95- r = num % 10000 ;
95+ let t = num / 10000 ;
96+ let r = num % 10000 ;
9697 num = t ;
9798
98- d1 = r / 100 ;
99- d2 = r % 100 ;
99+ let d1 = r / 100 ;
100+ let d2 = r % 100 ;
100101
101102 let digits1 = loadUnsafe < u32 , u64 > ( lutbuf , d1 ) ;
102103 let digits2 = loadUnsafe < u32 , u64 > ( lutbuf , d2 ) ;
@@ -106,8 +107,8 @@ function utoa32_lut(buffer: usize, num: u32, offset: u32): void {
106107 }
107108
108109 if ( num >= 100 ) {
109- t = num / 100 ;
110- d1 = num % 100 ;
110+ let t = num / 100 ;
111+ let d1 = num % 100 ;
111112 num = t ;
112113 offset -= 2 ;
113114 let digits = loadUnsafe < u32 , u32 > ( lutbuf , d1 ) ;
@@ -125,24 +126,21 @@ function utoa32_lut(buffer: usize, num: u32, offset: u32): void {
125126 }
126127}
127128
128- function utoa64_lut ( buffer : usize , num : u64 , offset : u32 ) : void {
129- var t : u64 , r : u32 , b : u32 , c : u32 ;
130- var b1 : u32 , b2 : u32 , c1 : u32 , c2 : u32 ;
131-
132- var lutbuf = changetype < ArrayBuffer > ( getDigitsTable ( ) . buffer_ ) ;
129+ function utoa64_lut ( buffer : usize , num : u64 , offset : usize ) : void {
130+ var lutbuf = < ArrayBuffer > DIGITS ( ) . buffer_ ;
133131
134132 while ( num >= 100000000 ) {
135- t = num / 100000000 ;
136- r = < u32 > ( num - t * 100000000 ) ;
133+ let t = num / 100000000 ;
134+ let r = < usize > ( num - t * 100000000 ) ;
137135 num = t ;
138136
139- b = r / 10000 ;
140- c = r % 10000 ;
137+ let b = r / 10000 ;
138+ let c = r % 10000 ;
141139
142- b1 = b / 100 ;
143- b2 = b % 100 ;
144- c1 = c / 100 ;
145- c2 = c % 100 ;
140+ let b1 = b / 100 ;
141+ let b2 = b % 100 ;
142+ let c1 = c / 100 ;
143+ let c2 = c % 100 ;
146144
147145 let digits1 = loadUnsafe < u32 , u64 > ( lutbuf , c1 ) ;
148146 let digits2 = loadUnsafe < u32 , u64 > ( lutbuf , c2 ) ;
@@ -157,15 +155,13 @@ function utoa64_lut(buffer: usize, num: u64, offset: u32): void {
157155 store < u64 > ( buffer + ( offset << 1 ) , digits1 | ( digits2 << 32 ) , STRING_HEADER_SIZE ) ;
158156 }
159157
160- r = < u32 > num ;
161- if ( r ) utoa32_lut ( buffer , r , offset ) ;
158+ utoa32_lut ( buffer , < u32 > num , offset ) ;
162159}
163160
164- function utoa_simple < T > ( buffer : usize , num : T , offset : u32 ) : void {
165- var t : T , r : u32 ;
161+ function utoa_simple < T > ( buffer : usize , num : T , offset : usize ) : void {
166162 do {
167- t = num / 10 ;
168- r = < u32 > ( num % 10 ) ;
163+ let t = num / 10 ;
164+ let r = < u32 > ( num % 10 ) ;
169165 num = t ;
170166 offset -= 1 ;
171167 store < u16 > ( buffer + ( offset << 1 ) , CharCode . _0 + r , STRING_HEADER_SIZE ) ;
@@ -175,26 +171,26 @@ function utoa_simple<T>(buffer: usize, num: T, offset: u32): void {
175171@inline
176172export function utoa32_core ( buffer : usize , num : u32 , offset : u32 ) : void {
177173 if ( ASC_SHRINK_LEVEL >= 1 ) {
178- utoa_simple ( buffer , num , offset ) ;
174+ utoa_simple ( buffer , num , < usize > offset ) ;
179175 } else {
180- utoa32_lut ( buffer , num , offset ) ;
176+ utoa32_lut ( buffer , num , < usize > offset ) ;
181177 }
182178}
183179
184180@inline
185181export function utoa64_core ( buffer : usize , num : u64 , offset : u32 ) : void {
186182 if ( ASC_SHRINK_LEVEL >= 1 ) {
187- utoa_simple ( buffer , num , offset ) ;
183+ utoa_simple ( buffer , num , < usize > offset ) ;
188184 } else {
189- utoa64_lut ( buffer , num , offset ) ;
185+ utoa64_lut ( buffer , num , < usize > offset ) ;
190186 }
191187}
192188
193189export function utoa32 ( value : u32 ) : string {
194190 if ( ! value ) return "0" ;
195191
196192 var decimals = decimalCount < u32 > ( value ) ;
197- var buffer = allocate ( decimals ) ;
193+ var buffer = allocateString ( decimals ) ;
198194
199195 utoa32_core ( changetype < usize > ( buffer ) , value , decimals ) ;
200196 return changetype < string > ( buffer ) ;
@@ -207,7 +203,7 @@ export function itoa32(value: i32): string {
207203 if ( isneg ) value = - value ;
208204
209205 var decimals = decimalCount < u32 > ( value ) + < i32 > isneg ;
210- var buffer = allocate ( decimals ) ;
206+ var buffer = allocateString ( decimals ) ;
211207
212208 utoa32_core ( changetype < usize > ( buffer ) , value , decimals ) ;
213209 if ( isneg ) store < u16 > ( changetype < usize > ( buffer ) , CharCode . MINUS , STRING_HEADER_SIZE ) ;
@@ -222,11 +218,11 @@ export function utoa64(value: u64): string {
222218 if ( value <= u32 . MAX_VALUE ) {
223219 let value32 = < u32 > value ;
224220 let decimals = decimalCount < u32 > ( value32 ) ;
225- buffer = allocate ( decimals ) ;
221+ buffer = allocateString ( decimals ) ;
226222 utoa32_core ( changetype < usize > ( buffer ) , value32 , decimals ) ;
227223 } else {
228224 let decimals = decimalCount < u64 > ( value ) ;
229- buffer = allocate ( decimals ) ;
225+ buffer = allocateString ( decimals ) ;
230226 utoa64_core ( changetype < usize > ( buffer ) , value , decimals ) ;
231227 }
232228
@@ -243,11 +239,11 @@ export function itoa64(value: i64): string {
243239 if ( < u64 > value <= < u64 > u32 . MAX_VALUE ) {
244240 let value32 = < u32 > value ;
245241 let decimals = decimalCount < u32 > ( value32 ) + < i32 > isneg ;
246- buffer = allocate ( decimals ) ;
242+ buffer = allocateString ( decimals ) ;
247243 utoa32_core ( changetype < usize > ( buffer ) , value32 , decimals ) ;
248244 } else {
249245 let decimals = decimalCount < u64 > ( value ) + < i32 > isneg ;
250- buffer = allocate ( decimals ) ;
246+ buffer = allocateString ( decimals ) ;
251247 utoa64_core ( changetype < usize > ( buffer ) , value , decimals ) ;
252248 }
253249 if ( isneg ) store < u16 > ( changetype < usize > ( buffer ) , CharCode . MINUS , STRING_HEADER_SIZE ) ;
0 commit comments