Files
Ustagammon/engine-wasm/wasm.mk
T
Pierre MARTINandClaude Opus 5.5 ae1ea54782 Moteur WebAssembly : remettre la pile en place après chaque commande
callMain (Emscripten) copie les arguments sur la pile du WebAssembly
(64 Ko) sans les retirer. Pendant une partie dans le navigateur, le même
moteur reçoit des centaines de commandes : vers la 540e, la pile débordait
et corrompait la mémoire du moteur (moteur muet dans Firefox, onglet planté
dans Chromium, « memory access out of bounds » sous Node). Repéré par
make test-browser. stackSave et stackRestore sont exportés et encadrent
chaque commande ; un test en envoie 3000 à la suite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 00:27:24 +01:00

85 lines
3.3 KiB
Makefile

# wasm.mk -- compilation du moteur en WebAssembly avec Emscripten.
#
# Lancé dans l'image Docker emscripten/emsdk par `make engine-wasm` (Makefile
# racine), depuis la racine du dépôt, après `make engine` qui produit les
# données dans build/data/. Tout est produit dans build/wasm/ :
#
# engine.mjs module JavaScript (ES) qui charge le WebAssembly
# engine.wasm le moteur et engine-cli compilés : mêmes sources qu'en
# natif (engine/engine.mk), en C générique, sans threads
# engine.data les données de build/data/, chargées une fois dans le
# système de fichiers virtuel d'Emscripten, sous /data
# positions.json les positions de référence, pour la page de mesure
#
# Le JavaScript appelle engine_init une fois, puis main (celui
# d'engine-cli/main.c) pour chaque commande : voir web/engine-wasm.mjs.
BUILD := build
OUT := $(BUILD)/wasm
GNUBG := engine/gnubg
COMPAT := engine/compat
CC := emcc
include engine/sources.mk
# Mêmes options que le build natif : le moteur calcule comme en natif.
OPTIMISATION := -O3 -ffast-math -DG_DISABLE_ASSERT
OUR_WARNINGS := -std=c11 -Wall -Wextra -Werror
ENGINE_INCLUDES := -I$(COMPAT) -I$(COMPAT)/glib-shim -I$(GNUBG) -I$(GNUBG)/lib -Iengine/include
# Édition des liens :
# - module ES « createEngineModule », utilisable dans un Web Worker et sous Node ;
# - main n'est pas lancé au chargement, et le programme ne s'arrête pas à sa
# sortie : le moteur reste chargé entre deux commandes ;
# - mémoire extensible : les bases de fin de partie occupent plusieurs
# mégaoctets ;
# - stackSave et stackRestore : callMain laisse ses arguments sur la pile
# (64 Ko) ; sans restauration après chaque commande, elle déborde au bout
# de quelques centaines de commandes et corrompt la mémoire du moteur
# (voir web/engine-wasm.mjs).
LINK_FLAGS := -O3 \
-sMODULARIZE -sEXPORT_ES6 -sEXPORT_NAME=createEngineModule \
-sENVIRONMENT=web,worker,node \
-sINVOKE_RUN=0 -sEXIT_RUNTIME=0 \
-sALLOW_MEMORY_GROWTH \
-sEXPORTED_FUNCTIONS=_main,_engine_init \
-sEXPORTED_RUNTIME_METHODS=callMain,ccall,HEAPU8,stackSave,stackRestore \
--preload-file $(BUILD)/data@/data
DATA := $(BUILD)/data/gnubg.wd $(BUILD)/data/gnubg_os0.bd $(BUILD)/data/gnubg_ts0.bd \
$(BUILD)/data/Kazaross-XG2.xml
OBJECTS := $(GNUBG_ENGINE:%.c=$(OUT)/obj/gnubg/%.o) \
$(OUT)/obj/compat/glib-shim.o $(OUT)/obj/compat/gnubg-support.o \
$(OUT)/obj/engine.o $(OUT)/obj/engine-cli/main.o
.PHONY: all
all: $(OUT)/engine.mjs $(OUT)/positions.json
$(OUT)/obj/gnubg/%.o: $(GNUBG)/%.c
@mkdir -p $(@D)
$(CC) $(OPTIMISATION) $(ENGINE_INCLUDES) -MMD -MP -c $< -o $@
$(OUT)/obj/compat/%.o: $(COMPAT)/%.c
@mkdir -p $(@D)
$(CC) $(OPTIMISATION) $(OUR_WARNINGS) $(ENGINE_INCLUDES) -MMD -MP -c $< -o $@
$(OUT)/obj/engine.o: engine/engine.c
@mkdir -p $(@D)
$(CC) $(OPTIMISATION) $(OUR_WARNINGS) $(ENGINE_INCLUDES) -MMD -MP -c $< -o $@
$(OUT)/obj/engine-cli/%.o: engine-cli/%.c
@mkdir -p $(@D)
$(CC) $(OPTIMISATION) $(OUR_WARNINGS) -Iengine/include -MMD -MP -c $< -o $@
# engine.wasm et engine.data sont produits en même temps qu'engine.mjs.
$(OUT)/engine.mjs: $(OBJECTS) $(DATA) engine-wasm/wasm.mk
$(CC) $(OBJECTS) $(LINK_FLAGS) -o $@
$(OUT)/positions.json: tests/reference/positions.json
@mkdir -p $(@D)
cp $< $@
-include $(shell find $(OUT) -name '*.d' 2>/dev/null)