方針: 完了済みウォークスルーは個別長文を保持せず、何をいつ完了したかを一元管理する。 最終更新: 2026-06-28
.next(v)
値受け渡し — replay 方式)generator は呼び出し時に本体を最後まで eager 実行し yield 値を Vec
に収集する方式で、無限 generator が無限ループし .next(v)
の双方向値渡しも不可だった。replay(再実行)方式へ全面再設計し真の遅延評価を実現。os_lib/js/{value,interp,builtins}.rs。
value.rs):
values/index/returned を廃し
func/args/this/sent(Vec)/started/done
を保持。yield 値の事前収集をやめ、関数定義・実引数・this を保存して
resume 時に本体を先頭から replay する。interp.rs): Interp の
gen_collector を gen_replay(GenReplay:
sent/counter/target/suspending/yielded) に置換。do_yield()
は counter<target なら保存済み sent 値を返して通過、target 到達で
suspend 番兵 Err を投げて巻き戻す。generator_resume() は
resume 値を sent に積み target=sent.len() 個の yield
を通過するまで本体を replay、次 yield で (value,false)・本体完了で
(value,true) を返す。スコープ/引数/rest/default/arguments
を毎回再構築(決定的)。yield* は各要素を個別 yield
点として委譲。interp.rs):
drain_generator()/iter_to_vec() を追加し
for-of・spread(配列リテラル/call-args)・Array.from が
generator を遅延駆動。無限 gen はステップ予算 (aborted)
で打ち切り。純関数 iterable_values の Generator
分岐は空返しにし iter_to_vec へ誘導。try/catch は
is_suspending() ガードで中断中は catch せず finally
もスキップ。builtins.rs):
gen_next を generator_resume に接続し
.next(v) の v を受け渡し。gen_return は done
化。Array.from
を全イテラブル対応に拡張(Array/Set/Map/Generator + array-like + 第2引数
mapFn)。.next(v) の受け渡しは正しい)。no_std
ツリーウォークで真のスタック退避は困難なための割り切りで、selftest
で再実行特性も明示検証。js/mod.rs): generator
ケースを 6→18 件に拡充(無限 gen の有限消費・.next(v)
双方向値渡し・generator 同士の yield*
委譲・return() 早期終了・replay
副作用再実行・Array.from(gen)+mapFn・try/finally 跨ぎ
yield)。QEMU 回帰で JS_SELFTEST: PASS(全12コア
[OK])、build/fmt/clippy ゼロを確認。grid の auto-flow
は行優先(row)固定で、grid-auto-flow:column(列優先:
行を縦に埋めてから次列へ)が未対応だった。列優先フローを実装。os_lib/layout.rs。
grid-auto-flow 値に
column を含むかで auto_flow_col
を判定。列優先時の行数上限
flow_rows = row_tracks.len().max(1)(明示
grid-template-rows 本数)。rr + row_span > flow_rows
で次列先頭へ折り返し、空きセルで確定。cursor_r/cursor_c を更新。layout::selftest() の measure ケースは 95 →
97 件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア
[OK])、build/fmt/clippy ゼロを確認。明示 grid-template-rows
の本数を超えて配置された暗黙行は内容実測(auto
相当)のみで、grid-auto-rows
によるサイズ指定が効かなかった。暗黙行のサイズ制御を実装。os_lib/layout.rs。
grid-auto-rows を
parse_grid_tracks で Veceff_row_track(r)
を追加。明示トラックがあればそれ、無ければ暗黙行インデックス
r - row_tracks.len() で grid-auto-rows
を循環適用。行高さ算出(初期 px/minmax シード・内容実測クランプ・fr
分配)の全箇所を row_tracks.get(r) から
eff_row_track(r) へ置換。fr 分配は明示行のみだった走査を全
n_rows 走査へ拡張し暗黙行 fr も対応。30px 60px 循環で row2 が
y=90)。layout::selftest() の measure ケースは 93 → 95
件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア [OK])、build/fmt/clippy
ゼロを確認。grid-template-rows の minmax(min, max) は
max 側のみ採用し
min(下限)を無視していた。minmax(50px, auto) で最低 50px
が保証されない等の不具合を修正。os_lib/layout.rs。
MinMax { min_px, max_fr, max_px, max_is_fr, max_is_auto }
変種を追加。parse_one_grid_track で min を px/%、max を
fr/px/auto に分解して保持。layout::selftest() の measure ケースは 90 → 93
件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア [OK])、build/fmt/clippy
ゼロを確認。width の min-content/max-content/fit-content
は実装済みだったが、min-width/max-width
制約ではこれらキーワードが無視されていた。両制約でも内容ベース幅を解決するよう拡張。os_lib/layout.rs。
resolve_sizing_value(value, base) メソッドを追加。px/% は
base 基準、min-content/max-content は
block_intrinsic_widths()、fit-content は
clamp(min, base, max) で解決。auto/未指定は None。resolve_length_value(intrinsic を無視)から
resolve_sizing_value へ置換。layout::selftest() の measure ケースは 88 → 90
件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア [OK])、build/fmt/clippy
ゼロを確認。flex/grid の
gap/row-gap/column-gap(および
grid-row-gap/grid-column-gap)が px
のみで、% 指定を 0 扱いしていた。% をコンテナ content
幅基準で解決するよう拡張。os_lib/layout.rs。
parse_flex_gap(node, base) に
base 引数を追加し、内部 px 解決を Percent(pct) → base*pct
対応に。呼び出し側は self.dimensions.content.width
を渡す。折返し経路(layout_flex_wrapped)も同じ gap
値を受けるため自動対応。gpx(px/% 両対応、% は content_w
基準)へ置換。gap ショートハンド + 個別
row-gap/column-gap + grid-*-gap
エイリアスすべてに適用。layout::selftest() の measure ケースは 85 → 88
件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア [OK])、build/fmt/clippy
ゼロを確認。flex アイテムの主軸方向
margin:auto(margin-left:auto
で右寄せ、margin:0 auto
で中央寄せ等)が未対応だった。余剰空間を auto margin
辺へ分配する一般的なセンタリング/押し出しパターンを実装。os_lib/layout.rs(非折返し
layout_flex 経路)。
box_main_auto_margins(item, is_row) -> (lead, trail)
を追加。row は left/right、column は top/bottom の auto
を判定(margin-<side>:auto 明示 + margin
ショートハンド 1/2/3/4 値展開)。main_free_space を全
auto margin 辺数で均等分配。配置ループで先頭辺ぶんを cursor
へ加算(後方へ押す)、末尾辺ぶんを次アイテム前に加算。layout::selftest() の measure ケースは 82 → 85
件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア [OK])、build/fmt/clippy
ゼロを確認。aspect-ratio は width→height
の一方向のみ対応していた。height 明示・width:auto のとき width
を逆算する方向を追加し、min/max-width
クランプも適用した。os_lib/layout.rs。
parse_aspect_ratio(s) -> Option<(num, den)>
を追加(16/9/1.5 形式、ゼロ・負・auto は
None)。既存のインライン解析を置換。width = height * num / den)の両対応に。逆算
width には min-width/max-width 制約を再適用。layout::selftest() の measure ケースは
79 → 82 件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア
[OK])、build/fmt/clippy ゼロを確認。ブロック要素の width がキーワード
min-content/max-content/fit-content
を解釈できなかった。内容ベース幅で要素を伸縮させるこれらを実装した機能ユニット。os_lib/layout.rs。
MinContent/MaxContent/FitContent
を追加し parse_length_value
で認識。resolve_length_value(min/max
制約解決)では内容ベースキーワードは None(無制約)扱いとし、width
解決側で内容計測する。block_intrinsic_widths(&self) -> (min_content, max_content)
を追加。inline/inline-block 子は
intrinsic_inline_size(明示 width
尊重)で計測し、同一行に並ぶため max-content は加算・min-content
は最大。ブロック子は縦積みのため両者最大。MinContent→min、MaxContent→max、FitContent→clamp(min,
available, max) を適用。layout::selftest()
の measure ケースは 75 → 79 件。QEMU 回帰で LAYOUT_SELFTEST:
PASS(全12コア [OK])、build/fmt/clippy ゼロを確認。www.sugi-lab.net を Chromium に近い見た目にするためのバッチ実装と git コンフリクト解消。
IntersectionObserver(Batch H 修正) -
io_observe() を observe()
が呼ばれた時点でコールバックを即時発火するよう変更(Chromium
の初回発火相当)。従来は JsRuntime::eval()
終了後に発火していたため、セルフテストの seen が
false のまま返っていた。JS_SELFTEST PASS を確認。
setInterval / clearInterval(Batch I) -
set_interval 関数を独立実装(最大 8
回発火でベアメタル無限ループ防止)。 - Interp に
intervals: Vec<(u64, Value, Vec<Value>, u32)>
フィールドを追加。 - run_event_loop()
にインターバル発火ループ(run_intervals())を組み込み。 -
clearInterval(id) で即時停止。
CSS @media クエリのパース・適用(Batch
I) - css.rs に media_query_matches()
を実装(max-width/min-width/max-height/min-height/orientation/screen/all/print
対応)。 - parse_css_declarations() ヘルパで
@media ブロック内のルールを再帰パース。 - VIEWPORT_HINT_W/H
を基準に適用可否を判定。 - LAYOUT selftest case38(@media max-width:
viewport=200 → ルール適用)を追加・PASS。
window.innerWidth / innerHeight 他(Batch I) -
innerWidth/innerHeight/outerWidth/outerHeight/devicePixelRatio
をグローバルと window オブジェクトに登録。VIEWPORT_HINT
から値を取得。 - scrollBy も window
オブジェクトに追加。
RenderElement フィールド拡充(Batch I) -
bg_size: String(background-size: cover/contain/auto 等) -
bg_position: String(background-position) -
text_shadow: Option<(i32, i32, i32, u32)>(offset_x,
offset_y, blur, color) -
before_content/after_content: String(::before/::after
の content) -
transform_tx/transform_ty: i32、transform_scale: f32、transform_rotate_deg: f32
- web_engine のスタイル収集パスで CSS
プロパティから各フィールドへマップ。
CSS transform パース → 描画座標反映(Batch
K) - parse_transform()
を追加(translateX/Y/translate/translate3d/scale/rotate/matrix 対応)。
-
el_x = el.x_offset + el.transform_tx、el_y = ... + el.transform_ty
で描画位置にオフセット適用。 - TODO.md の「CSS
transform(translate/scale/rotate)」を完了へ。
CSS aspect-ratio レイアウト(Batch K)
- layout_block のデストラクタに
aspect_ratio_val を追加。 - height が auto の場合のみ
aspect-ratio: W/H から height = width * H/W
を算出。 - LAYOUT selftest case36(16/9 → 90px)・case37(1/1
正方形)を追加・PASS。
ResizeObserver / MutationObserver / CustomEvent(Batch
J) - ResizeObserver: observe() 時に contentRect=0
の即時コールバック発火。 - MutationObserver:
observe/disconnect/takeRecords を no-op として登録(クラッシュ防止)。 -
CustomEvent(type, {detail}): type/detail/bubbles/cancelable
付きオブジェクトを生成。
document API 拡充(Batch J) -
createRange() →
selectNodeContents/collapse/getBoundingClientRect 付き Range
オブジェクト。 - getSelection() →
removeAllRanges/addRange/toString(→““) 付き Selection オブジェクト。 -
execCommand() → no-op、hasFocus() → true
を返す。
Element.animate()(Batch K) - DOM
メソッドディスパッチに "animate"
を追加。playState:"finished"、finished: Promise<void>(即時
fulfilled)付きの Animation
オブジェクトを返す。play/pause/cancel/currentTime
を提供。
git コンフリクト解消 -
src/os_lib/js/mod.rs(UU): setInterval
セルフテストの重複を整理してマージ。 -
src/kernel/net.rs(UD): net/
ディレクトリ分割済みのため削除を採用(git rm)。
flex-basis を実装 — 主軸初期サイズを
width/height より優先)flexbox は flex-grow/flex-shrink/order
まで実装済みだったが、主軸初期サイズを指定する flex-basis
が未対応だった。これを実装した機能ユニット。os_lib/layout.rs(非折返し
layout_flex 経路)。
box_flex_basis(item, main_size)
を追加。flex-basis 優先、無ければ flex
ショートハンドの長さトークン(px/%/em)。auto/content/未指定は
None(width/height に従う)。flex:N(単一数値)は
basis=0。%
はコンテナ主軸長基準で解決(resolve_basis_len)。layout::selftest() の measure ケースは 72 →
75 件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア
[OK])、build/fmt/clippy ゼロを確認。kernel/net/dns.rs の
c.to_digit(10).unwrap()(clippy unwrap_used
違反、並行編集由来)を (c as u32) - ('0' as u32) へ置換し
clippy ゼロを回復。flex-shrink と order
を実装 — 超過時の縮小とアイテム並び替え)flexbox は flex-grow(余剰分配)まで実装済みだったが、主軸超過時の
flex-shrink(縮小)と
order(描画順並び替え)が未対応だった。これを実装した機能ユニット。os_lib/layout.rs(非折返し
layout_flex 経路)。
box_flex_shrink(flex-shrink 優先、無ければ
flex
ショートハンドの2番目。flex:none=0、flex:N単一数値=1、未指定=1)と
box_order(order
値、未指定/不正=0、負値可)を追加。total_main > container_main(超過)のとき、超過分を各アイテムの
shrink 係数比で按分して content サイズから減算(0 クランプ、端数は末尾
shrinker へ寄せて合計一致)。flex-shrink:0
のアイテムは縮小対象外。layout::selftest() の measure ケースは 67 →
72 件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア
[OK])、build/fmt/clippy ゼロを確認。CSS Grid は2次元配置まで実装済みだったが、アイテムをセル内で整列する
justify-self(インライン=列軸)/
align-self(ブロック=行軸)と、コンテナ既定の justify-items /
align-items が未対応で、アイテムは常にセルへ stretch
されていた。これを実装した機能ユニット。os_lib/layout.rs。
grid_item_align(item, self_prop, items_default)
を追加。アイテムの justify-self/align-self が auto/未指定ならコンテナの
justify-items/align-items
値へ委譲し、start/end/center/stretch
に正規化(flex-start/flex-end/self-start/self-end/left/right
も吸収)。justify-items/align-items(既定
stretch)を取得。shift_layout_box により整列。width:auto
のブロックはセル幅を埋めるため整列の余地がなく start
相当(予測可能な挙動)。layout::selftest() の measure ケースは
61 → 67 件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア
[OK])、build/fmt/clippy ゼロを確認。letter-spacing を実装 —
文字幅計測・折返し・描画の全経路対応)letter-spacing は CSS
パーサに登録済みだったが計測にも描画にも未適用だった。文字間に
px(負も可)
を加える本プロパティを、テキスト計測→折返し→RenderElement→ピクセル描画の全経路へ通した横断的ユニット。既存の多数の呼び出し(string_width
23・wrapped_size 7・draw_string 22 箇所)を壊さないため、各 API に
_ls 派生を追加し旧 API は ls=0 で委譲する方式を採用。
get_string_width_ls /
get_string_wrapped_size_ls(VectorFont メソッド)と free
関数 get_vector_string_width_ls /
get_vector_string_wrapped_size_ls を追加。各文字 advance に
ls を加算(0 でクランプ)。折返し規則は従来と同一を維持。parse_letter_spacing(normal/未指定/不正→0、px・em 等は
parse_px_like 経由、負値可)を追加。intrinsic_inline_size
の Text 分岐で letter-spacing を読み取り
get_vector_string_wrapped_size_ls へ渡す。final_ls を抽出し、per-char advance(折返し)と nowrap
幅計算へ加算。生成する 4 箇所の RenderElement すべてに
letter_spacing: final_ls を設定。letter_spacing: i32 フィールド追加(Default=0)。draw_string_ja_size_ext_bg_ls(ls
引数付き)を追加。ベクター/フォールバック両経路で各文字 advance に ls
を加える。旧 draw_string_ja_size_ext_bg は ls=0 委譲。_ls 版へ切替え、el.letter_spacing
を渡す。layout::selftest() の extra
チェックに letter-spacing 計測の不変条件 4 件を追加(ls=0 は base 一致 /
ls=2 は base+n×2 / ls=-1 は base-n / parse_letter_spacing の
normal・px・負値・未指定・無単位)。フォント実体非依存の関係式で検証。QEMU
回帰で LAYOUT_SELFTEST: PASS(全12コア [OK])、build/fmt/clippy
ゼロを確認。align-content を実装 —
複数行フレックスの交差軸ライン配置)flex-wrap:wrap
の複数行レイアウト(layout_flex_wrapped)は実装済みだったが、生成した複数行ブロックを交差軸方向にどう配置するか(align-content)が未対応で、常に交差軸先頭から詰めるだけだった。これを
CSS
仕様の全値に対応させた機能ユニット。os_lib/layout.rs。
layout_flex
のスタイルタプルに align-content(既定
stretch)を追加し、layout_flex_wrapped
へ引数として伝播。total_cross とコンテナ交差長 container_cross
の差 cross_free を求め、align-content
に応じて各行の交差軸開始位置 line_cross_start[] と行サイズ
line_cross_size[] を確定してから配置。従来の「ループ内で
cross_cursor を逐次加算」を置き換え。flex-start/start、flex-end/end(末尾寄せ)、center、space-between(行間に均等分配)、space-around(行の上下に半分ずつ)、space-evenly(行間+端を均等)、stretch(既定:
余剰を各行高さへ均等加算、端数は先頭行)。layout::selftest() は 55 → 61 件。QEMU
回帰で LAYOUT_SELFTEST: PASS(全12コア自己テスト
[OK])、build/fmt/clippy ゼロを確認。従来 layout_grid は grid-template-columns と単純な行優先
auto-flow(列カーソルだけ)しか持たず、行は実測の最大高さで畳むだけだった。これを
CSS Grid
の2次元プレースメントモデルへ一気に拡張した機能ユニット。os_lib/layout.rs
を横断。
GridTrack
enum(Px/Fr/Auto)、split_top_level_ws(括弧内の空白を割らずトップレベル分割。string_slice
lint 回避のため char_indices + get
実装)、parse_one_grid_track(100px/2fr/auto/50%/minmax(a,b)
は max
側採用)、parse_grid_tracks(repeat(N,def) と
repeat(auto-fit|auto-fill,def) を展開)。grid_axis_placement):
grid-row/grid-column
ショートハンド(a / b)優先、無ければ
*-start/*-end longhand
を読む。ライン番号(1始まり→0始まりへ変換)と
span N、start / end からの span
算出に対応。戻り値 (明示開始 Option, span)。grid_ensure_row /
grid_cells_free / grid_mark):
Vec<Vec<bool>>
でセル占有を管理し、明示配置・auto-flow
双方で矩形(row_span×col_span)の空き判定と占有確定を行う。これにより
span したアイテムを避けて後続が次の空きセルへ流れる正しい auto-flow
を実現。grid-template-rows の px/auto/fr を確定(コンテナに明示
height がある場合のみ余白を fr へ分配)し、確定行 y
で再レイアウト。parse_grid_template_columns): repeat(3,100px)
のような固定 px
列定義を均等割り(avail_w/n)してしまっていた不具合を修正。固定 px
のときはその幅を尊重し、fr/minmax/%
のときのみ均等割りするよう分岐。layout::selftest() は
49 → 55 件。QEMU 回帰で LAYOUT_SELFTEST: PASS(全12コア自己テスト
[OK])、build/fmt/clippy ゼロを確認。CSS positioned
要素(position: relative/absolute/fixed)の後処理が
block コンテナ専用だった制約を解消し、flex / grid / table
の全フォーマッティングコンテキストで動くよう一気に拡張した機能ユニット。os_lib/layout.rs
を横断。
apply_positioned_offsets): block 専用だった positioned
後処理(relative=フロー確定位置から top/left もしくは bottom/right
符号反転でオフセット、absolute=最近傍 positioned 祖先 ABS_CB
基準、fixed=ビューポート原点基準、transform: translate
を最後に視覚シフト)を LayoutBox
の共有メソッドへ括り出し、全コンテキストから呼べるようにした。establish_abs_cb /
restore_abs_cb / child_is_out_of_flow):
positioned 要素が子孫 absolute の包含ブロック(ABS_CB)を自身の content
box
へ切替え、後処理後に復元する操作をヘルパ化。out-of-flow(absolute/fixed)判定も共通化。layout_flex): out-of-flow
子をフレックスライン計算(主軸測定・flex-grow 配分・cross
stretch・最終配置)の全ループから除外しつつ、サイズ確定のため layout
自体は実施。末尾で ABS_CB を確立し共有後処理を適用。layout_flex_wrapped):
フロー参加インデックスを flow_idx
で管理し、行分割・行内配置を位置(pos)ベースへ書き換え(flow_idx[pos]
で実子へマップ)。out-of-flow
を折り返し計算から除外して共有後処理を適用。layout_grid): out-of-flow
子がグリッドセルを消費しないようフロー配置から除外し、共有後処理で grid
を包含ブロックに配置。layout_table):
セルは行(tr)の grandchild のため、各行を包含ブロックとして行単位で
apply_positioned_offsets を呼び、relative
セル等のオフセットを適用。table 自体の positioned 後処理も実施。layout::selftest,
49→55件): ケース44〜49を追加 — flex 内 absolute
の配置とフロー外(兄弟が主軸先頭維持)/ flex 内 relative オフセット /
grid 内 absolute の配置とセル非消費 / table 内 relative セル。cargo build --release
成功、cargo fmt / cargo clippy --release
警告ゼロ(doc_lazy_continuation 1件を空行挿入で解消)、QEMU
ヘッドレスブートで全12自己テスト
PASS(LAYOUT_SELFTEST: PASS 含む [OK]、panic なし)。ブラウザ/ノートの描画パイプライン(os_lib/web_engine/layout.rs::parse_and_layout)が、JS
による DOM
変更やサイズ変更のたびに毎回フル再構築していた問題を緩和する機能ユニット。web_engine/mod.rs(状態フィールド)・os_lib/dom.rs(ヘルパ)・os_lib/layout.rs(セルフテスト)を横断。
usb_poll_thread(Core1=HID入力)が ntp_sync()
を同期ブロッキング呼び出ししており、最大約36秒キーボード/タブレットが固まる
#3「起動直後フリーズ」の根因。NTP処理を専用
net_service_thread
に分離し、HIDポーリングを二度とブロックしないよう構造修正(src/main.rs)。os_lib/js/bigint.rs の
BIGINT_SELFTEST が .unwrap() 18箇所で clippy
unwrap_used=deny に抵触し CI
が赤だった。check_opt(Option<String>
検証)/check_bool ヘルパ経由に書き換えて unwrap
を全廃。dom_needs_rebuild または HTML
変化)でのみ画像キャッシュを破棄。JS
変更によるインクリメンタル再レイアウトでは保持し、毎回の画像再フェッチ暴走を防止。<style> 連結文字列をキーに parse_css
結果(StyleSheet)をキャッシュ(cached_css_key
/
cached_stylesheet)。同一なら再パースを丸ごと省略でき、大きなスタイルシートで効く。built && dirty && !dom_needs_rebuild)の時、最終描画ツリーは
to_dom_node() から作られ parse_html
の結果は破棄されるため、再パース自体を Node::empty_root()
プレースホルダで省略。layout::selftest, 46→49件):
キャッシュ再利用の正当性を担保する3件 — (a)
レイアウト決定性(同一入力→同一出力)/ (b) キャッシュ済み StyleSheet
clone が再パースと同結果 / (c) Node::empty_root() が子なし
html 要素。cargo build --release
成功、cargo fmt / cargo clippy --release
警告ゼロ、QEMU ヘッドレスブートで全自己テスト
PASS(LAYOUT_SELFTEST: PASS 含む全12項目 [OK]、panic
なし)。ブラウザ JS エンジンの DOM
イベントを、本物のブラウザに近い標準プロパティ・イベント種別まで一気に拡充した機能ユニット。os_lib/web_engine/render.rs(発火)と
os_lib/js/interp.rs(イベントオブジェクト生成)、kernel/keyboard.rs(修飾キー状態)を横断。
kernel/keyboard.rs が AtomicU8(bit0=Shift /
bit1=Ctrl / bit2=Alt /
bit3=Meta)で修飾キー状態を公開。decode()
の特殊キー処理で同期し、main.rs の入力パイプラインから JS
層が参照可能に。interp.rs):
button / buttons / detail /
offsetX / offsetY / movementX /
movementY +
修飾キー(shiftKey/ctrlKey/altKey/metaKey)を付与。dispatch_mouse_full(button, wheel)
を追加。interp.rs): 標準の
key /
code(KeyA/Digit1/Enter/ArrowLeft
等)/ keyCode / which / charCode
/ location / repeat +
修飾キーを付与。特殊キー(Enter/Tab/Backspace/Escape/Arrow*/Home/End/PageUp/PageDown/修飾キー)を標準
code と legacy keyCode
へマッピング。dispatch_key_full(repeat) を追加。render.rs):
keypress(文字生成キーのみ、keydown 直後)/
wheel(ヒット要素へ発火、preventDefault
でスクロール抑制)/
focusin・focusout(focus/blur
のバブリング版)。WindowMgrApp::on_mouse トレイトに btn_right
を追加し、全 9
実装(browser/note/drive/music/settings/canvas/files/keymap/user_win)+
window_mgr.rs::handle_mouse + main.rs
のマウス/タブレット両入力経路を更新。MouseEvent.right_btn(mouse.rs
で 0x02 検出済み)を末端まで伝搬。エンジンに
prev_btn_right を追加し、右ボタン押下エッジで
contextmenu を発火。bubbles フラグに関わらず全イベントを capture→target→bubble
の 3
フェーズで祖先まで伝播させる設計(イベント委譲を成立させるため)。初回テストで
focus 非バブリングを前提にした 1 件が FAIL
したため、テストを実装の契約(委譲成立)に合わせて修正。js/mod.rs): 16
ケースを追加 — 基本発火 / 複数リスナ順序 / removeEventListener /
バブリング / target・currentTarget / stopPropagation /
stopImmediatePropagation / preventDefault 戻り値 / defaultPrevented /
once / capture フェーズ / type 転送 / カスタムプロパティ(detail) /
型不一致非発火 / イベント委譲。cargo build --release
成功、cargo fmt / cargo clippy --release
警告ゼロ、QEMU
ヘッドレスブート(-display none -serial stdio)で全自己テスト
PASS(JS_SELFTEST / AURA / CSS /
LAYOUT / IME / CLOUD /
H264 / H264_GOLDEN / RECLOCK /
FS / USBSCHED すべて [OK])。www.google.com ロード中/直後に GUI
全体が超スローモーション化(事実上フリーズ)するバグの修正。 (旧
spec/task.md / spec/walkthrough.md /
spec/implementation_plan.md
の単発タスク3ファイルを本ログへ統合。spec
運用ルール「ファイル数を増やさない/完了タスクは本ログへ圧縮記録」に従い、それらは削除)
yield_now() が他に Ready
タスクが無いと即座に実行権を返すため CPU を 100%
占有(ビジースピン)。これが Core 0 の GUI メインループ(本来 16ms
周期)の実行隙間を奪い、描画が数秒〜数十秒に 1
回しか回らなくなっていた。yield_now() を scheduler::sleep(1)(1 tick =
10ms)へ移行し、待機スレッドを Waiting 状態へ遷移させて CPU
を解放。interrupt.rs の FIFO を
spin::Mutex<Fifo<N>> 化し、usb.rs
の push と main.rs の pop を .lock()
経由に統一。setInterval/clearInterval の検証を、登録 eval
→ イベントループ実行 → 再 eval で状態確認する 2
段階評価に分離し、非同期タイマーを正しく検証(JS_SELFTEST
PASS)。make
でクリーンビルド、./test_google_verbose.sh で
JS_SELFTEST: PASS とロード後の GUI 描画継続を確認。⚠️ 既知の不整合(2026-06-26 spec 整理時に発見・要確認): 上記タスクは当時の単一ファイル
src/kernel/net.rsに対して実施されたが、その後のリファクタ(コミットb99becde「src整理と分割」)でnet.rsがsrc/kernel/net/配下へ分割された。現状コードではnet/tcp.rsはsleep(1)済みだが、net/dns.rsのdns_query_a_via_udp(57行付近)・ntp_query(99行付近)、net/icmp.rs・net/arp.rsにはyield_now()が残存している。分割時に sleep 移行が一部引き継がれなかった可能性が高い。TODO.md の P0 として再修正対象に登録済み。
actions/checkout@v6
に更新しました。AppManifest に
width と height
フィールドを追加し、manifest.json
から安全にパース可能にしました。parse_launch_options
と、それを用いてウィンドウ生成と登録を一元化する
create_and_register_window
を実装。未指定時はデフォルトで最大化、サイズ指定時は自動で通常表示になります。youtube.com
入力時にローカルテストページへリダイレクトする処理を解除し、デフォルトホームページのリンク先も公式URLに変更。ping
組み込み関数でホスト名を指定した際、IPパースに失敗した場合に自動でDNS解決を試みるようにフォールバック処理を実装。window_mgr.rs, h264_decode.rs
等)の境界チェックや unwrap
回避部等に丁寧な日本語の解説コメントを付加。また、net.rs
および parser.rs を精査して安全性を点検。「本物のサイトを表示したい」という要望に対し、Chromium 級は規模・DRM 的に非現実的と正直に 共有した上で、毎ターン「実在サイトがより動く具体的 1 機能」を自己テスト検証付きで積む長期 キャンペーンを実施。各機能はビルド警告ゼロ + セルフテストで非回帰を確認。最終: JS 220 / CSS 38 / LAYOUT 24 全 PASS、クリーンビルド警告ゼロ。
layout::selftest()(LAYOUT_SELFTEST)を新設。
html+css を固定幅でレイアウトし要素の矩形 (x,y,w,h) をビット検証(H.264
ゴールデン方式の レイアウト版)。data: URL 対応で fetch/XHR
をネット非依存にオフライン検証。fetch(GET/POST、options.method/body/headers、data:)、XMLHttpRequest
(同期取得 + onload/onreadystatechange 発火)、相対 URL
解決(Interp.base_url を現在ページ URL
から導出、builtins::resolve_url)。HTTP は同期 GET/POST
プリミティブ(web_get/web_post)。window/document.location(href/protocol/host/hostname/pathname/search/hash/
origin、3
参照で共有オブジェクト)、history.pushState/replaceState(location
を再読込なしで 書換え、Interp.global 経由で共有 location
更新。SPA ルーティング)。dataset
の camelCase↔︎ data-* 変換)、セレクタ(matches/closest/要素スコープ
querySelector(All))、ツリーナビ
(parentElement/children/sibling/firstElementChild
等)、ミューテーション(insertBefore/
replaceChild/cloneNode・classList.replace)。dispatch_click→dispatch_event に一般化し
target→祖先のバブリングを実装
(イベント委譲が動作)。共有 Event に
target/currentTarget/defaultPrevented +
preventDefault/stopPropagation/stopImmediatePropagation。height/min-height(従来は内容フロー高さのみで無視)、flexbox
の
align-items:stretch(既定値)・flex-grow/flex:1、position(relative/absolute/fixed、
最近傍 positioned 祖先への昇りを ABS_CB static で実現、fixed
は描画側でスクロール非追従)、 overflow(hidden/scroll/auto
の coarse クリップを子孫インデックス範囲へ後付け)。旧モック(「簡易レンダリング(模倣)」)を撤去し、src/os_lib/h264_decode.rs
に本物の Baseline H.264 デコーダを実装。ffmpeg/x264
出力とビット完全一致を達成。
src/os_lib/h264_golden.rs
に埋め込み、デコード結果をリファレンス YUV とビット比較
(h264_decode::golden_test() を起動時実行、計11素材すべて全
YUV 一致)。CAVLC テーブル・ デブロック閾値・CBP マップは ffmpeg
ソースから機械生成し、手作業転記の誤りを排除。mp4.rs が avcC から
SPS/PPS と NAL 長さサイズを抽出。h264_decode::VideoDecoder
(参照フレーム保持)が AVCC サンプルを復号し、YUV→RGB(BT.601)を
web_engine::video_playback_thread
の共有フレームへ供給(旧モック
h264.rs::decode_access_unit_avcc の呼び出しを置換)。(...)
をリストリテラルとして評価するよう
src/os_lib/aura/eval.rs を修正(旧実装は全
AST::List を関数適用していた)。関数呼び出しは
func(a, b) 形式のみ。obj.key を
src/os_lib/aura/parser.rs でサポート(コロン
obj:key と等価。内部で (get obj "key")
に変換)。net.udp("send", ...) でリスト (1 81 0 0)
によるバイナリ送信に対応(src/os_lib/aura/builtins.rs)。spec/AURA.md
を大幅詳細化(関数呼び出しの唯一形式、辞書/リスト、エラーハンドリング、用例)。autofocus
を付与し、起動時に即入力可能化。src/os_lib/cloud.rs に Drive 読み書き REST(download /
Docs export / multipart upload / update /
delete)、デバイスフロー駆動、gdrive_auth.json
永続化を追加。CLOUD_SELFTEST 25/25。src/apps/drive/mod.rs を新規作成(Drive↔︎ローカル FS
の2ペイン GUI)。os.launch_gui("drive")
配線とアプリレジストリ登録。h264.rs
は「簡易レンダリング(模倣)」のモック。撤去して再実装):
src/os_lib/h264.rs: BitReader + Exp-Golomb、RBSP
脱エミュ、NAL 分割(Annex-B/AVCC)、SPS/PPS 実パース(avcC
抽出)、逆量子化 + 4x4 整数 IDCT、イントラ予測(輝度 4x4/16x16・クロマ
8x8 全モード)。H264_SELFTEST 39 件(実 x264 SPS
でも検証)。src/os_lib/mp4.rs:
stsd→avc1→avcC
抽出を追加。src/os_lib/web_engine.rs: avcC から
SPS/PPS・NAL 長さを取り込み decode_access_unit_avcc
で復号する配線。src/os_lib/h264_decode.rs(新規): CAVLC
残差復号(coeff_token nC<2 + chroma
DC、level、total_zeros、run_before)、スライスヘッダ、I_16x16 MB、輝度
DC Hadamard、再構成。src/os_lib/h264_golden.rs(新規): ffmpeg/x264
で生成した検証素材(単色・testsrc、deblock=0
cabac=0)。golden_test() を起動時実行。H264_GOLDEN flat: Y 256/256 match(ffmpeg
リファレンスとビット完全一致)。CAVLC 中核と再構成を非循環に実証。spec/TODO.md(H.264
段階チェックリスト・優先順位)、spec/DESIGN.md
§9.1(実デコーダ状況)、spec/INVENTORY.md(Drive/H.264
追加)、spec/README.md(Phase 7/8
の状態を正確化)を更新。src/os_lib/mp4.rs, src/os_lib/h264.rs,
src/os_lib/mp3.rs
を新規追加(または安定化)し、no_std の Rust
ネイティブで動作する mp4 Demuxer, H.264 ビデオデコーダ, MP3
オーディオデコーダを登録して公開。src/kernel/audio.rs を修正し、HDMI出力用の I2S (PCM)
コントローラと DMA 4 転送を有効化。デコードされた 16-bit PCM
をアナログ(8ビット PWM 転送 / DMA 3)とデジタル(16ビット I2S / DMA
4)に同期供給するデュアルオーディオ同期転送を実装。src/kernel/net.rs
を修正し、youtube.atmos-project.org をゲートウェイ
10.0.2.2 に静的解決。接続ホストから :port
を分離する parse_host_port
を実装し、ポート番号付きHTTP接続を可能にしました。src/os_lib/web_engine.rs
を修正し、動画要素クリック時に非同期デコード再生スレッド
video_playback_thread
を起動。デコードされた映像フレーム(RGB)を WebEngine::draw
から Nearest Neighbor
拡大縮小でウィンドウに描画し、ページ遷移時に消音とスレッドの停止を保証。src/apps/browser/mod.rs を修正し、アドレスバーで
youtube.com
等が入力された際のリダイレクト処理、内蔵ホームページへのリンク追加、および動画再生中のタイマー再描画ループの維持
(needs_timer_redraw) を実装。src/kernel/window.rs を修正し、不要となった CPU 使用率
(C) およびメモリ使用量 (R) 列の表示を廃止。Info 列の開始位置を左側の 55%(以前の CPU
列の位置)へ詰め、プロセス引数やURL情報を長文で広く確認できるように変更。src/os_lib/aura/eval.rs にあった unclosed delimiter
{
(リストリテラル評価への誤った早期リターンによる構文エラー)を修正し、組み込み関数
os.run の呼び出しを含む Aura
インタプリタが正しく機能するように復元。README.md、spec/README.md、spec/DESIGN.md
の設計仕様、および spec/WALKTHROUGH_COMPLETION_LOG.md
の開発ロードマップと変更内容を最新の Phase 8
としてアップデート完了。make clean && make でのカーネルビルド、および
expect test_browser.sh によるシリアル自動テストが完全に
PASS(TEST_PASSED)することを確認しました。spec/INVENTORY.md
を新規作成し、現在のリポジトリ構成やファイルの担当機能、テスト構成を棚卸しして整理。arm/v1/DEVELOPMENT_NOTES.md
を最新のディレクトリ構成、実装・バグ修正状況に合わせて上書き更新。[1] から 1)
に変更して表示幅を節約。\n
または6文字自動折り返し)による最大2行描画を実装。マウスのクリック・クローズ座標判定を間隔42pxベースに修正。ColorTheme
に「Custom」テーマを追加し、選択時に詳細色(デスクトップ背景、ウィンドウ枠、タイトルバーなど7項目)の
R/G/B 各値を ◀/▶ ボタンで +/-16 ずつ変更できる調整 UI
とプレビューを実装。/os/config.json 内で
custom_colors オブジェクトとして保存・復元できるように
config.rs を改修。FontOrder タブにフォントフォールバック設定を移植。make および Expect スクリプト
./test_browser.sh(EL0アボート検知、ログイン、DuckDuckGo
HTTPS通信などを含む全自動回帰テスト)が正常に PASS することを確認。btree.rs::insert_recursive
が内部ノードでも キー一致時に子ポインタを上書き →
右部分木を破壊。葉ノード限定の上書きに修正、内部は右へ降下)。 ②
read_file
のメタデータ無境界添字(data_sectors[i] に
i < MAX_FILE_SECTORS を追加)。 ③ block 層の
crc_stored != 0 条件が CRC=0
の正規データを破損誤判定(条件を == のみに)。fs::selftest() 新設(B-Tree
分割後の全キー上書き整合 3 + 二重化自己修復/両系破損検知 3 = 6
ケース)。 起動時 FS_SELFTEST: PASS 6/6、test_browser.sh に
CI ガード追加。①の修正を一旦戻すと FS_SELFTEST が FAIL
することを確認し、テストが回帰を捕捉できることを検証済み。mount() は RAMDisk
を毎起動生成し揮発するため、COW の電源断耐性は永続バックエンド
導入時に効く性質。上書き保存は旧セクタを解放しないため永続化時はリーク回収が別途必要(TECHNOTE
§13)。os_lib/js/)に残っていた
unwrap_used = deny 違反 5 件
(lexer/parser/builtins/regex)を安全形に修正。cargo build
は通るが cargo clippy が失敗していた。manual_clamp→.clamp()、manual_strip→strip_prefix、
legacy_numeric_constants、field_reassign_with_default、vec_init_then_push、ptr_arg、
sliced_string_as_bytes、while_let_loop、match
ガード化、missing_safety_doc、transmute 注釈、
if_same_then_else
のブロック統合)と、ベアメタル特有の意図的パターン(needless_range_loop/
too_many_arguments/type_complexity 等)の
#で対応。
cargo build・cargo clippy
ともエラー0/警告0。clippy::string_slice をクレート全体で
#: 段階導入を完了し全面施錠。
全 100 箇所の &str バイト境界スライスを
find()/strip_prefix() 由来 or
str::get で撤去。
副産物として実潜在パニックも除去(&resp.body[..96]×3・&html[..120]・resolve_css_var
末尾 var()。os_lib/aura・apps/terminal/shell.rs)へ更新。JS 133/133・CSS 36/36・IME 18/18・CLOUD 16/16・RECLOCK PASS、
DDG ロード成功・KERNEL PANIC 0。kernel .text は約 2.39MB /
4MB 制約内(ヘッドルーム約 1.6MB)。panic=abort で unwind
が無く、ロック保持中にプロセスが死ぬと MutexGuard の Drop
が走らず ロックが永久保持→以後デッドロック(OS
が静かに壊れる)問題に対処。kernel/reclock.rs を新設: 保持コア ID
を記録する
RecoverableMutex<T>(lock/try_lock/
force_release_if_core(cid))。NET_LOCK(net.rs)・USB_LOCK(usb.rs)
を置換。ヒープアロケータの Locked
にも保持追跡+強制解放を追加(独自 spin に force_unlock
を実装)。#[panic_handler] の最初に
allocator/net/usb::force_release_*(cid)
を呼び、当該コアが保持中の
ロックだけ解放(他コアの正当な保持には触れない)。ヒープロックは直後の
println!(=確保) が取りに
行くため最優先で解放し、ハンドラ自身のデッドロックを防ぐ。reclock::selftest()(leak
で取得不能→誤コア指定では解放されず→正コア指定で再取得可)を追加し
起動時 RECLOCK_SELFTEST: PASS(test_browser.sh で CI
ガード)。QEMU 全 selftest PASS・スモーク PASS。apps コマンド刷新 + terminal
エイリアス: builtin_apps
を重複行排除(/apps/ 配下の全ファイルから
アプリ名を一意集合化。旧実装はファイル毎に行を出していた)+整形(Name/Version/Display/Run・実行方法表示)。
os.apps に加え bare apps を top-level builtin
として登録(ls/help と同様)。vector_font::VectorFont に
fallbacks: Vec<Face> を追加し、get_glyph
がプライマリ→フォールバック順にグリフ所有 face を探索(外部 API
不変、draw.rs 等は無変更)。フォント レジストリ
font_bytes(name) / AVAILABLE_FONTS /
DEFAULT_FONT_CHAIN を新設し
init_global_font_chain でチェーン構築。config
を単一 font_name → font_names:[String;3]
へ(JSON font_names 配列、旧 font_name
後方互換)。既定: Mplus1Code-Regular → HackGenConsoleNF-Regular →
ipam。埋め込みフォント 追加でイメージは 26→45MB(.rodata。.text
制約には無関係)。PRESET_THEMES.len() 基準に修正。["Mplus1Code-Regular","HackGenConsoleNF-Regular","ipam"](3
fonts)初期化・ PANIC 0・スモークテスト PASS。os_lib/js/ に本物の JS エンジンを新設
(lexer/parser/ast/value(Rc参照カウント)/interp(ツリーウォーク)/builtins)。<script>/onclick
の実行を Aura(Lisp系)→JS へ切替(Aura は .aura
用に存続)。実用コア言語(変数・関数・クロージャ・制御
構文・全演算子・オブジェクト/配列・try-catch・アロー)+
console/Math/JSON/Object/Array/String/Number。
協調シングルスレッドのためステップ予算・再帰深度上限で無限ループから
OS を保護。起動時 js::selftest() →
JS_SELFTEST: PASS(CI ガード)。以降のセッション 7-b〜7-g
で Map/Set・分割代入・class・Promise/async・ generator・RegExp・DOM
動的ノードまで拡充(各セッション記録参照)。詳細設計は
DESIGN「JavaScript エンジン」。keys
配列容量が不足し領域外アクセス。keys/values を
+1/+2 拡張(計
508B=1セクタ、静的アサート付き)し、split_node
を葉=B+Tree/内部=B-Tree で正しく分割。.text 2MB 境界パニック +
scheduler::exit() UAF 修正(06-15、TECHNOTE §12):
JS エンジンでバイナリ肥大→kernel .text が 2MB を越え block1
へ。ユーザーページテーブルが block1 を EL0
アクセス可のままにしていたため EL1
命令フェッチが変換フォルト。.user_text(0x400000) 未満を EL1
専用に マップして解決。併せて exit()
が実行中の自カーネルスタックを所有 Process ごと即 drop していた
use-after-free を、墓場(ZOMBIES)退避→文脈切替後 reap 方式へ修正。apps/note/mod.rs):
タブごと独立ファイル名/内容/未保存フラグ、Ctrl+S/N/W/O、 未保存
* マーカー、NoteApp::open_file
で外部起動。os_lib/cloud.rs を新設し、ヘッドレス OS 向けの
OAuth2 デバイスフロー + Google Drive / GitHub REST の
リクエスト構築・JSON
解析を実装。url_encode/form_encode、parse_token_response(access/refresh/expires/
error)、parse_device_code(Google
verification_url/GitHub verification_uri
両対応)、Google/GitHub の token/device body
構築、parse_drive_file_list→DriveFile、parse_github_user/parse_github_repos。kernel/tls.rs に
https_request(method, host, path, extra_headers, content_type, body)
を追加(Authorization: Bearer
等の任意ヘッダ・任意メソッド)。既存
https_get/https_post は無改変で DDG
経路に回帰なし。live 関数
oauth_post/api_get/drive_list_files/github_get_user/github_list_repos
も用意。cloud::selftest()(16 ケース)で
CLOUD_SELFTEST: PASS 16/16、test_browser.sh に判定追加。
JS 133/133 + CSS 24/24 +
IME 18/18 + DDG 回帰なし。ime::selftest()(ローマ字→かな 13 + かな→漢字
5)を新設したところ、konnichiha→こんいちは(「に」欠落)の
実バグを検出。原因は ①("nn","ん")
テーブル項が n を 2 文字消費して次母音と結合できない、②促音規則
bytes[0]==bytes[1] が nn を っ
化しうる、の二点。修正: テーブルから nn を削除、促音規則を
n 除外、 starts_with_n_before_consonant
の除外集合から n を外して「nn は撥音+n を 1
つ消費」に統一。
konnichiha→こんにちは、annai→あんない
を確認。handle_enter の candidates[selected_idx]
直接添字を get(...).unwrap_or(kana)
にしてパニック安全化。IME_SELFTEST: PASS 18/18、test_browser.sh
に判定追加。JS 133/133 + CSS 24/24 + DDG
回帰なし。css::apply_text_transform(uppercase/lowercase/capitalize)を
flatten のテキスト出力に適用。 INHERITED_PROPS に追加し継承。RenderElement.list_style_type を追加。flatten の li 出力で
extract_list_style(list-style
ショートハンドも解釈)から設定し、マーカー描画で
none(非表示)/disc(•)/circle(◦)/square(▪)/decimal(番号)
を分岐。継承対応。layout_flex に
parse_flex_gap(gap/row-gap/column-gap)を導入。主軸合計(n-1
箇所)と 配置オフセットに gap を加算。css::selftest を 29→36 に拡張(text-transform
関数4+継承1、list-style-type 継承1、flex gap カスケード1)。
CSS 36/36 + JS 133/133 +
IME 18/18 + CLOUD 16/16、DDG 回帰なし、警告
0。!important)Declaration に important: bool
を追加。parse_css で値末尾の
!important(大小無視)を切り出して格納。compute_styles_with_vars)の採用判定を
(important, specificity, source_order) 比較に変更。
!important は非 !important
に特異度を問わず勝ち、同 important 同士は特異度→ソース順。css::selftest
に値検証ケース(プロパティの最終値を確認)を 5 件追加し
24→29、CSS_SELFTEST: PASS 29/29。 ※インライン
style
属性は従来通り最後に適用(インライン優先)。!important
のインライン適用は今後の課題。css.rs のセレクタを拡充: 属性セレクタ
[attr]/[attr=v]/[^=]/[$=]/[*=]/[~=]/[|=]、
:nth-child(an+b)(odd/even
含む)/:nth-last-child、ユニバーサル
*、:not(simple)。
SimpleSelector に
attrs/universal、PseudoClass に
NthChild/NthLastChild/Not
を追加。
関数形式疑似クラスの括弧引数パース、属性照合(大小無視フォールバック)、nth
判定(a*n+b, n>=0)を実装。 セレクタチェーン分割は
[]/() 入れ子内で結合子を区切らないよう depth
追跡。specificity も attrs を加算。css::selftest()(19 ケース:
属性各演算子・nth-child/last/odd/even/式・not・universal・複合)を新設し、
起動時に CSS_SELFTEST: PASS 19/19 を出力。test_browser.sh
に判定を追加。+/~:
Combinator::NextSibling/SubsequentSibling
を追加。chain 照合で兄弟内インデックス cur_sib_index
を追跡し、親(ancestors 末尾)の children
から先行する要素兄弟を逆走査して照合(+ は直前の
要素兄弟のみ、~
は先行要素兄弟いずれか)。[attr~=v] の ~
と衝突しないよう chain 分割は [] 内を depth 保護。JS_SELFTEST 133/133 +
CSS_SELFTEST 24/24、QEMU で DDG
フルレンダリング回帰なし。last_html
を再パース → apply_overrides で同順走査して JS
の変更を焼き戻す」
方式で、ノード追加/削除を表現できなかった。DomBridge
を唯一の真実源へ変更し、parse_and_layout
は 初回に bridge を構築した後、毎レイアウトで
bridge.to_dom_node()(アリーナ→dom::Node
再構築)から描画。 これで textContent/style/class
に加え動的ノードも自然に反映され、apply_overrides
は不要化。QEMU で DDG が
従来同様フルレンダリング(body_len=2070)することを確認し回帰なし。document.createElement/createTextNode、要素の
appendChild/removeChild/remove、
innerHTML=(フラグメントを parse_html して
import_node
で取り込み子を置換)、document.body/head/
documentElement(bridge.query)。textContent=
はテキスト子が無ければ新設するよう改良。createElement 直後や
remove 済みのノードは node[0]
から非到達。get_element_by_id/
query/query_all を
is_attached(親チェーンが node[0]
へ到達するか)でフィルタし、デタッチ済みを除外。JS_SELFTEST: PASS 133/133、QEMU
スモークテスト PASS。<script> は実行しない。function*/yield/yield*、is_generator
を Function/FunctionDeclaration/ FunctionData
に追加。呼出時に本体を同期実行し Interp.gen_collector へ
yield 値を収集して ObjKind::Generator
(GenState{values,index,returned})を返す。.next()/.return()、iterable_values/iterate_values
経由で for-of・spread
反復。無限ループはステップ予算で打ち切り。.next(v)
の値受け渡しは未対応。Rc<RefCell<VecDeque<(cb,args,id)>>>
のマクロタスクキューを runtime/Interp で共有。
setTimeout/setInterval(一発)/clearTimeout/clearInterval/queueMicrotask。run_event_loop
(マイクロ→マクロ1つ→繰り返し)で eval/クリック後に駆動。await
もマイクロ枯渇時にマクロを 1 つ進める。os_lib/js/regex.rs
にバックトラッキング
VM(命令列へコンパイル→再帰実行、実行予算で暴走防止)。
文字クラス/範囲/\d\w\s\b・量指定子
*+?{n,m}(貪欲/非貪欲)・グループ
()/(?:)・選択 |・アンカー
^$・後方参照、フラグ
gims。ObjKind::RegExpObj。new RegExp()
と正規表現リテラル /.../flags (lexer に prev
トークン追跡を足し除算と判別)。test/exec、String
の match/matchAll/replace
($&/$1/関数リプレーサ・g
全置換)/split/search。JS_SELFTEST: PASS 125/125、QEMU
スモークテスト(DDG lite)PASS。iterate_values が
Generator 未対応)も修正。ObjKind::PromiseObj(Rc<RefCell<PromiseState>>)・Resolver{state,reject}
を追加。
PromiseState(status/value/reactions)・Reaction・Job(マイクロタスク)を
value.rs に定義。JsRuntime と per-eval Interp
が Rc<RefCell<VecDeque<Job>>>
のマイクロタスクキューを共有。resolver は callable として
call_value_inner で
promise_resolve/reject にディスパッチ。promise_resolve(thenable
採用)/promise_reject/promise_then(派生
Promise・
反応の登録/スケジュール)/run_microtasks/run_one_microtask/await_value
を実装。then/catch/finally は
get_property でメソッド dispatch(builtins)。async/await
キーワード。Expression::Await、Function/
FunctionDeclaration/FunctionData に
is_async。async function(宣言/式)・async ()=>/async x=>
アロー・ await expr をパース(try_parse_arrow に async
接頭辞+pos 巻き戻し)。async 関数は同期実行し結果/例外を Promise に
包んで返す。await
は到達可能なマイクロタスクを駆動して解決まで進める(イベントループ無しの同期完結モデル)。
トップレベル await も可。マイクロタスクは eval/クリックディスパッチ後に
drain。Promise(executor)・Promise.resolve/reject/all(駆動して集約)。JS_SELFTEST: PASS 104/104、QEMU スモークテスト(DDG
lite)PASS。setTimeout・generator
は無し。外部非同期に依存する未解決 Promise の await は undefined
を返す。Expression::Class(name/superclass/members)・Expression::Super・ClassMember・MethodKind
を追加。parse_class で
constructor・メソッド・static
メソッド・extends をパース。クラス宣言は
let Name = class ...
相当へ脱糖、クラス式・super プリミティブも対応。eval_class
がクラスを「コンストラクタ関数+prototype(メソッド置き場)」へ脱糖。継承時は
prototype.proto に基底 prototype を、コンストラクタ obj の proto
に基底コンストラクタ(static 継承)を接続。 new
がインスタンスの proto をコンストラクタ prototype
に設定(メソッド解決)。super(...)/super.method()
は メソッド closure(class_scope)に仕込んだ
__superclass__ 経由で現在 this
のままディスパッチ。デフォルト コンストラクタは継承時に
super(...arguments) を自動呼出。new X(...).method() が
new の後続メンバ/呼出チェーンを消費せず壊れていた問題を、
parse_call_member から parse_call_member_tail
を抽出し parse_new 末尾で継続する形で修正。JS_SELFTEST: PASS 90/90、QEMU スモークテスト(DDG
lite)PASS。instanceof
のクラス対応・private フィールド。Pattern(Identifier/Object/Array)・Param(pattern+default+is_rest)・Property.computed
を 追加。FunctionData.params: Vec<String> →
Vec<Param>、VarDeclaration.decls
の左辺・ForIn を Pattern 化 (ForIn.name →
pattern)。"...name" 文字列規約のレスト引数は
Param.is_rest に置換。parse_pattern/parse_object_pattern/parse_array_pattern
を新設。オブジェクト {a, b: c, d = 1, ...rest}
(別名・デフォルト・ネスト・rest)、配列
[a, , b = 1, ...rest](穴・デフォルト・rest)、デフォルト引数
function(a, b = 10)、引数の分割代入
function({x,y})/([a,b])、算出キー
{[expr]: v}、for-of の分割
for (const [k,v] of ...) を対応。bind_pattern(オブジェクト/配列/rest/デフォルト値を再帰束縛)を追加し、var
宣言・関数引数・for-of で 共通利用。デフォルト引数は実引数 undefined
時に評価。算出キーは object リテラル eval で
to_property_key 化。JS_SELFTEST: PASS 82/82、QEMU スモークテスト(DDG lite
ロード)PASS。class(+継承)、Promise/async/RegExp 等。switch 文: lexer に
switch/case/default
キーワード追加。AST に
Statement::Switch+SwitchCase、 parser
parse_switch、interp は discriminant を
strict_eq で照合→マッチ無しは default、フォールスルー+
break で離脱。...
トークン追加(当初 SYMBOLS に未登録で全 spread
が失敗→追加で解決)。 Expression::Spread
を導入し、配列リテラル [...a]・呼出引数
f(...a)(eval_arguments で展開)・オブジェクト
{...o}(番兵キー
OBJECT_SPREAD_KEY)で展開。レスト引数は params に
"...name" 規約で格納し、call_value_inner
で残余を配列束縛。ObjKind::MapObj(Vec<(Value,Value)>)/SetObj(Vec<Value>)(挿入順保持)。Map/Set
コンストラクタ
(new Map([[k,v]])/new Set([..])
初期化)、メソッド(Map: set/get/has/delete/clear/forEach/keys/values/
entries、Set: add/has/delete/clear/forEach/values)と size
を interp の get_property でディスパッチ。キー等価は
SameValueZero 近似(NaN===NaN)。for-of・スプレッド共通の
iterable_values(配列/文字列/Set/Map 展開)も追加。JS_SELFTEST: PASS 65/65、 QEMU スモークテスト(DDG lite
ロード)PASS。class・デフォルト引数・算出キー・Promise/async/RegExp
等は次段。os_lib/js/dom_bridge.rs
を新設。dom::parse_html
をドキュメント順にフラット化した軽量アリーナ +リスナ表を
JsRuntime が
Rc<RefCell<DomBridge>>
で保持(ページ寿命で永続、クリックリスナを保持)。 実装 API:
document.getElementById/querySelector/querySelectorAll(#id/.class/tag)、
要素の
textContent/innerText/tagName/id/className、style.*(camelCase→kebab)、
classList.add/remove/toggle/contains、getAttribute/setAttribute、addEventListener('click', fn)。
interp の get_property/set_property で
DomElement / style / classList プロキシを動的ディスパッチ。apply_overrides(text/class/style を焼き戻し)してから 既存
CSS カスケード/レイアウト経路をそのまま再利用。web_engine
の on_click でヒット要素 id→ブリッジ
idx→dispatch_click 発火、relayout_if_dom_dirty
が executing_script ガード下でスクリプト再実行を
抑止しつつ再描画。JS_SELFTEST: PASS 49/49。QEMU
スモークテスト(DDG lite ロード)PASS。display: table/table-row/ table-cell/table-row-group と
<table><tr><td><th>
を実装(layout.rs::layout_table、 列幅 intrinsic
基準・行高さ揃え)。layout_block が BlockNode 以外で早期
return しセルが (0,0) に積む不具合も修正。QEMU で表描画を確認。tls::https_post +
net_stack::web_post 振り分け実装。 ②決定打は TLS
受信バッファ 16384 が DDG の大レコード(16640)で溢れ
InsufficientSpace → read_buf を 18432
に拡大。③autofocus 対応・on_mouse 二重送信修正・read タイムアウト 15
秒化。 pcap で「サーバ 29KB 応答済み・ACK 済みなのに TLS 0
バイト」を観測して特定。QEMU で 467 要素の
検索結果レンダリングを確認。WebEngine
を持つ完全分離方式へ。core::mem::swap で
クローン・再取得なしの切替。QEMU
で検索結果が切替後も再取得ゼロ(ロード回数 4→4)で保持される
ことを確認。vector.S の el0_exception_return が
sub sp,#800 に対し add sp,#288 しか戻さず、EL0
例外ごとにカーネルスタックが 512
バイトずつ降下し隣接ヒープを破壊していた。q0-q31 復元追加 +
add sp,#800 で修正。 起動時 100% 再現の破損が 0 件に(§7
を「根治済み」へ更新)。Result<_, &'static str> の
意味あるメッセージ付きに。該当 clippy 警告 12→0。main.rs で UART_FIFO をドレインし
keyboard::ascii_to_scancode(レイアウト総当たり逆引き)で合成スキャンコード化
→ 物理キーボードと同一パイプラインへ。test_browser.sh
を実動作に書き直し、 ci.yml に qemu-smoke-test
ジョブ追加(user-mode netdev で sudo 不要)。QEMU で TEST_PASSED。<style>html{margin:0}</style> +
width/height: 100% 化、余白帯を撤去% 寸法解決にビューポートヒント
(set_viewport_hint) を導入cargo clippy --fix 一括適用で警告 324 → 95 件(残りは
API 形状の提案系)
map_entry lint の自動修正が
std:: パスを生成し全体が
ロールバックされる。-A clippy::map_entry で除外し手動で
alloc:: パスに修正WebEngine::wrap_editor_lines +
vector_font::get_vector_char_width に一元化allocator::check_heap_integrity()(物理走査 canary
診断)を実装、USB ポーリング スレッドから定期実行。ブート時 EL0
テスト直後の破壊(256KB ブロック終端 +16 の size
フィールドゼロ化)を捕捉し、証拠を TODO.md に記録kernel/usercopy.rs 新規:
ユーザポインタ検証の一元化(範囲・オーバーフロー・アライメント・長さ上限)syscall.rs: SYS_PRINT
の下限アドレス未チェック(カーネルメモリのダンプが可能だった)を修正、安定性ポリシーをモジュールドキュメントに明文化user_win.rs: 全システムコールを usercopy
経由に変更(不整列ポインタ参照の UB を解消)net.rs: HTTP 受信ループの unwrap()
パニック 2 箇所(ソケットが RST 等で先に解放されると発生)を修正Cargo.toml [lints.clippy] で unwrap_used /
expect_used を crate 全体 deny。既存 25 箇所を全て排除
arp("inject" "不正IP")
等のユーザ入力で即パニックする 5
箇所(builtins.rs)はエラー返却に修正panic!・添字アクセスも deny.github/workflows/ci.yml 新規: push/PR ごとに clippy +
build を実行cargo doc --document-private-items)を
docs/api/ へ自動公開--layout dot は graphviz の
cluster バグで abort するため sfdp を使用top_offset() に一元化WindowManager::any_window_covers_rect()
でガードhttps://lite.duckduckgo.com/ を TLS1.3 でロード成功(302 →
/lite/ 200 chunked)。フリーズ・パニックなし<hr> 重なりバグ: 根本原因は
flatten('\n' = 強制改行)と計測('\n' = 幅
8px のグリフ)の行数不一致。get_string_wrapped_size を
flatten と同一規則に書き直して修正UART_FIFO に push
されるだけで未消費 → test_browser.sh は機能しない(TODO
に追記)kernel/audio.rs:
再生スレッドを常駐化(ensure_playback_thread で一度だけ
spawn、キュー空はアイドル待機)Window::resize()
新設(kernel/window_mgr.rs)
resize()
は拡張前にヒープ残量を確認、不足ならリサイズ拒否で旧状態を維持kernel/watchdog.rs
新規)
kernel/user_win.rs
新規)
user_pixel_demo(全描画・入力を EL0
で実行)を os:launch_gui("eldemo") で起動可能src/ 直下のフラット構造を 3 層に整理
src/kernel/ : OS カーネル(draw, scheduler, fs, mmu,
uart 等)src/os_lib/ : 共通ライブラリ(web_engine, css, layout,
dom, json, aura 等)src/apps/<name>/ : 組み込みアプリ(browser, note,
files, terminal, music, settings 等)src/main.rs の mod 宣言を 3
グループに整理、#[macro_use] pub mod kernel;
でマクロ伝播kernel/boot.S の .include "src/vector.S" →
"src/kernel/vector.S" に修正include_bytes! / include_str!
のパス深度を各ファイルの新位置に合わせ修正lib → os_lib に改名(Rust
の慣例名衝突を回避)files_app / music_app /
keymap_app を files / music /
keymap に改名kernel/fs/ サブモジュールで
use crate::println; を追加(マクロ可視性修正)os_lib/web_engine.rs の on_mouse
を修正el.width.max(1320)
でヒット範囲が行幅全体に広がっていたバグを除去el.x_offset / el.width を使った 2D
バウンディングボックス判定に変更focused_input フラグ導入:input フォーカス後は button
クリックを無視os_lib/web_engine.rs に SylFS
ベースのディスクキャッシュを追加cache_path_for(host, path): FNV-1a 64bit ハッシュで
/cache/browser/<host>/<hash16> に変換write_cache / read_cache: SylFS
save_file / read_file
でバイト列を保存・読込async_load_thread_entry:
ページ取得前にキャッシュを確認。ヒット時はネットワーク不使用ensure_image_cached:
同様にキャッシュファースト方式clear_browser_cache(): ブラウザ終了時に
/cache/browser/ 以下を全削除apps/browser/mod.rs の close_tab
最終タブ時に clear_browser_cache() を呼ぶkernel/window_mgr.rs の App トレイトに
tab_thread_fn() -> Option<fn()> を追加(デフォルト
None)Window 構造体に
tab_pids: Vec<Option<usize>> を追加Window::spawn_tab_thread(idx) /
clear_tab_thread(idx) メソッド追加add_window() で初期タブ 0 のスレッドを起動add_tab() +
spawn_tab_thread(new_idx) を実行main.rs の Alt+T ハンドラにも
spawn_tab_thread 呼び出しを追加(漏れバグ修正)clear_tab_thread(clicked_tab) →
close_tab() の順で処理apps/note/mod.rs を全面改修NoteTab { filename, content, dirty }
構造体でタブごとに独立した状態を保持*
プレフィックスで未保存マーカーを表示flush_current_tab() /
load_tab_into_engine(idx)
でエンジンとタブ状態を双方向同期open_file_dialog() / save_file() を
App トレイトに追加(OS グローバルで Alt+O / Alt+S
にバインド)save_file() は Save As
ダイアログへ自動誘導NoteApp::open_file(filename, content) で外部起動対応kernel/shortcut_manager.rs の InputAction
に OpenFileDialog / SaveFile を追加main.rs に Alt+O (0x18) →
OpenFileDialog、Alt+S (0x1F) → SaveFile
を登録kernel/window_mgr.rs の App トレイトに
open_file_dialog() / save_file()
メソッド追加(デフォルト no-op)os_lib/web_engine.rs の
ensure_image_cached を完全ノンブロッキングに刷新ImageFetchReq / ImageLoadQueue /
IMAGE_QUEUE: Mutex<ImageLoadQueue>
グローバルキューenqueue_image(req): キューに追加し、スレッド未稼働なら
image_loader_thread を spawnimage_loader_thread(): pending を順次処理。SylFS 読込
or HTTP 取得 → PNG/JPEG/BMP デコード → results に積むpoll_image_results(): draw() 冒頭で results を
image_cache に取り込み dirty=true をセットdecode_image(data) ヘルパーに PNG/JPEG/BMP
デコードを集約(旧実装からコード移動)os_lib/css.rs:
StyledNode に
css_vars: BTreeMap<String, String> を追加resolve_css_var(value, vars): var(--name)
/ var(--name, fallback) 解決eval_calc(expr, containing_width):
calc(100% - 20px) 等を評価(px/rem/em/%対応)compute_styles_with_vars()
でカスタムプロパティを分離しカスケード継承os_lib/layout.rs:
apply_edge_value / apply_box_value で
calc() を評価display: none ノードを完全除外(確認)os_lib/web_engine.rs の RenderElement
に新フィールド追加:
position, pos_top/left/right/bottom:
relative/absolute/fixed 配置z_index, is_fixed:
スタッキング・固定配置overflow_hidden, clip_x0/y0/x1/y1:
クリップ領域box_shadow: offset_x/y/blur/colorwhite_space_nowrap,
text_overflow_ellipsislinear_gradient: (color1, color2, is_vertical)opacity: 0〜255visibility_hiddenflatten_layout で上記プロパティを CSS
から解析・設定draw():
sorted_indices.sort_by_key(z_index) で z-index
描画順を制御is_fixed 要素はスクロール非依存の viewport
座標で描画position: relative/absolute の top/left/right/bottom を
draw 座標に適用overflow_hidden で clip 境界外要素をスキップbox_shadow
を背景前に半透明オフセット矩形として描画linear_gradient を 2 色グラデーション矩形で描画opacity を bg・テキスト色のアルファに乗算text_overflow_ellipsis
で幅超過テキストを「…」で切り詰めkernel/draw.rs:
draw_gradient_rect(x0, y0, x1, y1, c1, c2, vertical):
行/列ごとに色を補間draw_shadow_rect(x0, y0, x1, y1, ox, oy, color):
オフセット半透明影矩形src/dom.rs:
find_implicitly_closeable(stack, target, stop_at) /
pop_to(stack, root, target_idx)
ヘルパーを追加して暗黙クローズロジックを共通化。<tr> → thead/tbody/tfoot/table で
stop、<td>/<th> → tr/table で stop
の暗黙クローズを追加。<option> → select/datalist で
stop、<dt>/<dd> → dl で stop
を追加。<p> の inline 停止リストに
small/sub/sup/abbr/cite/q/s/u を追加。src/net.rs:
http_raw_request(host, port, raw_bytes)
ヘルパーを抽出。http_get_real に 3xx redirect
follow(最大5回、http://
と相対パス両対応)を追加。http_post_real(host, path, content_type, body_bytes)
を新規追加。src/net_stack.rs: ApplicationLayerApi
トレイトに http_post メソッド追加。TcpIpStack
に実装。src/aura/builtins.rs: builtin_http が
"post" メソッドを受け付け http_post_real
に委譲。parse_http_response(transfer-encoding: chunked
検出)で既に実装済みを確認。src/layout.rs の intrinsic_inline_size
を修正: CSS
width/height(px値)を先にチェックし、設定されていれば
intrinsic サイズより優先する。inline-block { width: 200px }
が正しく機能するようになった。apply_edge_value / apply_box_value に
% 解決を追加: resolve_edge(s, base) ヘルパーが
parse_length_value を使い Percent を base
幅に対して計算。apply_box_model_styles_with_base(containing_width)
を追加し、layout_block / layout_flex /
layout_inline から
containing_block.content.width を渡すよう変更。:hover
疑似クラス動作確認
src/css.rs: PseudoClass::Hover,
hover_values: Option<BTreeMap<String, String>>,
compute_styles(&["hover"]) で hover 時 CSS を抽出src/web_engine.rs:
extract_hover_color_alt() が hover_values
から色を取得。描画ループで
is_hovered = mouse_y/x が要素 bounding box 内
を計算し、hover_bg_color / hover_color /
hover_border_color を実際の描画色として使用is_button)と通常要素の両方で
:hover が機能するmailbox::power_on_usb()
追加。Mailbox SET_POWER_STATE(device 3=USB, state=3)を
usb::init()
前に呼ぶ。RPi3B+はこれなしでUSBバスにVBusが入らない。usb.rs の
HCFG.FSLSPclkSel 値を修正。旧: FullSpeed=3(無効値)→新:
FullSpeed=1(48MHz), LowSpeed=2(6MHz)。mailbox.rs の
FrameBufferRequest に SET_PIXEL_ORDER
タグ(0x00048006,
値1=RGB)を追加。RPi3ハードウェアのデフォルトはBGRで赤青が逆になる問題を解決。get_info()
のタグインデックスを更新(pointer: 17→21, pitch: 22→26)。framebuffer_depth=32,
framebuffer_ignore_alpha=1,
dtparam=ant2(WiFiアンテナ)。src/sdio.rs, src/wifi.rs):
sdio.rs: Arasan
eMMC2コントローラ(0x3F340000)初期化、CMD52/CMD53、4-bitバス設定、RCA取得、CLK設定。wifi.rs:
CYW43455バックプレーンアクセス(window+CMD53)、SylFSからファームウェアロード(/boot/brcmfmac43455-sdio.bin)、ARM
coreリセット解除。WPA2接続はFMAC HLPプロトコル実装が次ステップ。fs::read_file() グローバルヘルパー追加。brcmfmac43455-sdio.bin を入手しSylFSの /boot/
に配置すること。方針(冒頭)に従い、旧 PROGRESS_LOG.md
と個別の実装計画書/タスク/ウォークスルーの
長文原文は「何をいつ完了したか」の要約に圧縮した(2026-06-14 セッション6
で実施)。 詳細な設計判断は各機能の現行コードと DESIGN.md / TECHNOTE.md
に反映済み。
いずれも完了済み。現行の DESIGN.md(設計)/ TECHNOTE.md(バグ分析)が最新の正典。
原文が必要な場合は本コミット以前 of git 履歴を参照(
git log -- spec/WALKTHROUGH_COMPLETION_LOG.md)。
yield_now() を sleep(1)
へ統一移行し、CPU 100% 占有によるフリーズを完全に解消。UDP_RX_QUEUE)および
TCPコネクト(tcp_connect_real)における
NET_LOCK
排他制御を導入し、複数スレッド間のデータ競合とパケットドロップを解消。dhcp_tick 内での NET_LOCK
獲得を解除し、受信ポーリング時のスピンデッドロックを防止。memcpy
などの実行時に発生していた特権命令アクセス例外による KERNEL PANIC
を解消。width: min-content / max-content / fit-content
に対応するレイアウト幅の算出ロジック(block_intrinsic_widths)の実装を完了。aspect-ratio による幅/高さの逆算(min/max-width
クランプ込み)、@media クエリ(min/max-width、orientation
等)、transform(translate/scale/rotate/matrix
等)を実装。vh/vw/rem/em
単位の解像度対応。IntersectionObserver, ResizeObserver,
MutationObserver の実装と CustomEvent
のサポート。setInterval / clearInterval
による非同期タイマー処理の複数回発火対応。window.innerWidth/innerHeight
等のビューポート情報および Element.animate() (no-op)
のサポート。H264_SELFTEST
および H264_GOLDEN テスト合格)。apps/drive/)の実装を完了。clippy::string_slice や
clippy::unwrap_used などの Clippy
エラーとコンパイル警告(48件)を完全に解消。