lvcabral / brs-engine

BrightScript Simulation Engine - Run Roku apps on Browsers and Node.js
https://lvcabral.com/brs/
MIT License
77 stars 14 forks source link

Boxing and Casting on function parameters #312

Closed lvcabral closed 5 months ago

lvcabral commented 6 months ago

in brs it was implemented an auto-box when the code has as object in the parameters, the example below shows how it works, in the RightTest() function param1 type is String and in LeftTest() function param1 type is roString. Also the param2 is auto-casted to boolean from Integer in the LeftTest()

sub main()
  myVar = "test"
  RightTest(myVar, 1.3)
  LeftTest(myVar, -1)
end sub

sub RightTest(param1 as dynamic, param2)
  print type(param1), type(param2)
  if param1 <> invalid
     print param1, param2
  else
     print "param invalid"
  end if
end sub

sub LeftTest(param1 as object, param2 as boolean)
  print type(param1), type(param2)
  if invalid <> param1
     print param1, param2
  else
     print "param invalid"
  end if
end sub

The output of this code in a Roku:

image
lvcabral commented 6 months ago

RBI automatically boxes function parameters and return values. As it turns out, RBI also unboxes function parameters and return values to match a function's declared signature. Consider this example:

sub main()
    boxed = createObject("roString")
    boxed.setString("lorem ipsum")
    print "type(boxed) = " type(boxed) " | boxed = " boxed

    unboxed = unboxing(boxed)
    print "type(unboxed) = " type(unboxed) " | unboxed = " unboxed
end sub

sub unboxing(s as string) as string
    print "type(s) = " type(s) " | s = " s
    return s
end sub

Inside of the unboxing function, s is always a primitive string and never an instance of roString. Similarly, the return value of unboxing is also always a primitive string and never an instance of roString.

brs currently doesn't handle this demotion properly, and throws type mismatch errors at runtime 😢

image