@amritk/nish-aarch64-darwin 0.34.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/nish +0 -0
- package/package.json +1 -1
- package/std/bytes.ts +26 -3
- package/std/crypto/base64url.ts +42 -21
- package/std/crypto/bcrypt.ts +222 -183
- package/std/net/http1-codec.ts +195 -37
- package/std/net/postgres.ts +50 -30
package/bin/nish
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/std/bytes.ts
CHANGED
|
@@ -26,7 +26,10 @@
|
|
|
26
26
|
* inside a call, and after `getU32LE` inlines, LLVM keeps the checks on
|
|
27
27
|
* `off + 1` to `off + 3`, because the guard compares the length truncated to
|
|
28
28
|
* `i32` and the checks compare it unsigned at 64 bits. A loop that needs them
|
|
29
|
-
* gone indexes the bytes itself.
|
|
29
|
+
* gone indexes the bytes itself. `getU64BE`, and with it `getI64BE` and
|
|
30
|
+
* `getF64BE`, is the exception: it checks the whole range once and reads the
|
|
31
|
+
* eight bytes unchecked, which lowers to one load and a byte swap. An offset
|
|
32
|
+
* outside the range still goes byte by byte, so it panics as the others do.
|
|
30
33
|
*
|
|
31
34
|
* The in-range answers are byte for byte those of the copies `std/` keeps for
|
|
32
35
|
* itself: `sha256LoadWord` (`std/crypto/sha256.ts`) for `getU32BE`,
|
|
@@ -91,8 +94,8 @@ export const getU64LE = (b: u8[], off: i32): u64 => {
|
|
|
91
94
|
return v
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
/**
|
|
95
|
-
|
|
97
|
+
/** `getU64BE` a byte at a time, each index checked: the path for an offset whose eight bytes are not all in the array. */
|
|
98
|
+
const getU64BEByByte = (b: u8[], off: i32): u64 => {
|
|
96
99
|
let v = toU64(0)
|
|
97
100
|
for (let i: i32 = 0; i < 8; i++) {
|
|
98
101
|
v = (v << toU64(8)) | toU64(b[off + i])
|
|
@@ -100,6 +103,26 @@ export const getU64BE = (b: u8[], off: i32): u64 => {
|
|
|
100
103
|
return v
|
|
101
104
|
}
|
|
102
105
|
|
|
106
|
+
/**
|
|
107
|
+
* The `u64` whose bytes, most significant first, are `b[off]` to `b[off + 7]`.
|
|
108
|
+
* The fast path's ors are grouped in pairs, which LLVM folds into one load and
|
|
109
|
+
* a `bswap`; a flat chain of eight `or`s stayed byte by byte. The byte loop is
|
|
110
|
+
* its own function so its last load is not merged with the fast path's.
|
|
111
|
+
*/
|
|
112
|
+
export const getU64BE = (b: u8[], off: i32): u64 => {
|
|
113
|
+
if (off >= 0 && off < 2147483640 && off + 8 <= toI32(b.length)) {
|
|
114
|
+
return (
|
|
115
|
+
(toU64(b[off]) << toU64(56)) |
|
|
116
|
+
(toU64(b[off + 1]) << toU64(48)) |
|
|
117
|
+
((toU64(b[off + 2]) << toU64(40)) | (toU64(b[off + 3]) << toU64(32))) |
|
|
118
|
+
((toU64(b[off + 4]) << toU64(24)) |
|
|
119
|
+
(toU64(b[off + 5]) << toU64(16)) |
|
|
120
|
+
((toU64(b[off + 6]) << toU64(8)) | toU64(b[off + 7])))
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
return getU64BEByByte(b, off)
|
|
124
|
+
}
|
|
125
|
+
|
|
103
126
|
/** `getU32LE`'s bits as a two's-complement `i32`. */
|
|
104
127
|
export const getI32LE = (b: u8[], off: i32): i32 => toI32(getU32LE(b, off))
|
|
105
128
|
|
package/std/crypto/base64url.ts
CHANGED
|
@@ -127,8 +127,9 @@ export const base64urlEncode = (data: u8[]): string => {
|
|
|
127
127
|
* one canonical spelling of any byte string — see the module comment for the
|
|
128
128
|
* five refusals.
|
|
129
129
|
*
|
|
130
|
-
*
|
|
131
|
-
* character,
|
|
130
|
+
* Each group of four characters becomes one 24-bit word, six bits a
|
|
131
|
+
* character, which splits into three bytes; a short final group of two or
|
|
132
|
+
* three characters fills the top of the word and gives one or two.
|
|
132
133
|
*/
|
|
133
134
|
export const base64urlDecode = (text: string): u8[] | null => {
|
|
134
135
|
// A text past 2^31 - 1 bytes is refused before `toI32`, which would
|
|
@@ -148,31 +149,51 @@ export const base64urlDecode = (text: string): u8[] | null => {
|
|
|
148
149
|
// short final group; `n * 3 / 4` would overflow for a text over 700 MB.
|
|
149
150
|
const out: u8[] = new Array<u8>((n >> 2) * 3 + (tail === 0 ? 0 : tail - 1))
|
|
150
151
|
const outLen: i32 = toI32(out.length)
|
|
151
|
-
// All ones once any character is outside the alphabet (
|
|
152
|
+
// All ones once any character is outside the alphabet (a sextet of `-1`
|
|
152
153
|
// shifted right by 31), and non-zero once the text ends on a bit that
|
|
153
154
|
// encodes no byte.
|
|
154
155
|
let bad: i32 = 0
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
// Four characters make one 24-bit word and three bytes, so a full group has
|
|
157
|
+
// no count of waiting bits to test, and its four sextets are independent.
|
|
157
158
|
let j: i32 = 0
|
|
158
|
-
for (let k: i32 = 0; k < n; k
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
j
|
|
159
|
+
for (let k: i32 = 0; k + 3 < n; k += 4) {
|
|
160
|
+
const s0: i32 = base64urlSextetOf(toI32(text.charCodeAt(k)))
|
|
161
|
+
const s1: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 1)))
|
|
162
|
+
const s2: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 2)))
|
|
163
|
+
const s3: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 3)))
|
|
164
|
+
bad = bad | ((s0 | s1 | s2 | s3) >> 31)
|
|
165
|
+
const word: i32 = ((s0 & 63) << 18) | ((s1 & 63) << 12) | ((s2 & 63) << 6) | (s3 & 63)
|
|
166
|
+
// Always true — `out` was sized from the same length — but written out so
|
|
167
|
+
// that the three stores keep no bounds check.
|
|
168
|
+
if (j >= 0 && j + 2 < outLen) {
|
|
169
|
+
out[j] = toU8(word >> 16)
|
|
170
|
+
out[j + 1] = toU8((word >> 8) & 255)
|
|
171
|
+
out[j + 2] = toU8(word & 255)
|
|
171
172
|
}
|
|
173
|
+
j += 3
|
|
174
|
+
}
|
|
175
|
+
// A short final group of two or three characters: one or two bytes, and the
|
|
176
|
+
// four or two bits left over belong to no byte, so they must be zero for `AA`
|
|
177
|
+
// to be the only spelling of a zero byte and `AB` refused (RFC 4648 §3.5).
|
|
178
|
+
if (tail !== 0) {
|
|
179
|
+
const k: i32 = n - tail
|
|
180
|
+
const s0: i32 = base64urlSextetOf(toI32(text.charCodeAt(k)))
|
|
181
|
+
const s1: i32 = base64urlSextetOf(toI32(text.charCodeAt(k + 1)))
|
|
182
|
+
// A third character only when the tail has one; a two-character tail reads
|
|
183
|
+
// its place as `A`, the zero sextet, which adds no bits.
|
|
184
|
+
const s2: i32 = tail === 3 ? base64urlSextetOf(toI32(text.charCodeAt(k + 2))) : 0
|
|
185
|
+
bad = bad | ((s0 | s1 | s2) >> 31)
|
|
186
|
+
const word: i32 = ((s0 & 63) << 18) | ((s1 & 63) << 12) | ((s2 & 63) << 6)
|
|
187
|
+
if (j >= 0 && j < outLen) {
|
|
188
|
+
out[j] = toU8(word >> 16)
|
|
189
|
+
}
|
|
190
|
+
if (tail === 3 && j + 1 >= 0 && j + 1 < outLen) {
|
|
191
|
+
out[j + 1] = toU8((word >> 8) & 255)
|
|
192
|
+
}
|
|
193
|
+
// The bits under the last byte written: sixteen of the word when one byte
|
|
194
|
+
// was, eight when two were.
|
|
195
|
+
bad = bad | (word & (tail === 2 ? 0xffff : 0xff))
|
|
172
196
|
}
|
|
173
|
-
// The two or four bits left over belong to no byte, and must be zero so that
|
|
174
|
-
// `AA` is the only spelling of a zero byte and `AB` is refused (RFC 4648 §3.5).
|
|
175
|
-
bad = bad | (acc & ((1 << bits) - 1))
|
|
176
197
|
if (bad !== 0) {
|
|
177
198
|
return null
|
|
178
199
|
}
|
package/std/crypto/bcrypt.ts
CHANGED
|
@@ -1021,12 +1021,14 @@ const bcryptLoadSlot = (state: Secret<u32[]>, password: Secret<u8[]>, slot: i32)
|
|
|
1021
1021
|
}
|
|
1022
1022
|
|
|
1023
1023
|
// The cost-round kernels, one per width. Each is `bcryptBody4`'s text with
|
|
1024
|
-
// the lane count changed
|
|
1024
|
+
// the lane count changed, except that six lanes' sixth lane takes its bytes
|
|
1025
|
+
// the previous way (see `bcryptBody4`); bench/crypto/bcrypt/gen-body.mjs
|
|
1026
|
+
// writes them all, so an edit is made there. They are not
|
|
1025
1027
|
// one loop over a lane count: the lanes' l and r must live in registers and
|
|
1026
1028
|
// their loads be scheduled together, which a loop over an array of lanes
|
|
1027
1029
|
// does not give. Two lanes take each byte by its own shift and write every
|
|
1028
1030
|
// lane's bytes before any lane's update, the form all widths had before the
|
|
1029
|
-
//
|
|
1031
|
+
// copies behind the barrier, which measured slower there.
|
|
1030
1032
|
|
|
1031
1033
|
/** `bcryptBody4`'s interleave on two lanes. */
|
|
1032
1034
|
const bcryptBody2 = (st: u32[]): void => {
|
|
@@ -1091,41 +1093,47 @@ const bcryptBody3 = (st: u32[]): void => {
|
|
|
1091
1093
|
l1 ^= st[1042]
|
|
1092
1094
|
l2 ^= st[2084]
|
|
1093
1095
|
for (let n: i32 = 1; n < 17; n += 2) {
|
|
1094
|
-
const l0e: u32 = ctSelect(
|
|
1095
|
-
const
|
|
1096
|
-
const
|
|
1097
|
-
const
|
|
1098
|
-
const
|
|
1096
|
+
const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
|
|
1097
|
+
const l0d: i32 = toI32(l0e) & 0xff
|
|
1098
|
+
const l0c: i32 = toI32(l0e >>> 8) & 0xff
|
|
1099
|
+
const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
|
|
1100
|
+
const l0b: i32 = toI32(l0f) & 0xff
|
|
1101
|
+
const l0a: i32 = toI32(l0f >>> 8) & 0xff
|
|
1099
1102
|
r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
|
|
1100
|
-
const l1e: u32 = ctSelect(
|
|
1101
|
-
const
|
|
1102
|
-
const
|
|
1103
|
-
const
|
|
1104
|
-
const
|
|
1103
|
+
const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
|
|
1104
|
+
const l1d: i32 = toI32(l1e) & 0xff
|
|
1105
|
+
const l1c: i32 = toI32(l1e >>> 8) & 0xff
|
|
1106
|
+
const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
|
|
1107
|
+
const l1b: i32 = toI32(l1f) & 0xff
|
|
1108
|
+
const l1a: i32 = toI32(l1f >>> 8) & 0xff
|
|
1105
1109
|
r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
|
|
1106
|
-
const l2e: u32 = ctSelect(
|
|
1107
|
-
const
|
|
1108
|
-
const
|
|
1109
|
-
const
|
|
1110
|
-
const
|
|
1110
|
+
const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
|
|
1111
|
+
const l2d: i32 = toI32(l2e) & 0xff
|
|
1112
|
+
const l2c: i32 = toI32(l2e >>> 8) & 0xff
|
|
1113
|
+
const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
|
|
1114
|
+
const l2b: i32 = toI32(l2f) & 0xff
|
|
1115
|
+
const l2a: i32 = toI32(l2f >>> 8) & 0xff
|
|
1111
1116
|
r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
|
|
1112
|
-
const r0e: u32 = ctSelect(
|
|
1113
|
-
const
|
|
1114
|
-
const
|
|
1115
|
-
const
|
|
1116
|
-
const
|
|
1117
|
+
const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
|
|
1118
|
+
const r0d: i32 = toI32(r0e) & 0xff
|
|
1119
|
+
const r0c: i32 = toI32(r0e >>> 8) & 0xff
|
|
1120
|
+
const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
|
|
1121
|
+
const r0b: i32 = toI32(r0f) & 0xff
|
|
1122
|
+
const r0a: i32 = toI32(r0f >>> 8) & 0xff
|
|
1117
1123
|
l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
|
|
1118
|
-
const r1e: u32 = ctSelect(
|
|
1119
|
-
const
|
|
1120
|
-
const
|
|
1121
|
-
const
|
|
1122
|
-
const
|
|
1124
|
+
const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
|
|
1125
|
+
const r1d: i32 = toI32(r1e) & 0xff
|
|
1126
|
+
const r1c: i32 = toI32(r1e >>> 8) & 0xff
|
|
1127
|
+
const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
|
|
1128
|
+
const r1b: i32 = toI32(r1f) & 0xff
|
|
1129
|
+
const r1a: i32 = toI32(r1f >>> 8) & 0xff
|
|
1123
1130
|
l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
|
|
1124
|
-
const r2e: u32 = ctSelect(
|
|
1125
|
-
const
|
|
1126
|
-
const
|
|
1127
|
-
const
|
|
1128
|
-
const
|
|
1131
|
+
const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
|
|
1132
|
+
const r2d: i32 = toI32(r2e) & 0xff
|
|
1133
|
+
const r2c: i32 = toI32(r2e >>> 8) & 0xff
|
|
1134
|
+
const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
|
|
1135
|
+
const r2b: i32 = toI32(r2f) & 0xff
|
|
1136
|
+
const r2a: i32 = toI32(r2f >>> 8) & 0xff
|
|
1129
1137
|
l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
|
|
1130
1138
|
}
|
|
1131
1139
|
const t0: u32 = r0
|
|
@@ -1153,17 +1161,20 @@ const bcryptBody3 = (st: u32[]): void => {
|
|
|
1153
1161
|
* hot loop of the batch: 2^(cost+1) calls of 521 blocks per lane.
|
|
1154
1162
|
*
|
|
1155
1163
|
* Each lane's half-round is written whole, its bytes and then its update,
|
|
1156
|
-
* before the next lane's. The
|
|
1157
|
-
*
|
|
1158
|
-
*
|
|
1159
|
-
*
|
|
1160
|
-
*
|
|
1161
|
-
*
|
|
1162
|
-
*
|
|
1163
|
-
*
|
|
1164
|
-
*
|
|
1165
|
-
*
|
|
1166
|
-
* the
|
|
1164
|
+
* before the next lane's. The bytes come in two pairs, each the low and
|
|
1165
|
+
* second byte of a copy behind the value barrier: `ctSelect(v, 0xffffffff, 0)`
|
|
1166
|
+
* is `v`, opaque. A copy of the word (`e`) gives bytes 0 and 1, and that copy
|
|
1167
|
+
* moved down by 16 (`f`) bytes 2 and 3, so a second byte is one `movzx` from
|
|
1168
|
+
* `ah`, `bh`, `ch` or `dh` and a lane takes its four bytes in six
|
|
1169
|
+
* instructions; without the barriers LLVM folds the pairs back into shifts of
|
|
1170
|
+
* the word. Only four registers have a second byte, and with all six lanes
|
|
1171
|
+
* paired the loop spilled more than it saved (counted), so at six lanes the
|
|
1172
|
+
* sixth lane takes bytes 1 and 2 from one copy moved down by 8 and bytes 0
|
|
1173
|
+
* and 3 by shifts of the word, the way every lane had before. On a Xeon Platinum
|
|
1174
|
+
* 8260 the pairs take about 3.5% less time a hash than that way at the best
|
|
1175
|
+
* width, five lanes, and 5.6% less at six (docs/security/crypto-bcrypt.md,
|
|
1176
|
+
* "Cascade Lake"). The barrier is an identity on a register: it adds no
|
|
1177
|
+
* branch and no load, and the round reads the same four S-box words.
|
|
1167
1178
|
*/
|
|
1168
1179
|
const bcryptBody4 = (st: u32[]): void => {
|
|
1169
1180
|
if (st.length < 4168) {
|
|
@@ -1183,53 +1194,61 @@ const bcryptBody4 = (st: u32[]): void => {
|
|
|
1183
1194
|
l2 ^= st[2084]
|
|
1184
1195
|
l3 ^= st[3126]
|
|
1185
1196
|
for (let n: i32 = 1; n < 17; n += 2) {
|
|
1186
|
-
const l0e: u32 = ctSelect(
|
|
1187
|
-
const
|
|
1188
|
-
const
|
|
1189
|
-
const
|
|
1190
|
-
const
|
|
1197
|
+
const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
|
|
1198
|
+
const l0d: i32 = toI32(l0e) & 0xff
|
|
1199
|
+
const l0c: i32 = toI32(l0e >>> 8) & 0xff
|
|
1200
|
+
const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
|
|
1201
|
+
const l0b: i32 = toI32(l0f) & 0xff
|
|
1202
|
+
const l0a: i32 = toI32(l0f >>> 8) & 0xff
|
|
1191
1203
|
r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
|
|
1192
|
-
const l1e: u32 = ctSelect(
|
|
1193
|
-
const
|
|
1194
|
-
const
|
|
1195
|
-
const
|
|
1196
|
-
const
|
|
1204
|
+
const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
|
|
1205
|
+
const l1d: i32 = toI32(l1e) & 0xff
|
|
1206
|
+
const l1c: i32 = toI32(l1e >>> 8) & 0xff
|
|
1207
|
+
const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
|
|
1208
|
+
const l1b: i32 = toI32(l1f) & 0xff
|
|
1209
|
+
const l1a: i32 = toI32(l1f >>> 8) & 0xff
|
|
1197
1210
|
r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
|
|
1198
|
-
const l2e: u32 = ctSelect(
|
|
1199
|
-
const
|
|
1200
|
-
const
|
|
1201
|
-
const
|
|
1202
|
-
const
|
|
1211
|
+
const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
|
|
1212
|
+
const l2d: i32 = toI32(l2e) & 0xff
|
|
1213
|
+
const l2c: i32 = toI32(l2e >>> 8) & 0xff
|
|
1214
|
+
const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
|
|
1215
|
+
const l2b: i32 = toI32(l2f) & 0xff
|
|
1216
|
+
const l2a: i32 = toI32(l2f >>> 8) & 0xff
|
|
1203
1217
|
r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
|
|
1204
|
-
const l3e: u32 = ctSelect(
|
|
1205
|
-
const
|
|
1206
|
-
const
|
|
1207
|
-
const
|
|
1208
|
-
const
|
|
1218
|
+
const l3e: u32 = ctSelect(l3, 0xffffffff, 0)
|
|
1219
|
+
const l3d: i32 = toI32(l3e) & 0xff
|
|
1220
|
+
const l3c: i32 = toI32(l3e >>> 8) & 0xff
|
|
1221
|
+
const l3f: u32 = ctSelect(l3e >>> 16, 0xffffffff, 0)
|
|
1222
|
+
const l3b: i32 = toI32(l3f) & 0xff
|
|
1223
|
+
const l3a: i32 = toI32(l3f >>> 8) & 0xff
|
|
1209
1224
|
r3 ^= st[3126 + n] ^ (((st[3144 + l3a] + st[3400 + l3b]) ^ st[3656 + l3c]) + st[3912 + l3d])
|
|
1210
|
-
const r0e: u32 = ctSelect(
|
|
1211
|
-
const
|
|
1212
|
-
const
|
|
1213
|
-
const
|
|
1214
|
-
const
|
|
1225
|
+
const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
|
|
1226
|
+
const r0d: i32 = toI32(r0e) & 0xff
|
|
1227
|
+
const r0c: i32 = toI32(r0e >>> 8) & 0xff
|
|
1228
|
+
const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
|
|
1229
|
+
const r0b: i32 = toI32(r0f) & 0xff
|
|
1230
|
+
const r0a: i32 = toI32(r0f >>> 8) & 0xff
|
|
1215
1231
|
l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
|
|
1216
|
-
const r1e: u32 = ctSelect(
|
|
1217
|
-
const
|
|
1218
|
-
const
|
|
1219
|
-
const
|
|
1220
|
-
const
|
|
1232
|
+
const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
|
|
1233
|
+
const r1d: i32 = toI32(r1e) & 0xff
|
|
1234
|
+
const r1c: i32 = toI32(r1e >>> 8) & 0xff
|
|
1235
|
+
const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
|
|
1236
|
+
const r1b: i32 = toI32(r1f) & 0xff
|
|
1237
|
+
const r1a: i32 = toI32(r1f >>> 8) & 0xff
|
|
1221
1238
|
l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
|
|
1222
|
-
const r2e: u32 = ctSelect(
|
|
1223
|
-
const
|
|
1224
|
-
const
|
|
1225
|
-
const
|
|
1226
|
-
const
|
|
1239
|
+
const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
|
|
1240
|
+
const r2d: i32 = toI32(r2e) & 0xff
|
|
1241
|
+
const r2c: i32 = toI32(r2e >>> 8) & 0xff
|
|
1242
|
+
const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
|
|
1243
|
+
const r2b: i32 = toI32(r2f) & 0xff
|
|
1244
|
+
const r2a: i32 = toI32(r2f >>> 8) & 0xff
|
|
1227
1245
|
l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
|
|
1228
|
-
const r3e: u32 = ctSelect(
|
|
1229
|
-
const
|
|
1230
|
-
const
|
|
1231
|
-
const
|
|
1232
|
-
const
|
|
1246
|
+
const r3e: u32 = ctSelect(r3, 0xffffffff, 0)
|
|
1247
|
+
const r3d: i32 = toI32(r3e) & 0xff
|
|
1248
|
+
const r3c: i32 = toI32(r3e >>> 8) & 0xff
|
|
1249
|
+
const r3f: u32 = ctSelect(r3e >>> 16, 0xffffffff, 0)
|
|
1250
|
+
const r3b: i32 = toI32(r3f) & 0xff
|
|
1251
|
+
const r3a: i32 = toI32(r3f >>> 8) & 0xff
|
|
1233
1252
|
l3 ^= st[3126 + n + 1] ^ (((st[3144 + r3a] + st[3400 + r3b]) ^ st[3656 + r3c]) + st[3912 + r3d])
|
|
1234
1253
|
}
|
|
1235
1254
|
const t0: u32 = r0
|
|
@@ -1277,65 +1296,75 @@ const bcryptBody5 = (st: u32[]): void => {
|
|
|
1277
1296
|
l3 ^= st[3126]
|
|
1278
1297
|
l4 ^= st[4168]
|
|
1279
1298
|
for (let n: i32 = 1; n < 17; n += 2) {
|
|
1280
|
-
const l0e: u32 = ctSelect(
|
|
1281
|
-
const
|
|
1282
|
-
const
|
|
1283
|
-
const
|
|
1284
|
-
const
|
|
1299
|
+
const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
|
|
1300
|
+
const l0d: i32 = toI32(l0e) & 0xff
|
|
1301
|
+
const l0c: i32 = toI32(l0e >>> 8) & 0xff
|
|
1302
|
+
const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
|
|
1303
|
+
const l0b: i32 = toI32(l0f) & 0xff
|
|
1304
|
+
const l0a: i32 = toI32(l0f >>> 8) & 0xff
|
|
1285
1305
|
r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
|
|
1286
|
-
const l1e: u32 = ctSelect(
|
|
1287
|
-
const
|
|
1288
|
-
const
|
|
1289
|
-
const
|
|
1290
|
-
const
|
|
1306
|
+
const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
|
|
1307
|
+
const l1d: i32 = toI32(l1e) & 0xff
|
|
1308
|
+
const l1c: i32 = toI32(l1e >>> 8) & 0xff
|
|
1309
|
+
const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
|
|
1310
|
+
const l1b: i32 = toI32(l1f) & 0xff
|
|
1311
|
+
const l1a: i32 = toI32(l1f >>> 8) & 0xff
|
|
1291
1312
|
r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
|
|
1292
|
-
const l2e: u32 = ctSelect(
|
|
1293
|
-
const
|
|
1294
|
-
const
|
|
1295
|
-
const
|
|
1296
|
-
const
|
|
1313
|
+
const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
|
|
1314
|
+
const l2d: i32 = toI32(l2e) & 0xff
|
|
1315
|
+
const l2c: i32 = toI32(l2e >>> 8) & 0xff
|
|
1316
|
+
const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
|
|
1317
|
+
const l2b: i32 = toI32(l2f) & 0xff
|
|
1318
|
+
const l2a: i32 = toI32(l2f >>> 8) & 0xff
|
|
1297
1319
|
r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
|
|
1298
|
-
const l3e: u32 = ctSelect(
|
|
1299
|
-
const
|
|
1300
|
-
const
|
|
1301
|
-
const
|
|
1302
|
-
const
|
|
1320
|
+
const l3e: u32 = ctSelect(l3, 0xffffffff, 0)
|
|
1321
|
+
const l3d: i32 = toI32(l3e) & 0xff
|
|
1322
|
+
const l3c: i32 = toI32(l3e >>> 8) & 0xff
|
|
1323
|
+
const l3f: u32 = ctSelect(l3e >>> 16, 0xffffffff, 0)
|
|
1324
|
+
const l3b: i32 = toI32(l3f) & 0xff
|
|
1325
|
+
const l3a: i32 = toI32(l3f >>> 8) & 0xff
|
|
1303
1326
|
r3 ^= st[3126 + n] ^ (((st[3144 + l3a] + st[3400 + l3b]) ^ st[3656 + l3c]) + st[3912 + l3d])
|
|
1304
|
-
const l4e: u32 = ctSelect(
|
|
1305
|
-
const
|
|
1306
|
-
const
|
|
1307
|
-
const
|
|
1308
|
-
const
|
|
1327
|
+
const l4e: u32 = ctSelect(l4, 0xffffffff, 0)
|
|
1328
|
+
const l4d: i32 = toI32(l4e) & 0xff
|
|
1329
|
+
const l4c: i32 = toI32(l4e >>> 8) & 0xff
|
|
1330
|
+
const l4f: u32 = ctSelect(l4e >>> 16, 0xffffffff, 0)
|
|
1331
|
+
const l4b: i32 = toI32(l4f) & 0xff
|
|
1332
|
+
const l4a: i32 = toI32(l4f >>> 8) & 0xff
|
|
1309
1333
|
r4 ^= st[4168 + n] ^ (((st[4186 + l4a] + st[4442 + l4b]) ^ st[4698 + l4c]) + st[4954 + l4d])
|
|
1310
|
-
const r0e: u32 = ctSelect(
|
|
1311
|
-
const
|
|
1312
|
-
const
|
|
1313
|
-
const
|
|
1314
|
-
const
|
|
1334
|
+
const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
|
|
1335
|
+
const r0d: i32 = toI32(r0e) & 0xff
|
|
1336
|
+
const r0c: i32 = toI32(r0e >>> 8) & 0xff
|
|
1337
|
+
const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
|
|
1338
|
+
const r0b: i32 = toI32(r0f) & 0xff
|
|
1339
|
+
const r0a: i32 = toI32(r0f >>> 8) & 0xff
|
|
1315
1340
|
l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
|
|
1316
|
-
const r1e: u32 = ctSelect(
|
|
1317
|
-
const
|
|
1318
|
-
const
|
|
1319
|
-
const
|
|
1320
|
-
const
|
|
1341
|
+
const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
|
|
1342
|
+
const r1d: i32 = toI32(r1e) & 0xff
|
|
1343
|
+
const r1c: i32 = toI32(r1e >>> 8) & 0xff
|
|
1344
|
+
const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
|
|
1345
|
+
const r1b: i32 = toI32(r1f) & 0xff
|
|
1346
|
+
const r1a: i32 = toI32(r1f >>> 8) & 0xff
|
|
1321
1347
|
l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
|
|
1322
|
-
const r2e: u32 = ctSelect(
|
|
1323
|
-
const
|
|
1324
|
-
const
|
|
1325
|
-
const
|
|
1326
|
-
const
|
|
1348
|
+
const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
|
|
1349
|
+
const r2d: i32 = toI32(r2e) & 0xff
|
|
1350
|
+
const r2c: i32 = toI32(r2e >>> 8) & 0xff
|
|
1351
|
+
const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
|
|
1352
|
+
const r2b: i32 = toI32(r2f) & 0xff
|
|
1353
|
+
const r2a: i32 = toI32(r2f >>> 8) & 0xff
|
|
1327
1354
|
l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
|
|
1328
|
-
const r3e: u32 = ctSelect(
|
|
1329
|
-
const
|
|
1330
|
-
const
|
|
1331
|
-
const
|
|
1332
|
-
const
|
|
1355
|
+
const r3e: u32 = ctSelect(r3, 0xffffffff, 0)
|
|
1356
|
+
const r3d: i32 = toI32(r3e) & 0xff
|
|
1357
|
+
const r3c: i32 = toI32(r3e >>> 8) & 0xff
|
|
1358
|
+
const r3f: u32 = ctSelect(r3e >>> 16, 0xffffffff, 0)
|
|
1359
|
+
const r3b: i32 = toI32(r3f) & 0xff
|
|
1360
|
+
const r3a: i32 = toI32(r3f >>> 8) & 0xff
|
|
1333
1361
|
l3 ^= st[3126 + n + 1] ^ (((st[3144 + r3a] + st[3400 + r3b]) ^ st[3656 + r3c]) + st[3912 + r3d])
|
|
1334
|
-
const r4e: u32 = ctSelect(
|
|
1335
|
-
const
|
|
1336
|
-
const
|
|
1337
|
-
const
|
|
1338
|
-
const
|
|
1362
|
+
const r4e: u32 = ctSelect(r4, 0xffffffff, 0)
|
|
1363
|
+
const r4d: i32 = toI32(r4e) & 0xff
|
|
1364
|
+
const r4c: i32 = toI32(r4e >>> 8) & 0xff
|
|
1365
|
+
const r4f: u32 = ctSelect(r4e >>> 16, 0xffffffff, 0)
|
|
1366
|
+
const r4b: i32 = toI32(r4f) & 0xff
|
|
1367
|
+
const r4a: i32 = toI32(r4f >>> 8) & 0xff
|
|
1339
1368
|
l4 ^= st[4168 + n + 1] ^ (((st[4186 + r4a] + st[4442 + r4b]) ^ st[4698 + r4c]) + st[4954 + r4d])
|
|
1340
1369
|
}
|
|
1341
1370
|
const t0: u32 = r0
|
|
@@ -1391,35 +1420,40 @@ const bcryptBody6 = (st: u32[]): void => {
|
|
|
1391
1420
|
l4 ^= st[4168]
|
|
1392
1421
|
l5 ^= st[5210]
|
|
1393
1422
|
for (let n: i32 = 1; n < 17; n += 2) {
|
|
1394
|
-
const l0e: u32 = ctSelect(l0
|
|
1395
|
-
const
|
|
1396
|
-
const
|
|
1397
|
-
const
|
|
1398
|
-
const
|
|
1423
|
+
const l0e: u32 = ctSelect(l0, 0xffffffff, 0)
|
|
1424
|
+
const l0d: i32 = toI32(l0e) & 0xff
|
|
1425
|
+
const l0c: i32 = toI32(l0e >>> 8) & 0xff
|
|
1426
|
+
const l0f: u32 = ctSelect(l0e >>> 16, 0xffffffff, 0)
|
|
1427
|
+
const l0b: i32 = toI32(l0f) & 0xff
|
|
1428
|
+
const l0a: i32 = toI32(l0f >>> 8) & 0xff
|
|
1399
1429
|
r0 ^= st[n] ^ (((st[18 + l0a] + st[274 + l0b]) ^ st[530 + l0c]) + st[786 + l0d])
|
|
1400
|
-
const l1e: u32 = ctSelect(l1
|
|
1401
|
-
const
|
|
1402
|
-
const
|
|
1403
|
-
const
|
|
1404
|
-
const
|
|
1430
|
+
const l1e: u32 = ctSelect(l1, 0xffffffff, 0)
|
|
1431
|
+
const l1d: i32 = toI32(l1e) & 0xff
|
|
1432
|
+
const l1c: i32 = toI32(l1e >>> 8) & 0xff
|
|
1433
|
+
const l1f: u32 = ctSelect(l1e >>> 16, 0xffffffff, 0)
|
|
1434
|
+
const l1b: i32 = toI32(l1f) & 0xff
|
|
1435
|
+
const l1a: i32 = toI32(l1f >>> 8) & 0xff
|
|
1405
1436
|
r1 ^= st[1042 + n] ^ (((st[1060 + l1a] + st[1316 + l1b]) ^ st[1572 + l1c]) + st[1828 + l1d])
|
|
1406
|
-
const l2e: u32 = ctSelect(l2
|
|
1407
|
-
const
|
|
1408
|
-
const
|
|
1409
|
-
const
|
|
1410
|
-
const
|
|
1437
|
+
const l2e: u32 = ctSelect(l2, 0xffffffff, 0)
|
|
1438
|
+
const l2d: i32 = toI32(l2e) & 0xff
|
|
1439
|
+
const l2c: i32 = toI32(l2e >>> 8) & 0xff
|
|
1440
|
+
const l2f: u32 = ctSelect(l2e >>> 16, 0xffffffff, 0)
|
|
1441
|
+
const l2b: i32 = toI32(l2f) & 0xff
|
|
1442
|
+
const l2a: i32 = toI32(l2f >>> 8) & 0xff
|
|
1411
1443
|
r2 ^= st[2084 + n] ^ (((st[2102 + l2a] + st[2358 + l2b]) ^ st[2614 + l2c]) + st[2870 + l2d])
|
|
1412
|
-
const l3e: u32 = ctSelect(l3
|
|
1413
|
-
const
|
|
1414
|
-
const
|
|
1415
|
-
const
|
|
1416
|
-
const
|
|
1444
|
+
const l3e: u32 = ctSelect(l3, 0xffffffff, 0)
|
|
1445
|
+
const l3d: i32 = toI32(l3e) & 0xff
|
|
1446
|
+
const l3c: i32 = toI32(l3e >>> 8) & 0xff
|
|
1447
|
+
const l3f: u32 = ctSelect(l3e >>> 16, 0xffffffff, 0)
|
|
1448
|
+
const l3b: i32 = toI32(l3f) & 0xff
|
|
1449
|
+
const l3a: i32 = toI32(l3f >>> 8) & 0xff
|
|
1417
1450
|
r3 ^= st[3126 + n] ^ (((st[3144 + l3a] + st[3400 + l3b]) ^ st[3656 + l3c]) + st[3912 + l3d])
|
|
1418
|
-
const l4e: u32 = ctSelect(l4
|
|
1419
|
-
const
|
|
1420
|
-
const
|
|
1421
|
-
const
|
|
1422
|
-
const
|
|
1451
|
+
const l4e: u32 = ctSelect(l4, 0xffffffff, 0)
|
|
1452
|
+
const l4d: i32 = toI32(l4e) & 0xff
|
|
1453
|
+
const l4c: i32 = toI32(l4e >>> 8) & 0xff
|
|
1454
|
+
const l4f: u32 = ctSelect(l4e >>> 16, 0xffffffff, 0)
|
|
1455
|
+
const l4b: i32 = toI32(l4f) & 0xff
|
|
1456
|
+
const l4a: i32 = toI32(l4f >>> 8) & 0xff
|
|
1423
1457
|
r4 ^= st[4168 + n] ^ (((st[4186 + l4a] + st[4442 + l4b]) ^ st[4698 + l4c]) + st[4954 + l4d])
|
|
1424
1458
|
const l5e: u32 = ctSelect(l5 >>> 8, 0xffffffff, 0)
|
|
1425
1459
|
const l5a: i32 = toI32(l5 >>> 24) & 0xff
|
|
@@ -1427,35 +1461,40 @@ const bcryptBody6 = (st: u32[]): void => {
|
|
|
1427
1461
|
const l5c: i32 = toI32(l5e) & 0xff
|
|
1428
1462
|
const l5d: i32 = toI32(l5) & 0xff
|
|
1429
1463
|
r5 ^= st[5210 + n] ^ (((st[5228 + l5a] + st[5484 + l5b]) ^ st[5740 + l5c]) + st[5996 + l5d])
|
|
1430
|
-
const r0e: u32 = ctSelect(r0
|
|
1431
|
-
const
|
|
1432
|
-
const
|
|
1433
|
-
const
|
|
1434
|
-
const
|
|
1464
|
+
const r0e: u32 = ctSelect(r0, 0xffffffff, 0)
|
|
1465
|
+
const r0d: i32 = toI32(r0e) & 0xff
|
|
1466
|
+
const r0c: i32 = toI32(r0e >>> 8) & 0xff
|
|
1467
|
+
const r0f: u32 = ctSelect(r0e >>> 16, 0xffffffff, 0)
|
|
1468
|
+
const r0b: i32 = toI32(r0f) & 0xff
|
|
1469
|
+
const r0a: i32 = toI32(r0f >>> 8) & 0xff
|
|
1435
1470
|
l0 ^= st[n + 1] ^ (((st[18 + r0a] + st[274 + r0b]) ^ st[530 + r0c]) + st[786 + r0d])
|
|
1436
|
-
const r1e: u32 = ctSelect(r1
|
|
1437
|
-
const
|
|
1438
|
-
const
|
|
1439
|
-
const
|
|
1440
|
-
const
|
|
1471
|
+
const r1e: u32 = ctSelect(r1, 0xffffffff, 0)
|
|
1472
|
+
const r1d: i32 = toI32(r1e) & 0xff
|
|
1473
|
+
const r1c: i32 = toI32(r1e >>> 8) & 0xff
|
|
1474
|
+
const r1f: u32 = ctSelect(r1e >>> 16, 0xffffffff, 0)
|
|
1475
|
+
const r1b: i32 = toI32(r1f) & 0xff
|
|
1476
|
+
const r1a: i32 = toI32(r1f >>> 8) & 0xff
|
|
1441
1477
|
l1 ^= st[1042 + n + 1] ^ (((st[1060 + r1a] + st[1316 + r1b]) ^ st[1572 + r1c]) + st[1828 + r1d])
|
|
1442
|
-
const r2e: u32 = ctSelect(r2
|
|
1443
|
-
const
|
|
1444
|
-
const
|
|
1445
|
-
const
|
|
1446
|
-
const
|
|
1478
|
+
const r2e: u32 = ctSelect(r2, 0xffffffff, 0)
|
|
1479
|
+
const r2d: i32 = toI32(r2e) & 0xff
|
|
1480
|
+
const r2c: i32 = toI32(r2e >>> 8) & 0xff
|
|
1481
|
+
const r2f: u32 = ctSelect(r2e >>> 16, 0xffffffff, 0)
|
|
1482
|
+
const r2b: i32 = toI32(r2f) & 0xff
|
|
1483
|
+
const r2a: i32 = toI32(r2f >>> 8) & 0xff
|
|
1447
1484
|
l2 ^= st[2084 + n + 1] ^ (((st[2102 + r2a] + st[2358 + r2b]) ^ st[2614 + r2c]) + st[2870 + r2d])
|
|
1448
|
-
const r3e: u32 = ctSelect(r3
|
|
1449
|
-
const
|
|
1450
|
-
const
|
|
1451
|
-
const
|
|
1452
|
-
const
|
|
1485
|
+
const r3e: u32 = ctSelect(r3, 0xffffffff, 0)
|
|
1486
|
+
const r3d: i32 = toI32(r3e) & 0xff
|
|
1487
|
+
const r3c: i32 = toI32(r3e >>> 8) & 0xff
|
|
1488
|
+
const r3f: u32 = ctSelect(r3e >>> 16, 0xffffffff, 0)
|
|
1489
|
+
const r3b: i32 = toI32(r3f) & 0xff
|
|
1490
|
+
const r3a: i32 = toI32(r3f >>> 8) & 0xff
|
|
1453
1491
|
l3 ^= st[3126 + n + 1] ^ (((st[3144 + r3a] + st[3400 + r3b]) ^ st[3656 + r3c]) + st[3912 + r3d])
|
|
1454
|
-
const r4e: u32 = ctSelect(r4
|
|
1455
|
-
const
|
|
1456
|
-
const
|
|
1457
|
-
const
|
|
1458
|
-
const
|
|
1492
|
+
const r4e: u32 = ctSelect(r4, 0xffffffff, 0)
|
|
1493
|
+
const r4d: i32 = toI32(r4e) & 0xff
|
|
1494
|
+
const r4c: i32 = toI32(r4e >>> 8) & 0xff
|
|
1495
|
+
const r4f: u32 = ctSelect(r4e >>> 16, 0xffffffff, 0)
|
|
1496
|
+
const r4b: i32 = toI32(r4f) & 0xff
|
|
1497
|
+
const r4a: i32 = toI32(r4f >>> 8) & 0xff
|
|
1459
1498
|
l4 ^= st[4168 + n + 1] ^ (((st[4186 + r4a] + st[4442 + r4b]) ^ st[4698 + r4c]) + st[4954 + r4d])
|
|
1460
1499
|
const r5e: u32 = ctSelect(r5 >>> 8, 0xffffffff, 0)
|
|
1461
1500
|
const r5a: i32 = toI32(r5 >>> 24) & 0xff
|
package/std/net/http1-codec.ts
CHANGED
|
@@ -81,7 +81,25 @@
|
|
|
81
81
|
* Written from RFC 9112 and RFC 9110, not ported from another implementation.
|
|
82
82
|
*/
|
|
83
83
|
import { copyBytes } from "nish/bytes"
|
|
84
|
-
import {
|
|
84
|
+
import {
|
|
85
|
+
and,
|
|
86
|
+
any,
|
|
87
|
+
bitmask,
|
|
88
|
+
eq,
|
|
89
|
+
extract,
|
|
90
|
+
gt,
|
|
91
|
+
loadU8x16,
|
|
92
|
+
lt,
|
|
93
|
+
mask8x16,
|
|
94
|
+
ne,
|
|
95
|
+
or,
|
|
96
|
+
replace,
|
|
97
|
+
select,
|
|
98
|
+
splatU8x16,
|
|
99
|
+
store,
|
|
100
|
+
subWrapping,
|
|
101
|
+
u8x16,
|
|
102
|
+
} from "nish:simd"
|
|
85
103
|
|
|
86
104
|
/** `next()`: the input so far holds no further event; feed more. */
|
|
87
105
|
export const HTTP1_NEED_MORE: i32 = 0
|
|
@@ -669,8 +687,9 @@ const http1TakeLine = (p: Http1Parser, limit: i32, overStatus: i32): i32 => {
|
|
|
669
687
|
* third (0x57ffffff). No byte below 33 or above 126 is a tchar.
|
|
670
688
|
* `http1IsTokenByte` reads them as two 64-bit masks, one for the bytes 0 to
|
|
671
689
|
* 63 and one for 64 to 127, so the test is a select and a shift with no
|
|
672
|
-
* branch on the byte
|
|
673
|
-
*
|
|
690
|
+
* branch on the byte. A field name goes sixteen bytes at a time through
|
|
691
|
+
* `http1NonTokenLanes`, the same set; this test is for the method, a trailer's
|
|
692
|
+
* name, and a name's last bytes when fewer than sixteen are left in the head.
|
|
674
693
|
*/
|
|
675
694
|
const HTTP1_TCHAR_32: i32 = 67071226
|
|
676
695
|
const HTTP1_TCHAR_64: i32 = -939524098
|
|
@@ -684,6 +703,66 @@ export const http1IsTokenByte = (c: i32): boolean => {
|
|
|
684
703
|
return c >= 0 && c < 128 && ((word >> toU64(c & 63)) & toU64(1)) !== toU64(0)
|
|
685
704
|
}
|
|
686
705
|
|
|
706
|
+
/**
|
|
707
|
+
* Which lanes of `v` are not tchars, as `http1IsTokenByte` answers for each,
|
|
708
|
+
* bit `k` for lane `k`: a byte outside 33 to 126, or one of the seventeen
|
|
709
|
+
* delimiters among them, `"` `(` `)` `,` `/` `:` to `@` (seven), `[` `\` `]`
|
|
710
|
+
* `{` and `}`. A name is mostly one vector, so these compares run once for
|
|
711
|
+
* the sixteen bytes where the table test ran once for each.
|
|
712
|
+
*/
|
|
713
|
+
const http1NonTokenLanes = (v: u8x16): i32 => {
|
|
714
|
+
const outside: mask8x16 = gt(subWrapping(v, splatU8x16(33)), splatU8x16(93))
|
|
715
|
+
const quote: mask8x16 = or(eq(v, splatU8x16(34)), lt(subWrapping(v, splatU8x16(40)), splatU8x16(2)))
|
|
716
|
+
const comma: mask8x16 = or(eq(v, splatU8x16(44)), eq(v, splatU8x16(47)))
|
|
717
|
+
const colon: mask8x16 = lt(subWrapping(v, splatU8x16(58)), splatU8x16(7))
|
|
718
|
+
const bracket: mask8x16 = lt(subWrapping(v, splatU8x16(91)), splatU8x16(3))
|
|
719
|
+
const brace: mask8x16 = or(eq(v, splatU8x16(123)), eq(v, splatU8x16(125)))
|
|
720
|
+
return bitmask(or(or(or(outside, quote), or(comma, colon)), or(bracket, brace)))
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Lowercases a field name in `head` from `k`, sixteen bytes at a time, and
|
|
725
|
+
* answers where it ends: the first byte before `stop` that is not a tchar, or
|
|
726
|
+
* `stop`. Each vector's name lanes are lowered, and every other lane is
|
|
727
|
+
* stored back as it was, so the value after the name and the bytes past the
|
|
728
|
+
* line keep their case. A tail of under sixteen bytes before `head`'s end
|
|
729
|
+
* goes a byte at a time. The answer and the bytes written are the byte loop's.
|
|
730
|
+
*/
|
|
731
|
+
const http1LowerName = (head: u8[], k0: i32, stop: i32): i32 => {
|
|
732
|
+
// Lane `j` holds `j`: the name's lanes are those below its length.
|
|
733
|
+
const lanes: u8x16 = u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
|
|
734
|
+
let k: i32 = k0
|
|
735
|
+
while (k >= 0 && k < stop && k <= toI32(head.length) - 16) {
|
|
736
|
+
const v: u8x16 = loadU8x16(head, k)
|
|
737
|
+
const bad: i32 = http1NonTokenLanes(v)
|
|
738
|
+
let run: i32 = 16
|
|
739
|
+
if (bad !== 0) {
|
|
740
|
+
run = toI32(31) - toI32(Math.clz32(toU32(bad & -bad)))
|
|
741
|
+
}
|
|
742
|
+
if (run > stop - k) {
|
|
743
|
+
run = stop - k
|
|
744
|
+
}
|
|
745
|
+
const upper: mask8x16 = and(
|
|
746
|
+
lt(subWrapping(v, splatU8x16(65)), splatU8x16(26)),
|
|
747
|
+
lt(lanes, splatU8x16(toU8(run)))
|
|
748
|
+
)
|
|
749
|
+
store(select(upper, or(v, splatU8x16(32)), v), head, k)
|
|
750
|
+
k += run
|
|
751
|
+
if (run < 16) {
|
|
752
|
+
return k
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
while (k >= 0 && k < stop && k < toI32(head.length)) {
|
|
756
|
+
const c: i32 = toI32(head[k])
|
|
757
|
+
if (!http1IsTokenByte(c)) {
|
|
758
|
+
break
|
|
759
|
+
}
|
|
760
|
+
head[k] = toU8(c >= 65 && c <= 90 ? c + 32 : c)
|
|
761
|
+
k += 1
|
|
762
|
+
}
|
|
763
|
+
return k
|
|
764
|
+
}
|
|
765
|
+
|
|
687
766
|
/** Whether `c` may appear in a field value (RFC 9110 §5.5): HTAB, SP, VCHAR or obs-text. */
|
|
688
767
|
export const http1IsValueByte = (c: i32): boolean => c === 9 || (c >= 32 && c !== 127)
|
|
689
768
|
|
|
@@ -1012,18 +1091,7 @@ const http1FieldLine = (p: Http1Parser, keep: boolean): i32 => {
|
|
|
1012
1091
|
let i: i32 = a
|
|
1013
1092
|
if (keep) {
|
|
1014
1093
|
at = http1HeadAppend(p, a, b)
|
|
1015
|
-
|
|
1016
|
-
let k: i32 = at
|
|
1017
|
-
const stop: i32 = at + (b - a)
|
|
1018
|
-
while (k >= 0 && k < stop && k < toI32(head.length)) {
|
|
1019
|
-
const c: i32 = toI32(head[k])
|
|
1020
|
-
if (!http1IsTokenByte(c)) {
|
|
1021
|
-
break
|
|
1022
|
-
}
|
|
1023
|
-
head[k] = toU8(c >= 65 && c <= 90 ? c + 32 : c)
|
|
1024
|
-
k += 1
|
|
1025
|
-
}
|
|
1026
|
-
i = a + (k - at)
|
|
1094
|
+
i = a + (http1LowerName(p.head, at, at + (b - a)) - at)
|
|
1027
1095
|
} else {
|
|
1028
1096
|
while (i >= 0 && i < b && i < toI32(buf.length) && http1IsTokenByte(toI32(buf[i]))) {
|
|
1029
1097
|
i += 1
|
|
@@ -1046,7 +1114,12 @@ const http1FieldLine = (p: Http1Parser, keep: boolean): i32 => {
|
|
|
1046
1114
|
if (keep) {
|
|
1047
1115
|
let valueStart: i32 = nameEnd + 1
|
|
1048
1116
|
let valueEnd: i32 = b
|
|
1049
|
-
while (
|
|
1117
|
+
while (
|
|
1118
|
+
valueStart >= 0 &&
|
|
1119
|
+
valueStart < valueEnd &&
|
|
1120
|
+
valueStart < toI32(buf.length) &&
|
|
1121
|
+
http1IsOws(toI32(buf[valueStart]))
|
|
1122
|
+
) {
|
|
1050
1123
|
valueStart += 1
|
|
1051
1124
|
}
|
|
1052
1125
|
while (valueEnd > valueStart && valueEnd - 1 >= 0 && http1IsOws(toI32(buf[valueEnd - 1]))) {
|
|
@@ -1591,14 +1664,39 @@ const http1BytesAreToken = (bytes: u8[]): boolean => {
|
|
|
1591
1664
|
return toI32(bytes.length) > 0
|
|
1592
1665
|
}
|
|
1593
1666
|
|
|
1594
|
-
/**
|
|
1667
|
+
/**
|
|
1668
|
+
* Whether no lane of `v` is a byte a field value may not hold: below 32 and
|
|
1669
|
+
* not HTAB, or DEL. `http1IsValueByte` on sixteen bytes at once, exactly, so
|
|
1670
|
+
* a vector may overlap one already checked.
|
|
1671
|
+
*/
|
|
1672
|
+
const http1LanesAreFieldText = (v: u8x16): boolean => {
|
|
1673
|
+
const control: mask8x16 = and(lt(v, splatU8x16(32)), ne(v, splatU8x16(9)))
|
|
1674
|
+
return !any(or(control, eq(v, splatU8x16(127))))
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
/**
|
|
1678
|
+
* Whether every byte of `bytes` may stand in a field value: sixteen at a
|
|
1679
|
+
* time, the last vector ending at the last byte and overlapping the one
|
|
1680
|
+
* before it, and one at a time below sixteen.
|
|
1681
|
+
*/
|
|
1595
1682
|
const http1BytesAreFieldText = (bytes: u8[]): boolean => {
|
|
1596
|
-
|
|
1597
|
-
|
|
1683
|
+
const n: i32 = toI32(bytes.length)
|
|
1684
|
+
if (n < 16) {
|
|
1685
|
+
for (let k: i32 = 0; k < n; k += 1) {
|
|
1686
|
+
if (!http1IsValueByte(toI32(bytes[k]))) {
|
|
1687
|
+
return false
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
return true
|
|
1691
|
+
}
|
|
1692
|
+
let k: i32 = 0
|
|
1693
|
+
while (k >= 0 && k <= n - 16) {
|
|
1694
|
+
if (!http1LanesAreFieldText(loadU8x16(bytes, k))) {
|
|
1598
1695
|
return false
|
|
1599
1696
|
}
|
|
1697
|
+
k += 16
|
|
1600
1698
|
}
|
|
1601
|
-
return
|
|
1699
|
+
return k === n || http1LanesAreFieldText(loadU8x16(bytes, n - 16))
|
|
1602
1700
|
}
|
|
1603
1701
|
|
|
1604
1702
|
/** Whether the octets of `bytes` spell `word`, which is lowercase, in any ASCII case: a field name compared as RFC 9110 §5.1 says. */
|
|
@@ -1628,6 +1726,14 @@ const http1DecimalDigits = (n: i32): i32 => {
|
|
|
1628
1726
|
/** Writes `text` at `out[at ..)`, which the caller has made sure holds it, and answers where it ends. */
|
|
1629
1727
|
export const http1PutText = (out: u8[], at: i32, text: string): i32 => {
|
|
1630
1728
|
const n: i32 = toI32(text.length)
|
|
1729
|
+
if (at >= 0 && at <= toI32(out.length) - n) {
|
|
1730
|
+
// It fits, the case every caller makes sure of: one test, then a loop
|
|
1731
|
+
// with no bounds check in it.
|
|
1732
|
+
for (let k: i32 = 0; k < n; k += 1) {
|
|
1733
|
+
out[at + k] = toU8(text.charCodeAt(k))
|
|
1734
|
+
}
|
|
1735
|
+
return at + n
|
|
1736
|
+
}
|
|
1631
1737
|
for (let k: i32 = 0; k < n && at + k < toI32(out.length); k += 1) {
|
|
1632
1738
|
if (at + k >= 0) {
|
|
1633
1739
|
out[at + k] = toU8(text.charCodeAt(k))
|
|
@@ -1669,6 +1775,50 @@ const http1PutBytes = (out: u8[], at: i32, bytes: u8[]): i32 => {
|
|
|
1669
1775
|
return at + n
|
|
1670
1776
|
}
|
|
1671
1777
|
|
|
1778
|
+
/**
|
|
1779
|
+
* Writes `text`, at most sixteen ASCII bytes, at `out[at ..)`, likewise, as
|
|
1780
|
+
* one sixteen-byte store of `v`, which holds `text` in its first lanes: when
|
|
1781
|
+
* `at + 16` does not pass `limit`, the end of the head being written, whose
|
|
1782
|
+
* every byte from `at` on is written after this one, so the lanes past
|
|
1783
|
+
* `text` are overwritten before the head is done. Byte by byte otherwise.
|
|
1784
|
+
*/
|
|
1785
|
+
const http1PutFixed = (out: u8[], at: i32, limit: i32, v: u8x16, text: string): i32 => {
|
|
1786
|
+
if (at >= 0 && at <= limit - 16 && limit <= toI32(out.length)) {
|
|
1787
|
+
store(v, out, at)
|
|
1788
|
+
return at + toI32(text.length)
|
|
1789
|
+
}
|
|
1790
|
+
return http1PutText(out, at, text)
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
/**
|
|
1794
|
+
* Writes `HTTP/1.1 `, the three digits of `status`, which is 100 to 599, and
|
|
1795
|
+
* a space at `out[at ..)`, likewise: one store, the digits replacing three
|
|
1796
|
+
* lanes of the constant.
|
|
1797
|
+
*/
|
|
1798
|
+
const http1PutStatusLine = (out: u8[], at: i32, limit: i32, status: i32): i32 => {
|
|
1799
|
+
const hundreds: i32 = status / 100
|
|
1800
|
+
const tens: i32 = (status / 10) % 10
|
|
1801
|
+
const ones: i32 = status % 10
|
|
1802
|
+
if (at >= 0 && at <= limit - 16 && limit <= toI32(out.length)) {
|
|
1803
|
+
// "HTTP/1.1 000 ", and three lanes the head's next bytes overwrite.
|
|
1804
|
+
const line: u8x16 = u8x16(72, 84, 84, 80, 47, 49, 46, 49, 32, 48, 48, 48, 32, 32, 32, 32)
|
|
1805
|
+
store(
|
|
1806
|
+
replace(replace(replace(line, 9, toU8(48 + hundreds)), 10, toU8(48 + tens)), 11, toU8(48 + ones)),
|
|
1807
|
+
out,
|
|
1808
|
+
at
|
|
1809
|
+
)
|
|
1810
|
+
return at + 13
|
|
1811
|
+
}
|
|
1812
|
+
const end: i32 = http1PutText(out, at, "HTTP/1.1 ")
|
|
1813
|
+
if (end >= 0 && end < toI32(out.length) - 3) {
|
|
1814
|
+
out[end] = toU8(48 + hundreds)
|
|
1815
|
+
out[end + 1] = toU8(48 + tens)
|
|
1816
|
+
out[end + 2] = toU8(48 + ones)
|
|
1817
|
+
out[end + 3] = 32
|
|
1818
|
+
}
|
|
1819
|
+
return end + 4
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1672
1822
|
/** Writes the decimal digits of `n`, which is not negative, at `out[at ..)`, likewise. */
|
|
1673
1823
|
const http1PutDecimal = (out: u8[], at: i32, n: i32): i32 => {
|
|
1674
1824
|
const digits: i32 = http1DecimalDigits(n)
|
|
@@ -1725,7 +1875,7 @@ export const http1WriteResponseHead = (
|
|
|
1725
1875
|
// is written, in 64 bits so that no caller's lengths can wrap the sum.
|
|
1726
1876
|
let need: i64 = toI64(17) + toI64(reason.length)
|
|
1727
1877
|
let sendDate: boolean = status >= 200 && toI32(date.length) > 0
|
|
1728
|
-
for (let i: i32 = 0; i <
|
|
1878
|
+
for (let i: i32 = 0; i < toI32(names.length) && i < toI32(values.length); i += 1) {
|
|
1729
1879
|
const name: u8[] = names[i]
|
|
1730
1880
|
const value: u8[] = values[i]
|
|
1731
1881
|
if (!http1BytesAreToken(name) || !http1BytesAreFieldText(value)) {
|
|
@@ -1757,41 +1907,49 @@ export const http1WriteResponseHead = (
|
|
|
1757
1907
|
if (at < 0 || at > toI32(out.length) || need > toI64(toI32(out.length) - at)) {
|
|
1758
1908
|
return HTTP1_NO_ROOM
|
|
1759
1909
|
}
|
|
1760
|
-
let end: i32 = http1PutText(out, at, "HTTP/1.1 ")
|
|
1761
1910
|
// A status is three digits, checked above: no division loop for them.
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
const tens: i32 = status / 10
|
|
1765
|
-
const tensDigit: i32 = tens % 10
|
|
1766
|
-
const ones: i32 = status % 10
|
|
1767
|
-
out[end] = toU8(48 + hundreds)
|
|
1768
|
-
out[end + 1] = toU8(48 + tensDigit)
|
|
1769
|
-
out[end + 2] = toU8(48 + ones)
|
|
1770
|
-
out[end + 3] = 32
|
|
1771
|
-
}
|
|
1772
|
-
end = end + 4
|
|
1911
|
+
const limit: i32 = at + toI32(need)
|
|
1912
|
+
let end: i32 = http1PutStatusLine(out, at, limit, status)
|
|
1773
1913
|
end = http1PutText(out, end, reason)
|
|
1774
1914
|
end = http1PutCrlf(out, end)
|
|
1775
|
-
for (let i: i32 = 0; i <
|
|
1915
|
+
for (let i: i32 = 0; i < toI32(names.length) && i < toI32(values.length); i += 1) {
|
|
1776
1916
|
end = http1PutBytes(out, end, names[i])
|
|
1777
1917
|
end = http1PutColonSpace(out, end)
|
|
1778
1918
|
end = http1PutBytes(out, end, values[i])
|
|
1779
1919
|
end = http1PutCrlf(out, end)
|
|
1780
1920
|
}
|
|
1781
1921
|
if (sendDate) {
|
|
1782
|
-
end =
|
|
1922
|
+
end = http1PutFixed(
|
|
1923
|
+
out,
|
|
1924
|
+
end,
|
|
1925
|
+
limit,
|
|
1926
|
+
u8x16(68, 97, 116, 101, 58, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32),
|
|
1927
|
+
"Date: "
|
|
1928
|
+
)
|
|
1783
1929
|
end = http1PutBytes(out, end, date)
|
|
1784
1930
|
end = http1PutCrlf(out, end)
|
|
1785
1931
|
}
|
|
1786
1932
|
if (bodyLength >= 0) {
|
|
1787
|
-
end =
|
|
1933
|
+
end = http1PutFixed(
|
|
1934
|
+
out,
|
|
1935
|
+
end,
|
|
1936
|
+
limit,
|
|
1937
|
+
u8x16(67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32),
|
|
1938
|
+
"Content-Length: "
|
|
1939
|
+
)
|
|
1788
1940
|
end = http1PutDecimal(out, end, bodyLength)
|
|
1789
1941
|
end = http1PutCrlf(out, end)
|
|
1790
1942
|
} else if (bodyLength === HTTP1_CHUNKED) {
|
|
1791
1943
|
end = http1PutText(out, end, "Transfer-Encoding: chunked\r\n")
|
|
1792
1944
|
}
|
|
1793
1945
|
if (toI32(connection.length) > 0) {
|
|
1794
|
-
end =
|
|
1946
|
+
end = http1PutFixed(
|
|
1947
|
+
out,
|
|
1948
|
+
end,
|
|
1949
|
+
limit,
|
|
1950
|
+
u8x16(67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 32, 32, 32, 32),
|
|
1951
|
+
"Connection: "
|
|
1952
|
+
)
|
|
1795
1953
|
end = http1PutText(out, end, connection)
|
|
1796
1954
|
end = http1PutCrlf(out, end)
|
|
1797
1955
|
}
|
package/std/net/postgres.ts
CHANGED
|
@@ -445,13 +445,56 @@ const pgBytesOf = (text: string): u8[] => {
|
|
|
445
445
|
|
|
446
446
|
/** How many bytes `value` takes in decimal, its sign included. */
|
|
447
447
|
const pgDecimalLength = (value: i64): i32 => {
|
|
448
|
+
// Counted on the negative side, where the most negative i64 fits, two digits a step.
|
|
448
449
|
let n: i32 = value < 0 ? 2 : 1
|
|
449
450
|
let v: i64 = value < 0 ? value : -value
|
|
450
|
-
while (v <= -
|
|
451
|
-
v = v /
|
|
452
|
-
n +=
|
|
451
|
+
while (v <= -100) {
|
|
452
|
+
v = v / 100
|
|
453
|
+
n += 2
|
|
453
454
|
}
|
|
454
|
-
return n
|
|
455
|
+
return v <= -10 ? n + 1 : n
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Writes `value` in decimal into `out[at, at + n)`, where `n` is
|
|
460
|
+
* `pgDecimalLength(value)`, and answers `at + n`. The digits go once, into
|
|
461
|
+
* their places, from the last, two a step from the magnitude as a `u64`
|
|
462
|
+
* (which holds the most negative i64's, and whose `/` and `%` are never
|
|
463
|
+
* checked). Panics unless the window is inside `out`; each step's guard
|
|
464
|
+
* restates it in the shape that proves its two stores.
|
|
465
|
+
*/
|
|
466
|
+
const pgPutDecimal = (out: u8[], at: i32, value: i64, n: i32): i32 => {
|
|
467
|
+
if (!(at >= 0 && at < 2147483620 && n >= 1 && n <= 20 && at + n <= toI32(out.length))) {
|
|
468
|
+
panic("nish/net/postgres: a decimal outside its room")
|
|
469
|
+
}
|
|
470
|
+
const first: i32 = value < 0 ? at + 1 : at
|
|
471
|
+
let m: u64 = value < 0 ? toU64(0) - toU64(value) : toU64(value)
|
|
472
|
+
// Where the last two digits start.
|
|
473
|
+
let j: i32 = at + n - 2
|
|
474
|
+
while (m >= 100 && j >= first && j >= 0 && j < 2147483640 && j + 2 <= toI32(out.length)) {
|
|
475
|
+
const pair: u32 = toU32(m % 100)
|
|
476
|
+
const tens: u32 = pair / 10
|
|
477
|
+
out[j] = toU8(48 + tens)
|
|
478
|
+
out[j + 1] = toU8(48 + pair - tens * 10)
|
|
479
|
+
m = m / 100
|
|
480
|
+
j -= 2
|
|
481
|
+
}
|
|
482
|
+
// One or two digits are left, ending at `j + 2`.
|
|
483
|
+
const pair: u32 = toU32(m)
|
|
484
|
+
if (pair >= 10 && j >= first && j >= 0 && j < 2147483640 && j + 2 <= toI32(out.length)) {
|
|
485
|
+
const tens: u32 = pair / 10
|
|
486
|
+
out[j] = toU8(48 + tens)
|
|
487
|
+
out[j + 1] = toU8(48 + pair - tens * 10)
|
|
488
|
+
} else {
|
|
489
|
+
const last: i32 = j + 1
|
|
490
|
+
if (last >= first && last >= 0 && last < toI32(out.length)) {
|
|
491
|
+
out[last] = toU8(48 + pair)
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (value < 0 && at < toI32(out.length)) {
|
|
495
|
+
out[at] = toU8(45)
|
|
496
|
+
}
|
|
497
|
+
return at + n
|
|
455
498
|
}
|
|
456
499
|
|
|
457
500
|
/** Whether `value` is an `int4`, -2^31..2^31-1. */
|
|
@@ -2274,32 +2317,9 @@ export class PgConnection {
|
|
|
2274
2317
|
|
|
2275
2318
|
/** `value` in decimal, `pgDecimalLength(value)` bytes. */
|
|
2276
2319
|
private putDecimal(value: i64): void {
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
let v: i64 = value < 0 ? value : -value
|
|
2281
|
-
if (value < 0) {
|
|
2282
|
-
this.out[this.outEnd] = toU8(45)
|
|
2283
|
-
this.outEnd += 1
|
|
2284
|
-
}
|
|
2285
|
-
const first: i32 = this.outEnd
|
|
2286
|
-
while (true) {
|
|
2287
|
-
this.out[this.outEnd] = toU8(48 - toI32(v % 10))
|
|
2288
|
-
this.outEnd += 1
|
|
2289
|
-
v = v / 10
|
|
2290
|
-
if (v === 0) {
|
|
2291
|
-
break
|
|
2292
|
-
}
|
|
2293
|
-
}
|
|
2294
|
-
let lo: i32 = first
|
|
2295
|
-
let hi: i32 = this.outEnd - 1
|
|
2296
|
-
while (lo < hi) {
|
|
2297
|
-
const t: u8 = this.out[lo]
|
|
2298
|
-
this.out[lo] = this.out[hi]
|
|
2299
|
-
this.out[hi] = t
|
|
2300
|
-
lo++
|
|
2301
|
-
hi--
|
|
2302
|
-
}
|
|
2320
|
+
const n: i32 = pgDecimalLength(value)
|
|
2321
|
+
this.reserve(this.outEnd + n)
|
|
2322
|
+
this.outEnd = pgPutDecimal(this.out, this.outEnd, value, n)
|
|
2303
2323
|
}
|
|
2304
2324
|
|
|
2305
2325
|
/**
|