From 7db30394a96edd49b1f7281c2b105418934e717c Mon Sep 17 00:00:00 2001 From: Grant Nelson Date: Tue, 30 Apr 2024 10:04:34 -0600 Subject: [PATCH] Fixing internalization of null slice and array fields --- compiler/prelude/jsmapping.js | 6 ++++++ tests/js_test.go | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/compiler/prelude/jsmapping.js b/compiler/prelude/jsmapping.js index b22454bc3..f5317d626 100644 --- a/compiler/prelude/jsmapping.js +++ b/compiler/prelude/jsmapping.js @@ -236,6 +236,9 @@ var $internalize = (v, t, recv, seen, makeWrapper) => { case $kindFloat64: return parseFloat(v); case $kindArray: + if (v === null || v === undefined) { + $throwRuntimeError("cannot internalize "+v+" as a "+t.string); + } if (v.length !== t.len) { $throwRuntimeError("got array with wrong size from JavaScript native"); } @@ -331,6 +334,9 @@ var $internalize = (v, t, recv, seen, makeWrapper) => { return $internalize(v, t.elem, makeWrapper); } case $kindSlice: + if (v == null) { + return t.zero(); + } return new t($mapArray(v, e => { return $internalize(e, t.elem, makeWrapper); })); case $kindString: v = String(v); diff --git a/tests/js_test.go b/tests/js_test.go index 2ce43865f..6f6eaa542 100644 --- a/tests/js_test.go +++ b/tests/js_test.go @@ -829,6 +829,45 @@ func TestExternalize(t *testing.T) { } } +func TestInternalizeSlice(t *testing.T) { + tests := []struct { + name string + init []int + want string + }{ + { + name: `nil slice`, + init: []int(nil), + want: `[]int(nil)`, + }, + { + name: `empty slice`, + init: []int{}, + want: `[]int{}`, + }, + { + name: `non-empty slice`, + init: []int{42, 53, 64}, + want: `[]int{42, 53, 64}`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := struct { + *js.Object + V []int `js:"V"` // V is externalized + }{Object: js.Global.Get("Object").New()} + b.V = tt.init + + result := fmt.Sprintf(`%#v`, b.V) // internalize b.V + if result != tt.want { + t.Errorf(`Unexpected result %q != %q`, result, tt.want) + } + }) + } +} + func TestInternalizeExternalizeNull(t *testing.T) { type S struct { *js.Object