Description
Problem
In the following code, the assignment of b.V
doesn't work:
type Bar struct {
*js.Object
V [3]int `js:"V"`
}
func main() {
b := Bar{Object: js.Global.Get("Object").New()}
b.V = [3]int{4, 5, 6}
fmt.Printf("%v\n", b.V)
}
This is because the code translates into:
arrayType.copy($internalize(b.Object.V, arrayType), $toNativeArray($kindInt, [4, 5, 6]));
The $internalize
creates a new array that is written to, but that new array is never set back to b.Object.V
meaning b.V
is not updated.
This isn't a problem with slices because the value is assigned to the externalized value instead. The following is the same example code above expect with [3]
changed to []
in both locations then translated into JS:
b.Object.V = $externalize(new sliceType([4, 5, 6, 7]), sliceType);
Possible Fixes
The compiler code, at statements.go:737, generating this code could do one of the following:
-
Pass in a flag to
translateExpr
to indicate that the result is the left hand side of an assignment. In this case the expression must reference the actual data being assigned or create a proxy to perform the conversion when a value is set (if such a thing is possible in JS). If the flag simply prevents internalization, then the copy method would have to be updated to also handle assigning to an externalized array. -
The returned
*expression
needs to indicate the result is internalized. This is similar to how the expression can have "paren" or not and hasStringWithParens() string
. The idea would be that it indicates that the normalString()
would internalize the value and we'd add aStringWithoutInternalize()
that either returns the expression without the internalization or the same thing asString()
if there is no internalization. This would allow us to use the internalize flag on*expression
to know we need to create a variable for the internalized instance, then we perform the array copy, then we add the code to assign the "un-internalized" value to the externalization of the newly updated internalized instance.
These two ideas aren't the only solution, they were just the two that came to my head first. We should look into what causes the slice not to use the copy in the assignment and try to get a whole picture of how externalized arrays work before coming up with a fix.