Changes between Version 1 and Version 2 of LevelOne

Show
Ignore:
Timestamp:
06/25/09 21:34:30 (5 years ago)
Author:
Austin_Hastings
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • LevelOne

    v1 v2  
    44 
    55The [wiki:L1Recap L1 Recap] describes the initial vision. 
     6 
     7== Thought Experiment == 
     8 
     9Consider writing a ''method'' for a PMC. Currently, they are written in a C-like language that is preprocessed by `pmc2c` (a perl script). 
     10  
     11The pmc2c preprocessor inserts code into each method body to handle interacting with the interpreter. This avoids having this boilerplate code in each function, which is convenient because it can be larger than the actual method code sometimes. 
     12  
     13But much of that boilerplate code is useless, or infrequently needed, or could and should be refactored outside the body of the 'method' itself. 
     14  
     15For example, each method specifies its parameters, and what register types it wants the parameters in. Why? The C doesn't use registers, but if the method were to call some other PIR, and that PIR needed to walk back up the call stack (for debugging, or an exception, or something far more sinister), the record has to exist even for "non-PIR" stack frames. 
     16  
     17Similarly, if the C wants to throw a resumable exception, or pass a return continuation to some other code, there has to be a certain amount of stuff set up. The boilerplate is doing some or all of that work now. 
     18  
     19But much of that could be coded a different way. Suppose instead of a big C function with a lot of boilerplate at the top (and bottom, and middle, and wherever pmc2c decides it's necessary...) there was a smaller data structure. 
     20 
     21Let's say that each method is actually a PmcMethod object, and it has an "invoke" method. Most of the time, do something like: 
     22 
     23{{{ 
     24    $P0 = get_method "foo" 
     25    $P1 = make_args($P0, ...) # I don't know, some registers? 
     26    make_stack_frame $P0, $P1 
     27    $P2 = $P0.invoke() 
     28 
     29    unless_exception $P2 goto no_exception 
     30 
     31    $P3 = get_current_stack_frame 
     32 
     33    $I0 = $P3.can_handle_exception($P2) 
     34    if $I0 goto handle_exception 
     35 
     36    chain_exception $P2 
     37 
     38  handle_exception: 
     39    # Lookup handler, etc. 
     40 
     41  no_exception: 
     42    get_return_results $P2 
     43    
     44}}} 
     45  
     46Of course, sometimes you do need there to be a stack frame in the interp. So the make_stack_frame could just create some fake data, and leave a pointer for the off chance that someone needs to hydrate the real thing. 
     47  
     48Likewise, exception processing might need some special processing.  
     49  
     50So the downside here is that there are a lot more ops. And the ops look funny. They don't look like "add two numbers" or "call this function". The upside is that each of these ops is a replacement for some code that already exists in the current pmc2c boilerplate, and if things are done right most of those ops won't get executed (making the actual code that gets executed shorter, and contain fewer calls to malloc).