On Mar 6, 2006, at 5:31 PM, Allison Randal wrote:

On Mar 6, 2006, at 4:08, Leopold Toetsch wrote:
   * opcode vs function / method

           open P0, "data.txt", ">"
           print P0, "sample data\n"

Using opcodes for all the IO has some disadvantages:
a) namespace pollution: all opcodes are reserved words in Parrot
b) opcodes aren't overridable, that is you can't provide your own 'print' opcode for e.g. debugging c) all such IO opcodes have to verify that the given PMC is actually a ParrotIO PMC.

E.g.

  new P0, .Undef   # or .Integer, ...
  print P0, "foo"

I'm in favor of using methods for almost all IO functionality:

   P0.'print'("sample data\n")

Generally, I'm in favor of opcodes for simple, common operations, and falling back to methods for more complex capabilities. It's overkill to require people to write:

P0 = getstdout
P0.'print'(S1)

everywhere they would currently write:

print S1

One place I'm in favor of eliminating the opcode in favor of a method call is the C<pioctl> opcode. I would also seriously consider it for the socket opcodes, but we need to kick that one around a bit to see if it really would be an improvement.

Personally I'm a little big indifferent towards the difference with methods and opcodes for most IO. But since each opcode added is really added at least four times(slow core, switch, cg, and cgp, plus jit if it's written), too many opcodes would increase size quickly. But, the basic print opcodes, easy capacity to work with stdin, stdout, and stderr, should remain with opcodes. Maybe have the io opcodes deal only with the std's, and pmc's and methods for the rest. If you take the "opcodes for easy things, methods for complex", stdout is easy, files are complex.

Combined with ...

   * [ return code vs exception ]

... we can also check, if this was a void call or not (Parrot *does have* the concept of a result context):

$I0 = pio.'print'("sample data\n") # return sucess (>=0) or failure (<0)
  pio.'print'("sample data\n")           # throw exception on failure

That solution is problematic in the "unintended consequences" department. Just because someone doesn't capture the return value doesn't necessarily mean they want exceptions turned on for failures. We would at least need to provide a flag for selecting exceptions vs integer return codes. But, even that is probably too minimal.

A side note: many of these opcodes also have another return value in addition to the integer error code, which makes the integer error code interface clumsy.

Any compiler targetting parrot should know parrot's behavior, so if the HLL program doesn't want the return value but the way the compiler handles it wants it, the compiler would add it in. Every pmc has eight private flags it can use, and currently ParrotIO uses none of them. So the "throw exception or ignore" can be set per pmc if the method approach is taken.

[...]
* [Nicholas] "Should the IO system provide symbolic lookup on AF_* and PF_* constants.
                  IIRC at least one of these groups is OS dependant"

Any such constants that aren't the same on all architectures have to be delt with at runtime, i.e. these constants can't be integers, because integer constants are compiled into the bytecode in the flavor of the compiling machine. That is: instead of

  .include "xF_foo.pasm"     # constants are resolved at compile time

we'd need something like:

  load_bytecode "xF_foo.pasm"  # postpone to runtime

We don't have a proper syntax for such (not so-) constants yet, but it could just be:

  pio = socket(".AF_UNIX", ...)

It seems like a more general problem than that. Like, you want a way of flagging a constant when you define it as to whether it should be substituted when compiling to bytecode or substituted when interpreting the bytecode. (And a way of storing delayed constant substitutions in the bytecode.)

An alternative, although cumbersome, would be to add a new opcode similar to sysinfo or interpinfo, where the IO constants would keep the same '.include "foo.pasm"' method, but would be used like '$I0 = ioconst .AF_WHATEVER' to get the native constant. Then it would mainly be a matter of having compiler writers knowing this, and still reminding people not to use hard coded constants.

Allison


Reply via email to