Below are some thoughts WRT C static vars and Perl6 INIT blocks.

Comments welcome,
leo
Supporting C static storage

There are some related Perl6 features, namely INIT and FIRST closure
traits [1], which aren't really covered by Parrot yet.

Parrot supports INIT blocks via :immediate, which allows e.g.
translation of:
  
  constant Num pi = { atan(1,1)*4 };           # [2]

But C statics can of course change. The problems is, where to
store the static variable, especially native integers.

  double gen_random(double max) {              # [3]
    static long last = 42;
    ...
  }

We could use closures, coroutines [4], or globals. The former provide
a persistent register frame, where the static can be kept. Translating
a sub with a C static to a coroutine seems to be a bit unnatural
though.  And all these solutions are a bit slow and lexicals/globals
are only providing PMC support.

I think, we should use the constant table and allow storing into
the constant table.

E.g.

  .static int last = 42             # ldc_i_ic

(We can't use the C<set_i_ic> opcode, as this is loading constants
from the bytecode, which, when mmaped, is readonly and doesn't allow
storing)

  last += 10                        # add_i_ic / set_ic_i

  .static float f = 3.14            # set_n_nc
  f += 2.0                          # add_n_nc / set_nc_n
  f = 5.0                           # set_n_nc / set_nc_n

  .static .Integer i = "42"         # set_p_pc

The 'static' variables are therefore working mostly like constants,
except that they are modifyable. One difference is of course, that
there would be no constant folding, each .static needs a distinct
storage in the constant table.

We'd need a few new opcodes:

  ldc_i_ic                 # load int constant from constant table
  set_ic_i                 # store int into constant table
  set_nc_n                 # store num
  assign_pc_p              # assign to PMC static value

And maybe some permutations like set_pc_i.

What do you think?
leo  


[1] S04 / Closure traits

[2] # t/pmc/sub_38.pir
.sub make_pi :immediate, :anon
    $N0 = atan 1.0, 1.0
    $N0 *= 4
    $P0 = new .Float
    $P0 = $N0
    .return ($P0)
.end

.sub main :main
    .const .Sub pi = "make_pi"
    print pi
    print "\n"
.end

[3] 
http://shootout.alioth.debian.org/sandbox/benchmark.php?test=random&lang=icc&id=0

[4] examples/shootout/random.pir

Reply via email to