Skip to content

Commit 0d5cce0

Browse files
committed
WIP fixes for internalize and zero val translation of undefined and null
1 parent 3496c6f commit 0d5cce0

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

compiler/prelude/jsmapping.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,12 @@ var $internalize = function(v, t, recv) {
321321
case $kindSlice:
322322
return new t($mapArray(v, function(e) { return $internalize(e, t.elem); }));
323323
case $kindString:
324+
if (v === undefined || v == null) {
325+
return "";
326+
}
327+
if (typeof v !== "string") {
328+
$throwRuntimeError("tried to internalize non-string value of type " + typeof v);
329+
}
324330
v = String(v);
325331
if (v.search(/^[\x00-\x7F]*$/) !== -1) {
326332
return v;

js/js.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ func (o *Object) New(args ...interface{}) *Object { return o.object.New(args...)
5858
// Bool returns the object converted to bool according to JavaScript type conversions.
5959
func (o *Object) Bool() bool { return o.object.Bool() }
6060

61-
// String returns the object converted to string according to JavaScript type conversions.
61+
// String returns the underlying Javascript value as a string. If the
62+
// Javascript type of the underlying value is not string, then a runtime error
63+
// is thrown. If you want non-string values to be converted to string values
64+
// you need to perform that conversion first using js.Global.Call("String",
65+
// o).String() or similar.
6266
func (o *Object) String() string { return o.object.String() }
6367

6468
// Int returns the object converted to int according to JavaScript type conversions (parseInt).

js/js_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,3 +571,45 @@ func TestUint8Array(t *testing.T) {
571571
t.Errorf("Non-empty byte array is not externalized as a Uint8Array")
572572
}
573573
}
574+
575+
func TestInternalizeString(t *testing.T) {
576+
type S struct {
577+
*js.Object
578+
579+
string string `js:"string"`
580+
}
581+
582+
s := &S{Object: js.Global.Get("Object").New()}
583+
584+
zero := ""
585+
if v := s.string; v != zero {
586+
t.Fatalf("expected string field to be %q, got %q", zero, v)
587+
}
588+
589+
if v := s.Object.Get("string").String(); v != zero {
590+
t.Fatalf("expected string field to be %q, got %q", zero, v)
591+
}
592+
593+
s.Object.Set("string", []int{1, 2, 3})
594+
595+
panicked := false
596+
597+
func() {
598+
defer func() {
599+
err := recover().(error)
600+
exp := "runtime error: tried to internalize non-string value of type object"
601+
602+
if err.Error() != exp {
603+
t.Fatalf("expected error %q, got %q", exp, err)
604+
}
605+
606+
panicked = true
607+
}()
608+
609+
_ = s.string
610+
}()
611+
612+
if !panicked {
613+
t.Fatalf("expected to have had to handle panic; we didn't see a panic")
614+
}
615+
}

0 commit comments

Comments
 (0)