@grain/stdlib 0.6.6 → 0.7.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/CHANGELOG.md +67 -0
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/array.gr +55 -7
- package/array.md +606 -560
- package/bigint.md +228 -228
- package/buffer.gr +85 -53
- package/buffer.md +442 -319
- package/bytes.gr +112 -35
- package/bytes.md +299 -219
- package/char.gr +201 -99
- package/char.md +447 -120
- package/exception.gr +11 -11
- package/exception.md +29 -4
- package/float32.gr +327 -3
- package/float32.md +698 -111
- package/float64.gr +320 -3
- package/float64.md +698 -111
- package/fs.gr +1082 -0
- package/fs.md +630 -0
- package/hash.gr +142 -88
- package/hash.md +105 -17
- package/int16.md +178 -178
- package/int32.gr +26 -5
- package/int32.md +266 -231
- package/int64.gr +27 -2
- package/int64.md +266 -231
- package/int8.md +178 -178
- package/json.gr +366 -51
- package/json.md +431 -15
- package/list.gr +328 -31
- package/list.md +759 -336
- package/map.gr +20 -12
- package/map.md +266 -260
- package/marshal.gr +41 -40
- package/marshal.md +14 -14
- package/number.gr +278 -35
- package/number.md +688 -269
- package/option.md +162 -162
- package/package.json +5 -3
- package/path.gr +48 -0
- package/path.md +180 -89
- package/pervasives.gr +2 -2
- package/pervasives.md +275 -275
- package/priorityqueue.gr +7 -7
- package/priorityqueue.md +131 -131
- package/queue.gr +183 -29
- package/queue.md +404 -148
- package/random.md +43 -43
- package/range.gr +4 -4
- package/range.md +42 -42
- package/rational.md +123 -123
- package/regex.gr +52 -51
- package/regex.md +102 -102
- package/result.md +118 -118
- package/runtime/atof/common.md +39 -39
- package/runtime/atof/decimal.gr +6 -6
- package/runtime/atof/decimal.md +14 -14
- package/runtime/atof/lemire.gr +5 -5
- package/runtime/atof/lemire.md +1 -1
- package/runtime/atof/parse.gr +16 -16
- package/runtime/atof/parse.md +2 -2
- package/runtime/atof/slow.md +1 -1
- package/runtime/atof/table.md +2 -2
- package/runtime/atoi/parse.gr +3 -3
- package/runtime/atoi/parse.md +1 -1
- package/runtime/bigint.gr +15 -47
- package/runtime/bigint.md +54 -60
- package/runtime/compare.gr +2 -2
- package/runtime/compare.md +8 -8
- package/runtime/dataStructures.md +211 -211
- package/runtime/debugPrint.gr +4 -1
- package/runtime/debugPrint.md +9 -9
- package/runtime/equal.gr +99 -77
- package/runtime/equal.md +8 -8
- package/runtime/exception.gr +62 -82
- package/runtime/exception.md +62 -11
- package/runtime/gc.gr +39 -45
- package/runtime/gc.md +4 -4
- package/runtime/malloc.gr +7 -7
- package/runtime/malloc.md +13 -13
- package/runtime/math/kernel/cos.gr +70 -0
- package/runtime/math/kernel/cos.md +14 -0
- package/runtime/math/kernel/sin.gr +65 -0
- package/runtime/math/kernel/sin.md +14 -0
- package/runtime/math/kernel/tan.gr +136 -0
- package/runtime/math/kernel/tan.md +14 -0
- package/runtime/math/rempio2.gr +244 -0
- package/runtime/math/rempio2.md +14 -0
- package/runtime/math/trig.gr +130 -0
- package/runtime/math/trig.md +28 -0
- package/runtime/math/umuldi.gr +26 -0
- package/runtime/math/umuldi.md +14 -0
- package/runtime/numberUtils.gr +29 -29
- package/runtime/numberUtils.md +12 -12
- package/runtime/numbers.gr +373 -381
- package/runtime/numbers.md +348 -342
- package/runtime/string.gr +37 -105
- package/runtime/string.md +20 -26
- package/runtime/unsafe/constants.md +24 -24
- package/runtime/unsafe/conv.md +19 -19
- package/runtime/unsafe/memory.gr +24 -20
- package/runtime/unsafe/memory.md +27 -7
- package/runtime/unsafe/offsets.gr +36 -0
- package/runtime/unsafe/offsets.md +88 -0
- package/runtime/unsafe/panic.gr +28 -0
- package/runtime/unsafe/panic.md +14 -0
- package/runtime/unsafe/tags.md +32 -32
- package/runtime/unsafe/wasmf32.md +28 -28
- package/runtime/unsafe/wasmf64.md +28 -28
- package/runtime/unsafe/wasmi32.md +47 -47
- package/runtime/unsafe/wasmi64.md +50 -50
- package/runtime/utf8.gr +189 -0
- package/runtime/utf8.md +117 -0
- package/runtime/wasi.gr +4 -2
- package/runtime/wasi.md +147 -147
- package/set.gr +18 -11
- package/set.md +253 -247
- package/stack.gr +171 -2
- package/stack.md +371 -89
- package/string.gr +352 -557
- package/string.md +298 -255
- package/uint16.md +170 -170
- package/uint32.gr +25 -4
- package/uint32.md +249 -214
- package/uint64.gr +25 -5
- package/uint64.md +249 -214
- package/uint8.md +170 -170
- package/uri.gr +57 -53
- package/uri.md +88 -89
- package/wasi/file.gr +67 -59
- package/wasi/file.md +308 -308
- package/wasi/process.md +26 -26
- package/wasi/random.md +12 -12
- package/wasi/time.md +16 -16
- package/runtime/utils/printing.gr +0 -60
- package/runtime/utils/printing.md +0 -26
package/runtime/gc.gr
CHANGED
|
@@ -21,21 +21,20 @@ module GC
|
|
|
21
21
|
|
|
22
22
|
from "runtime/malloc" include Malloc
|
|
23
23
|
from "runtime/unsafe/tags" include Tags
|
|
24
|
+
from "runtime/unsafe/panic" include Panic
|
|
24
25
|
from "runtime/unsafe/wasmi32" include WasmI32
|
|
25
26
|
use WasmI32.{ (+), (-), (*), (&), (==), (!=) }
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
foreign wasm fd_write:
|
|
29
|
-
(WasmI32, WasmI32, WasmI32, WasmI32) => WasmI32 from "wasi_snapshot_preview1"
|
|
30
|
-
|
|
28
|
+
primitive (!) = "@not"
|
|
31
29
|
primitive (&&) = "@and"
|
|
32
30
|
primitive (||) = "@or"
|
|
33
|
-
primitive throw = "@throw"
|
|
34
31
|
primitive ignore = "@ignore"
|
|
35
32
|
primitive box = "@box"
|
|
36
33
|
primitive unbox = "@unbox"
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
let throwDecRefError = () => {
|
|
36
|
+
Panic.panic("DecRefError: Reference count of zero")
|
|
37
|
+
}
|
|
39
38
|
|
|
40
39
|
let mut _DEBUG = false
|
|
41
40
|
|
|
@@ -86,24 +85,37 @@ let rec decRef = (userPtr: WasmI32, ignoreZeros: Bool) => {
|
|
|
86
85
|
// }
|
|
87
86
|
|
|
88
87
|
if (WasmI32.eqz(refCount)) {
|
|
89
|
-
if (ignoreZeros) {
|
|
90
|
-
|
|
91
|
-
} else {
|
|
92
|
-
throw DecRefError
|
|
88
|
+
if (!ignoreZeros) {
|
|
89
|
+
throwDecRefError()
|
|
93
90
|
}
|
|
94
91
|
} else {
|
|
95
92
|
let refCount = refCount - 1n
|
|
96
93
|
setRefCount(userPtr, refCount)
|
|
97
94
|
|
|
98
95
|
if (WasmI32.eqz(refCount)) {
|
|
99
|
-
|
|
96
|
+
/*
|
|
97
|
+
* Note: We call free before decRefChildren to allow for a tail call.
|
|
98
|
+
* This is okay because no allocations occur while we traverse the
|
|
99
|
+
* structure and free does not mangle the data.
|
|
100
|
+
*/
|
|
100
101
|
free(userPtr)
|
|
102
|
+
decRefChildren(userPtr)
|
|
101
103
|
}
|
|
102
|
-
|
|
103
|
-
userPtr
|
|
104
104
|
}
|
|
105
|
-
}
|
|
106
|
-
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
and decRefChildrenHelp = (
|
|
108
|
+
userPtr: WasmI32,
|
|
109
|
+
arityOffset: WasmI32,
|
|
110
|
+
offset: WasmI32,
|
|
111
|
+
) => {
|
|
112
|
+
let arity = WasmI32.load(userPtr, arityOffset)
|
|
113
|
+
if (arity != 0n) {
|
|
114
|
+
let maxOffset = (arity - 1n) * 4n
|
|
115
|
+
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
116
|
+
decRef(WasmI32.load(userPtr + i, offset), false)
|
|
117
|
+
}
|
|
118
|
+
decRef(WasmI32.load(userPtr + maxOffset, offset), false)
|
|
107
119
|
}
|
|
108
120
|
}
|
|
109
121
|
and decRefChildren = (userPtr: WasmI32) => {
|
|
@@ -112,43 +124,25 @@ and decRefChildren = (userPtr: WasmI32) => {
|
|
|
112
124
|
let tag = WasmI32.load(userPtr, 4n)
|
|
113
125
|
if (userPtr == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG) {
|
|
114
126
|
// decRef underlying BigInts
|
|
115
|
-
|
|
116
|
-
|
|
127
|
+
decRef(WasmI32.load(userPtr, 8n), false)
|
|
128
|
+
decRef(WasmI32.load(userPtr, 12n), false)
|
|
117
129
|
}
|
|
118
130
|
},
|
|
119
131
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
120
|
-
|
|
121
|
-
let maxOffset = arity * 4n
|
|
122
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
123
|
-
ignore(decRef(WasmI32.load(userPtr + i, 20n), false))
|
|
124
|
-
}
|
|
132
|
+
decRefChildrenHelp(userPtr, 16n, 20n)
|
|
125
133
|
},
|
|
126
|
-
t when t == Tags._GRAIN_RECORD_HEAP_TAG => {
|
|
127
|
-
|
|
128
|
-
let maxOffset = arity * 4n
|
|
129
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
130
|
-
ignore(decRef(WasmI32.load(userPtr + i, 16n), false))
|
|
131
|
-
}
|
|
134
|
+
t when t == Tags._GRAIN_RECORD_HEAP_TAG || t == Tags._GRAIN_LAMBDA_HEAP_TAG => {
|
|
135
|
+
decRefChildrenHelp(userPtr, 12n, 16n)
|
|
132
136
|
},
|
|
133
137
|
t when t == Tags._GRAIN_ARRAY_HEAP_TAG || t == Tags._GRAIN_TUPLE_HEAP_TAG => {
|
|
134
|
-
|
|
135
|
-
let maxOffset = arity * 4n
|
|
136
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
137
|
-
ignore(decRef(WasmI32.load(userPtr + i, 8n), false))
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
t when t == Tags._GRAIN_LAMBDA_HEAP_TAG => {
|
|
141
|
-
let arity = WasmI32.load(userPtr, 12n)
|
|
142
|
-
let maxOffset = arity * 4n
|
|
143
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
144
|
-
ignore(decRef(WasmI32.load(userPtr + i, 16n), false))
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
_ => {
|
|
148
|
-
// No travelsal necessary for other tags
|
|
149
|
-
void
|
|
138
|
+
decRefChildrenHelp(userPtr, 4n, 8n)
|
|
150
139
|
},
|
|
140
|
+
// No traversal necessary for other tags
|
|
141
|
+
_ => void,
|
|
151
142
|
}
|
|
152
143
|
}
|
|
153
144
|
|
|
154
|
-
provide let decRef = userPtr =>
|
|
145
|
+
provide let decRef = userPtr => {
|
|
146
|
+
decRef(userPtr, false)
|
|
147
|
+
userPtr
|
|
148
|
+
}
|
package/runtime/gc.md
CHANGED
|
@@ -9,24 +9,24 @@ Functions and constants included in the GC module.
|
|
|
9
9
|
### GC.**malloc**
|
|
10
10
|
|
|
11
11
|
```grain
|
|
12
|
-
malloc
|
|
12
|
+
malloc: (size: WasmI32) => WasmI32
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### GC.**free**
|
|
16
16
|
|
|
17
17
|
```grain
|
|
18
|
-
free
|
|
18
|
+
free: (userPtr: WasmI32) => Void
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
### GC.**incRef**
|
|
22
22
|
|
|
23
23
|
```grain
|
|
24
|
-
incRef
|
|
24
|
+
incRef: (userPtr: WasmI32) => WasmI32
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### GC.**decRef**
|
|
28
28
|
|
|
29
29
|
```grain
|
|
30
|
-
decRef
|
|
30
|
+
decRef: (userPtr: WasmI32) => WasmI32
|
|
31
31
|
```
|
|
32
32
|
|
package/runtime/malloc.gr
CHANGED
|
@@ -21,7 +21,7 @@ use WasmI32.{
|
|
|
21
21
|
(&),
|
|
22
22
|
(^),
|
|
23
23
|
}
|
|
24
|
-
from "runtime/
|
|
24
|
+
from "runtime/unsafe/panic" include Panic
|
|
25
25
|
|
|
26
26
|
primitive memorySize = "@wasm.memory_size"
|
|
27
27
|
primitive memoryGrow = "@wasm.memory_grow"
|
|
@@ -38,12 +38,12 @@ primitive heapStart = "@heap.start"
|
|
|
38
38
|
* lists are maintained, one for small blocks of 64 bytes, and one for larger
|
|
39
39
|
* blocks of multiples of 64 bytes. Each block has an 8-byte header and 8-byte
|
|
40
40
|
* footer to keep track of block sizes and maintain the free list.
|
|
41
|
-
*
|
|
41
|
+
*
|
|
42
42
|
* Most allocations in programs are small, so the separate free lists allow us
|
|
43
43
|
* to implement `malloc` and `free` in O(1) for small allocations and O(n)
|
|
44
44
|
* `malloc` and O(1) `free` for large allocations, where `n` is the size of the
|
|
45
45
|
* free list for large blocks.
|
|
46
|
-
*
|
|
46
|
+
*
|
|
47
47
|
* The small blocks are able to service:
|
|
48
48
|
* - Numbers (with the exception of large BigInts/Rationals)
|
|
49
49
|
* - Tuples/Arrays up to 8 elements
|
|
@@ -51,7 +51,7 @@ primitive heapStart = "@heap.start"
|
|
|
51
51
|
* - Variants up to 5 elements
|
|
52
52
|
* - Closures up to 6 elements
|
|
53
53
|
* - Bytes/Strings up to length 32
|
|
54
|
-
*
|
|
54
|
+
*
|
|
55
55
|
* Blocks in memory look like this:
|
|
56
56
|
*
|
|
57
57
|
* 8 bytes 8 bytes 64n - 16 bytes 8 bytes 8 bytes
|
|
@@ -71,11 +71,11 @@ primitive heapStart = "@heap.start"
|
|
|
71
71
|
*
|
|
72
72
|
* The size is kept in the header and footer to allow us to quickly combine
|
|
73
73
|
* free blocks when blocks are freed.
|
|
74
|
-
*
|
|
74
|
+
*
|
|
75
75
|
* Pointers to the previous/next free blocks give us doubly-linked free lists,
|
|
76
76
|
* which makes it possible to remove blocks from the free list in constant
|
|
77
77
|
* time.
|
|
78
|
-
*
|
|
78
|
+
*
|
|
79
79
|
* A block is considered in use when the previous/next pointers are both zero.
|
|
80
80
|
*/
|
|
81
81
|
|
|
@@ -329,7 +329,7 @@ let morecore = (nunits: WasmI32) => {
|
|
|
329
329
|
|
|
330
330
|
// If there was an error, fail
|
|
331
331
|
if (cp == -1n) {
|
|
332
|
-
|
|
332
|
+
Panic.panic("OutOfMemory: Maximum memory size exceeded")
|
|
333
333
|
} else {
|
|
334
334
|
// Set up the block. We'll add dummy headers/footers before and after the
|
|
335
335
|
// block to avoid unnecessary bounds checks elsewhere in the code.
|
package/runtime/malloc.md
CHANGED
|
@@ -9,47 +9,47 @@ Functions and constants included in the Malloc module.
|
|
|
9
9
|
### Malloc.**_RESERVED_RUNTIME_SPACE**
|
|
10
10
|
|
|
11
11
|
```grain
|
|
12
|
-
_RESERVED_RUNTIME_SPACE
|
|
12
|
+
_RESERVED_RUNTIME_SPACE: WasmI32
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### Malloc.**free**
|
|
16
16
|
|
|
17
17
|
```grain
|
|
18
|
-
free
|
|
18
|
+
free: (ap: WasmI32) => Void
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Frees the given allocated pointer.
|
|
22
22
|
|
|
23
23
|
Parameters:
|
|
24
24
|
|
|
25
|
-
|param|type|description|
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
| param | type | description |
|
|
26
|
+
| ----- | --------- | ------------------- |
|
|
27
|
+
| `ap` | `WasmI32` | The pointer to free |
|
|
28
28
|
|
|
29
29
|
### Malloc.**malloc**
|
|
30
30
|
|
|
31
31
|
```grain
|
|
32
|
-
malloc
|
|
32
|
+
malloc: (nbytes: WasmI32) => WasmI32
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
Allocates the requested number of bytes, returning a pointer.
|
|
36
36
|
|
|
37
37
|
Parameters:
|
|
38
38
|
|
|
39
|
-
|param|type|description|
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
| param | type | description |
|
|
40
|
+
| -------- | --------- | ------------------------------- |
|
|
41
|
+
| `nbytes` | `WasmI32` | The number of bytes to allocate |
|
|
42
42
|
|
|
43
43
|
Returns:
|
|
44
44
|
|
|
45
|
-
|type|description|
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
| type | description |
|
|
46
|
+
| --------- | ----------------------------------------------------------------------------------- |
|
|
47
|
+
| `WasmI32` | The pointer to the allocated region (8-byte aligned) or -1 if the allocation failed |
|
|
48
48
|
|
|
49
49
|
### Malloc.**leakAll**
|
|
50
50
|
|
|
51
51
|
```grain
|
|
52
|
-
leakAll
|
|
52
|
+
leakAll: () => Void
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
Leaks all memory in all free lists; used for testing.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ====================================================
|
|
3
|
+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
|
6
|
+
* Permission to use, copy, modify, and distribute this
|
|
7
|
+
* software is freely granted, provided that this notice
|
|
8
|
+
* is preserved.
|
|
9
|
+
* ====================================================
|
|
10
|
+
*/
|
|
11
|
+
module Cosine
|
|
12
|
+
|
|
13
|
+
from "runtime/unsafe/wasmf64" include WasmF64
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Source: https://git.musl-libc.org/cgit/musl/tree/src/math/__cos.c
|
|
17
|
+
*
|
|
18
|
+
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
|
|
19
|
+
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
|
20
|
+
* Input y is the tail of x.
|
|
21
|
+
*
|
|
22
|
+
* Algorithm
|
|
23
|
+
* 1. Since cos(-x) = cos(x), we need only to consider positive x.
|
|
24
|
+
* 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
|
|
25
|
+
* 3. cos(x) is approximated by a polynomial of degree 14 on
|
|
26
|
+
* [0,pi/4]
|
|
27
|
+
* 4 14
|
|
28
|
+
* cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
|
|
29
|
+
* where the remez error is
|
|
30
|
+
*
|
|
31
|
+
* | 2 4 6 8 10 12 14 | -58
|
|
32
|
+
* |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
|
|
33
|
+
* | |
|
|
34
|
+
*
|
|
35
|
+
* 4 6 8 10 12 14
|
|
36
|
+
* 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
|
|
37
|
+
* cos(x) ~ 1 - x*x/2 + r
|
|
38
|
+
* since cos(x+y) ~ cos(x) - sin(x)*y
|
|
39
|
+
* ~ cos(x) - x*y,
|
|
40
|
+
* a correction term is necessary in cos(x) and hence
|
|
41
|
+
* cos(x+y) = 1 - (x*x/2 - (r - x*y))
|
|
42
|
+
* For better accuracy, rearrange to
|
|
43
|
+
* cos(x+y) ~ w + (tmp + (r-x*y))
|
|
44
|
+
* where w = 1 - x*x/2 and tmp is a tiny correction term
|
|
45
|
+
* (1 - x*x/2 == w + tmp exactly in infinite precision).
|
|
46
|
+
* The exactness of w + tmp in infinite precision depends on w
|
|
47
|
+
* and tmp having the same precision as x. If they have extra
|
|
48
|
+
* precision due to compiler bugs, then the extra precision is
|
|
49
|
+
* only good provided it is retained in all terms of the final
|
|
50
|
+
* expression for cos(). Retention happens in all cases tested
|
|
51
|
+
* under FreeBSD, so don't pessimize things by forcibly clipping
|
|
52
|
+
* any extra precision in w.
|
|
53
|
+
*/
|
|
54
|
+
@unsafe
|
|
55
|
+
provide let cos = (x: WasmF64, y: WasmF64) => {
|
|
56
|
+
use WasmF64.{ (+), (-), (*) }
|
|
57
|
+
let c1 = 4.16666666666666019037e-02W /* 0x3FA55555, 0x5555554C */
|
|
58
|
+
let c2 = -1.38888888888741095749e-03W /* 0xBF56C16C, 0x16C15177 */
|
|
59
|
+
let c3 = 2.48015872894767294178e-05W /* 0x3EFA01A0, 0x19CB1590 */
|
|
60
|
+
let c4 = -2.75573143513906633035e-07W /* 0xBE927E4F, 0x809C52AD */
|
|
61
|
+
let c5 = 2.08757232129817482790e-09W /* 0x3E21EE9E, 0xBDB4B1C4 */
|
|
62
|
+
let c6 = -1.13596475577881948265e-11W /* 0xBDA8FAE9, 0xBE8838D4 */
|
|
63
|
+
|
|
64
|
+
let z = x * x
|
|
65
|
+
let w = z * z
|
|
66
|
+
let r = z * (c1 + z * (c2 + z * c3)) + w * w * (c4 + z * (c5 + z * c6))
|
|
67
|
+
let hz = 0.5W * z
|
|
68
|
+
let w = 1.0W - hz
|
|
69
|
+
w + (1.0W - w - hz + (z * r - x * y))
|
|
70
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ====================================================
|
|
3
|
+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
|
6
|
+
* Permission to use, copy, modify, and distribute this
|
|
7
|
+
* software is freely granted, provided that this notice
|
|
8
|
+
* is preserved.
|
|
9
|
+
* ====================================================
|
|
10
|
+
*/
|
|
11
|
+
module Sine
|
|
12
|
+
|
|
13
|
+
from "runtime/unsafe/wasmf64" include WasmF64
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Source: https://git.musl-libc.org/cgit/musl/tree/src/math/__sin.c
|
|
17
|
+
*
|
|
18
|
+
* kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
|
|
19
|
+
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
|
20
|
+
* Input y is the tail of x.
|
|
21
|
+
* Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
|
|
22
|
+
*
|
|
23
|
+
* Algorithm
|
|
24
|
+
* 1. Since sin(-x) = -sin(x), we need only to consider positive x.
|
|
25
|
+
* 2. Callers must return sin(-0) = -0 without calling here since our
|
|
26
|
+
* odd polynomial is not evaluated in a way that preserves -0.
|
|
27
|
+
* Callers may do the optimization sin(x) ~ x for tiny x.
|
|
28
|
+
* 3. sin(x) is approximated by a polynomial of degree 13 on
|
|
29
|
+
* [0,pi/4]
|
|
30
|
+
* 3 13
|
|
31
|
+
* sin(x) ~ x + S1*x + ... + S6*x
|
|
32
|
+
* where
|
|
33
|
+
*
|
|
34
|
+
* |sin(x) 2 4 6 8 10 12 | -58
|
|
35
|
+
* |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
|
|
36
|
+
* | x |
|
|
37
|
+
*
|
|
38
|
+
* 4. sin(x+y) = sin(x) + sin'(x')*y
|
|
39
|
+
* ~ sin(x) + (1-x*x/2)*y
|
|
40
|
+
* For better accuracy, let
|
|
41
|
+
* 3 2 2 2 2
|
|
42
|
+
* r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
|
|
43
|
+
* then 3 2
|
|
44
|
+
* sin(x) = x + (S1*x + (x *(r-y/2)+y))
|
|
45
|
+
*/
|
|
46
|
+
@unsafe
|
|
47
|
+
provide let sin = (x: WasmF64, y: WasmF64, iy: Bool) => { // see: musl/tree/src/math/__sin.c
|
|
48
|
+
use WasmF64.{ (+), (-), (*) }
|
|
49
|
+
let s1 = -1.66666666666666324348e-01W /* 0xBFC55555, 0x55555549 */
|
|
50
|
+
let s2 = 8.33333333332248946124e-03W /* 0x3F811111, 0x1110F8A6 */
|
|
51
|
+
let s3 = -1.98412698298579493134e-04W /* 0xBF2A01A0, 0x19C161D5 */
|
|
52
|
+
let s4 = 2.75573137070700676789e-06W /* 0x3EC71DE3, 0x57B1FE7D */
|
|
53
|
+
let s5 = -2.50507602534068634195e-08W /* 0xBE5AE5E6, 0x8A2B9CEB */
|
|
54
|
+
let s6 = 1.58969099521155010221e-10W /* 0x3DE5D93A, 0x5ACFD57C */
|
|
55
|
+
|
|
56
|
+
let z = x * x
|
|
57
|
+
let w = z * z
|
|
58
|
+
let r = s2 + z * (s3 + z * s4) + z * w * (s5 + z * s6)
|
|
59
|
+
let v = z * x
|
|
60
|
+
if (!iy) {
|
|
61
|
+
x + v * (s1 + z * r)
|
|
62
|
+
} else {
|
|
63
|
+
x - (z * (0.5W * y - v * r) - y - v * s1)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ====================================================
|
|
3
|
+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Developed at SunSoft, a Sun Microsystems, Inc. business.
|
|
6
|
+
* Permission to use, copy, modify, and distribute this
|
|
7
|
+
* software is freely granted, provided that this notice
|
|
8
|
+
* is preserved.
|
|
9
|
+
* ====================================================
|
|
10
|
+
*/
|
|
11
|
+
module Tangent
|
|
12
|
+
|
|
13
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
14
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
15
|
+
from "runtime/unsafe/wasmf64" include WasmF64
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* Source: lib/msun/src/k_tan.c
|
|
19
|
+
*
|
|
20
|
+
* kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
|
|
21
|
+
* Input x is assumed to be bounded by ~pi/4 in magnitude.
|
|
22
|
+
* Input y is the tail of x.
|
|
23
|
+
* Input k indicates whether tan (if k = 1) or -1/tan (if k = -1) is returned.
|
|
24
|
+
*
|
|
25
|
+
* Algorithm
|
|
26
|
+
* 1. Since tan(-x) = -tan(x), we need only to consider positive x.
|
|
27
|
+
* 2. Callers must return tan(-0) = -0 without calling here since our
|
|
28
|
+
* odd polynomial is not evaluated in a way that preserves -0.
|
|
29
|
+
* Callers may do the optimization tan(x) ~ x for tiny x.
|
|
30
|
+
* 3. tan(x) is approximated by a odd polynomial of degree 27 on
|
|
31
|
+
* [0,0.67434]
|
|
32
|
+
* 3 27
|
|
33
|
+
* tan(x) ~ x + T1*x + ... + T13*x
|
|
34
|
+
* where
|
|
35
|
+
*
|
|
36
|
+
* |tan(x) 2 4 26 | -59.2
|
|
37
|
+
* |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
|
|
38
|
+
* | x |
|
|
39
|
+
*
|
|
40
|
+
* Note: tan(x+y) = tan(x) + tan'(x)*y
|
|
41
|
+
* ~ tan(x) + (1+x*x)*y
|
|
42
|
+
* Therefore, for better accuracy in computing tan(x+y), let
|
|
43
|
+
* 3 2 2 2 2
|
|
44
|
+
* r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
|
|
45
|
+
* then
|
|
46
|
+
* 3 2
|
|
47
|
+
* tan(x+y) = x + (T1*x + (x *(r+y)+y))
|
|
48
|
+
*
|
|
49
|
+
* 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
|
|
50
|
+
* tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
|
|
51
|
+
* = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
|
|
52
|
+
*/
|
|
53
|
+
@unsafe
|
|
54
|
+
provide let tan = (x: WasmF64, y: WasmF64, iy: Bool) => {
|
|
55
|
+
use WasmI32.{ (&), (>>), (<), (>=) }
|
|
56
|
+
use WasmI64.{ (>>>) }
|
|
57
|
+
use WasmF64.{ (-), (+), (*), (/) }
|
|
58
|
+
let t0 = 3.33333333333334091986e-01W /* 3FD55555, 55555563 */
|
|
59
|
+
let t1 = 1.33333333333201242699e-01W /* 3FC11111, 1110FE7A */
|
|
60
|
+
let t2 = 5.39682539762260521377e-02W /* 3FABA1BA, 1BB341FE */
|
|
61
|
+
let t3 = 2.18694882948595424599e-02W /* 3F9664F4, 8406D637 */
|
|
62
|
+
let t4 = 8.86323982359930005737e-03W /* 3F8226E3, E96E8493 */
|
|
63
|
+
let t5 = 3.59207910759131235356e-03W /* 3F6D6D22, C9560328 */
|
|
64
|
+
let t6 = 1.45620945432529025516e-03W /* 3F57DBC8, FEE08315 */
|
|
65
|
+
let t7 = 5.88041240820264096874e-04W /* 3F4344D8, F2F26501 */
|
|
66
|
+
let t8 = 2.46463134818469906812e-04W /* 3F3026F7, 1A8D1068 */
|
|
67
|
+
let t9 = 7.81794442939557092300e-05W /* 3F147E88, A03792A6 */
|
|
68
|
+
let t10 = 7.14072491382608190305e-05W /* 3F12B80F, 32F0A7E9 */
|
|
69
|
+
let t11 = -1.85586374855275456654e-05W /* BEF375CB, DB605373 */
|
|
70
|
+
let t12 = 2.59073051863633712884e-05W /* 3EFB2A70, 74BF7AD4 */
|
|
71
|
+
let pio4 = 7.85398163397448278999e-01W /* 3FE921FB, 54442D18 */
|
|
72
|
+
let pio4lo = 3.06161699786838301793e-17W /* 3C81A626, 33145C07 */
|
|
73
|
+
|
|
74
|
+
let mut x = x
|
|
75
|
+
let mut y = y
|
|
76
|
+
let mut z = 0.0W
|
|
77
|
+
let mut r = 0.0W
|
|
78
|
+
let mut w = 0.0W
|
|
79
|
+
|
|
80
|
+
let h = WasmI64.reinterpretF64(x)
|
|
81
|
+
let hx = WasmI32.wrapI64(h >>> 32N) // High word of {x}
|
|
82
|
+
let ix = hx & 0x7FFFFFFFn // High word of |x|
|
|
83
|
+
|
|
84
|
+
let isBig = ix >= 0x3FE59428n
|
|
85
|
+
if (isBig) { /* |x| >= 0.6744 */
|
|
86
|
+
if (hx < 0n) {
|
|
87
|
+
x *= -1.0W
|
|
88
|
+
y *= -1.0W
|
|
89
|
+
}
|
|
90
|
+
z = pio4 - x
|
|
91
|
+
w = pio4lo - y
|
|
92
|
+
x = z + w
|
|
93
|
+
y = 0.0W
|
|
94
|
+
}
|
|
95
|
+
z = x * x
|
|
96
|
+
w = z * z
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
* Break x^5*(T[1]+x^2*T[2]+...) into
|
|
100
|
+
* x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
|
|
101
|
+
* x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
|
|
102
|
+
*/
|
|
103
|
+
r = t1 + w * (t3 + w * (t5 + w * (t7 + w * (t9 + w * t11))))
|
|
104
|
+
let v = z * (t2 + w * (t4 + w * (t6 + w * (t8 + w * (t10 + w * t12)))))
|
|
105
|
+
let s = z * x
|
|
106
|
+
r = y + z * (s * (r + v) + y)
|
|
107
|
+
r += t0 * s
|
|
108
|
+
w = x + r
|
|
109
|
+
if (isBig) {
|
|
110
|
+
let v = if (iy) 1.0W else 0.0W
|
|
111
|
+
return 1.0W
|
|
112
|
+
- WasmF64.convertI32S(hx >> 30n & 2n)
|
|
113
|
+
* (v - 2.0W * (x - (w * w / (w + v) - r)))
|
|
114
|
+
}
|
|
115
|
+
if (iy) return w
|
|
116
|
+
/*
|
|
117
|
+
* if allow error up to 2 ulp, simply return
|
|
118
|
+
* -1.0 / (x+r) here
|
|
119
|
+
*/
|
|
120
|
+
// compute -1.0 / (x+r) accurately
|
|
121
|
+
use WasmI64.{ (&) }
|
|
122
|
+
// Set low bits
|
|
123
|
+
let z = w
|
|
124
|
+
let z = WasmF64.reinterpretI64(
|
|
125
|
+
WasmI64.reinterpretF64(z) & 0xFFFFFFFF00000000N
|
|
126
|
+
)
|
|
127
|
+
let v = r - (z - x) // z + v = r + x
|
|
128
|
+
let a = -1.0W / w
|
|
129
|
+
let t = a
|
|
130
|
+
// Set low bits
|
|
131
|
+
let t = WasmF64.reinterpretI64(
|
|
132
|
+
WasmI64.reinterpretF64(t) & 0xFFFFFFFF00000000N
|
|
133
|
+
)
|
|
134
|
+
let s = 1.0W + t * z
|
|
135
|
+
return t + a * (s + t * v)
|
|
136
|
+
}
|