goscript 0.2.0 → 0.2.2
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/cmd/goscript-wasm/main.go +38 -6
- package/compiler/diagnostic.go +104 -12
- package/compiler/diagnostic_test.go +106 -0
- package/compiler/gotest/runner.go +99 -17
- package/compiler/gotest/runner_test.go +65 -0
- package/compiler/index.test.ts +23 -0
- package/compiler/lowered-program.go +9 -7
- package/compiler/lowering.go +361 -72
- package/compiler/lowering_bench_test.go +1 -0
- package/compiler/lowering_internal_test.go +18 -0
- package/compiler/protobuf-ts-binding.go +65 -12
- package/compiler/protobuf-ts-binding_test.go +339 -0
- package/compiler/runtime-contract.go +4 -0
- package/compiler/runtime-contract_test.go +2 -0
- package/compiler/service.go +1 -0
- package/compiler/skeleton_test.go +60 -3
- package/compiler/wasm/compile_test.go +37 -4
- package/compiler/wasm-api.go +57 -7
- package/dist/gs/builtin/hostio.js +6 -1
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +11 -1
- package/dist/gs/builtin/slice.js +158 -2
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/crypto/aes/index.d.ts +15 -0
- package/dist/gs/crypto/aes/index.js +57 -0
- package/dist/gs/crypto/aes/index.js.map +1 -0
- package/dist/gs/crypto/cipher/index.d.ts +41 -0
- package/dist/gs/crypto/cipher/index.js +255 -0
- package/dist/gs/crypto/cipher/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +30 -5
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +17 -11
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.d.ts +31 -0
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.js +117 -0
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.js.map +1 -0
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/io/io.js +18 -2
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/reflect/type.js +57 -0
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/runtime/debug/index.js +2 -1
- package/dist/gs/runtime/debug/index.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.js +7 -6
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/go.mod +2 -2
- package/go.sum +2 -0
- package/gs/builtin/hostio.test.ts +22 -1
- package/gs/builtin/hostio.ts +6 -1
- package/gs/builtin/runtime-contract.test.ts +28 -0
- package/gs/builtin/slice.ts +225 -20
- package/gs/crypto/aes/index.test.ts +120 -0
- package/gs/crypto/aes/index.ts +76 -0
- package/gs/crypto/cipher/index.ts +345 -0
- package/gs/crypto/cipher/meta.json +6 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +162 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +41 -5
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +18 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +17 -11
- package/gs/golang.org/x/crypto/chacha20poly1305/index.test.ts +91 -0
- package/gs/golang.org/x/crypto/chacha20poly1305/index.ts +245 -0
- package/gs/internal/byteorder/index.test.ts +2 -2
- package/gs/internal/byteorder/index.ts +2 -2
- package/gs/io/io.test.ts +56 -1
- package/gs/io/io.ts +19 -2
- package/gs/reflect/type.ts +64 -0
- package/gs/reflect/typefor.test.ts +21 -1
- package/gs/runtime/debug/index.test.ts +32 -4
- package/gs/runtime/debug/index.ts +5 -2
- package/gs/sync/atomic/doc_64.gs.ts +6 -7
- package/gs/sync/atomic/doc_64.test.ts +43 -0
- package/package.json +10 -3
package/gs/reflect/type.ts
CHANGED
|
@@ -3326,6 +3326,60 @@ function basicTypeFromName(name: string, typeName = ''): BasicType {
|
|
|
3326
3326
|
}
|
|
3327
3327
|
}
|
|
3328
3328
|
|
|
3329
|
+
function typeFromGoTypeName(typeName: string): Type | null {
|
|
3330
|
+
const trimmed = typeName.trim()
|
|
3331
|
+
if (trimmed === '') return null
|
|
3332
|
+
|
|
3333
|
+
if (trimmed.startsWith('<-chan ')) {
|
|
3334
|
+
return new ChannelType(typeFromGoTypeName(trimmed.slice(7)) ?? anyType(), RecvDir)
|
|
3335
|
+
}
|
|
3336
|
+
if (trimmed.startsWith('chan<- ')) {
|
|
3337
|
+
return new ChannelType(typeFromGoTypeName(trimmed.slice(7)) ?? anyType(), SendDir)
|
|
3338
|
+
}
|
|
3339
|
+
if (trimmed.startsWith('chan ')) {
|
|
3340
|
+
return new ChannelType(typeFromGoTypeName(trimmed.slice(5)) ?? anyType(), BothDir)
|
|
3341
|
+
}
|
|
3342
|
+
if (trimmed.startsWith('[]')) {
|
|
3343
|
+
return new SliceType(typeFromGoTypeName(trimmed.slice(2)) ?? anyType())
|
|
3344
|
+
}
|
|
3345
|
+
if (trimmed.startsWith('*')) {
|
|
3346
|
+
return new PointerType(typeFromGoTypeName(trimmed.slice(1)) ?? anyType())
|
|
3347
|
+
}
|
|
3348
|
+
if (trimmed === 'struct{}' || trimmed === 'struct {}') {
|
|
3349
|
+
return new StructType('', [], '', 'struct {}')
|
|
3350
|
+
}
|
|
3351
|
+
if (trimmed === 'interface{}' || trimmed === 'any') {
|
|
3352
|
+
return anyType()
|
|
3353
|
+
}
|
|
3354
|
+
if (trimmed === 'error') {
|
|
3355
|
+
return new InterfaceType('error', 'error')
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
const registered = builtinGetTypeByName(trimmed)
|
|
3359
|
+
if (registered) {
|
|
3360
|
+
return typeFromTypeInfo(registered)
|
|
3361
|
+
}
|
|
3362
|
+
|
|
3363
|
+
const basic = basicTypeFromName(trimmed)
|
|
3364
|
+
if (basic.Kind() !== Invalid) {
|
|
3365
|
+
return basic
|
|
3366
|
+
}
|
|
3367
|
+
|
|
3368
|
+
return null
|
|
3369
|
+
}
|
|
3370
|
+
|
|
3371
|
+
function channelTypeFromGoTypeName(typeName: string): Type | null {
|
|
3372
|
+
const typ = typeFromGoTypeName(typeName)
|
|
3373
|
+
if (typ?.Kind() === Chan) {
|
|
3374
|
+
return typ
|
|
3375
|
+
}
|
|
3376
|
+
return null
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
function anyType(): Type {
|
|
3380
|
+
return new BasicType(Interface, 'interface{}', 16)
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3329
3383
|
function structFieldsFromTypeInfo(
|
|
3330
3384
|
ti: $.StructTypeInfo,
|
|
3331
3385
|
seen = new Set<string>(),
|
|
@@ -3743,6 +3797,16 @@ function getTypeOf(value: ReflectValue): Type {
|
|
|
3743
3797
|
)
|
|
3744
3798
|
}
|
|
3745
3799
|
|
|
3800
|
+
if ('__goType' in value) {
|
|
3801
|
+
const goType = (value as { __goType?: unknown }).__goType
|
|
3802
|
+
if (typeof goType === 'string') {
|
|
3803
|
+
const channelType = channelTypeFromGoTypeName(goType)
|
|
3804
|
+
if (channelType) {
|
|
3805
|
+
return channelType
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3746
3810
|
if (
|
|
3747
3811
|
'real' in value &&
|
|
3748
3812
|
'imag' in value &&
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
2
|
import {
|
|
3
|
+
interfaceValue,
|
|
4
|
+
makeChannel,
|
|
3
5
|
makeMap,
|
|
4
6
|
mapGet,
|
|
5
7
|
mapSet,
|
|
@@ -11,7 +13,9 @@ import {
|
|
|
11
13
|
varRef,
|
|
12
14
|
} from '../builtin/index.js'
|
|
13
15
|
import { StructField } from './types.js'
|
|
16
|
+
import { SelectCase, SelectRecv } from './types.js'
|
|
14
17
|
import {
|
|
18
|
+
Chan,
|
|
15
19
|
Int,
|
|
16
20
|
Ptr,
|
|
17
21
|
Struct,
|
|
@@ -21,7 +25,7 @@ import {
|
|
|
21
25
|
Uint64,
|
|
22
26
|
ValueOf,
|
|
23
27
|
} from './type.js'
|
|
24
|
-
import { Indirect, New, Zero } from './value.js'
|
|
28
|
+
import { Indirect, New, Select, Zero } from './value.js'
|
|
25
29
|
|
|
26
30
|
describe('TypeFor', () => {
|
|
27
31
|
it('exposes StructField PkgPath and exported semantics', () => {
|
|
@@ -184,6 +188,22 @@ describe('TypeFor', () => {
|
|
|
184
188
|
expect(target.value).toBe(15)
|
|
185
189
|
})
|
|
186
190
|
|
|
191
|
+
it('preserves channel type metadata on interface boxes', () => {
|
|
192
|
+
const ch = makeChannel<{}>(0, {}, 'both')
|
|
193
|
+
const chanValue = ValueOf(interfaceValue(ch, '<-chan struct{}'))
|
|
194
|
+
|
|
195
|
+
expect(chanValue.Type().Kind()).toBe(Chan)
|
|
196
|
+
expect(chanValue.Type().String()).toBe('<-chan struct {}')
|
|
197
|
+
expect(chanValue.Type().Elem().Kind()).toBe(Struct)
|
|
198
|
+
|
|
199
|
+
const [chosen, recv, ok] = Select([
|
|
200
|
+
new SelectCase({ Dir: SelectRecv, Chan: chanValue }),
|
|
201
|
+
])
|
|
202
|
+
expect(chosen).toBe(0)
|
|
203
|
+
expect(ok).toBe(true)
|
|
204
|
+
expect(recv.Type().String()).toBe('struct {}')
|
|
205
|
+
})
|
|
206
|
+
|
|
187
207
|
it('formats literal interface methods from type metadata', () => {
|
|
188
208
|
const ifaceType = TypeFor({
|
|
189
209
|
T: {
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { resetHostRuntimeForTests } from '@goscript/builtin/hostio.js'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
BuildInfo,
|
|
7
|
+
BuildSetting,
|
|
8
|
+
Module,
|
|
9
|
+
PrintStack,
|
|
10
|
+
ReadBuildInfo,
|
|
11
|
+
Stack,
|
|
12
|
+
} from './index.js'
|
|
4
13
|
|
|
5
14
|
describe('runtime/debug override', () => {
|
|
6
15
|
it('returns a stack trace as bytes', () => {
|
|
@@ -10,14 +19,33 @@ describe('runtime/debug override', () => {
|
|
|
10
19
|
expect(new TextDecoder().decode(stack)).toContain('Error')
|
|
11
20
|
})
|
|
12
21
|
|
|
13
|
-
it('prints the current stack trace', () => {
|
|
22
|
+
it('prints the current stack trace through the browser-like stderr console fallback', () => {
|
|
23
|
+
const consoleLog = vi.spyOn(console, 'log').mockImplementation(() => {})
|
|
14
24
|
const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
25
|
+
const originalDeno = (globalThis as any).Deno
|
|
26
|
+
const originalProcess = (globalThis as any).process
|
|
27
|
+
delete (globalThis as any).Deno
|
|
28
|
+
delete (globalThis as any).process
|
|
29
|
+
resetHostRuntimeForTests()
|
|
15
30
|
|
|
16
31
|
try {
|
|
17
32
|
PrintStack()
|
|
18
|
-
expect(
|
|
19
|
-
expect(
|
|
33
|
+
expect(consoleLog).toHaveBeenCalledTimes(1)
|
|
34
|
+
expect(consoleLog.mock.calls[0][0]).toContain('Error')
|
|
35
|
+
expect(consoleError).not.toHaveBeenCalled()
|
|
20
36
|
} finally {
|
|
37
|
+
if (originalDeno === undefined) {
|
|
38
|
+
delete (globalThis as any).Deno
|
|
39
|
+
} else {
|
|
40
|
+
;(globalThis as any).Deno = originalDeno
|
|
41
|
+
}
|
|
42
|
+
if (originalProcess === undefined) {
|
|
43
|
+
delete (globalThis as any).process
|
|
44
|
+
} else {
|
|
45
|
+
;(globalThis as any).process = originalProcess
|
|
46
|
+
}
|
|
47
|
+
resetHostRuntimeForTests()
|
|
48
|
+
consoleLog.mockRestore()
|
|
21
49
|
consoleError.mockRestore()
|
|
22
50
|
}
|
|
23
51
|
})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as $ from '@goscript/builtin/index.js'
|
|
2
|
+
import { writeHostStderrText } from '@goscript/builtin/hostio.js'
|
|
2
3
|
|
|
3
4
|
export class BuildSetting {
|
|
4
5
|
public Key: string
|
|
@@ -10,7 +11,9 @@ export class BuildSetting {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
public clone(): BuildSetting {
|
|
13
|
-
return $.markAsStructValue(
|
|
14
|
+
return $.markAsStructValue(
|
|
15
|
+
new BuildSetting({ Key: this.Key, Value: this.Value }),
|
|
16
|
+
)
|
|
14
17
|
}
|
|
15
18
|
}
|
|
16
19
|
|
|
@@ -88,7 +91,7 @@ export function Stack(): Uint8Array {
|
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
export function PrintStack(): void {
|
|
91
|
-
|
|
94
|
+
writeHostStderrText(new TextDecoder().decode(Stack()))
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
export function ReadBuildInfo(): [BuildInfo | null, boolean] {
|
|
@@ -59,7 +59,7 @@ export function CompareAndSwapUint64(addr: $.VarRef<number> | null, old: number,
|
|
|
59
59
|
//go:noescape
|
|
60
60
|
export function AddInt64(addr: $.VarRef<number> | null, delta: number): number {
|
|
61
61
|
if (!addr) return 0;
|
|
62
|
-
addr.value = addr.value
|
|
62
|
+
addr.value = $.int64Add(addr.value, delta);
|
|
63
63
|
return addr.value;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -72,7 +72,7 @@ export function AddInt64(addr: $.VarRef<number> | null, delta: number): number {
|
|
|
72
72
|
//go:noescape
|
|
73
73
|
export function AddUint64(addr: $.VarRef<number> | null, delta: number): number {
|
|
74
74
|
if (!addr) return 0;
|
|
75
|
-
addr.value = addr.value
|
|
75
|
+
addr.value = $.uint64Add(addr.value, delta);
|
|
76
76
|
return addr.value;
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -84,7 +84,7 @@ export function AddUint64(addr: $.VarRef<number> | null, delta: number): number
|
|
|
84
84
|
export function AndInt64(addr: $.VarRef<number> | null, mask: number): number {
|
|
85
85
|
if (!addr) return 0;
|
|
86
86
|
let old = addr.value;
|
|
87
|
-
addr.value = addr.value
|
|
87
|
+
addr.value = $.int64And(addr.value, mask);
|
|
88
88
|
return old;
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -96,7 +96,7 @@ export function AndInt64(addr: $.VarRef<number> | null, mask: number): number {
|
|
|
96
96
|
export function AndUint64(addr: $.VarRef<number> | null, mask: number): number {
|
|
97
97
|
if (!addr) return 0;
|
|
98
98
|
let old = addr.value;
|
|
99
|
-
addr.value = addr.value
|
|
99
|
+
addr.value = $.uint64And(addr.value, mask);
|
|
100
100
|
return old;
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -108,7 +108,7 @@ export function AndUint64(addr: $.VarRef<number> | null, mask: number): number {
|
|
|
108
108
|
export function OrInt64(addr: $.VarRef<number> | null, mask: number): number {
|
|
109
109
|
if (!addr) return 0;
|
|
110
110
|
let old = addr.value;
|
|
111
|
-
addr.value = addr.value
|
|
111
|
+
addr.value = $.int64Or(addr.value, mask);
|
|
112
112
|
return old;
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -120,7 +120,7 @@ export function OrInt64(addr: $.VarRef<number> | null, mask: number): number {
|
|
|
120
120
|
export function OrUint64(addr: $.VarRef<number> | null, mask: number): number {
|
|
121
121
|
if (!addr) return 0;
|
|
122
122
|
let old = addr.value;
|
|
123
|
-
addr.value = addr.value
|
|
123
|
+
addr.value = $.uint64Or(addr.value, mask);
|
|
124
124
|
return old;
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -165,4 +165,3 @@ export function StoreUint64(addr: $.VarRef<number> | null, val: number): void {
|
|
|
165
165
|
addr.value = val;
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import * as $ from '../../builtin/index.js'
|
|
4
|
+
import {
|
|
5
|
+
AddInt64,
|
|
6
|
+
AddUint64,
|
|
7
|
+
AndUint64,
|
|
8
|
+
OrUint64,
|
|
9
|
+
} from './doc_64.gs.js'
|
|
10
|
+
|
|
11
|
+
function asBigInt(value: number): bigint {
|
|
12
|
+
return typeof value === 'bigint' ? value : BigInt(value)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('sync/atomic 64-bit operations', () => {
|
|
16
|
+
test('adds uint64 values without mixing number and bigint arithmetic', () => {
|
|
17
|
+
const value = $.varRef($.uint('18446744073709551614', 64))
|
|
18
|
+
|
|
19
|
+
expect(AddUint64(value, $.uint(2, 64))).toBe(0)
|
|
20
|
+
expect(value.value).toBe(0)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('preserves high uint64 bits for bitwise operations', () => {
|
|
24
|
+
const value = $.varRef($.uint('9223372036854775808', 64))
|
|
25
|
+
|
|
26
|
+
expect(asBigInt(OrUint64(value, $.uint(1, 64)))).toBe(
|
|
27
|
+
9223372036854775808n,
|
|
28
|
+
)
|
|
29
|
+
expect(asBigInt(value.value)).toBe(9223372036854775809n)
|
|
30
|
+
|
|
31
|
+
expect(asBigInt(AndUint64(value, $.uint('18446744073709551614', 64)))).toBe(
|
|
32
|
+
9223372036854775809n,
|
|
33
|
+
)
|
|
34
|
+
expect(asBigInt(value.value)).toBe(9223372036854775808n)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test('adds int64 values without number coercion', () => {
|
|
38
|
+
const value = $.varRef($.int('9223372036854775807', 64))
|
|
39
|
+
|
|
40
|
+
expect(AddInt64(value, 1)).toBe(-9223372036854775808)
|
|
41
|
+
expect(value.value).toBe(-9223372036854775808)
|
|
42
|
+
})
|
|
43
|
+
})
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goscript",
|
|
3
3
|
"description": "Go to TypeScript transpiler",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Aperture Robotics LLC.",
|
|
7
7
|
"email": "support@aperture.us",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"./{src,builtin,example}/**/(*.ts|*.tsx|*.html|*.css|*.scss)": "prettier --config .prettierrc.yaml --write"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@aptre/protobuf-es-lite": "
|
|
97
|
+
"@aptre/protobuf-es-lite": "1.1.0",
|
|
98
98
|
"@eslint/js": "^10.0.0",
|
|
99
99
|
"@types/node": "^25.5.2",
|
|
100
100
|
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
|
@@ -108,12 +108,19 @@
|
|
|
108
108
|
"husky": "^9.1.7",
|
|
109
109
|
"lint-staged": "^17.0.0",
|
|
110
110
|
"prettier": "^3.8.1",
|
|
111
|
-
"starpc": "0.49.
|
|
111
|
+
"starpc": "0.49.17",
|
|
112
112
|
"typescript": "^6.0.0",
|
|
113
113
|
"typescript-eslint": "^8.58.0",
|
|
114
114
|
"vitest": "^4.1.2"
|
|
115
115
|
},
|
|
116
116
|
"dependencies": {
|
|
117
|
+
"@noble/ciphers": "2.2.0",
|
|
117
118
|
"globals": "^17.4.0"
|
|
119
|
+
},
|
|
120
|
+
"resolutions": {
|
|
121
|
+
"@aptre/protobuf-es-lite": "1.1.0"
|
|
122
|
+
},
|
|
123
|
+
"overrides": {
|
|
124
|
+
"@aptre/protobuf-es-lite": "1.1.0"
|
|
118
125
|
}
|
|
119
126
|
}
|