Skip to content

Commit 1da20ac

Browse files
Fixing internalization of null slice and array fields
1 parent d25ca33 commit 1da20ac

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

compiler/prelude/jsmapping.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ var $internalize = (v, t, recv, seen, makeWrapper) => {
236236
case $kindFloat64:
237237
return parseFloat(v);
238238
case $kindArray:
239+
if (v == null) {
240+
return t.zero();
241+
}
239242
if (v.length !== t.len) {
240243
$throwRuntimeError("got array with wrong size from JavaScript native");
241244
}
@@ -331,6 +334,9 @@ var $internalize = (v, t, recv, seen, makeWrapper) => {
331334
return $internalize(v, t.elem, makeWrapper);
332335
}
333336
case $kindSlice:
337+
if (v == null) {
338+
return t.zero();
339+
}
334340
return new t($mapArray(v, e => { return $internalize(e, t.elem, makeWrapper); }));
335341
case $kindString:
336342
v = String(v);

tests/js_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,82 @@ func TestExternalize(t *testing.T) {
829829
}
830830
}
831831

832+
func TestInternalizeSlice(t *testing.T) {
833+
tests := []struct {
834+
name string
835+
init []int
836+
want string
837+
}{
838+
{
839+
name: `nil slice`,
840+
init: []int(nil),
841+
want: `[]int(nil)`,
842+
},
843+
{
844+
name: `empty slice`,
845+
init: []int{},
846+
want: `[]int{}`,
847+
},
848+
{
849+
name: `non-empty slice`,
850+
init: []int{42, 53, 64},
851+
want: `[]int{42, 53, 64}`,
852+
},
853+
}
854+
855+
for _, tt := range tests {
856+
t.Run(tt.name, func(t *testing.T) {
857+
b := struct {
858+
*js.Object
859+
V []int `js:"V"` // V is externalized
860+
}{Object: js.Global.Get("Object").New()}
861+
b.V = tt.init
862+
863+
result := fmt.Sprintf(`%#v`, b.V) // internalize b.V
864+
if result != tt.want {
865+
t.Errorf(`Unexpected result %q != %q`, result, tt.want)
866+
}
867+
})
868+
}
869+
}
870+
871+
func TestInternalizeArray(t *testing.T) {
872+
tests := []struct {
873+
name string
874+
init [3]int
875+
want string
876+
}{
877+
{
878+
name: `zeros array`,
879+
init: [3]int{},
880+
want: `[3]int{0, 0, 0}`,
881+
},
882+
// TODO(grantnelson-wf): The following test doesn't pass because
883+
// the assignment of an externalized array doesn't work when this was written,
884+
// see https://github.com/gopherjs/gopherjs/issues/1302
885+
//{
886+
// name: `non-zero array`,
887+
// init: [3]int{42, 53, 64},
888+
// want: `[3]int{42, 53, 64}`,
889+
//},
890+
}
891+
892+
for _, tt := range tests {
893+
t.Run(tt.name, func(t *testing.T) {
894+
b := struct {
895+
*js.Object
896+
V [3]int `js:"V"` // V is externalized
897+
}{Object: js.Global.Get("Object").New()}
898+
b.V = tt.init
899+
900+
result := fmt.Sprintf(`%#v`, b.V) // internalize b.V
901+
if result != tt.want {
902+
t.Errorf(`Unexpected result %q != %q`, result, tt.want)
903+
}
904+
})
905+
}
906+
}
907+
832908
func TestInternalizeExternalizeNull(t *testing.T) {
833909
type S struct {
834910
*js.Object

0 commit comments

Comments
 (0)