feat(phase90): Ring0Context fs/time/thread migration complete
Phase 90 完了: IO/fs/time/thread 系の Ring0 移行 **Phase 90-A: fs 系移行(7箇所)** - FsApi trait 追加(6メソッド) - StdFs 実装(std::fs ベース) - IoError 拡張(4バリアント追加) - 移行: strip.rs(4), dispatch.rs(1), mod.rs(3) **Phase 90-B: io 系移行** - Phase 88 完了済み(スキップ) **Phase 90-C: time 系移行(3箇所)** - TimeApi に elapsed() 追加 - 移行: selfhost_exe.rs(1), io.rs(1), plugin_loader_unified.rs(1) **Phase 90-D: thread 系移行(2箇所)** - ThreadApi trait 追加(sleep メソッド) - StdThread 実装 - 移行: global_hooks.rs(1), plugin_loader_unified.rs(1) **Phase 90-E: 統合テスト** - ビルド成功(6 warnings, 0 errors) - テスト: 522/554 passed (94.2%) - 退行なし **実装成果**: - Ring0Context 拡張: fs, thread フィールド追加 - 総移行: 12箇所(fs: 7, time: 3, thread: 2) - 移行率: fs(2.9%), time(2.1%), thread(5.4%) **次のステップ**: Phase 91 (PluginHost/CoreServices skeleton) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -28,7 +28,9 @@ pub(crate) fn execute_file_with_backend(runner: &NyashRunner, filename: &str) {
|
||||
let groups = runner.config.as_groups();
|
||||
// Diagnostic/Exec: accept MIR JSON file direct (experimental; default OFF)
|
||||
if let Some(path) = groups.parser.mir_json_file.as_ref() {
|
||||
match std::fs::read_to_string(path) {
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
match ring0.fs.read_to_string(std::path::Path::new(path)) {
|
||||
Ok(text) => {
|
||||
// Try schema v1 first (preferred by emitter)
|
||||
match crate::runner::json_v1_bridge::try_parse_v1_to_module(&text) {
|
||||
|
||||
@ -119,7 +119,9 @@ impl NyashRunner {
|
||||
}
|
||||
// Early: direct MIR JSON execution (no source file). Experimental diagnostics/exec.
|
||||
if let Some(path) = groups.parser.mir_json_file.as_ref() {
|
||||
match std::fs::read_to_string(path) {
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
match ring0.fs.read_to_string(std::path::Path::new(path)) {
|
||||
Ok(text) => match crate::runner::json_v1_bridge::try_parse_v1_to_module(&text) {
|
||||
Ok(Some(module)) => {
|
||||
let rc = self.execute_mir_module_quiet_exit(&module);
|
||||
@ -176,7 +178,9 @@ impl NyashRunner {
|
||||
std::process::exit(0);
|
||||
}
|
||||
} else if let Some(file) = groups.input.file.as_ref() {
|
||||
match std::fs::read_to_string(file) {
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
match ring0.fs.read_to_string(std::path::Path::new(file)) {
|
||||
Ok(code) => match crate::parser::NyashParser::parse_from_string(&code) {
|
||||
Ok(ast) => {
|
||||
let prog = crate::r#macro::ast_json::ast_to_json(&ast);
|
||||
@ -281,7 +285,9 @@ impl NyashRunner {
|
||||
}
|
||||
// Optional dependency tree bridge (log-only)
|
||||
if let Ok(dep_path) = std::env::var("NYASH_DEPS_JSON") {
|
||||
match std::fs::read_to_string(&dep_path) {
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
match ring0.fs.read_to_string(std::path::Path::new(&dep_path)) {
|
||||
Ok(s) => {
|
||||
let bytes = s.as_bytes().len();
|
||||
let mut root_info = String::new();
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::io::Read;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct ChildOutput {
|
||||
pub stdout: Vec<u8>,
|
||||
@ -19,7 +19,12 @@ pub fn spawn_with_timeout(mut cmd: Command, timeout_ms: u64) -> std::io::Result<
|
||||
let mut child = cmd.spawn()?;
|
||||
let ch_stdout = child.stdout.take();
|
||||
let ch_stderr = child.stderr.take();
|
||||
let start = Instant::now();
|
||||
// Phase 90-C: time 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
let start = ring0
|
||||
.time
|
||||
.monotonic_now()
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;
|
||||
let mut timed_out = false;
|
||||
let mut exit_status: Option<std::process::ExitStatus> = None;
|
||||
loop {
|
||||
@ -29,7 +34,7 @@ pub fn spawn_with_timeout(mut cmd: Command, timeout_ms: u64) -> std::io::Result<
|
||||
break;
|
||||
}
|
||||
None => {
|
||||
if start.elapsed() >= Duration::from_millis(timeout_ms) {
|
||||
if ring0.time.elapsed(start) >= Duration::from_millis(timeout_ms) {
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
timed_out = true;
|
||||
|
||||
@ -547,7 +547,11 @@ pub fn resolve_prelude_paths_profiled(
|
||||
if !seen.insert(key.clone()) {
|
||||
return Ok(());
|
||||
}
|
||||
let src = std::fs::read_to_string(&real_path)
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
let src = ring0
|
||||
.fs
|
||||
.read_to_string(std::path::Path::new(&real_path))
|
||||
.map_err(|e| format!("using: failed to read '{}': {}", real_path, e))?;
|
||||
let (_cleaned, nested, _nested_imports) =
|
||||
collect_using_and_strip(runner, &src, &real_path)?;
|
||||
@ -643,7 +647,11 @@ pub fn parse_preludes_to_asts(
|
||||
prelude_path
|
||||
);
|
||||
}
|
||||
let src = std::fs::read_to_string(prelude_path)
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
let src = ring0
|
||||
.fs
|
||||
.read_to_string(std::path::Path::new(prelude_path))
|
||||
.map_err(|e| format!("using: error reading {}: {}", prelude_path, e))?;
|
||||
let (clean_src, _nested, _nested_imports) =
|
||||
collect_using_and_strip(runner, &src, prelude_path)?;
|
||||
@ -890,7 +898,11 @@ pub fn merge_prelude_text(
|
||||
if !seen.insert(key.clone()) {
|
||||
return Ok(());
|
||||
}
|
||||
let src = std::fs::read_to_string(path)
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
let src = ring0
|
||||
.fs
|
||||
.read_to_string(std::path::Path::new(path))
|
||||
.map_err(|e| format!("using: failed to read '{}': {}", path, e))?;
|
||||
let (_cleaned, nested, _nested_imports) = collect_using_and_strip(runner, &src, path)?;
|
||||
for n in nested.iter() {
|
||||
@ -926,7 +938,11 @@ pub fn merge_prelude_text(
|
||||
|
||||
// Add preludes in DFS order
|
||||
for (idx, path) in prelude_paths.iter().enumerate() {
|
||||
let content = std::fs::read_to_string(path)
|
||||
// Phase 90-A: fs 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
let content = ring0
|
||||
.fs
|
||||
.read_to_string(std::path::Path::new(path))
|
||||
.map_err(|e| format!("using: failed to read '{}': {}", path, e))?;
|
||||
|
||||
// Strip using lines from prelude and normalize
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use std::io::Read;
|
||||
use std::process::Stdio;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Try external selfhost compiler EXE to parse Ny -> JSON v0 and return MIR module.
|
||||
/// Returns Some(module) on success, None on failure (timeout/invalid output/missing exe)
|
||||
@ -57,13 +57,15 @@ pub fn exe_try_parse_json_v0(filename: &str, timeout_ms: u64) -> Option<crate::m
|
||||
};
|
||||
let ch_stdout = child.stdout.take();
|
||||
let ch_stderr = child.stderr.take();
|
||||
let start = Instant::now();
|
||||
// Phase 90-C: time 系移行
|
||||
let ring0 = crate::runtime::ring0::get_global_ring0();
|
||||
let start = ring0.time.monotonic_now().ok()?;
|
||||
let mut timed_out = false;
|
||||
loop {
|
||||
match child.try_wait() {
|
||||
Ok(Some(_)) => break,
|
||||
Ok(None) => {
|
||||
if start.elapsed() >= Duration::from_millis(timeout_ms) {
|
||||
if ring0.time.elapsed(start) >= Duration::from_millis(timeout_ms) {
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
timed_out = true;
|
||||
|
||||
Reference in New Issue
Block a user