When PIR code has a function call syntax:

  foo(i, j)

the created code has currently (amongst other) a line:

  newsub Px, .Sub, foo

where the label "foo" is a relative branch offset.

This is suboptimal for several reasons:

- it creates a new PMC for every call albeit in 99.99% of cases the PMC constant for the sub could be used directly [1]

- the created subroutine PMC lacks information: only the start label is known, when the PMC is created. The subroutine's name and the end of the opcodes for that sub isn't in Px. Obtaining that information would be a costy O(n) lookup in the fixup segement of the bytecode (or in the constants, which is probably still larger). Subroutine length and name information is needed for introspection and for bounds checking in safe run cores.

So I think, we should do instead something like this:

  get_sub Px, foo   # find the PMC with label "foo" in constants
                    # at compile time and
                    # replace "foo" with the index in constants
  clone Py, Px      # if Px would be modified, clone it first [1]

  find_global Px, "foo"   # we have that already, but hash lookup!

The current syntax:

  newsub Px, .Closure, foo

could remain unchanged, except that again under the hood, the label foo is replaced with the index in the constant table. For closures it's probably best to actually return a new object per default, as a closure might have different state in the lexical pad in each invocation.

Is that reasonable?

leo

[1] a few tests attach properties to the Sub PMC



Reply via email to