Class MapSpecialRolloutDifferTest
為何 C8 才驗這兩類:C3–C7 的逐類別 rollout 白名單為 portal,reactor,npc,quest,event
(五類),scripts/map/*(60 檔:onUserEnter/ + onFirstUserEnter/ 兩子目錄)與
scripts/special/*(13 檔)始終留在 Nashorn。C8 全域切 GraalJS 後,這 73 檔首次
在 GraalJS 上執行 —— 過去任何 differ 都未涵蓋,正是「全域 flip」相對於「逐類別 rollout」新增的風險面。
本檔補上該缺口,把這兩類也納入黃金參考 differ。
執行緒模型(已確認:不需新增鎖)
map/ 與 special/ 皆不是新的引擎共用形態 —— 它們與 npc/quest 同經 NPCScriptManager
的 per-client 引擎快取(AbstractScriptManager → MapleClient.getScriptEngine(String)),
且三個進入點皆先取 per-client npc_mutex(c.getNPCLock())、橫跨
getInvocable(compile+eval)+ invokeFunction 全程持鎖:
special/<script>.js←NPCScriptManager.start(MapleClient, int)(npc_mutex 內,line 88)map/onUserEnter/<script>.js←NPCScriptManager.onUserEnter(MapleClient, String)(npc_mutex 內,line 290)map/onFirstUserEnter/<script>.js←NPCScriptManager.onFirstUserEnter(MapleClient, String)(npc_mutex 內,line 336)
三者皆透過 start(失敗回退 action((byte)1,(byte)0,0))驅動。off-Netty 進入
(onUserEnter/onFirstUserEnter 經 EtcTimer/EventTimer)亦先取同一把 npc_mutex → 不可能兩執行緒同進同一
client 的 Context。與 C5(npc)/C6(quest)結論一致:不需新增任何鎖(C5 的並發回歸組已在引擎層
證明 per-client ReentrantLock 序列化即足,此處不重複)。
進入點為 start/action,故以「typeof start 與 typeof action 逐檔跨引擎
一致」驗綁定 parity(線上實際呼叫路徑),並要求「解析分歧(XOR)= 零」。同一 JVM 並存 nashorn-core
(黃金參考,GoldenReference.nashorn())與 GraalJS(候選,ScriptEngines.fresh())。
不需 DB / wz / 網路 / Timer。
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final class錄製式msstub —— 忠實鏡射 map/special 實際打到的「陣列型 / 多載 / Point」host 簽章 (AbstractPlayerInteraction.lockUI ×3、NPCConversationManager.getEventEffect/forcedAction/sendOthersTalk ×2/sendStyle/getSearchData),使多載解析/marshalling/數值強制的差異只會來自引擎而非 stub 缺方法。 -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidnew java.awt.Point(x,y)—— 經 GraalJSjava套件命名空間建構 host 物件並 marshall 成 JavaPoint參數(線上map.spawnMonsterOnGroundBelow(MapleMonster, Point))。voidJS 陣列 → Javaboolean[]marshalling + 3 引數 vs 4 引數(byte type)多載選擇。void全scripts/map/**(遞迴 onUserEnter/onFirstUserEnter)+scripts/special/*.js在 nashorn-core 與 GraalJS 必須等價: 解析分歧(XOR)= 零:不得有任何腳本「一引擎解析成功、另一引擎失敗」(E4X/Nashorn-only 語法殘留會在此現形 —— C8 全域 flip 硬門檻)。voidJavaint[]回傳值的「foreign 陣列索引」+ 再 marshall 回int[]參數。voidJS 陣列字面 → Javaint[]marshalling(含負值元素強制),且lockUI(1,1)同 fixture 併驗。voidlockUI 多載選擇(map 最普遍 idiom,49/60 onUserEnter 至少一處)。
-
Constructor Details
-
MapSpecialRolloutDifferTest
public MapSpecialRolloutDifferTest()
-
-
Method Details
-
corpusParseAndStartActionBindingAreEngineEquivalent
全scripts/map/**(遞迴 onUserEnter/onFirstUserEnter)+scripts/special/*.js在 nashorn-core 與 GraalJS 必須等價:- 解析分歧(XOR)= 零:不得有任何腳本「一引擎解析成功、另一引擎失敗」(E4X/Nashorn-only 語法殘留會在此現形 —— C8 全域 flip 硬門檻)。
- start/action 綁定逐檔等價:eval(容忍頂層丟)後
typeof start與typeof action兩引擎須各自一致 —— 驗線上invokeFunction("start"|"action")路徑。
build/map-special-parse-broken-both.txt,不擋 C8)。- Throws:
Exception
-
lockUiOverloadSelectionMatchesAcrossEngines
lockUI 多載選擇(map 最普遍 idiom,49/60 onUserEnter 至少一處)。線上三多載:lockUI(boolean)/lockUI(boolean,int)/lockUI(int,int)—— 無lockUI(int)。 真實腳本(onUserEnter_743030100/map_913070000…)同時用ms.lockUI(1,1)(→ int,int)、ms.lockUI(0)(JS 數字 0 → boolean false,因無 int 單參多載)、ms.lockUI(false)。 這正是 Nashorn vs GraalJS 多載解析/數字→boolean 強制文件上會分歧之處。- Throws:
Exception
-
intArrayMarshallingMatchesAcrossEngines
-
booleanArrayAndByteOverloadMatchesAcrossEngines
-
awtPointConstructionMatchesAcrossEngines
-
foreignIntArrayIndexAndRemarshalMatchesAcrossEngines
-