xbintsc 0.3.4 → 0.3.6
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/README.md +51 -8
- package/README.zh-CN.md +50 -8
- package/dist/src/codegen/generator/calls/invocation.js +9 -0
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +27 -1
- package/dist/src/codegen/generator/context.js +57 -5
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/state.d.ts +8 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.js +1 -8
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +11 -0
- package/dist/src/codegen/generator/tables.js +13 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/driver/toolchain-download.js +26 -0
- package/dist/src/driver/toolchain-download.js.map +1 -1
- package/dist/tests/ast/factory.test.d.ts +1 -0
- package/dist/tests/ast/factory.test.js +35 -0
- package/dist/tests/ast/factory.test.js.map +1 -0
- package/dist/tests/ast/visitor.test.d.ts +1 -0
- package/dist/tests/ast/visitor.test.js +53 -0
- package/dist/tests/ast/visitor.test.js.map +1 -0
- package/dist/tests/cli/main.test.js +109 -9
- package/dist/tests/cli/main.test.js.map +1 -1
- package/dist/tests/codegen/closures.test.d.ts +1 -0
- package/dist/tests/codegen/closures.test.js +32 -0
- package/dist/tests/codegen/closures.test.js.map +1 -0
- package/dist/tests/codegen/expressions.test.d.ts +1 -0
- package/dist/tests/codegen/expressions.test.js +149 -0
- package/dist/tests/codegen/expressions.test.js.map +1 -0
- package/dist/tests/codegen/llvm.test.js +38 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/codegen/values.test.d.ts +1 -0
- package/dist/tests/codegen/values.test.js +48 -0
- package/dist/tests/codegen/values.test.js.map +1 -0
- package/dist/tests/diagnostics/diagnostic.test.d.ts +1 -0
- package/dist/tests/diagnostics/diagnostic.test.js +117 -0
- package/dist/tests/diagnostics/diagnostic.test.js.map +1 -0
- package/dist/tests/diagnostics/source.test.d.ts +1 -0
- package/dist/tests/diagnostics/source.test.js +58 -0
- package/dist/tests/diagnostics/source.test.js.map +1 -0
- package/dist/tests/driver/modules.test.d.ts +1 -0
- package/dist/tests/driver/modules.test.js +140 -0
- package/dist/tests/driver/modules.test.js.map +1 -0
- package/dist/tests/driver/paths.test.js +17 -1
- package/dist/tests/driver/paths.test.js.map +1 -1
- package/dist/tests/driver/runtime-lib.test.d.ts +1 -0
- package/dist/tests/driver/runtime-lib.test.js +19 -0
- package/dist/tests/driver/runtime-lib.test.js.map +1 -0
- package/dist/tests/driver/toolchain-download.test.js +15 -0
- package/dist/tests/driver/toolchain-download.test.js.map +1 -1
- package/dist/tests/driver/toolchain-provider.test.js +112 -1
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
- package/dist/tests/e2e/compile-node.test.js +11 -0
- package/dist/tests/e2e/compile-node.test.js.map +1 -1
- package/dist/tests/extensions/node.test.d.ts +1 -0
- package/dist/tests/extensions/node.test.js +32 -0
- package/dist/tests/extensions/node.test.js.map +1 -0
- package/dist/tests/helpers.d.ts +4 -1
- package/dist/tests/helpers.js +2 -1
- package/dist/tests/helpers.js.map +1 -1
- package/dist/tests/lexer/identifiers.test.d.ts +1 -0
- package/dist/tests/lexer/identifiers.test.js +13 -0
- package/dist/tests/lexer/identifiers.test.js.map +1 -0
- package/dist/tests/lexer/numbers.test.d.ts +1 -0
- package/dist/tests/lexer/numbers.test.js +23 -0
- package/dist/tests/lexer/numbers.test.js.map +1 -0
- package/dist/tests/lexer/strings.test.d.ts +1 -0
- package/dist/tests/lexer/strings.test.js +72 -0
- package/dist/tests/lexer/strings.test.js.map +1 -0
- package/dist/tests/parser/declarations.test.d.ts +1 -0
- package/dist/tests/parser/declarations.test.js +70 -0
- package/dist/tests/parser/declarations.test.js.map +1 -0
- package/dist/tests/parser/expressions.test.d.ts +1 -0
- package/dist/tests/parser/expressions.test.js +47 -0
- package/dist/tests/parser/expressions.test.js.map +1 -0
- package/dist/tests/parser/helpers.test.d.ts +1 -0
- package/dist/tests/parser/helpers.test.js +58 -0
- package/dist/tests/parser/helpers.test.js.map +1 -0
- package/dist/tests/parser/literals.test.d.ts +1 -0
- package/dist/tests/parser/literals.test.js +70 -0
- package/dist/tests/parser/literals.test.js.map +1 -0
- package/dist/tests/parser/module-syntax.test.d.ts +1 -0
- package/dist/tests/parser/module-syntax.test.js +91 -0
- package/dist/tests/parser/module-syntax.test.js.map +1 -0
- package/dist/tests/parser/statements.test.d.ts +1 -0
- package/dist/tests/parser/statements.test.js +85 -0
- package/dist/tests/parser/statements.test.js.map +1 -0
- package/dist/tests/parser/type-members.test.d.ts +1 -0
- package/dist/tests/parser/type-members.test.js +86 -0
- package/dist/tests/parser/type-members.test.js.map +1 -0
- package/dist/tests/parser/types.test.d.ts +1 -0
- package/dist/tests/parser/types.test.js +143 -0
- package/dist/tests/parser/types.test.js.map +1 -0
- package/package.json +1 -1
- package/runtime/rt_internal.h +5 -3
- package/runtime/xt_io.c +15 -14
- package/src/codegen/generator/calls/invocation.ts +8 -0
- package/src/codegen/generator/context.ts +59 -5
- package/src/codegen/generator/state.ts +5 -0
- package/src/codegen/generator/statements/control-flow.ts +1 -8
- package/src/codegen/generator/tables.ts +14 -0
- package/src/driver/toolchain-download.ts +27 -0
package/package.json
CHANGED
package/runtime/rt_internal.h
CHANGED
|
@@ -235,9 +235,11 @@ typedef struct xt_try_frame {
|
|
|
235
235
|
* `_setjmp(jmp_buf, void *frame)` itself, so the frame must be passed
|
|
236
236
|
* explicitly -- exactly what its own `setjmp` macro does.
|
|
237
237
|
*
|
|
238
|
-
* The generated IR
|
|
239
|
-
*
|
|
240
|
-
*
|
|
238
|
+
* The generated IR emits the two-argument form, because it is already IR and
|
|
239
|
+
* clang will not rewrite it. On Windows ARM64 it names `_setjmpex` (and the
|
|
240
|
+
* entry stack pointer from `llvm.sponentry`) instead, matching clang's own
|
|
241
|
+
* lowering there. `_setjmp`/`_setjmpex` (rather than the `setjmp` macro) is
|
|
242
|
+
* used so it pairs with the plain `longjmp` in `xt_throw`. */
|
|
241
243
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
|
242
244
|
#define xt_try_setjmp(framePtr) _setjmp(((xt_try_frame *)(framePtr))->buf)
|
|
243
245
|
#elif defined(_WIN32) && defined(__aarch64__)
|
package/runtime/xt_io.c
CHANGED
|
@@ -5,20 +5,21 @@
|
|
|
5
5
|
* innermost frame when one is active and otherwise prints + exits. Also holds
|
|
6
6
|
* `print`/`console` output and the Node-like value inspector.
|
|
7
7
|
*
|
|
8
|
-
* The generated IR
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
13
|
-
* `
|
|
14
|
-
* 0xC00000FF).
|
|
15
|
-
*
|
|
16
|
-
* the
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
8
|
+
* The generated IR saves each frame with a `setjmp`-family call that passes
|
|
9
|
+
* the frame explicitly — the jmp_buf plus a frame pointer — because the call
|
|
10
|
+
* is already IR and clang will not rewrite it. On Linux/macOS that is
|
|
11
|
+
* `_setjmp(buf, frame)`; the extra argument is ignored. On Windows the UCRT
|
|
12
|
+
* `_setjmp` stores the frame in `_JUMP_BUFFER.Frame` and `longjmp` passes it
|
|
13
|
+
* to `RtlUnwind` to run the unwind, so omitting it makes `longjmp` unwind to a
|
|
14
|
+
* bogus target (`STATUS_BAD_FUNCTION_TABLE`, 0xC00000FF). Windows ARM64 has
|
|
15
|
+
* no `_setjmp` at all: the generated IR uses `_setjmpex(buf, entry-sp)` with
|
|
16
|
+
* the stack pointer on entry (`@llvm.sponentry`), exactly as clang lowers a C
|
|
17
|
+
* `setjmp` there. The C runtime (see `xt_try_setjmp`) calls whatever the
|
|
18
|
+
* active `<setjmp.h>` declares — one argument on MSVC (clang injects the
|
|
19
|
+
* frame) and two on MinGW-w64. `_setjmp`/`_setjmpex` are used rather than the
|
|
20
|
+
* exported `setjmp` symbol, whose Windows ABI is an incompatible two-argument
|
|
21
|
+
* routine; on Linux/macOS `_setjmp` takes only the buffer and pairs with
|
|
22
|
+
* `longjmp` (the XSI `_longjmp` does not exist on Windows).
|
|
22
23
|
*/
|
|
23
24
|
|
|
24
25
|
#include "rt_internal.h"
|
|
@@ -206,6 +206,14 @@ export const invocationCallMethods: InvocationCallMethods = {
|
|
|
206
206
|
return result;
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
+
// Modules with no namespace dispatcher (`fs`, `child_process`, ...): lower
|
|
210
|
+
// `import fs from "node:fs"; fs.readFileSync(...)` through the module's
|
|
211
|
+
// named exports, exactly like a named import of `readFileSync`.
|
|
212
|
+
const moduleExports = this.moduleExportsOfSymbol(targetSymbol);
|
|
213
|
+
if (moduleExports) {
|
|
214
|
+
const exported = moduleExports[method];
|
|
215
|
+
if (exported) return this.emitModuleExport(node, exported);
|
|
216
|
+
}
|
|
209
217
|
}
|
|
210
218
|
|
|
211
219
|
void BUILTIN_METHODS;
|
|
@@ -15,9 +15,10 @@ import type {
|
|
|
15
15
|
BuiltinFunction,
|
|
16
16
|
ExtensionModule,
|
|
17
17
|
ModuleExport,
|
|
18
|
+
ModuleExports,
|
|
18
19
|
} from "../../extensions/registry.js";
|
|
19
20
|
import type { CodegenOptions, FunctionState } from "./state.js";
|
|
20
|
-
import { escapeBytes, isErrorFamily, kindName, utf8Bytes } from "./tables.js";
|
|
21
|
+
import { escapeBytes, isErrorFamily, kindName, requiresSetjmpex, utf8Bytes } from "./tables.js";
|
|
21
22
|
|
|
22
23
|
export class GeneratorContext {
|
|
23
24
|
readonly binding: BindResult;
|
|
@@ -25,10 +26,19 @@ export class GeneratorContext {
|
|
|
25
26
|
readonly diagnostics: DiagnosticBag;
|
|
26
27
|
readonly builtins: Readonly<Record<string, BuiltinFunction>>;
|
|
27
28
|
readonly modules: Readonly<Record<string, ExtensionModule>>;
|
|
29
|
+
/** Host the emitted IR targets (the process by default; see `CodegenOptions`). */
|
|
30
|
+
readonly target: { readonly platform: string; readonly arch: string };
|
|
28
31
|
/** Imported symbol id -> the module binding it refers to. */
|
|
29
32
|
readonly importExports = new Map<number, ModuleExport>();
|
|
30
33
|
/** Imported symbol id -> the namespace it aliases (e.g. `path`). */
|
|
31
34
|
readonly importNamespaces = new Map<number, string>();
|
|
35
|
+
/**
|
|
36
|
+
* Imported symbol id -> the named exports of the module it aliases, for
|
|
37
|
+
* modules that do not expose a runtime namespace dispatcher (`fs`,
|
|
38
|
+
* `child_process`, `crypto`, ...). Lets `import fs from "node:fs"` lower
|
|
39
|
+
* `fs.readFileSync(...)` straight to the module's runtime symbol.
|
|
40
|
+
*/
|
|
41
|
+
readonly importModuleExports = new Map<number, ModuleExports>();
|
|
32
42
|
readonly globals: string[] = [];
|
|
33
43
|
readonly functions: string[] = [];
|
|
34
44
|
readonly strings = new Map<string, { label: string; length: number }>();
|
|
@@ -44,6 +54,7 @@ export class GeneratorContext {
|
|
|
44
54
|
this.binding = bind(sourceFile);
|
|
45
55
|
this.builtins = options.builtins ?? {};
|
|
46
56
|
this.modules = options.modules ?? {};
|
|
57
|
+
this.target = options.target ?? { platform: process.platform, arch: process.arch };
|
|
47
58
|
this.resolveImports();
|
|
48
59
|
}
|
|
49
60
|
|
|
@@ -61,9 +72,9 @@ export class GeneratorContext {
|
|
|
61
72
|
if (!module) continue;
|
|
62
73
|
const clause = declaration.importClause;
|
|
63
74
|
if (!clause) continue;
|
|
64
|
-
if (clause.name
|
|
75
|
+
if (clause.name) {
|
|
65
76
|
const symbol = this.binding.symbolOfDeclaration.get(clause.name);
|
|
66
|
-
if (symbol) this.
|
|
77
|
+
if (symbol) this.bindModuleAlias(symbol, module);
|
|
67
78
|
}
|
|
68
79
|
const bindings = clause.namedBindings;
|
|
69
80
|
if (bindings && bindings.kind === SyntaxKind.NamedImports) {
|
|
@@ -73,19 +84,37 @@ export class GeneratorContext {
|
|
|
73
84
|
const symbol = this.binding.symbolOfDeclaration.get(specifier.name);
|
|
74
85
|
if (symbol && exported) this.importExports.set(symbol.id, exported);
|
|
75
86
|
}
|
|
76
|
-
} else if (bindings && bindings.kind === SyntaxKind.NamespaceImport
|
|
87
|
+
} else if (bindings && bindings.kind === SyntaxKind.NamespaceImport) {
|
|
77
88
|
const symbol = this.binding.symbolOfDeclaration.get(bindings.name);
|
|
78
|
-
if (symbol) this.
|
|
89
|
+
if (symbol) this.bindModuleAlias(symbol, module);
|
|
79
90
|
}
|
|
80
91
|
}
|
|
81
92
|
}
|
|
82
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Bind a default/namespace import to either the module's runtime namespace
|
|
96
|
+
* dispatcher (when it has one) or its named exports (when it does not).
|
|
97
|
+
*/
|
|
98
|
+
private bindModuleAlias(symbol: SymbolInfo, module: ExtensionModule): void {
|
|
99
|
+
if (module.namespace) {
|
|
100
|
+
this.importNamespaces.set(symbol.id, module.namespace);
|
|
101
|
+
} else if (module.exports) {
|
|
102
|
+
this.importModuleExports.set(symbol.id, module.exports);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
83
106
|
/** Namespace name an imported alias refers to, if any. */
|
|
84
107
|
namespaceOfSymbol(symbol: SymbolInfo | undefined): string | undefined {
|
|
85
108
|
if (!symbol || symbol.kind !== SymbolKind.Import) return undefined;
|
|
86
109
|
return this.importNamespaces.get(symbol.id);
|
|
87
110
|
}
|
|
88
111
|
|
|
112
|
+
/** Named exports a default/namespace import aliases, if any. */
|
|
113
|
+
moduleExportsOfSymbol(symbol: SymbolInfo | undefined): ModuleExports | undefined {
|
|
114
|
+
if (!symbol || symbol.kind !== SymbolKind.Import) return undefined;
|
|
115
|
+
return this.importModuleExports.get(symbol.id);
|
|
116
|
+
}
|
|
117
|
+
|
|
89
118
|
// -- emission primitives -------------------------------------------------
|
|
90
119
|
|
|
91
120
|
emit(line: string): void {
|
|
@@ -101,6 +130,31 @@ export class GeneratorContext {
|
|
|
101
130
|
return `%r${this.current.reg++}`;
|
|
102
131
|
}
|
|
103
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Emit the `setjmp` that opens a `try` frame and return the register holding
|
|
135
|
+
* its result. The frame address is always passed explicitly because Windows
|
|
136
|
+
* `_setjmp` stores it in `_JUMP_BUFFER.Frame` for `longjmp` to unwind to; the
|
|
137
|
+
* extra argument is ignored by the one-argument `_setjmp` on Linux/macOS.
|
|
138
|
+
*/
|
|
139
|
+
emitSetjmp(frame: string): string {
|
|
140
|
+
if (requiresSetjmpex(this.target.platform, this.target.arch)) {
|
|
141
|
+
// Windows ARM64 has no `_setjmp`; use `_setjmpex`, which expects the
|
|
142
|
+
// caller's stack pointer on entry (`llvm.sponentry`).
|
|
143
|
+
this.extraDeclarations.add("declare i8* @llvm.sponentry()");
|
|
144
|
+
this.extraDeclarations.add("declare i32 @_setjmpex(i8*, i8*) returns_twice");
|
|
145
|
+
const entry = this.reg();
|
|
146
|
+
this.emit(` ${entry} = call i8* @llvm.sponentry()`);
|
|
147
|
+
const jump = this.reg();
|
|
148
|
+
this.emit(` ${jump} = call i32 @_setjmpex(i8* ${frame}, i8* ${entry})`);
|
|
149
|
+
return jump;
|
|
150
|
+
}
|
|
151
|
+
const frameAddress = this.reg();
|
|
152
|
+
this.emit(` ${frameAddress} = call i8* @llvm.frameaddress(i32 0)`);
|
|
153
|
+
const jump = this.reg();
|
|
154
|
+
this.emit(` ${jump} = call i32 @_setjmp(i8* ${frame}, i8* ${frameAddress})`);
|
|
155
|
+
return jump;
|
|
156
|
+
}
|
|
157
|
+
|
|
104
158
|
label(prefix: string): string {
|
|
105
159
|
return `${prefix}.${this.current.label++}`;
|
|
106
160
|
}
|
|
@@ -62,6 +62,11 @@ export interface CodegenOptions {
|
|
|
62
62
|
readonly builtins?: Readonly<Record<string, BuiltinFunction>>;
|
|
63
63
|
/** Importable modules supplied by registered extensions. */
|
|
64
64
|
readonly modules?: Readonly<Record<string, ExtensionModule>>;
|
|
65
|
+
/**
|
|
66
|
+
* Host the IR is generated for. xbintsc builds for its own host, so this
|
|
67
|
+
* defaults to the running process; it is overridable for tests.
|
|
68
|
+
*/
|
|
69
|
+
readonly target?: { readonly platform: string; readonly arch: string };
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
export const RUNTIME_DECLARATIONS: readonly string[] = [
|
|
@@ -166,14 +166,7 @@ export const controlFlowStatementMethods: ControlFlowStatementMethods = {
|
|
|
166
166
|
this.emit(` ${frame} = call i8* @xt_try_enter()`);
|
|
167
167
|
this.emit(` store i8* ${frame}, i8** ${frameSlot}`);
|
|
168
168
|
this.emit(` store i64 0, i64* ${flagSlot}`);
|
|
169
|
-
|
|
170
|
-
// (`_JUMP_BUFFER.Frame`); `longjmp` uses it to run the unwind. clang lowers
|
|
171
|
-
// a C call to `_setjmp` exactly like this. The extra argument is ignored by
|
|
172
|
-
// the one-argument `_setjmp` on Linux/macOS.
|
|
173
|
-
const frameAddress = this.reg();
|
|
174
|
-
this.emit(` ${frameAddress} = call i8* @llvm.frameaddress(i32 0)`);
|
|
175
|
-
const jump = this.reg();
|
|
176
|
-
this.emit(` ${jump} = call i32 @_setjmp(i8* ${frame}, i8* ${frameAddress})`);
|
|
169
|
+
const jump = this.emitSetjmp(frame);
|
|
177
170
|
const isThrow = this.reg();
|
|
178
171
|
this.emit(` ${isThrow} = icmp ne i32 ${jump}, 0`);
|
|
179
172
|
const exceptionTarget = hasCatch ? catchLabel : exceptionLabel;
|
|
@@ -9,6 +9,20 @@ import {
|
|
|
9
9
|
type Node,
|
|
10
10
|
} from "../../ast/nodes.js";
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* True when a `try` frame must be saved with `_setjmpex` rather than `_setjmp`.
|
|
14
|
+
*
|
|
15
|
+
* 64-bit Windows on ARM has no `_setjmp`: both the UCRT and MinGW-w64 declare
|
|
16
|
+
* `setjmp` as `_setjmpex(buf, sponentry)` there, so the linker expects
|
|
17
|
+
* `_setjmpex` (with the caller's stack pointer at entry, `llvm.sponentry`,
|
|
18
|
+
* instead of its frame pointer). clang lowers a C `setjmp` on this target to
|
|
19
|
+
* exactly that pair. Checked at code-generation time because xbintsc builds for
|
|
20
|
+
* its own host.
|
|
21
|
+
*/
|
|
22
|
+
export function requiresSetjmpex(platform: string, arch: string): boolean {
|
|
23
|
+
return platform === "win32" && arch === "arm64";
|
|
24
|
+
}
|
|
25
|
+
|
|
12
26
|
export const BINARY_RUNTIME: Record<string, string | undefined> = {
|
|
13
27
|
[BinaryOperator.Add]: "xt_add",
|
|
14
28
|
[BinaryOperator.Subtract]: "xt_sub",
|
|
@@ -65,6 +65,18 @@ export function toolchainDownload(
|
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
if (platform === "win32" && arch === "arm64") {
|
|
69
|
+
// The llvm-mingw `aarch64` package is the Windows-on-ARM host build; its
|
|
70
|
+
// clang targets aarch64 by default, so a native Windows ARM64 runner gets
|
|
71
|
+
// native MinGW-w64 binaries with no MSVC dependency.
|
|
72
|
+
return {
|
|
73
|
+
url: `https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_VERSION}/llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-aarch64.zip`,
|
|
74
|
+
archive: `llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-aarch64.zip`,
|
|
75
|
+
kind: "zip",
|
|
76
|
+
stripComponents: 1,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
68
80
|
// macOS (and any other host) uses the system SDK; nothing to bundle.
|
|
69
81
|
return undefined;
|
|
70
82
|
}
|
|
@@ -104,5 +116,20 @@ export function toolchainSupportLibraries(
|
|
|
104
116
|
},
|
|
105
117
|
];
|
|
106
118
|
}
|
|
119
|
+
if (platform === "linux" && arch === "arm64") {
|
|
120
|
+
// The aarch64 release build links the same removed `libtinfo.so.5` soname as
|
|
121
|
+
// the x86_64 one; arm64 packages live in the Ubuntu ports archive.
|
|
122
|
+
return [
|
|
123
|
+
{
|
|
124
|
+
urls: [
|
|
125
|
+
"https://ports.ubuntu.com/ubuntu-ports/pool/main/n/ncurses/libtinfo5_6.1-1ubuntu1.18.04.1_arm64.deb",
|
|
126
|
+
"http://ports.ubuntu.com/ubuntu-ports/pool/main/n/ncurses/libtinfo5_6.1-1ubuntu1.18.04.1_arm64.deb",
|
|
127
|
+
],
|
|
128
|
+
archive: "libtinfo5.deb",
|
|
129
|
+
member: "lib/aarch64-linux-gnu/libtinfo.so.5.9",
|
|
130
|
+
dest: "libtinfo.so.5",
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
}
|
|
107
134
|
return [];
|
|
108
135
|
}
|