codecin 5.5.0__tar.gz → 5.5.3__tar.gz
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.
- {codecin-5.5.0 → codecin-5.5.3}/CHANGELOG.md +54 -0
- {codecin-5.5.0 → codecin-5.5.3}/MANIFEST.in +7 -1
- {codecin-5.5.0/codecin.egg-info → codecin-5.5.3}/PKG-INFO +93 -55
- {codecin-5.5.0 → codecin-5.5.3}/README.md +92 -54
- {codecin-5.5.0 → codecin-5.5.3}/codecin/__init__.py +1 -1
- {codecin-5.5.0 → codecin-5.5.3}/codecin/cin.py +28 -7
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/aot/aot.go +0 -15
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/compiler/codegen.go +27 -9
- codecin-5.5.3/codecin/native/compiler/compile_test.go +368 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/version_gen.go +1 -1
- {codecin-5.5.0 → codecin-5.5.3/codecin.egg-info}/PKG-INFO +93 -55
- {codecin-5.5.0 → codecin-5.5.3}/codecin.egg-info/SOURCES.txt +2 -6
- {codecin-5.5.0 → codecin-5.5.3}/script/gen_isa_docs.py +68 -20
- codecin-5.5.3/tests/test_index_subscript_type.py +142 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_isa_dispatch.py +5 -9
- codecin-5.5.3/tests/test_nested_subscript_codegen.py +220 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_workflows.py +37 -3
- codecin-5.5.0/codecin/native/compiler/compile_test.go +0 -164
- codecin-5.5.0/docs/BUILDING.md +0 -541
- codecin-5.5.0/docs/CIN_GUIDE.md +0 -723
- codecin-5.5.0/docs/ISA.md +0 -90
- codecin-5.5.0/docs/REMOTE_DEBUG.md +0 -175
- codecin-5.5.0/docs/SUGGESTIONS.md +0 -583
- codecin-5.5.0/docs/SUGGESTIONS_NEXT.md +0 -568
- {codecin-5.5.0 → codecin-5.5.3}/LICENSE +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/aot.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/assembler.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/cache.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/cli.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/config.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/console.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/cpu.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/crom.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/debugger.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/disasm.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/errors.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/isa.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/jit.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/array.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/bits.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/conv.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/gui.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/hash.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/io.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/json.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/math.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/matrix.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/queue.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/rand.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/sort.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/stat.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/str.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/termux.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/test.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/time.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/validate.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/lib/vec.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/logger.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/memory.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/aot/stub_main.go.txt +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/build.ps1 +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/build.sh +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/compiler/parser.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/compiler/syscalls.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/compiler/tokenizer.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/compiler/types.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/audio.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/audio_other.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/audio_windows.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/canvas.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/crom.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/encode.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/engine_test.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/isa_gen.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/system.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/termux.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/engine/vm.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/go.mod +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/ir/ir.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native/main.go +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/native.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/registers.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin/stats.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin.egg-info/dependency_links.txt +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin.egg-info/entry_points.txt +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin.egg-info/requires.txt +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/codecin.egg-info/top_level.txt +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/examples/asm_constants.asm +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/examples/bitwise_builtins.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/examples/control_flow.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/examples/literals_types.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/examples/modules_demo.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/examples/stdlib_demo.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/examples/system_interaction.cin +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/misc/vim/ftdetect/codecin.vim +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/misc/vim/syntax/cin.vim +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/misc/vim/syntax/codecinasm.vim +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/pyproject.toml +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/script/check_paths.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/script/gen_native_isa.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/setup.cfg +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/setup.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_aot.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_assembler_ext.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_cache.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_cin_host.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_cin_new_features.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_cin_syntax.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_cin_system.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_cli.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_compiler_errors.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_cpu_interpreted.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_debugger.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_examples.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_features_ab.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_features_crom_mmu.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_features_import.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_features_importloc.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_features_mmu.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_features_remote.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_isa_single_source.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_libs.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_libs_ext.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_literals_and_bom.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_memory_protection.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_native_hardening.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_native_lib_lookup.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_no_go_cli.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_packaging.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_paths_consistency.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_switch_semantics.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_three_paths.py +0 -0
- {codecin-5.5.0 → codecin-5.5.3}/tests/test_version.py +0 -0
|
@@ -5,6 +5,60 @@
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [5.5.3] - 2026-09-26
|
|
9
|
+
|
|
10
|
+
以「消除静默算错地址」为主线的一次修复发布:两个会**读错/写错内存且不报错**的
|
|
11
|
+
代码生成缺陷,配套文档站独立与 CI 适配。
|
|
12
|
+
|
|
13
|
+
### 修复 (Fixed)
|
|
14
|
+
|
|
15
|
+
#### 嵌套下标算错基址(静默读写错误内存)
|
|
16
|
+
- **`A[B[i]]` 一类的嵌套下标把外层基址弄丢**。编译器约定是"任何跨子表达式存活
|
|
17
|
+
的临时值都存栈",但 `_gen_index` 把数组/字符串基址暂存在 `x3` 才去求下标;
|
|
18
|
+
内层下标自己也要用 `x3` 存基址,于是外层 `ADD` 用的是**内层数组的基址**:
|
|
19
|
+
`A[B[i]]` 被算成 `&B[0]`,读取静默得到错值、赋值静默写到别的变量内存上
|
|
20
|
+
(不越界、不报错)。实测 11 个用例里 10 个算错。
|
|
21
|
+
现在基址改为入栈(`PUSH`/`POP`),Python 与 Go 两个编译器同步修复。
|
|
22
|
+
- **同类缺陷一并修掉**:`_gen_assign` 把待写入的值放在 `x2` 之后才求左值地址
|
|
23
|
+
(`A[f(i)] = v` 会存错值);`gen_init_2d_literal` 把行指针数组 `x4`、当前行
|
|
24
|
+
`x5` 跨元素表达式存活(`int[][] m = {{g(1), g(2)}, ...}` 元素含函数调用时写错行)。
|
|
25
|
+
两处均改为求值前入栈。
|
|
26
|
+
|
|
27
|
+
#### 浮点下标被当成字节偏移
|
|
28
|
+
- **`G_C[(lo + hi) / 2]` 抛 `address 379800000000000 out of bounds`**
|
|
29
|
+
(issue #1)。`/` 恒为浮点除法,所以下标类型是 float,而 `_gen_index` 是唯一
|
|
30
|
+
漏掉"int 上下文隐式截断"的地方:float 的 IEEE-754 位模式被直接当作字节偏移
|
|
31
|
+
乘 8(249.5 的位模式 × 8 = `0x0379_8000_0000_0000`,正是报告里那个恒定高位
|
|
32
|
+
`0x3798`)。标准 Hoare 快排因此完全无法运行。现在数组与字符串下标都会先按
|
|
33
|
+
与 `int x = 1.9` 一致的规则向零截断,且截断发生在边界检查之前。
|
|
34
|
+
|
|
35
|
+
### 变更 (Changed)
|
|
36
|
+
|
|
37
|
+
- **文档站迁至独立仓库** [Code-CIN-Docs](https://github.com/ByUsiStudio/Code-CIN-Docs):
|
|
38
|
+
本仓库不再内嵌 `docs/` 子模块(`.gitmodules` 不再使用),README 相应改为单独克隆;
|
|
39
|
+
ISA 指令表文档一致性由文档仓库自己保证(`script/gen_isa_docs.py` 保留为生成器)。
|
|
40
|
+
- **CI 适配 Node 20 下线**(GitHub 于 2026-09-23 移除 Node 20 运行时):工作流里
|
|
41
|
+
全部动作升级到 Node 24 版本 —— `checkout@v6`、`setup-python@v7`、`setup-go@v7`、
|
|
42
|
+
`upload-artifact@v7`、`download-artifact@v7`、`softprops/action-gh-release@v3`。
|
|
43
|
+
- **修复 `release.yml` 的非法工作流**:4 个 checkout 步骤各写了两个 `with:` 键,
|
|
44
|
+
GitHub 会判 `Invalid workflow file`(发布流程此前根本跑不起来)。同时移除所有
|
|
45
|
+
`submodules: recursive` 与已失效的文档一致性检查步骤。
|
|
46
|
+
- **`requirements-dev.txt` 补 `PyYAML`**:`tests/test_workflows.py` 用
|
|
47
|
+
`pytest.importorskip('yaml')`,缺依赖时整块门禁被静默跳过 —— 上面那个重复键
|
|
48
|
+
错误就是这样漏过 CI 的。该文件现在还会检测**同层重复键**(PyYAML 默认静默
|
|
49
|
+
后者覆盖前者)。
|
|
50
|
+
- **`.gitignore`/leak-check 排除表**补 `.gotmp`、`.gocache`、`pytest-cache-*`
|
|
51
|
+
(都是记录在案的临时/构建目录);`MANIFEST.in` 去掉已不存在的 `docs/` 条目。
|
|
52
|
+
|
|
53
|
+
### 测试 (Tests)
|
|
54
|
+
- 新增 `tests/test_nested_subscript_codegen.py`:17 个嵌套下标用例 × 解释器/JIT/
|
|
55
|
+
原生三条路径,另有"写 `A[B[i]]` 不得触碰 `B` 的内存"用例;回退修复后 52 条中
|
|
56
|
+
46 条失败。
|
|
57
|
+
- `codecin/native/compiler/compile_test.go` 新增同类 Go 侧用例(编译后直接在
|
|
58
|
+
Go VM 中执行)。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
8
62
|
## [5.5.0] - 2026-09-24
|
|
9
63
|
|
|
10
64
|
以「Python 只做 CLI、Go 是唯一实现」为主线的架构收敛,配套标准库打包修复与 AOT 依赖加固。
|
|
@@ -7,7 +7,13 @@ recursive-include codecin/lib *.cin
|
|
|
7
7
|
recursive-include codecin/native *.go *.txt go.mod go.sum build.sh build.ps1
|
|
8
8
|
# 注: 不 include 预编译原生库 (*.dll/*.so/*.dylib) —— 它们在用户安装时由
|
|
9
9
|
# setup.py 现场编译, 见 pyproject.toml 的 package-data 说明。
|
|
10
|
-
|
|
10
|
+
# 注: 文档站已迁至独立仓库 Code-CIN-Docs, 本仓库不再有 docs/ —— 这里不收
|
|
11
|
+
# docs 内容, 以免本地残留的文档检出 (node_modules 里有大量 *.md) 被误打进 sdist。
|
|
12
|
+
# 注: Go 构建缓存 (AOT 构建器在只读 HOME 下的回退目录) 不属于源码。
|
|
13
|
+
prune codecin/native/.gocache
|
|
14
|
+
# 兜底: 任何本地编译出的预编译库都不得进入 sdist —— 即使 egg-info/SOURCES.txt
|
|
15
|
+
# 里残留了历史条目 (setuptools 会保留已存在文件的旧清单), 这里也强制排除。
|
|
16
|
+
global-exclude *.dll *.so *.dylib
|
|
11
17
|
recursive-include misc *
|
|
12
18
|
recursive-include examples *.cin *.asm *.pl
|
|
13
19
|
recursive-include script *.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecin
|
|
3
|
-
Version: 5.5.
|
|
3
|
+
Version: 5.5.3
|
|
4
4
|
Summary: Code CIN - 高级语言与运行时 (CIN/PL/ASM 工具链 + Go 原生 VM + ARM64/RISC-V/FP/Vector 指令集)
|
|
5
5
|
Author: ByUsi Studio, 北啊呢
|
|
6
6
|
License-Expression: MIT
|
|
@@ -36,12 +36,35 @@ Code CIN 是一门简洁的类 C 高级语言及其跨平台运行时(VM)。
|
|
|
36
36
|
|
|
37
37
|
## 文档
|
|
38
38
|
|
|
39
|
+
**官方文档站**位于独立仓库
|
|
40
|
+
[Code-CIN-Docs](https://github.com/ByUsiStudio/Code-CIN-Docs) (VitePress +
|
|
41
|
+
vitepress-plugin-tabs); 线上站点即由该仓库构建。本仓库不再内嵌 `docs/`
|
|
42
|
+
(子模块已移除), 需要本地预览时请**单独克隆该仓库**:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/ByUsiStudio/Code-CIN-Docs.git
|
|
46
|
+
cd Code-CIN-Docs
|
|
47
|
+
npm install
|
|
48
|
+
npm run docs:dev # 本地预览 (http://localhost:5173)
|
|
49
|
+
npm run docs:build # 构建静态站点到 .vitepress/dist
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
站点内容划分: `guide/` (安装/快速开始/命令行/执行路径/架构/示例/FAQ)、`language/` (CIN 语言)、
|
|
53
|
+
`asm/` (汇编与 ISA)、`stdlib/` (内置标准库参考)、`runtime/` (原生/JIT/格式/AOT)、
|
|
54
|
+
`tools/` (调试器/远程调试/日志/性能/内存缓存)、`reference/` (ISA 编码表/寄存器与内存/Python API/更新日志)、
|
|
55
|
+
`dev/` (项目结构/构建/测试/打包/扩展/贡献)。
|
|
56
|
+
|
|
57
|
+
仓库的开发用文档**全部在独立仓库** [Code-CIN-Docs](https://github.com/ByUsiStudio/Code-CIN-Docs)
|
|
58
|
+
(不进站点, 供源码树内直接查阅):
|
|
59
|
+
|
|
39
60
|
| 文档 | 说明 |
|
|
40
61
|
|------|------|
|
|
41
|
-
| [指令集参考 (ISA)](
|
|
42
|
-
| [开发者编译文档 (BUILDING)](
|
|
43
|
-
| [CIN 编程指南 (CIN_GUIDE)](
|
|
44
|
-
| [远程调试协议 (REMOTE_DEBUG)](
|
|
62
|
+
| [指令集参考 (ISA)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/ISA.md) | 由 `codecin/isa.py` 自动生成的逐条指令表 (唯一真源; 站点版为 `reference/isa.md`) |
|
|
63
|
+
| [开发者编译文档 (BUILDING)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/BUILDING.md) | 环境搭建、Go 原生库编译、构建产物、打包、日志系统、扩展指南 |
|
|
64
|
+
| [CIN 编程指南 (CIN_GUIDE)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/CIN_GUIDE.md) | CIN 高级语言完整语法:类型/函数/struct/数组/字符串/内建函数 |
|
|
65
|
+
| [远程调试协议 (REMOTE_DEBUG)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/REMOTE_DEBUG.md) | `--debug-server` 换行文本协议:命令/响应/状态机/示例会话 |
|
|
66
|
+
|
|
67
|
+
> 这些文件不在本仓库内: 需要时单独 `git clone` 上述文档仓库即可。
|
|
45
68
|
|
|
46
69
|
---
|
|
47
70
|
|
|
@@ -229,7 +252,8 @@ pie title Code CIN 指令集组成
|
|
|
229
252
|
```
|
|
230
253
|
|
|
231
254
|
> 指令总数与分组由 `python script/gen_isa_docs.py` 依据 `codecin/isa.py` 自动生成/校验;
|
|
232
|
-
> 完整的逐条指令表见 [
|
|
255
|
+
> 完整的逐条指令表见 [ISA.md](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/ISA.md)
|
|
256
|
+
> (文档站已在独立仓库)。ARM64 的 WFE/WFI/SEV 无事件模型, 语义等同 NOP。
|
|
233
257
|
|
|
234
258
|
### 指令分类
|
|
235
259
|
|
|
@@ -430,7 +454,6 @@ codecin --version
|
|
|
430
454
|
|
|
431
455
|
```bash
|
|
432
456
|
python -m pytest # 指令黄金 / 三路径一致性 / 断点回归 / 内存保护 / CLI
|
|
433
|
-
python script/gen_isa_docs.py --check # docs/ISA.md 与指令集同步
|
|
434
457
|
python script/gen_native_isa.py --check # Go 原生常量与指令集同步
|
|
435
458
|
ruff check codecin cpu.py script tests
|
|
436
459
|
```
|
|
@@ -438,7 +461,8 @@ ruff check codecin cpu.py script tests
|
|
|
438
461
|
仓库内置 GitHub Actions CI (`.github/workflows/ci.yml`): 多 Python 版本测试、ruff、Go 构建校验,
|
|
439
462
|
一个 `integration` 作业会**真实编译原生库**后跑全量测试 (带覆盖率门槛),
|
|
440
463
|
以及一个 `dist` 作业断言 wheel/sdist 里确实带有内置标准库。
|
|
441
|
-
完整逐条指令表由 `script/gen_isa_docs.py` 从 `codecin/isa.py`
|
|
464
|
+
完整逐条指令表由 `script/gen_isa_docs.py` 从 `codecin/isa.py` 生成到文档仓库
|
|
465
|
+
([ISA.md](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/ISA.md))。
|
|
442
466
|
|
|
443
467
|
### 执行路径
|
|
444
468
|
|
|
@@ -817,67 +841,81 @@ function main() {
|
|
|
817
841
|
|
|
818
842
|
### 斐波那契 (PL)
|
|
819
843
|
|
|
820
|
-
```
|
|
844
|
+
```asm
|
|
821
845
|
.text
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
846
|
+
main:
|
|
847
|
+
set x0, 10 ; n = 10
|
|
848
|
+
call fib
|
|
849
|
+
sys #22 ; ITOA: x0 -> 十进制字符串
|
|
850
|
+
sys #24 ; PRINT_STR
|
|
851
|
+
output #10
|
|
852
|
+
stop
|
|
853
|
+
|
|
854
|
+
fib: ; 入口 x0 = n, 返回 x0 = fib(n)
|
|
855
|
+
compare x0, 1
|
|
856
|
+
jump_greater recurse
|
|
857
|
+
set x0, 1
|
|
858
|
+
return
|
|
859
|
+
|
|
860
|
+
recurse:
|
|
830
861
|
push x0
|
|
831
|
-
|
|
832
|
-
call
|
|
862
|
+
decrement x0
|
|
863
|
+
call fib
|
|
833
864
|
pop x1
|
|
834
865
|
push x0
|
|
866
|
+
set x0, x1
|
|
867
|
+
decrement x0
|
|
868
|
+
decrement x0
|
|
869
|
+
call fib
|
|
870
|
+
pop x1
|
|
835
871
|
add x0, x1
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
base_case:
|
|
839
|
-
set x0, 1
|
|
840
|
-
ret
|
|
872
|
+
return
|
|
841
873
|
```
|
|
842
874
|
|
|
843
|
-
|
|
875
|
+
> 注意: 本 ISA **没有 `jle` / `jge`** 这类指令, 比较请用 `CMP` + `JG`/`JL`/`JE`
|
|
876
|
+
> (PL 风格: `compare` + `jump_greater`/`jump_less`/`jump_equal`), 或 ARM64 的 `B.<cond>`。
|
|
877
|
+
> 上面这段实测输出 `89`; 完整语法与逐条语义见文档站 (仓库内路径 `docs/asm/`)。
|
|
844
878
|
|
|
845
|
-
|
|
846
|
-
|
|
879
|
+
### 循环求和 + 字符串打印 (ASM, 见 `test_asm.asm`)
|
|
880
|
+
|
|
881
|
+
```asm
|
|
847
882
|
.text
|
|
848
883
|
main:
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
884
|
+
MOV x0, #msg
|
|
885
|
+
SYS #24 ; PRINT_STR
|
|
886
|
+
|
|
887
|
+
MOV x1, #0 ; sum
|
|
888
|
+
MOV x2, #1 ; i
|
|
889
|
+
loop:
|
|
890
|
+
ADD x1, x2
|
|
891
|
+
INC x2
|
|
892
|
+
CMP x2, #11
|
|
893
|
+
B.NE loop
|
|
894
|
+
|
|
895
|
+
MOV x0, x1
|
|
896
|
+
SYS #22 ; ITOA -> x0 = 缓冲
|
|
897
|
+
SYS #24 ; PRINT_STR
|
|
898
|
+
OUT #10 ; 换行
|
|
899
|
+
|
|
900
|
+
MOV x3, #nums
|
|
901
|
+
SD x1, [x3] ; 存回数据段
|
|
902
|
+
LD x4, [x3]
|
|
903
|
+
ADDI x4, x4, #100
|
|
904
|
+
MOV x0, x4
|
|
905
|
+
SYS #22
|
|
906
|
+
SYS #24
|
|
907
|
+
OUT #10
|
|
908
|
+
|
|
909
|
+
HALT
|
|
875
910
|
|
|
876
911
|
.data
|
|
877
|
-
|
|
878
|
-
|
|
912
|
+
msg: ASCIZ "Sum 1..10 = "
|
|
913
|
+
nums: DQ 0
|
|
879
914
|
```
|
|
880
915
|
|
|
916
|
+
> 实测输出: `Sum 1..10 = 55` 与 `155` (退出码 0)。更多汇编示例 (递归、数组遍历、
|
|
917
|
+
> 立即数与表达式、条件后缀) 见文档站 `docs/asm/` 与 `docs/guide/examples.md`。
|
|
918
|
+
|
|
881
919
|
---
|
|
882
920
|
|
|
883
921
|
## 技术栈
|
|
@@ -18,12 +18,35 @@ Code CIN 是一门简洁的类 C 高级语言及其跨平台运行时(VM)。
|
|
|
18
18
|
|
|
19
19
|
## 文档
|
|
20
20
|
|
|
21
|
+
**官方文档站**位于独立仓库
|
|
22
|
+
[Code-CIN-Docs](https://github.com/ByUsiStudio/Code-CIN-Docs) (VitePress +
|
|
23
|
+
vitepress-plugin-tabs); 线上站点即由该仓库构建。本仓库不再内嵌 `docs/`
|
|
24
|
+
(子模块已移除), 需要本地预览时请**单独克隆该仓库**:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/ByUsiStudio/Code-CIN-Docs.git
|
|
28
|
+
cd Code-CIN-Docs
|
|
29
|
+
npm install
|
|
30
|
+
npm run docs:dev # 本地预览 (http://localhost:5173)
|
|
31
|
+
npm run docs:build # 构建静态站点到 .vitepress/dist
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
站点内容划分: `guide/` (安装/快速开始/命令行/执行路径/架构/示例/FAQ)、`language/` (CIN 语言)、
|
|
35
|
+
`asm/` (汇编与 ISA)、`stdlib/` (内置标准库参考)、`runtime/` (原生/JIT/格式/AOT)、
|
|
36
|
+
`tools/` (调试器/远程调试/日志/性能/内存缓存)、`reference/` (ISA 编码表/寄存器与内存/Python API/更新日志)、
|
|
37
|
+
`dev/` (项目结构/构建/测试/打包/扩展/贡献)。
|
|
38
|
+
|
|
39
|
+
仓库的开发用文档**全部在独立仓库** [Code-CIN-Docs](https://github.com/ByUsiStudio/Code-CIN-Docs)
|
|
40
|
+
(不进站点, 供源码树内直接查阅):
|
|
41
|
+
|
|
21
42
|
| 文档 | 说明 |
|
|
22
43
|
|------|------|
|
|
23
|
-
| [指令集参考 (ISA)](
|
|
24
|
-
| [开发者编译文档 (BUILDING)](
|
|
25
|
-
| [CIN 编程指南 (CIN_GUIDE)](
|
|
26
|
-
| [远程调试协议 (REMOTE_DEBUG)](
|
|
44
|
+
| [指令集参考 (ISA)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/ISA.md) | 由 `codecin/isa.py` 自动生成的逐条指令表 (唯一真源; 站点版为 `reference/isa.md`) |
|
|
45
|
+
| [开发者编译文档 (BUILDING)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/BUILDING.md) | 环境搭建、Go 原生库编译、构建产物、打包、日志系统、扩展指南 |
|
|
46
|
+
| [CIN 编程指南 (CIN_GUIDE)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/CIN_GUIDE.md) | CIN 高级语言完整语法:类型/函数/struct/数组/字符串/内建函数 |
|
|
47
|
+
| [远程调试协议 (REMOTE_DEBUG)](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/REMOTE_DEBUG.md) | `--debug-server` 换行文本协议:命令/响应/状态机/示例会话 |
|
|
48
|
+
|
|
49
|
+
> 这些文件不在本仓库内: 需要时单独 `git clone` 上述文档仓库即可。
|
|
27
50
|
|
|
28
51
|
---
|
|
29
52
|
|
|
@@ -211,7 +234,8 @@ pie title Code CIN 指令集组成
|
|
|
211
234
|
```
|
|
212
235
|
|
|
213
236
|
> 指令总数与分组由 `python script/gen_isa_docs.py` 依据 `codecin/isa.py` 自动生成/校验;
|
|
214
|
-
> 完整的逐条指令表见 [
|
|
237
|
+
> 完整的逐条指令表见 [ISA.md](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/ISA.md)
|
|
238
|
+
> (文档站已在独立仓库)。ARM64 的 WFE/WFI/SEV 无事件模型, 语义等同 NOP。
|
|
215
239
|
|
|
216
240
|
### 指令分类
|
|
217
241
|
|
|
@@ -412,7 +436,6 @@ codecin --version
|
|
|
412
436
|
|
|
413
437
|
```bash
|
|
414
438
|
python -m pytest # 指令黄金 / 三路径一致性 / 断点回归 / 内存保护 / CLI
|
|
415
|
-
python script/gen_isa_docs.py --check # docs/ISA.md 与指令集同步
|
|
416
439
|
python script/gen_native_isa.py --check # Go 原生常量与指令集同步
|
|
417
440
|
ruff check codecin cpu.py script tests
|
|
418
441
|
```
|
|
@@ -420,7 +443,8 @@ ruff check codecin cpu.py script tests
|
|
|
420
443
|
仓库内置 GitHub Actions CI (`.github/workflows/ci.yml`): 多 Python 版本测试、ruff、Go 构建校验,
|
|
421
444
|
一个 `integration` 作业会**真实编译原生库**后跑全量测试 (带覆盖率门槛),
|
|
422
445
|
以及一个 `dist` 作业断言 wheel/sdist 里确实带有内置标准库。
|
|
423
|
-
完整逐条指令表由 `script/gen_isa_docs.py` 从 `codecin/isa.py`
|
|
446
|
+
完整逐条指令表由 `script/gen_isa_docs.py` 从 `codecin/isa.py` 生成到文档仓库
|
|
447
|
+
([ISA.md](https://github.com/ByUsiStudio/Code-CIN-Docs/blob/main/ISA.md))。
|
|
424
448
|
|
|
425
449
|
### 执行路径
|
|
426
450
|
|
|
@@ -799,67 +823,81 @@ function main() {
|
|
|
799
823
|
|
|
800
824
|
### 斐波那契 (PL)
|
|
801
825
|
|
|
802
|
-
```
|
|
826
|
+
```asm
|
|
803
827
|
.text
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
828
|
+
main:
|
|
829
|
+
set x0, 10 ; n = 10
|
|
830
|
+
call fib
|
|
831
|
+
sys #22 ; ITOA: x0 -> 十进制字符串
|
|
832
|
+
sys #24 ; PRINT_STR
|
|
833
|
+
output #10
|
|
834
|
+
stop
|
|
835
|
+
|
|
836
|
+
fib: ; 入口 x0 = n, 返回 x0 = fib(n)
|
|
837
|
+
compare x0, 1
|
|
838
|
+
jump_greater recurse
|
|
839
|
+
set x0, 1
|
|
840
|
+
return
|
|
841
|
+
|
|
842
|
+
recurse:
|
|
812
843
|
push x0
|
|
813
|
-
|
|
814
|
-
call
|
|
844
|
+
decrement x0
|
|
845
|
+
call fib
|
|
815
846
|
pop x1
|
|
816
847
|
push x0
|
|
848
|
+
set x0, x1
|
|
849
|
+
decrement x0
|
|
850
|
+
decrement x0
|
|
851
|
+
call fib
|
|
852
|
+
pop x1
|
|
817
853
|
add x0, x1
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
base_case:
|
|
821
|
-
set x0, 1
|
|
822
|
-
ret
|
|
854
|
+
return
|
|
823
855
|
```
|
|
824
856
|
|
|
825
|
-
|
|
857
|
+
> 注意: 本 ISA **没有 `jle` / `jge`** 这类指令, 比较请用 `CMP` + `JG`/`JL`/`JE`
|
|
858
|
+
> (PL 风格: `compare` + `jump_greater`/`jump_less`/`jump_equal`), 或 ARM64 的 `B.<cond>`。
|
|
859
|
+
> 上面这段实测输出 `89`; 完整语法与逐条语义见文档站 (仓库内路径 `docs/asm/`)。
|
|
826
860
|
|
|
827
|
-
|
|
828
|
-
|
|
861
|
+
### 循环求和 + 字符串打印 (ASM, 见 `test_asm.asm`)
|
|
862
|
+
|
|
863
|
+
```asm
|
|
829
864
|
.text
|
|
830
865
|
main:
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
866
|
+
MOV x0, #msg
|
|
867
|
+
SYS #24 ; PRINT_STR
|
|
868
|
+
|
|
869
|
+
MOV x1, #0 ; sum
|
|
870
|
+
MOV x2, #1 ; i
|
|
871
|
+
loop:
|
|
872
|
+
ADD x1, x2
|
|
873
|
+
INC x2
|
|
874
|
+
CMP x2, #11
|
|
875
|
+
B.NE loop
|
|
876
|
+
|
|
877
|
+
MOV x0, x1
|
|
878
|
+
SYS #22 ; ITOA -> x0 = 缓冲
|
|
879
|
+
SYS #24 ; PRINT_STR
|
|
880
|
+
OUT #10 ; 换行
|
|
881
|
+
|
|
882
|
+
MOV x3, #nums
|
|
883
|
+
SD x1, [x3] ; 存回数据段
|
|
884
|
+
LD x4, [x3]
|
|
885
|
+
ADDI x4, x4, #100
|
|
886
|
+
MOV x0, x4
|
|
887
|
+
SYS #22
|
|
888
|
+
SYS #24
|
|
889
|
+
OUT #10
|
|
890
|
+
|
|
891
|
+
HALT
|
|
857
892
|
|
|
858
893
|
.data
|
|
859
|
-
|
|
860
|
-
|
|
894
|
+
msg: ASCIZ "Sum 1..10 = "
|
|
895
|
+
nums: DQ 0
|
|
861
896
|
```
|
|
862
897
|
|
|
898
|
+
> 实测输出: `Sum 1..10 = 55` 与 `155` (退出码 0)。更多汇编示例 (递归、数组遍历、
|
|
899
|
+
> 立即数与表达式、条件后缀) 见文档站 `docs/asm/` 与 `docs/guide/examples.md`。
|
|
900
|
+
|
|
863
901
|
---
|
|
864
902
|
|
|
865
903
|
## 技术栈
|
|
@@ -1664,9 +1664,15 @@ class CodeGen:
|
|
|
1664
1664
|
self.emit('ADDI', self.reg(0), self.reg(0), self.imm(i * 8))
|
|
1665
1665
|
self.emit('SD', self.reg(5), ('mem', 0, 0))
|
|
1666
1666
|
for j, elem in enumerate(row):
|
|
1667
|
+
# x4 (outer) 与 x5 (当前行) 要跨元素表达式求值存活, 而元素里
|
|
1668
|
+
# 可能有函数调用/嵌套下标 (会覆盖 x1..x6), 因此先存栈。
|
|
1669
|
+
self.emit('PUSH', self.reg(4))
|
|
1670
|
+
self.emit('PUSH', self.reg(5))
|
|
1667
1671
|
vt = self.gen_value(elem)
|
|
1668
1672
|
self._convert(vt, 'int')
|
|
1669
|
-
self.emit('MOV', self.reg(2), self.reg(0))
|
|
1673
|
+
self.emit('MOV', self.reg(2), self.reg(0)) # x2 = value
|
|
1674
|
+
self.emit('POP', self.reg(5)) # 恢复当前行
|
|
1675
|
+
self.emit('POP', self.reg(4)) # 恢复 outer
|
|
1670
1676
|
self.emit('MOV', self.reg(0), self.reg(5))
|
|
1671
1677
|
if j:
|
|
1672
1678
|
self.emit('ADDI', self.reg(0), self.reg(0), self.imm(j * 8))
|
|
@@ -1907,8 +1913,12 @@ class CodeGen:
|
|
|
1907
1913
|
if lvalue:
|
|
1908
1914
|
raise CompilerError(
|
|
1909
1915
|
"Cannot assign to string element (strings are immutable)")
|
|
1910
|
-
|
|
1911
|
-
|
|
1916
|
+
# 基址必须存栈: 下标表达式里可能有嵌套下标/函数调用, 它们会覆盖
|
|
1917
|
+
# x1..x6。s[B[i]] 曾因此把字符串基址弄丢, 读出错误内存。
|
|
1918
|
+
self.emit('PUSH', self.reg(0)) # 保存字符串基址
|
|
1919
|
+
idx_t = self.gen_value(idx_node) # x0 = index
|
|
1920
|
+
self._convert(idx_t, 'int') # 下标是 int 上下文
|
|
1921
|
+
self.emit('POP', self.reg(3)) # x3 = 字符串基址
|
|
1912
1922
|
self.emit('ADD', self.reg(0), self.reg(3)) # x0 = base + i (字节偏移)
|
|
1913
1923
|
self.emit('LB', self.reg(0), ('mem', 0, 0)) # 读 1 字节 (符号扩展)
|
|
1914
1924
|
self.emit('ANDI', self.reg(0), self.reg(0), self.imm(0xFF)) # 0..255
|
|
@@ -1918,9 +1928,17 @@ class CodeGen:
|
|
|
1918
1928
|
else:
|
|
1919
1929
|
raise CompilerError(f"Indexing non-array type: {base_t}")
|
|
1920
1930
|
|
|
1921
|
-
# x0 = base pointer; 计算 elem
|
|
1922
|
-
|
|
1923
|
-
|
|
1931
|
+
# x0 = base pointer; 计算 elem 地址。
|
|
1932
|
+
# 基址必须存栈, 不能用寄存器"暂存": 下标表达式里可能有嵌套下标或函数
|
|
1933
|
+
# 调用, 它们会覆盖 x1..x6。此前 base 放在 x3, 于是 A[B[i]] 的内层下标
|
|
1934
|
+
# 把 x3 改成 B 的基址, 外层 ADD 用 B 的基址当 A 的 —— 读错地址, 写的
|
|
1935
|
+
# 时候直接写坏别的内存 (静默, 不报错)。
|
|
1936
|
+
self.emit('PUSH', self.reg(0)) # 保存 base
|
|
1937
|
+
idx_t = self.gen_value(idx_node) # x0 = index
|
|
1938
|
+
# 下标是 int 上下文 (与赋值/传参/返回一致): float 隐式截断为 int。
|
|
1939
|
+
# 缺这一步时 float 的 IEEE-754 位模式会被当作字节偏移直接乘 8,
|
|
1940
|
+
# 产生 0x0379_8000_0000_0000 之类的高位垃圾地址 (issue #1)。
|
|
1941
|
+
self._convert(idx_t, 'int')
|
|
1924
1942
|
|
|
1925
1943
|
# A1 --bounds-check: 定长数组索引 0 <= i < size
|
|
1926
1944
|
if self._bounds and _is_fixed_array(base_t):
|
|
@@ -1939,6 +1957,7 @@ class CodeGen:
|
|
|
1939
1957
|
scale = _type_slots(elem_t) * 8
|
|
1940
1958
|
self.emit('MOV', self.reg(1), self.imm(scale))
|
|
1941
1959
|
self.emit('MUL', self.reg(0), self.reg(1)) # x0 = index * scale
|
|
1960
|
+
self.emit('POP', self.reg(3)) # x3 = base (存栈时压入的)
|
|
1942
1961
|
self.emit('ADD', self.reg(0), self.reg(3)) # x0 = elem 地址
|
|
1943
1962
|
|
|
1944
1963
|
if lvalue:
|
|
@@ -1971,8 +1990,10 @@ class CodeGen:
|
|
|
1971
1990
|
# 目标类型
|
|
1972
1991
|
tt = self._expr_type(target)
|
|
1973
1992
|
self._convert(vt, tt)
|
|
1974
|
-
|
|
1993
|
+
# 左值地址求值可能覆盖 x1..x6 (例如 A[f(i)] = v), 值必须存栈。
|
|
1994
|
+
self.emit('PUSH', self.reg(0)) # 保存 value
|
|
1975
1995
|
self._gen_lvalue_addr(target) # x0 = addr
|
|
1996
|
+
self.emit('POP', self.reg(2)) # x2 = value
|
|
1976
1997
|
self.emit('SD', self.reg(2), ('mem', 0, 0))
|
|
1977
1998
|
return tt
|
|
1978
1999
|
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
// Package aot 提供 AOT 构建: 把 CIN 程序编译成**独立静态可执行文件**。
|
|
2
|
-
//
|
|
3
|
-
// 产物不依赖 Python、不依赖 Go 工具链、不依赖任何动态库:
|
|
4
|
-
// 字节码与初始内存镜像被嵌入二进制, 由内置的 Go VM 执行
|
|
5
|
-
// (构建时 CGO_ENABLED=0, 因此 Windows / Linux / macOS 均为静态链接)。
|
|
6
|
-
//
|
|
7
|
-
// 构建流程 (Build):
|
|
8
|
-
// 1. 在 codecin-native 模块内创建临时包目录 .aotbuild-<rand>/
|
|
9
|
-
// (Go 工具链会忽略以 '.' 开头的目录, 因此不影响 go build ./...);
|
|
10
|
-
// 2. 写入 main.go (由共享模板 stub_main.go.txt 提供) 与两个资源文件;
|
|
11
|
-
// 3. CGO_ENABLED=0 + GOOS/GOARCH 交叉编译出目标平台可执行文件;
|
|
12
|
-
// 4. 删除临时目录。
|
|
13
1
|
package aot
|
|
14
2
|
|
|
15
3
|
import (
|
|
@@ -21,9 +9,6 @@ import (
|
|
|
21
9
|
"codecin-native/engine"
|
|
22
10
|
)
|
|
23
11
|
|
|
24
|
-
// StubSource 是生成的 main.go 模板, 与 Python 侧 codecin/aot.py 共用同一份
|
|
25
|
-
// 文件 (codecin/native/aot/stub_main.go.txt), 避免两处模板漂移。
|
|
26
|
-
//
|
|
27
12
|
//go:embed stub_main.go.txt
|
|
28
13
|
var stubSource string
|
|
29
14
|
|
|
@@ -12,8 +12,6 @@ import (
|
|
|
12
12
|
"codecin-native/ir"
|
|
13
13
|
)
|
|
14
14
|
|
|
15
|
-
// ---------------- 代码生成 ----------------
|
|
16
|
-
|
|
17
15
|
// hostBuiltin 宿主能力内建 (表驱动): 名称 -> (SYS 号, 参数个数, 返回类型)。
|
|
18
16
|
type hostBuiltin struct {
|
|
19
17
|
sysID int64
|
|
@@ -647,9 +645,15 @@ func (c *compiler) genInit2dLiteral(name string, t *Type, lit *Node) {
|
|
|
647
645
|
c.emit("ADDI", c.reg(0), c.reg(0), c.imm(int64(i*8)))
|
|
648
646
|
c.emit("SD", c.reg(5), ir.Mem(0, 0))
|
|
649
647
|
for j, elem := range row {
|
|
648
|
+
// x4 (outer) 与 x5 (当前行) 要跨元素表达式求值存活, 而元素里
|
|
649
|
+
// 可能有函数调用/嵌套下标 (会覆盖 x1..x6), 因此先存栈。
|
|
650
|
+
c.emit("PUSH", c.reg(4))
|
|
651
|
+
c.emit("PUSH", c.reg(5))
|
|
650
652
|
vt := c.genValue(elem)
|
|
651
653
|
c.convert(vt, scalarT(kInt))
|
|
652
|
-
c.emit("MOV", c.reg(2), c.reg(0))
|
|
654
|
+
c.emit("MOV", c.reg(2), c.reg(0)) // x2 = value
|
|
655
|
+
c.emit("POP", c.reg(5))
|
|
656
|
+
c.emit("POP", c.reg(4))
|
|
653
657
|
c.emit("MOV", c.reg(0), c.reg(5))
|
|
654
658
|
if j != 0 {
|
|
655
659
|
c.emit("ADDI", c.reg(0), c.reg(0), c.imm(int64(j*8)))
|
|
@@ -963,8 +967,12 @@ func (c *compiler) genIndex(baseNode, idxNode *Node, lvalue bool) *Type {
|
|
|
963
967
|
c.failf("Cannot assign to string index")
|
|
964
968
|
return nil
|
|
965
969
|
}
|
|
966
|
-
|
|
967
|
-
|
|
970
|
+
// 基址必须存栈: 下标表达式里可能有嵌套下标/函数调用, 它们会覆盖
|
|
971
|
+
// x1..x6。s[B[i]] 曾因此把字符串基址弄丢, 读出错误内存。
|
|
972
|
+
c.emit("PUSH", c.reg(0))
|
|
973
|
+
idxT := c.genValue(idxNode)
|
|
974
|
+
c.convert(idxT, scalarT(kInt)) // 下标是 int 上下文
|
|
975
|
+
c.emit("POP", c.reg(3))
|
|
968
976
|
c.emit("ADD", c.reg(0), c.reg(3))
|
|
969
977
|
c.emit("LB", c.reg(0), ir.Mem(0, 0))
|
|
970
978
|
c.emit("ANDI", c.reg(0), c.reg(0), c.imm(0xFF))
|
|
@@ -976,9 +984,16 @@ func (c *compiler) genIndex(baseNode, idxNode *Node, lvalue bool) *Type {
|
|
|
976
984
|
}
|
|
977
985
|
elemT := baseT.Elem
|
|
978
986
|
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
987
|
+
// 基址必须存栈, 不能用寄存器"暂存": 下标表达式里可能有嵌套下标或函数
|
|
988
|
+
// 调用, 它们会覆盖 x1..x6。此前 base 放在 x3, 于是 A[B[i]] 的内层下标
|
|
989
|
+
// 把 x3 改成 B 的基址, 外层 ADD 用 B 的基址当 A 的 —— 读错地址, 写的
|
|
990
|
+
// 时候直接写坏别的内存 (静默, 不报错)。
|
|
991
|
+
c.emit("PUSH", c.reg(0))
|
|
992
|
+
idxT := c.genValue(idxNode)
|
|
993
|
+
// 下标是 int 上下文 (与赋值/传参/返回一致): float 隐式截断为 int。
|
|
994
|
+
// 缺这一步时 float 的 IEEE-754 位模式会被当作字节偏移直接乘 8,
|
|
995
|
+
// 产生 0x0379_8000_0000_0000 之类的高位垃圾地址 (issue #1)。
|
|
996
|
+
c.convert(idxT, scalarT(kInt))
|
|
982
997
|
if c.bounds && isFixedArray(baseT) {
|
|
983
998
|
size := baseT.Size
|
|
984
999
|
lGe := c.newLabel("bndok")
|
|
@@ -996,6 +1011,7 @@ func (c *compiler) genIndex(baseNode, idxNode *Node, lvalue bool) *Type {
|
|
|
996
1011
|
scale := typeSlots(elemT) * 8
|
|
997
1012
|
c.emit("MOV", c.reg(1), c.imm(int64(scale)))
|
|
998
1013
|
c.emit("MUL", c.reg(0), c.reg(1))
|
|
1014
|
+
c.emit("POP", c.reg(3)) // x3 = base (存栈时压入的)
|
|
999
1015
|
c.emit("ADD", c.reg(0), c.reg(3))
|
|
1000
1016
|
|
|
1001
1017
|
if lvalue {
|
|
@@ -1026,8 +1042,10 @@ func (c *compiler) genAssign(target, valueNode *Node) *Type {
|
|
|
1026
1042
|
vt := c.genValue(valueNode)
|
|
1027
1043
|
tt := c.exprType(target)
|
|
1028
1044
|
c.convert(vt, tt)
|
|
1029
|
-
|
|
1045
|
+
// 左值地址求值可能覆盖 x1..x6 (例如 A[f(i)] = v), 值必须存栈。
|
|
1046
|
+
c.emit("PUSH", c.reg(0))
|
|
1030
1047
|
c.genLvalueAddr(target)
|
|
1048
|
+
c.emit("POP", c.reg(2))
|
|
1031
1049
|
c.emit("SD", c.reg(2), ir.Mem(0, 0))
|
|
1032
1050
|
return tt
|
|
1033
1051
|
}
|