From d40c4dfcd94d86a176d76ff6923ec45597674569 Mon Sep 17 00:00:00 2001 From: starainrt Date: Sun, 17 May 2026 21:19:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=BC=E5=AE=B9=20TinyGo=20wasm=20?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E8=A1=8C=E6=98=9F=E6=98=9F=E5=8E=86=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 planetViews 从包级初始化改为 sync.Once 懒加载,避免 TinyGo interp 在编译期处理大型 float64 表切片索引时触发 unsupported fcmp - 将行星视图构建失败改为内部返回 error,并由兼容层统一 panic - 补充无效行星数据切片边界测试 --- planet/planet.go | 2 +- planet/planet_test.go | 15 ++++++++++++++- planet/view.go | 29 +++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/planet/planet.go b/planet/planet.go index 03a9e6f..bda41af 100644 --- a/planet/planet.go +++ b/planet/planet.go @@ -25,7 +25,7 @@ func WherePlanetN(xt, zn int, jd float64, n int) float64 { t := (jd - 2451545) / 36525.0000 t /= 10 // 转为儒略千年数 - body := planetViews[xt] + body := planetViews()[xt] coord := body.coords[zn] baseOrderTerms := len(coord.orders[0]) diff --git a/planet/planet_test.go b/planet/planet_test.go index 1f846dc..b169e80 100644 --- a/planet/planet_test.go +++ b/planet/planet_test.go @@ -25,8 +25,9 @@ func TestWherePlanetNFullMatchesDefault(t *testing.T) { } func TestPlanetViewsMatchRawCuts(t *testing.T) { + views := planetViews() for bodyIndex, raw := range planetRawData { - view := planetViews[bodyIndex] + view := views[bodyIndex] if math.Float64bits(view.scale) != math.Float64bits(raw[0]) { t.Fatalf("body=%d scale mismatch", bodyIndex) } @@ -42,3 +43,15 @@ func TestPlanetViewsMatchRawCuts(t *testing.T) { } } } + +func TestBuildPlanetViewsRejectsInvalidCuts(t *testing.T) { + _, err := buildPlanetViews([][]float64{{ + 10000000000, + 20, 21, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, + }}) + if err == nil { + t.Fatal("expected invalid cut error") + } +} diff --git a/planet/view.go b/planet/view.go index df807f0..2f9ecda 100644 --- a/planet/view.go +++ b/planet/view.go @@ -1,6 +1,9 @@ package planet -import "fmt" +import ( + "fmt" + "sync" +) type coordSeriesView struct { orders [6][]float64 @@ -11,13 +14,27 @@ type planetView struct { coords [3]coordSeriesView } -var planetViews = buildPlanetViews(planetRawData) +var ( + planetViewsOnce sync.Once + planetViewsCache []planetView + planetViewsErr error +) -func buildPlanetViews(rawData [][]float64) []planetView { +func planetViews() []planetView { + planetViewsOnce.Do(func() { + planetViewsCache, planetViewsErr = buildPlanetViews(planetRawData) + }) + if planetViewsErr != nil { + panic(planetViewsErr) + } + return planetViewsCache +} + +func buildPlanetViews(rawData [][]float64) ([]planetView, error) { views := make([]planetView, len(rawData)) for bodyIndex, raw := range rawData { if len(raw) < 20 { - panic(fmt.Sprintf("planet raw data %d too short: %d", bodyIndex, len(raw))) + return nil, fmt.Errorf("planet raw data %d too short: %d", bodyIndex, len(raw)) } view := planetView{scale: raw[0]} for zn := 0; zn < 3; zn++ { @@ -26,12 +43,12 @@ func buildPlanetViews(rawData [][]float64) []planetView { start := int(raw[pn+order]) end := int(raw[pn+order+1]) if start < 0 || end < start || end > len(raw) { - panic(fmt.Sprintf("planet raw data %d coord %d order %d invalid cut: %d..%d (len=%d)", bodyIndex, zn, order, start, end, len(raw))) + return nil, fmt.Errorf("planet raw data %d coord %d order %d invalid cut: %d..%d (len=%d)", bodyIndex, zn, order, start, end, len(raw)) } view.coords[zn].orders[order] = raw[start:end] } } views[bodyIndex] = view } - return views + return views, nil }