手冊導讀
本手冊面向已閱讀《深度解析 J2ME Snake 腳本引擎架構》的開發者,提供語法速查、常見陷阱、效能調優、調試技巧四大實用章節,助你在實戰中少走彎路。
一、高階語法速查表
| 特性 | 語法示例 | 備註 |
| 變量聲明 | var x; | 弱類型,後續可賦任意類型值 |
| 函數定義 | func add(a,b) { return a+b; } | 支援遞歸、巢狀函數 |
| 陣列 | var arr[10]; arr[0]=5; | 下標從 0 起,動態擴容 |
| 條件分支 | if (x>0) {..} else {..} | 無 switch,用 if-else 鏈 |
| 循環 | while(cond){..} for(i=0;i<10;i++){..} | break/continue 支援 |
| 註釋 | // 單行\n/* 多行 */ | 編譯器自動剝離 |
| 轉義字符 | "換行\\n制表\\t引號\\\" | 字串字面量中使用 |
二、低階指令集速查(33 條核心指令)
數據移動/運算
Mov dst, src // 複製
Push src // 入棧
Pop dst // 出棧
Add dst, src // dst += src
Sub dst, src // dst -= src
Mul dst, src // dst *= src
Div dst, src // dst /= src
And dst, src // 位與
Or dst, src // 位或
Xor dst, src // 位異或
Not dst // 位非
Shl dst, n // 左移 n 位
Shr dst, n // 右移 n 位
流程控制
Jmp label // 無條件跳轉
Jz label // 零值跳轉
Jnz label // 非零跳轉
Call func // 函數調用
Ret // 返回
RetVal // 返回並攜帶 _RetVal
函數參數/返回
param name // 宣告參數(按序對應調用方 Push 順序)
Mov_RetVal, src // 設置返回值寄存器
三、虛擬機(SVM)運維操作手冊
1. 棧大小配置
// 低階碼檔案首行
SetStackSize 1024 // 設置 1MB 棧(單位 KB)
_MyScript()
{ ... }
2. 宿主方法庫開發規範
- 繼承
Lib.class,實現 public void methodName(int[] params)
- 嚴禁 在方法中創建 Java 物件、使用反射、拋出異常
- 參數通過
params[0]..params[n] 傳遞,返回值寫入 params[0]
- 測試包中列出的 2 條注意事項必讀(線程安全、重入)
3. 多線程控制 API(宿主端)
SVM vm = new SVM();
vm.loadScript("ai.script"); // 載入
vm.setPriority(threadId, 10); // 優先級 1~10
vm.resumeScript(threadId); // 運行
vm.pauseScript(threadId); // 暫停
vm.stopScript(threadId); // 停止並釋放資源
// 主循環
while (running) {
vm.runScript(16); // 給 16ms 時間片
renderFrame();
}
四、調試與效能調優清單
- 編譯器參數:
-A 輸出低階碼對照學習;-O 啟用基礎優化(常量折疊、死碼消除)。
- 執行時追蹤:SVM 支援
traceOn() 輸出指令級日誌,定位死循環/棧溢出。
- 表達式外包:複雜數學公式(矩陣、三角函數)改寫為低階指令或宿主原生方法。
- 字節碼體積控制:單腳本 < 20KB,超過拆分模塊動態載入。
- 真機壓測:在目標機型連續跑 30 分鐘,監控記憶體增長、幀率抖動。
五、常見錯誤碼對照表
| 碼 | 含義 | 排查方向 |
| 101 | 語法錯誤 | 檢查括號匹配、關鍵字拼寫 |
| 203 | 棧溢出 | 增大 SetStackSize 或優化遞歸深度 |
| 305 | 宿主方法未找到 | 確認 Lib 子類方法簽名、拼寫、大小寫 |
| 409 | 非法指令 | 低階碼手寫錯誤,建議由高階編譯生成 |
| 512 | 線程死鎖 | 檢查宿主方法是否阻塞、同步鎖順序 |
附錄:最小可運行範例
// hello.snake (高階)
func main() {
print("Hello Snake VM!");
}
// 編譯:snakecc -A hello.snake -o hello.bin
// 宿主載入並運行
SVM vm = new SVM();
vm.loadScript("hello.bin");
vm.runScript(100); // 印出訊息並退出