Chapter 14: Context

Blue Chapter -- Machine Translation

Much of very wide range. The first step is to evaluate how the internal state apparatus to be represented by Whether the story. Then, the defining statement in the class as an example of the state Changes in the city. Following the internal state sentence is a method definition of what an impact. Finally, both the variable definitions and references to observe the behavior of the change.

Ruby stack

context and the stack

A typical image of a procedural language, calling the procedure every time the local queer And return to areas where the number of procedures required to perform an information structure (Stack frames) and stored, Stack it. From the top of the stack and procedures Back in the structure to pop back to the previous method. For example Chapter 5 of moths - as described, BEJIKOREKUSHON That program is run C-called true image.

I want to note where the program is running into a stack, just type It is the location of the program changed or not. For example, a "strange local Count i reference "," The current frame i , please "Oh instruction Only of this, "frame i , please" is not write. In other words stack State "that" will not change the results. That is why procedures, etc. When I have attempted several times called the code will only have one (Figure 1).

(stack)
Figure 1: The only change is a stack

Ruby's execution method is basically a process that is nothing other than a chain of calls , Which is essentially the same image have run. That is the same code , Accessed by the local side of the block local variables and variable scope Schou It is a change in the group. And that scope is represented by the stack.

However, Ruby and iterator Proc scope to use previously used to temporarily return Or from a stack of Pop pushed only simple to implement. Resona Ruby is running for the stack piled into the complex. So stack ICHIOU And said that the list should be considered not just a maybe.

The method calls in addition to the class definition has changed the scope of local variables RISURU, local calls and variable methods do not match the scope of the transition. Other blocks have also split and we do not have to. That is why in this A variety of reasons, as far away as a stack of seven books.

stack pointer stack frame type explain
ruby_frame struct FRAME method calls recorded
ruby_scope struct SCOPE local variable scope
ruby_block struct BLOCK block scope
ruby_iter struct iter current FRAME or enumeration is
ruby_dyna_vars struct Varmap block local variable scope
ruby_class VALUE method definition class at
ruby_cref NODE ( NODE_CREF ) class nesting information

C is a stack of seven books, this means that Ruby, Ruby and the execution of simple arithmetic image The seven-fold from the C is supposed to be tough. But the fact is it's not a seven-fold You see, Ruby is 20 times more tough.

First of all these stacks and stacks of the frame (of) the structure of Let's easy to explain. Defined in the file is eval.c or env.h . Basically These frames are stacked in touch eval.c …… just do not want, but gc.c marked when you need to know the structure for env.h , has been the Above.

Of course it is spam gc.c , even if it is possible, to separate the function so that the Essential Is required. Then of course slower. That program is normal by the Do not, however, GABEJIKOREKUTA and evaluation of the core instruments ruby largest BOTO RUNEKKU so, even if our function calls once he's not dumb.

ruby_frame

ruby_frame method is to call a stack of records. Stack frame Structure is struct FRAME . Terminology is a little confusing, generic noun, "Su Tuck frame "It's just a frame, struct FRAME that FRAME and writing Note that divide.

ruby_frame

 
   16 extern struct FRAME ( 
   17 VALUE self; / * self * / 
   18 int argc; / * * the number of arguments / 
   19 VALUE * argv; / * argument array * / 
   20 ID last_func; / * This method FRAME (name called) * / 
   21 ID orig_func; / * FRAME this method (as defined when the name) * / 
   22 VALUE last_class; / * last_func receivers class * / 
   23 VALUE cbase; / * class variables constant search for the origin * / 
   24 struct FRAME * prev; 
   25 struct FRAME * tmp; / * GC avoided. See below * / 
   26 struct RNode * node; / * line running file name and line number * / 
   27 int iter; / * call with blocks? * / 
   28 int flags; / * * The following two / 
   29) * ruby_frame; 

   33 # define FRAME_ALLOCA 0 / * FRAME stack is in the * / 
   34 # define FRAME_MALLOC 1 / * FRAME is to ensure that malloc * / 

(env.h) 

First, prev to be a member of the stack is made of the linked list Known (see Figure 2).

(framestack)
Figure 2: ruby_frame

ruby_xxxx is the tip of the stack frame to point to the stack after all Common to all of the time, so writing.

Members of the first structure self . rb_eval () argument is self happened See also the separate self to remember is why. That level is C For the function. Say more super corresponding rb_call_super () . For the function. super to run the current method is needed receiver However, rb_call_super () side of the call should not have such information. I say The user's control is shifted to C code at the time of rb_eval () break the cycle of the other . So zero information from the state self to obtain information on the Contact Kana Must be the conclusion. And FRAME in the yard as a CHO Exactly.

I think about it some more, argc and argv is also strange. Variable parameters It's the end of it from local variables, methods at the start of the same local strange The number assigned to the argument once and then I got the need to keep it is not No? This is not going to be used for me, actually another super NOTA Because of it. Ruby is no argument super to call the method parameters and variables Super-class value method has been handed over to them. In order to Meanwhile, is variable parameters (equivalent to a local variable area)-placed to take There will be.

And last_func and orig_func difference is alias and Methods come. For example

 
class C 
   def orig () end 
   alias ali orig 
end 
C.new.ali 

If the case, last_func = ali , orig_func = orig . All in all, this is also a member of super KARAN, if you will.

ruby_scope

ruby_scope stack represents a local scope. Methods module class definitions, including definitions specific definitions of class The scope of independence. Stack frame structure is struct SCOPE . The frame is SCOPE and call.

ruby_scope

 
   36 extern struct SCOPE ( 
   37 struct RBasic super; 
   38 ID * local_tbl; / * * An array of local variable name / 
   39 VALUE * local_vars; / * * local variable storage / 
   40 int flags; / * * The following four / 
   41) * ruby_scope; 

   43 # define SCOPE_ALLOCA 0 / * local_vars alloca is assigned * / 
   44 # define SCOPE_MALLOC 1 / * local_vars malloc is assigned * / 
   45 # define SCOPE_NOSTACK 2 / * POP_SCOPE in the * / 
   46 # define SCOPE_DONT_RECYCLE 4 / * This is generated by SCOPE, Proc * / 

(env.h) 

The first element is struct RBasic So this is the object of Ruby. That is It is Proc for dealing with the object. For example, to consider the following cases: I try.

 
def make_counter 
   lvar = 0 
   return Proc.new (lvar + = 1) 
end 

cnt = make_counter () 
p cnt.call # 1 
p cnt.call # 2 
p cnt.call # 3 
cnt = nil # reference to pieces. Proc here and finally made it unnecessary 

This method made Proc objects are created than the original method itself Live longer. And the Proc from the local variables lvar of reference, I made Proc With the disappearance of OKANE to hold local variables. So GABEJIKOREKUTA it up as you do not not know the timing of release .

And even bother struct SCOPE is struct FRAME cut off from the second reason is Point. The first is that the class definitions and methods are not a local call The scope of the independent variables. Second, C-defined method to call SU Ruby's when the local variable area is not required.

ruby_block

struct BLOCK and the Ruby's ITERETABUROKKU Proc object entity, At some point, the evaluator's like a snapshot. This Kulun Page also FRAME SCOPE the same way as BLOCK and a rough sketch.

ruby_block

 
  580 static struct BLOCK * ruby_block; 

  559 struct BLOCK ( 
  560 NODE * var; / * block parameter (mlhs) * / 
  561 NODE * body; / * number of body block * / 
  562 VALUE self; / * BLOCK generation of self * / 
  563 struct FRAME frame; / * BLOCK ruby_frame generated when a copy * / 
  564 struct SCOPE * scope; / * BLOCK generated when ruby_scope * / 
  565 struct BLOCKTAG * tag; / * BLOCK identity * / 
  566 VALUE klass; / * BLOCK generated when ruby_class * / 
  567 int iter; / * BLOCK generated when ruby_iter * / 
  568 int vmode; / * BLOCK generated when scope_vmode * / 
  569 int flags; / * BLOCK_D_SCOPE, BLOCK_DYNAMIC * / 
  570 struct RVarmap * dyna_vars; / * * block local variable area / 
  571 VALUE orig_thread; / * block to generate the thread * / 
  572 VALUE wrapper; / * block generation when ruby_wrapper * / 
  573 struct BLOCK * prev; 
  574); 

  553 struct BLOCKTAG ( 
  554 struct RBasic super; 
  555 long dst; / * destination that is to return * / 
  556 long flags; / * BLOCK_DYNAMIC, BLOCK_ORPHAN * / 
  557); 

  576 # define BLOCK_D_SCOPE 1 / * an independent variable scope block * / 
  577 # define BLOCK_DYNAMIC 2 / * BLOCK Ruby is obtained from the program * / 
  578 # define BLOCK_ORPHAN 4 / * origin to the end of the FRAME * / 

(eval.c) 

frame pointer does not pay attention. This means that struct FRAME until the contents For each copy of the fact that you hold. struct FRAME (for speed) Stack on a solid machine will be placed in secure, but, BLOCK of origin FRAME than Because of the potential longevity of the case the copy.

Also struct BLOCKTAG is that the separation is a block from multiple Proc may also generate the same block in order to determine that. Vu same Rock-generated Proc is the same BLOCKTAG with.

ruby_iter

Stack ruby_iter is calling the current method of enumeration (Block with whether the call). Frame is struct iter . But more unity among the stack frame and consider ITER referred to it.

ruby_iter

 
  767 static struct iter * ruby_iter; 

  763 struct iter ( 
  764 int iter; / * * following three / 
  765 struct iter * prev; 
  766); 

  769 # define ITER_NOT 0 / * methods are currently evaluating the non-enumeration * / 
  770 # define ITER_PRE 1 / * * I call the method of enumeration / 
  771 # define ITER_CUR 2 / * is currently evaluating methods of enumeration * / 

(eval.c) 

Enumeration of the method or not, but should be determined by the unit, Thus struct FRAME and another structure that is available, why?

Methods "iterator" If you need to tell it is natural and The "enumeration," even if the facts must be知らせなけれ. However, the order BLOCK to load a whole is very heavy. The caller variables References such as waste disposal is also increasing. So BLOCK instead of more small Com and light ITER to積もう, he said. It is more Chapter 16, described the block.

ruby_dyna_vars

Block local variable area. The second part of the frame structure is also seen struct RVarmap . It is simply VARS called.

struct RVarmap

 
   52 struct RVarmap ( 
   53 struct RBasic super; 
   54 ID id; / * variable name * / 
   55 VALUE val; / * The value * / 
   56 struct RVarmap * next; 
   57); 

(env.h) 

Note that I ask is, struct RVarmap list is the first one in Kulun It's that time (Figure 3). And one frame in one low - In response to the local variable scope. "Local variable scope", not "block KUROKARU variable scope "because the block is nested in places like He is represented by one list. Blocks separated when the parser and look like, id = 0 - RVarmap (header) represented by. This will also further delay. Chapter 16, described the block.

(vars)
Figure 3: ruby_dyna_vars

ruby_class

ruby_class is def and the method to define when the target class, respectively. The statement is usually the class definition self is because the class ruby_class == self . , And top-level eval , instance_eval a special method in the middle self! = ruby_class to be.

ruby_class frame is simple VALUE in the frame structure is not. , Etc. POKU playing a stack of thousand? But it than I ever prev Po There is no inter-structure is a lot of it, what do you stack the The? Answer the following sections.

After the frame is CLASS to call them.

ruby_cref

ruby_cref reference to the class respectively. Frame remains the same nomenclature, CREF said. The structure is……

ruby_cref

 
  847 static NODE * ruby_cref = 0; 

(eval.c) 

Why…… NODE . This is simply "does not need a new definition, VALUE 's finger Up structure "It used to be just. Node type is NODE_CREF , The allocation is a member of the following.

union members access macro used in the way
u1.value nd_clss outside of class ( VALUE ) < td>
u2 - -
u3.node nd_next previous CREF to hold

Member name is nd_next can actually hold that "before (prev)" of CREF . For example, following the example of a program to explain the actual figure.

 
class A 
   class B 
     class C 
       nil # (A) 
     end 
   end 
end 

(A) to evaluate the code when, ruby_cref is shown in Figure 4. So on.

(crefstack)
Figure 4: ruby_cref

But each time drawing and writing of繁雑is intended to obscure. So in what follows Figure 4 and the same state as follows words to it.

 
A ← B ← C 

PUSH / POP macro

More than a stack frame structure would also push for macro-Pop is Have already done that. For example FRAME , PUSH_FRAME () and POP_FRAME () , the At this time. Since coming real soon and is using the time to explain it Especially now.

other states

The main stack is not important, but so, ruby evaluator of the other There are several states. I'll list easily. However stack, and these are Not necessarily. Rather, it is not so much.

variable name - meaning
scope_vmode int default method definition visibility
ruby_in_eval int rating after the start of the Perth
ruby_current_node NODE * currently evaluating the file name and line number
ruby_safe_level int $ SAFE
ruby_errinfo VALUE exception being processed
ruby_wrapper VALUE isolated environment for RAPPAMOJURU

module definition

class statement module statement, class-specific definitions and the implementation of any Similar. Three similar ones continue to look at it is not fun and this is the most A small number of elements (so simple) module look at the statement to it.

First of all, module What sentence? In other words, that is what is起こるべき module a statement? Several characteristics of the whole world.

These things having to do what I do, it will be on the point. Let's look at the code to it.

survey

▼ source program

 
module M 
   a = 1 
end 

▼ corresponding syntax tree

 
NODE_MODULE 
nd_cname = 9621 (M) 
nd_body: 
     NODE_SCOPE 
     nd_rval = (null) 
     nd_tbl = 3 [_ ~ a] 
     nd_next: 
         NODE_LASGN 
         nd_cnt = 2 
         nd_value: 
             NODE_LIT 
             nd_lit = 1: Fixnum 

nd_cname 名らしいmodules. cname is Const NAME or Class NAME, etc. CHIRAKA. And some have tried to dump nd_body always NODE_SCOPE on. As a member of nd_tbl table is a local variable And in that, struct SCOPE and the name is similar to that at the thought of this NODE_SCOPE scope of local variables to produce an important role in the There is no doubt seem

NODE_MODULE

, rb_eval () - NODE_MODULE handlers to look at. rb_raise () relations, Error handling, and the main topic of the relationship is a thin cut back on BASSARI. So far more than 200 pages It also cut back on work done on it, because every other source code to be示さなく Sure.

rb_eval () - NODE_MODULE (condensed version)

 
case NODE_MODULE: 
   ( 
       VALUE module; 

       if (rb_const_defined_at (ruby_class, node-> nd_cname)) ( 
           / * Already created modules to gain the kind of * / 
           module = rb_const_get (ruby_class, node-> nd_cname); 
       ) 
       else ( 
           / * Create a new module and a constant set * / 
           module = rb_define_module_id (node-> nd_cname); 
           rb_const_set (ruby_cbase, node-> nd_cname, module); 
           rb_set_class_path (module, ruby_class, rb_id2name (node-> nd_cname)); 
       ) 

       result = module_setup (module, node-> nd_body); 
   ) 
   break; 

First module is ruby_class (inside the module) on the nest It defines that you want to see. It is ruby_class for rb_const_xxxx () to call it understandable. Only once ruby_cbase for Players, but they are usually ruby_class the same, so it's fine to ignore. This difference is an issue that first and foremost.

The first half, if , divided into the modules, Predefined already whether or not Check. Ruby is one of several modules that can "add" definition Because you can.

 
module M 
   def a # M # a define 
   end 
end 
Add module M # define (or redefine not override) 
   def b # M # b define 
   end 
end 

This program is a module M in a and b is defined by the two methods.

In this case, the second M definition of the module M is already in constant or And, when used alone to retrieve it. Constant M If there is no definition of the first And ( rb_define_module_id () ) to make the module.

Finally module_setup () However, this function is performed on the body module statement. Sentence statement modules as well as class and class-specific statement of module_setup () run. "None of the three similar statement," and said it is the reason. Let's argument node-> nd_body ( NODE_SCOPE ) that the passing The attention you want.

module_setup ()

Module, or class, or class-specific body of the execution sentence is carried out module_setup () . Ruby stack of mass action is finally coming to tell me.

module_setup ()

 
3424 static VALUE 
3425 module_setup (module, n) 
3426 VALUE module; 
3427 NODE * n; 
(3428 
3429 NODE * volatile node = n; 
3430 int state; 
3431 struct FRAME frame; 
3432 VALUE result; / * OK * / 
3433 TMP_PROTECT; 
3434 
3435 frame = * ruby_frame; 
3436 frame.tmp = ruby_frame; 
3437 ruby_frame = &frame; 
3438 
3439 PUSH_CLASS (); 
3440 ruby_class = module; 
3441 PUSH_SCOPE (); 
3442 PUSH_VARS (); 
3443 
           / * (A) ruby_scope-> local_vars initialization * / 
3444 if (node-> nd_tbl) ( 
3445 VALUE * vars = TMP_ALLOC (node-> nd_tbl [0] +1); 
3446 * vars + + = (VALUE) node; 
3447 ruby_scope-> local_vars = vars; 
3448 rb_mem_clear (ruby_scope-> local_vars, node-> nd_tbl [0]); 
3449 ruby_scope-> local_tbl = node-> nd_tbl; 
3450) 
3451 else ( 
3452 ruby_scope-> local_vars = 0; 
3453 ruby_scope-> local_tbl = 0; 
3454) 
3455 
3456 PUSH_CREF (module); 
3457 ruby_frame-> cbase = (VALUE) ruby_cref; 
3458 PUSH_TAG (PROT_NONE); 
3459 if ((state = EXEC_TAG ()) == 0) ( 
3460 if (trace_func) ( 
3461 call_trace_func ( "class", ruby_current_node, ruby_class, 
3462 ruby_frame-> last_func, 
3463 ruby_frame-> last_class); 
3464) 
3465 result = rb_eval (ruby_class, node-> nd_next); 
3466) 
3467 POP_TAG (); 
3468 POP_CREF (); 
3469 POP_VARS (); 
3470 POP_SCOPE (); 
3471 POP_CLASS (); 
3472 
3473 ruby_frame = frame.tmp; 
3474 if (trace_func) ( 
3475 call_trace_func ( "end", ruby_last_node, 0, 
3476 ruby_frame-> last_func, ruby_frame-> last_class); 
3477) 
3478 if (state) JUMP_TAG (state); 
3479 
3480 return result; 
3481) 

(eval.c) 

In one breath to read the rather too large. IRANA likely, it's time to cut back to it.

First trace_func 消せるArea is unconditional.

Idiom relationship tag is visible, so it will become more clear, Ruby's ensure to represent the SHIMAOU.

Starting immediately after the function, eliminating the argument n to a local variable node to the assignment, node in volatile and they have another assignment that is not completely This is to avoid known GC. So the first argument from node to have Meaning is not changed.

The first half of the function, ruby_frame and had to mess it up and Late ruby_frame = frame.tmp is nothing if not in pairs. Here is a look at the future, just ruby_frame - push pop and Consider it.

Also (A) to comment on the code ruby_scope-> local_vars initialization, and will I stopped by. Later.

Consequently, the only summarized below.

module_setup (condensed version)

 
static VALUE 
module_setup (module, node) 
     VALUE module; 
     NODE * node; 
( 
     struct FRAME frame; 
     VALUE result; 

     push FRAME 
     PUSH_CLASS (); 
     ruby_class = module; 
     PUSH_SCOPE (); 
     PUSH_VARS (); 
     ruby_scope-> local_vars initialization 
     PUSH_CREF (module);
ruby_frame-> cbase = (VALUE) ruby_cref; 
     begin 
         result = rb_eval (ruby_class, node-> nd_next); 
     ensure 
         POP_TAG (); 
         POP_CREF (); 
         POP_VARS (); 
         POP_SCOPE (); 
         POP_CLASS (); 
         pop FRAME 
     end 
     return result; 
) 

node-> nd_next $ B $ r rb_eval () $ B $ 7 $ F $ $ $ k $ N $ G $ 3 $ l $,% b% 8% e ! <% kJ8K \ BN $ N% 3! <% I $ G $ B $ "$ k $ 3 $ H $ O $$$$$ H $ 7 $ h $ &! # LdBj $ O $ = $ l0J30 $ @! # 8 + $ k $ Y $-%]%$% s% H $ O8 ^ $ D $ "$ k! #

$ B = gHV $ KD4:: $ 7 $ F $ $ $ 3 $ &! #

$ B% m !<%+% kJQ? t% 9% 3! <% W $ N @ 8 @.

PUSH_SCOPE () $ B $,% m !<%+% kJQ? tNN0h $ r @ Q $_!"< code> PUSH_VARS () $ B $,% V% m % C% /% m !<%+% k $ BJQ? TNN0h $ r @ Q $ `$ o $ 1 $@$+$ i!" $ 3 $ NFs $ D $ G? 7 $ 7 $ $% m !<%+% kJQ? T% 9% 3! <% W $,: n $ j $ B = P $ 5 $ l $ k $ 3 $ H $ K $ J $ k! # $ 3 $ l $ i $ N %^%/% m $ NCf? H $ rDI $ C $ F! "

$ B " ' PUSH_SCOPE () POP_SCOPE ()

 
  852 # define PUSH_SCOPE () do (\ 
  853 volatile int _vmode = scope_vmode; \ 
  854 struct SCOPE * volatile _old; \ 
  855 NEWOBJ (_scope, struct SCOPE); \ 
  856 OBJSETUP (_scope, 0, T_SCOPE); \ 
  857 _scope-> local_tbl = 0; \ 
  858 _scope-> local_vars = 0; \ 
  859 _scope-> flags = 0; \ 
  860 _old = ruby_scope; \ 
  861 ruby_scope = _scope; \ 
  862 scope_vmode = SCOPE_PUBLIC 

  869 # define POP_SCOPE () \ 
  870 if (ruby_scope-> flags & SCOPE_DONT_RECYCLE) (\ 
  871 if (_old) scope_dup (_old); \ 
  872) \ 
  873 if (! (Ruby_scope-> flags & SCOPE_MALLOC)) (\ 
  874 ruby_scope-> local_vars = 0; \ 
  875 ruby_scope-> local_tbl = 0; \ 
  876 if (! (Ruby_scope-> flags & SCOPE_DONT_RECYCLE) & & \ 
  877 ruby_scope! = Top_scope) (\ 
  878 rb_gc_force_recycle ((VALUE) ruby_scope); \ 
  879) \ 
  880) \ 
  881 ruby_scope-> flags | = SCOPE_NOSTACK; \ 
  882 ruby_scope = _old; \ 
  883 scope_vmode = _vmode; \ 
  884) while (0) 

(eval.c) 

SCOPE $ B $ b%?% 0 $ H0l = o $ G !"%^% 7% s% 9%?% C% / $ HF14 | $ 5 $; $ F% 9%? % C% / $ r: n $ j = P $ 7 $ F $ $ $ B $ k $ h $&$@!#$?$HyL / $ K0c $ & $ N $ O! "$ 3 $ A $ i $ O% 9%?% C% /% U% l! <% `$ NNN0h <+ BN $ O% R! < $ B% W $ + $ i3NJ] $ 7 $ F $ * $ j! "% 9%?% C% / 9 = B $ $ r: n $ j = P $ 9 $? $ A $ K% ^% 7% s% 9%?% C% / $ r; H $ C $ B $ F $ $ $ k $ H $$$&$ H $ 3 $ m $ @ $ m $ &! J? ^ 5 $ B! K! #

(scopestack)
$ B? ^ 5: $ B% ^% 7% s% 9%?% C% / $ HSCOPE $ B% 9%?% C% /

$ B $ = $ l $ H %^%/% m $ NCf $ G2? EY $ b = P $ F $ / $ k SCOPE_ $ B $ J $ s $? $ I $ H $$$&% U% i% 0 $ K $ D $ $ $ F $ O! " $ B3F% 9%?% C% /% U% l !<%`$ N5-217A <0 $ H% V% m% C% / $ N $ 3 $ H $ rA4 $ FOC $ 7 $ F $ + $ i $ G $ J $ $ $ H $ B @ bL @ $ G $ - $ J $ $! # Bh16 $ B> O! X% V% m% C% /! Y $ G $ ^ $ H $ a $ F $ d $ k $ 3 $ H $ K $ 9 $ k! #

$ B% m !<%+% kJQ? tNN0h $ N3NJ]

$ B2? EY $ b8 @ $ C $ F $ $ $ kDL $ j% m !<%+% kJQ? T% 9% 3! <% W $ O struct SCOPE $ B $ GI = $ 5 $ l $ k $ N $ B $@$,!"< code> struct SCOPE $ B $ OJ8; zDL $ j! V% 9% 3! <% W! W $ G $ "$ C $ F!"% M! <% +% kJQ? t $ r $ B3JG <$ 9 $ k Y # E * $ K8 @ $ & $ H! "NN0h $ X $ N%]% $% s%? $ O $ B $ "$ C $ F $ b $ = $ N @ h $ NG [Ns $, $ J $ $ $ N $@!#$=$ NG [Ns $ r =` Hw $ 7 $ F $ $ $ k $ N $, module_setup () $ B $ N

$ B " '% m !<%+% kJQ? t% 9% m% C% H $ N =` Hw

 
3444 if (node-> nd_tbl) ( 
3445 VALUE * vars = TMP_ALLOC (node-> nd_tbl [0] +1); 
3446 * vars + + = (VALUE) node; 
3447 ruby_scope-> local_vars = vars; 
3448 rb_mem_clear (ruby_scope-> local_vars, node-> nd_tbl [0]); 
3449 ruby_scope-> local_tbl = node-> nd_tbl; 
3450) 
3451 else ( 
3452 ruby_scope-> local_vars = 0; 
3453 ruby_scope-> local_tbl = 0; 
3454) 

(eval.c) 

$ BKAF, $ N TMP_ALLOC () $ B $ O $ C $ FGC $ B $ r9MN8 $ 7 $ J $ / $ F $ h $ $! K alloca () $ B! W $ @! #

$ B $ = $ l $ G node-> nd_tbl $ B $ K $ O O! X9 = J8LZ $ N9 = C [! Y $ G $ d $ C $?% M !<%+% kJQ? TL> $ N $ B% F! <% V% k $, F ~ $ C $ F $ $ $ k! # $ D $ ^ $ j nd_tbl [0] $ B $ K% F! <% V% k% 5 %$%:$, F ~ $ C $ F $ $ $ F! " $ B; D $ j $ O ID $ B $ NG [Ns $ K $ J $ C $ F $ $ $ k !#$=$ N% F! <% V% k $ O SCOPE $ B $ N local_tbl $ B $ K $ = $ N $ B $ ^ $ ^ 0 \? "$ 7 !"$^$?% m !<%+% kJQ? T $ NCM $ r3JG <$ 9 $ k $? $ A $ K local_vars $ B $ r3d $ jEv $ F $ B $ F $ $ $ k $ h $&$@!#$ 3 $ N $"$?$ j $ OJ6 $ i $ o $ 7 $ $ $ N $ G! V $ 3 $ C $ A $, JQ? TL >! W! V $ 3 $ C $ A $, CM! W $ B $ H = q $ -9 ~ $ s $ G $*$/$ H $$$$!#< code> tbl $ B $, IU $/$[$&$, L> A0 $ G $ "$ k! #

$ B $ 5 $ F! " Local_vars $ B $ N3d $ jEv $ F $ r: Y $ + $ / 8 + $ F $ _ $ h $&!#< code> local_tbl [0] $ B $,% m! <% + $ B% kJQ? T $ N? T $@$+$ i! "$ J $<$+% 5 %$%:$ r +1 $ B $ 7 $ F3d $ jEv $ F $ F $ $ $ k! # $ 3 $ 3 $ K $ O: # EY $ O module_setup () $ B $ N0z? t node $ B! J NODE_SCOPE $ B! K $ rF ~ $ l $ F $ $ $ k $ h $&$@!# $ B $ D $ ^ $ j $ 3 $ NJ8 $,=*$ o $ C $? $ H $ 3 $ m $ G? ^ 6 $ B $ N $ h $ & $ K $ J $ k! #

(localvars)
$ B? ^ 6: ruby_scope-> local_vars

$ B $ 3 $ N node $ B $ O $ I $ 3 $ G; H $ o $ l $ F $ $ $ k $ N $ @ $ m $ &! # local_vars $ B% a% s% P $ r @ v $ C $ F $_$?$,< code> eval.c $ B $ G $ O% $% s % G% C% /% 9 -1 $ B $ X $ N %"%/%;% 9 $ O $ B8 + Ev $? $ I $ J $ $! # BP>]% U %!%$% k $ r9-$ 2 $ F $ _ $ k $ H! " Gc.c $ B $ G %"%/%;% 9 $ 7 $ F $$$?!#

$ B " ' rb_gc_mark_children () $ B! = T_SCOPE

 
  815 case T_SCOPE: 
  816 if (obj-> as.scope.local_vars & & 
             (obj-> as.scope.flags & SCOPE_MALLOC)) ( 
  817 int n = obj-> as.scope.local_tbl [0] +1; 
  818 VALUE * vars = & obj-> as.scope.local_vars [-1]; 
  819 
  820 while (n -) ( 
  821 rb_gc_mark (* vars); 
  822 vars + +; 
  823) 
  824) 
  825 break; 

(gc.c) 

$ B $ D $ ^ $ j $ I $ & $ d $ i $ 3 $ l $ O node $ B $ rGC $ B $ + $ iJ] 8n $ 9 $ k $? $ A $ N ; E3] $ 1 $ i $ 7 $$!#$@$,$ J $<%^!< $ B% / $ 7 $ J $ $ $ H $ $ $ 1 $ J $ $ $ N $ @ $ m $&!#< code> node $ B $ O $ o $ 6 $ o $ 6 volatile $ B $ J% m !<%+% kJQ? t $ KF ~ $ l $ B $ F $ "$ k $ N $@$+$ i!" Module_setup () $ B $ N

$ B @ 5D> $ K8 @ $ & $ HI.

$ B " ' ruby_scope-> local_tbl

 
3449 ruby_scope-> local_tbl = node-> nd_tbl; 

(eval.c) 

$ B% Q! <% 5 $ GMQ0U $ 7 $?% M !<%+% kJQ? TL> $ N% F! <% V% k $ r $ = $ N $^$^; H $ C $ F $ $ $ k! # $ 3 $ N% F! < $ B% V% k $ O $ $ $ D2rJ | $ 5 $ l $ k $ N $ @ $ m $&!#$=$ l $ O $ 3 $ N node $ B $,; 2> H $ 5 $ l $ J $ / $ J $ C $? $ H $ - $ G $ B $ "$ k! # $ G $ O node $ B $ O $ $ $ D2rJ | $ 5 $ l $ k $ Y $-$@$ m $&!#$=$ l $ O $ 3 $ N9T $ GBeF ~ $ r9T $ C $? SCOPE $ B $, A4 $ F> C $ ($ F $ + $ i $ G $ "$ k! # $ G $ O $ = $ l $ O $ $ $ D $ N $ 3 $ H $ @ $ m $&$+!#

SCOPE $ B $ O $ = $ l $, @ 8 @. $ 5 $ l $ k860x $ K $ J $ C $? J8 $ h $ j $ bD9 @ 8 $ - $ 9 $ k $ 3 $ H $,$"$ k! # $ BBh16 $ B> O! X% V% m% C% /! Y $ G @ bL @ $ 9 $ k $ H $ * $ j! " Proc $ B% *% V% 8 %'%/% H $ r @ 8 @. $ 9 $ k $ H $ = $ B $ 3 $ + $ i SCOPE $ B $,; 2> H $ 5 $ l $ k $ + $ i $@!#$ D $ ^ $ j module_setup () $ B $,=*$ o $ C $ F $ b $ = $ B $ 3 $ G: n $ C $? SCOPE $ B $, MQ: Q $ _ $ K $ J $ k $ H $ O8B $ i $ J $$!#$@$+ $ i node $ B $ O module_setup () $ B! J $ N% 9%?% C% /% U% l !<%`! K $ + $ i; 2> H $ 5 $ l $ F $ $ $ k $ @ $ 1 $ G $ OIT == J, $ B $ G! " SCOPE $ B $ + $ i! VD> @ \ $ K! W; 2> H $ 5 $ l $ F $ $ $ J $ / $ F $ O $ J $ i $ J $ $ $ N $ @! #

$ B $^$?$=$ N0lJ) $ G% m !<%+% kJQ? T $ N volatile node $ B $ b30 $; $ J $$!#$ G $ J $ $ $ H local_vars $ B $ KBeF ~ $ 9 $ k $ ^ $ G $ N $"$$$@< code> node $ B $, Ch $ KIb $ $ $ F $ 7 $ ^ $ & #

$ B $ 7 $ + $ 7 !"$=$ l $ J $ i: # EY $ O SCOPE $ B $ N local_vars $ B $,$^$:$ $ $ N $ G $ O $ J $$$@$ m $&$+!# TMP_ALLOC () $ B $ O8 @ $ C $? $ H $ * $ j% 9%?% C% / 3d $ jEv $ F $ J $ N $ G! " module_setup () $ B $ N $ B =* N; $ HF1; ~ $ KL58z $ K $ J $ C $ F $ 7 $^$&!#$ 3 $ l $, Proc $ B $ r @ 8 @. $ 7 $?; ~ E @ $ G $ B $$$-$ J $ j malloc () $ B3d $ jEv $ F $ K @ Z $ jBX $ ($ k $ h $ & $ K $ J $ C $ F $ $ $ k $ N $@!#> \ $ 7 $ $ $ 3 $ H $ O $ BBh16 $ B> O! X% V% m% C% /! Y $ G2r @ b $ 9 $ k! #

$ B $ = $ 7 $ F: G8e $ K! " Rb_mem_clear () $ B $ O0 $ B = VALUE $ B $ NG [Ns $ K $ BBP $ 9 $ k Qnil $ B = array.c $ B! K! # $ 3 $ l $ GA4 $ F $ NDj5A: Q $ _% m !<%+% kJQ? T $, nil $ B $ K = i4 | 2 = $ 5 $ l $ k! #

TMP_ALLOC ()

$ B TMP_ALLOC () $ B $ rFI $ b $ &! # $ B $ 3 $ N %^%/% m $ O module_setup () $ B $ N: G = i $ N $[$&$ K $ R $ C $ = $ j $ HB8: _ $ 9 $ k TMP_PROTECT $ B $ HAH $ K $ J $ C $ F $ $ $ k! # E57? E * $ J; H $$$+$?$ O $ 3 $&$@!#

 
VALUE * ptr; 
TMP_PROTECT; 

ptr = TMP_ALLOC (size); 

$ B $ J $ < TMP_PROTECT $ B $,% m !<%+% kJQ? TDj5A $ N0LCV $ K $ "$ k $ + $ H $$$&$ H! D! D $ BDj5A $ r8 + $ F $ _ $ h $ &! #

$ B " ' TMP_ALLOC ()

 
1769 # ifdef C_ALLOCA 
1770 # define TMP_PROTECT NODE * volatile tmp__protect_tmp = 0 
1771 # define TMP_ALLOC (n) \ 
1772 (tmp__protect_tmp = rb_node_newnode (NODE_ALLOCA, \ 
1773 ALLOC_N (VALUE, n), tmp__protect_tmp, n), \ 
1774 (void *) tmp__protect_tmp-> nd_head) 
1775 # else 
1776 # define TMP_PROTECT typedef int foobazzz 
1777 # define TMP_ALLOC (n) ALLOCA_N (VALUE, n) 
1778 # endif 

(eval.c) 

$ B! D! D% m !<%+% kJQ? T $ rDj5A $ 7 $ F $ $ $ k $ + $ i! # $ H $$$&$ N $, Ez $($@!#

$ BBh5 $ B> O! X %,!]% Y! <% 8% 3% l% /% 7% g% s! Y $ G2r @ b $ 7 $? $ H $ * $ j! " # ifdef C_ALLOCA $ B $ N! J% M% $% F% #% V $ N alloca () $ B $, $ J $ $! K4D6-$ G $ O malloc () $ B $ G alloca () $ B $ r %(%_% e% l! <% H $ 7 $ F $ $ $ k! # $ B $ 7 $ + $ 7% a% =% C% I $ N0z? T $ H $$$&$ N $ OEvA3 VALUE $ B $ G $ "$ j!"% R! < % W $ K VALUE $ B $ rCV $ $ $ B $ F $ 7 $^$&$ HGC $ B $ G8! = P $ G $ - $ J $ / $ J $ C $ F $ 7 $^$&!#$=$ 3 $ G NODE $ B $ r7PM3 $ 7 $ FL5M) LpM) GC $ B $ NBP>] $ K $ 9 $ k! J? ^ 7 $ B! K! #

(tmpprotecttmp)
$ B? ^ 7: NODE $ B7PM3 $ GNN0h $ r% 9%?% C% / $ KHK $.;_$ a $ k

$ B0lJ }!"??$ N alloca () $ B $,$"$ k4D6-$ G $ OIaDL $ K alloca () $ B $ r; H $ ($ P $$$$$ N $ G TMP_PROTECT $ B $ OI, MW $ J $$!#$=$ 3 $ GL532 $ J <0 $ rE, Ev $ KF ~ $ l $ F $*$/!#

$ B $ H $ 3 $ m $ G! "$ J $ <$ 3 $ 3 $ ^ $ G $ 7 $ F alloca () $ B $ r; H $$$?$,$ k $ N $ @ $ m $&$+!# $ B $ = $ NM) M3 $ OC1 $ K! V alloca () $ B $ N $[$&$,< code> malloc () $ B $ h $ jB .$$$+$ i! W $@$=$&$@!# $ B $ = $ N $ / $ i $ $ $ N0c $ $ $ O $ I $ & $ G $ b $$$$$ h $ & $ J5 $ $ b $ 9 $ k $ N $@$,!" $ J $ K $ 7 $ m $ BI> 2A4o% 3% "$ O ruby $ B: GBg $ N% \% H% k% M% C% / $ J $ N $ G!" 0J2

$ B% a% =% C% IDj5A @ h $ NJQ99

$ B% 9%?% C% / ruby_class $ B $ NCM $,$=$ N $ H $ - $ N% a% =% C% I $ NDj5A @ h% /% i % 9 $ K $ J $ k! # 5U $ K8 @ $ B $ & $ H ruby_class $ B $ KCM $ r% W% C% 7% e $ 9 $ k $ HDj5A @ h% /% i% 9 $, JQ $ o $ k! # $ = $ l $ 3 $=$,%/% i $ B% 9J8 $ KI, MW $ J $ 3 $ H $@!#=>$ C $ F module_setup () $ B $ G $ b PUSH_CLASS () $ B $ 7 $ J $ 1 $ l $ P $ J $ i $ B $ J $$!#$=$ l $, $ 3 $ N% 3! <% I $ @! #

 
PUSH_CLASS (); 
ruby_class = module; 
       $ B! ' 
       $ B! ' 
POP_CLASS (); 

$ B $ J $ < PUSH_CLASS () $ B $ 7 $ F $ + $ i ruby_class $ B $ K2 ~ $ a $ FBeF ~ $ 7 $ F $ $ $ k $ N $ @ $ m $ &! # $ B $ 3 $ l $ ODj5A $ r8 + $ k $ H0U30 $ H $ "$ C $ 5 $ j $ o $ + $ k! #

$ B " ' PUSH_CLASS () POP_CLASS ()

 
  841 # define PUSH_CLASS () do (\ 
  842 VALUE _class = ruby_class 

  844 # define POP_CLASS () ruby_class = _class; \ 
  845) while (0) 

(eval.c) 

PUSH_CLASS () $ B $ 7 $ F $ b ruby_class $ B $, = q $ -49 $ o $ k $ o $ 1 $ G $ O $ J $ $ $ N $ G !"$=$ N $ "$ H $ K

PUSH_CLASS () $ B $ N0z? t $ K% /% i% 9 $ rEO $ 9 $ h $ & $ K $ 9 $ l $ P $ b $ C $ H $ - $ l $ $ $ J %^%/% m $ K $ J $ B $ k $ 8 $ c $ J $$$+! D! D $ H $$$&$ N $ OA4 $/$=$ NDL $ j $ J $ N $@$,!"% W% C% 7% e $ 9 $ kA0 $ K% /% i% 9 $ B $, F @ $ i $ l $ J $ $> l = j $,$"$ k $? $ A $ K $ 3 $&$$$&$ 3 $ H $ K $ J $ C $ F $ $ $ k! #

$ B% /% i% 9 $ N% M% 9% H

ruby_cref $ B $ O pJs $ rI = 8 = $ 7 $ F $ $ $ k $ N $ @ $ C $? # $ B $@$+$ i% b% 8% e! <% KJ8 $ d% /% i% 9J8 $ G ruby_cref $ B $, @ Q $ ^ $ l $ k $ N $ OEvA3M = A [$ G $ - $ k! # module_setup () $ B $ G $ O $ 3 $ s $ J $ U $ & $ K @ Q $ s $ G $$$?!#

 
PUSH_CREF (module); 
ruby_frame-> cbase = (VALUE) ruby_cref; 
     $ B! ' 
     $ B! ' 
POP_CREF (); 

$ B $ 3 $ 3 $ G! " Module $ B $ ODj5ACf $ N% b% 8% e! <% K $ G $" $ k! # PUSH_CREF () $ B $ H POP_CREF () $ B $ NDj5A $ b8 + $ F $ * $ 3 $ &! #

$ B " ' PUSH_CREF () POP_CREF ()

 
  849 # define PUSH_CREF (c) \ 
           ruby_cref = rb_node_newnode (NODE_CREF, (c), 0, ruby_cref) 
  850 # define POP_CREF () ruby_cref = ruby_cref-> nd_next 

(eval.c) 

PUSH_SCOPE () $ B $ J $ I $ N $ h $ & $ J $ H $ s $ G $ b $ J $ $ 9) IW $,$"$ k $ o $ 1 $ G $ b $ J $ /! " $ BHs> o $ K07 $ $ $ d $ 9 $$!#$ d $ O $ j $?$^$ K $ O $ 3 $&$$$&$ N $ b $ J $ $ $ H: $ $ k #

$ B $ 9 $ k $ H; D $ kLdBj $ O ruby_frame-> cbase $ B $, 2? $ R0UL # $ 7 $ F $ $ $ k $ N $ + $ H $ $ $ & $ 3 $ H $@$,!" $ B $ 3 $ l $ O8 =: _ $ N FRAME $ BFb $ + $ iDj? T $ d% /% i% 9JQ? T $ r; 2> H $ 9 $ k $ N $ K; H $ &> pJs $ G $ "$ k! # $ B> \ $ 7 $ $ $ 3 $ H $ OK \> O $ N: G8e $ N @ a $ G8 + $ F $$$/!#

$ B% U% l !<%`$ N $ 9 $ j $+$(

$ B: G8e $ K ruby_frame $ B $ NA `: n $ KCmL \ $ 9 $ k !#$^$:$ ODj5A $ N $ H $ 3 $ m $ + $ i! #

 
struct FRAME frame; 

$ B %]%$% s%? $ G $ O $ J $$!#$ D $ ^ $ j $ 3 $ l $ O% ^% 7% s% 9%?% C% /> e $ K < code> FRAME $ B $ r% Y%? CV $ - $ G3NJ] $ B $ 9 $ k $ H $ $ $ & 0UL # $ G $ "$ k! # Ruby $ B% 9%?% C% / $ N4IM) 9 = B $ $ b% m !<%+% kJQ? TNN0h $ b% ^% 7% s $ B% 9%?% C% /> e $ @ $ C $?$,!"$ J $ s $ H FRAME $ B $ K; j $ C $ F $ O9 = B $ BN $ ^ $ k $ 4 $ H% 9%?% C% /> e $ KCV $ B $ $ $ F $ 7 $^$*$&$ H $$$&$ N $@!#< code> ruby $ B $,%^% 7% s% 9%?% C% / $ r% P %+?)$$$ 9 $ k $ N $ b $ 3 $&$$$& $ B! V>. $ 5 $ J9) IW! W $, @ Q $ _ = E $ J $ C $? @ .2 L $ J $ N $ G $ "$ k! #

$ B $ = $ 7 $ F frame $ B $ r2? $ D $ i $ $ $ m $ $ $ m $ 7 $ F $ $ $ k $ H $ 3 $ m $ r8 + $ h $ &! #

 
frame = * ruby_frame; / * $ B9 = B $ BN $ ^ $ k $ 4 $ H% 3% T! <* / 
frame.tmp = ruby_frame; / * $ B85 $ NFRAME $ B $ rGC $ B $ + $ iJ] 8n $ 9 $ k * / 
ruby_frame = &frame; / * ruby_frame $ B $ r: 9 $ 7BX $ ($ k * / 
         $ B! ' 
         $ B! ' 
ruby_frame = frame.tmp; / * $ BLa $ 9 * / 

$ B $ D $ ^ $ j ruby_frame $ B $ r0l; ~ E * $ K: 9 $ 7BX $ ($ F $ $ $ k! J% W% C% 7% e $ G $ O $ J $ $! K $ h $&$@!#$ I $ B $ & $ 7 $ F $ 3 $ s $ J $ 3 $ H $ r $ 7 $ F $ $ $ k $ N $ @ $ m $ &! #

FRAME $ B $ H $$$&$ N $ O! V% a% =% C% I8F $ S = P $ 7 $ G @ Q $ ^ $ l $ k! W $ H @ bL @ $ 7 $?$,!"$ h $ j87L) $ K $ B8 @ $ & $ H! VRuby $ B% W% m% 0% i% `$ r ruby_frame-> cbase $ B $ J $ I $ r8 + $ k $ H $ =$&$$$& 0UL # 9g $ $ $, $ B8 + $ F $ K $ b! V: G8e $ K8F $ s $ @% a% =% C% IL>! W $ rI = $ 9 last_func $ B $ J $ I $ b $=$&$@!#

$ B $ G $ O $ I $ & $ 7 $ F $ 3 $ 3 $ GAGD> $ K FRAME $ B $ r @ Q $ ^ $ J $$$+$ H $$$&$ H ! "$ 3 $ 3 $ O FRAME $ B $ r @ Q $ s $ G $ B $$$$> l = j $ G $ O $ J $$$+$ i $ G $ "$ k! #; EAH $_$+$ i8 @ $ ($ PK \ Ev $ O FRAME $ B $ r @ Q $_$?$$$ o $ 1 $ B $@$,!"< code> FRAME $ B $ r @ Q $ `$ HNc30 $, H / @ 8 $ 7 $? $ H $ - $ K% W% m% 0% i% `$ N% P% C% /% H% l! <% 9 $ K $ = $ B $ l $, = P $ F $ 7 $^$&!#% P% C% /% H% l! <% 9 $ H $$$&$ N $ O

 
% Ruby t.rb 
t.rb: 11: in `c ': some error occured (ArgumentError) 
         from t.rb: 7: in `b ' 
         from t.rb: 3: in `a ' 
         from t.rb: 14 

$ B $ 7 $ + $ 7% b% 8% e! <% KJ8 $ d% /% i% 9J8 $ O% a% =% C% I8F $ S = P $ 7 $ G $ O $ J $$$+$ i $ 3 $ NCf $ K $ O $ B = P $ F $ - $ F $ [$ 7 $ / $ J $$!#$@$+$ i! V @ Q $^$:$ K! W! "! V: 9 $ 7BX $ ($ k! W $ o $ 1 $ @! #

$ B% a% =% C% I $ NDj5A

$ B% b% 8% e! <% KDj5A $ N

$ BD4::

$ B "'%=!<% 9% W% m% 0% i% `

 
def m (a, b, c) 
   nil 
end 

$ B " 'BP1 ~ $ 9 $ k9 = J8LZ

 
NODE_DEFN 
nd_mid = 9617 (m) 
nd_noex = 2 (NOEX_PRIVATE) 
nd_defn: 
     NODE_SCOPE 
     nd_rval = (null) 
     nd_tbl = 5 [_ ~ a b c] 
     nd_next: 
         NODE_ARGS 
         nd_cnt = 3 
         nd_rest = -1 
         nd_opt = (null) 
         NODE_NIL 

$ B $$$/$ D $+%@% s% W $ 7 $ F $_$?$ H $ 3 $ m! " Nd_defn $ B $ K $ O> o $ K NODE_SCOPE $ B $, F ~ $ C $ F $ B $ $ $ k $ h $&$@!#< code> NODE_SCOPE $ B $ H8 @ $ ($ P% b% 8% e! <% KJ8 $ N $ H $ 3 $ m $ G $ b8 + $? $ h $ & $ K% m! < $ B% +% kJQ? T% 9% 3! <% W $ r @ Q $`$?$ a $ N> pJs $ r3JG <$ 9 $ k% N! <% I $ G $ "$ k! #

NODE_DEFN

$ BB3 $ $ $ F rb_eval () $ B $ N3: Ev% 3! <% I $ r8 + $ F $$$/!#%(% i! <= HM) $, $ d $? $ iB? $ / $ F $ BLLE] $ @ $ C $? $ N $ G: F $ SA4It $ ^ $ H $ a $ F> JN, $ 7 $?! # $ B $ = $ NJ) K! $ O $ $ $ D $ b $ HF1 $ 8 $ G $ "$ k! # B ($ A rb_raise () rb_warn () rb_warning () $ B $ r8F $ V $ B $ @ $ 1 $ N $ b $ N !"$*$ h $ S4V @ \ E * $ K $ = $ l $ r8F $ V $ b $ N $ rA4It> C $ 7 $?! #

$ B " ' rb_eval () $ B!] NODE_DEFN $ B! J4JLsHG! K

 
NODE * defn; 
int noex; 

if (SCOPE_TEST (SCOPE_PRIVATE) | | node-> nd_mid == init) ( 
     noex = NOEX_PRIVATE; $ B! JA $ B! K 
) 
else if (SCOPE_TEST (SCOPE_PROTECTED)) ( 
     noex = NOEX_PROTECTED; $ B! JB $ B! K 
) 
else if (ruby_class == rb_cObject) ( 
     noex = node-> nd_noex; $ B! JC $ B! K 
) 
else ( 
     noex = NOEX_PUBLIC; $ B! JD $ B! K 
) 

defn = copy_node_scope (node-> nd_defn, ruby_cref); 
rb_add_method (ruby_class, node-> nd_mid, defn, noex); 
result = Qnil; 

$ BA0H> $ K $ O private $ B $ @ $ N protected $ B $ @ $ N $ H $ $ $ & C18l $, = P $ F $ / $ k $ N $ G2D; k $ B @-4X78 $ @ $ m $&!#% U% i% 0 $ NL> A0 $ K; H $ o $ l $ F $ $ $ k noex $ B $ O < code> NOde EXposure $ B! J% N! < $ B% I $ N2D; k @ -! K $ @ $ H; W $ o $ l $ k! # If $ BJ8 $ N @ a $ r = gHV $ K8 + $ F $ $ $ 3 $ & #

$ B! JA $ B! K SCOPE_TEST () $ B $ O scope_vmode $ B $ K0z? T $ N% U% i% 0 $, N) $ C $ F $ $ $ k $ +3 NG '$ 9 $ k $ B %^%/% m $ G $ "$ k !#=>$ C $ F $ 3 $ N> r7oJ8 $ NA0H> $ O! V private $ B% 9% 3! < % W $ G $ "$ k $ +! W $ H $ B $ $ $ & 0UL #$@!# 8eH> $ O! V initialize $ B $ NDj5A $ J $ i private $ B! W $ G $ "$ k !#%*% V% 8% ' $ B% /% H $ N = i4 | 2 = MQ% a% =% C% I initialize $ B $ OLdEzL5MQ $ G private $ B $ K $ J $ k $ N $ @! #

$ B! JB $ B! K protected $ B% 9% 3! <% W $ @ $ C $? $ I protected $ B! J $ "$? $ j $^$(! K! # Ruby $ B $ G $ O protected $ B $ O $$$^$$$ A; H $ $

$ B! JC $ B! K $ 3 $ 3 $ O% P% 0 $ C $ F $ $ $ k! # K \ = q $ NF ~ 9FD> A0 $ KH / 8 + $ 7 $? $ N $ G = $ @ 5 $ O4V $ K9g $ o $ J $ B $ + $ C $?!#: G? 7 $ N% 3! <% I $ G $ O $ J $ / $ J $ C $ F $ $ $ k $ O $:$@!#% H % C% W% l% Y% k $ GDj5A $ 5 $ l $? $ B% a% =% C% I $ r3N private $ B $ K $ 7 $ h $ & $ H $ 7 $?!"$ H $$$&$ N $, 85! 9 $ N0U? ^ $ G $ "$ k! #

$ B! JD $ B! K $ 3 $ l $ ^ $ G $ N $ I $ l $ G $ b $ J $ + $ C $? $ I! " Public $ B $ @! #

$ B $ 5 $ F! "

 
defn = copy_node_scope (node-> nd_defn, ruby_cref); 
rb_add_method (ruby_class, node-> nd_mid, defn, noex); 

copy_node_scope () $ B $ O% a% =% C% IK \ BN $ N @ hF, $ KIU $ $ $ F $ $ $ k NODE_SCOPE $ B! J $ @ $ 1! K $ r $ B% 3% T! <$ 9 $ k4X? T $@!#< code> ruby_cref $ B $ rEO $ 7 $ F $ $ $ k $ H $ 3 $ m $,%]%$% s% H $ J $ N $ @ $ B $,! D! D> \ $ 7 $ / $ O $ 9 $ 08e $ G8 + $ F $$$/!#

$ B% 3% T! <$ 7 $?$"$ H !"$=$ l $ r rb_add_method () $ B $ GDI2C $ 9 $ l $ PDj5A $ O40N; $ G $ "$ k! # $ BDj5A $ 9 $ k @ h $ O $ b $ A $ m $ s ruby_class $ B $ @! #

copy_node_scope ()

copy_node_scope () $ B $ O rb_eval () $ B $ N% a% =% C% IDj5A! J NODE_DEFN $ B! K $ H $ BFC0 [% a% =% C% IDj5A! J NODE_DEFS $ B! K $ @ $ 1 $ + $ i8F $ P $ l $ k $ N $ G !"$=$ NFs% v = j $ @ $ 1 $ B8 + $ l $ P; H $ o $ l $+$?$ rFCDj $ G $ - $ k !#$=$ 7 $ F $ = $ NFs% v = j $ G $ N; H $$$+$ ? $ O $ [$ \ $ BF1 $ 8 $ @! #

$ B " ' copy_node_scope ()

 
1752 static NODE * 
1753 copy_node_scope (node, rval) 
1754 NODE * node; 
1755 VALUE rval; 
(1756 
1757 NODE * copy = rb_node_newnode (NODE_SCOPE, 0, rval, node-> nd_next); 
1758 
1759 if (node-> nd_tbl) ( 
1760 copy-> nd_tbl = ALLOC_N (ID, node-> nd_tbl [0] +1); 
1761 MEMCPY (copy-> nd_tbl, node-> nd_tbl, ID, node-> nd_tbl [0] +1); 
1762) 
1763 else ( 
1764 copy-> nd_tbl = 0; 
1765) 
1766 return copy; 
1767) 

(eval.c) 

$ B0z? T $ N rval $ B $ O% a% =% C% I $, Dj5A $ 5 $ l $?;~$ N% /% i% 9 $ N% M% 9 % H> pJs! J ruby_cref $ B! K $ B $ @ $ C $?!#< code> nd_rval $ B $ K%;% C% H $ 5 $ l $ k $ + $ i rval $ B $ H $ $ $ & $ 3 $ H $ @ $ m $ &! #

$ BK \ BN $ N if $ BJ8 $ G $ O NODE_SCOPE $ B $ N nd_tbl $ B $ r% 3% T! < $ 7 $ F $ $ $ k! # $ D $ ^ $ j% m !<%+% k $ BJQ? TL> $ N% F! <% V% k $ G $ "$ k! # ALLOC_N () $ B $ G +1 $ B $ 7 $ F $ $ $ k $ N $ O nd_tbl [0] $ B $ NJ, $ b9g $ B $ o $; $ F3NJ] $ 9 $ k $? $ A $ @! # BhFsIt $ G8 + $? $ H $ * $ j nd_tbl [0] $ B $ K $ O% m !<%+% kJQ? t $ N $ B? T $, F ~ $ C $ F $ * $ j !"$=$ l $ O $ D $ ^ $ j! V nd_tbl $ B $ N

$ B $ ^ $ H $ a $ k $ H! " Copy_node_scope () $ B $ O% a% =% C% IK \ BN $ N% X% C% @ $ G $" $ k NODE_SCOPE $ B $ r $ BJ # @ = $ 9 $ k !"$?$@$ 7 nd_rval $ B $, DI2C $ G%;% C% H $ 5 $ l $ k !#$=$ 7 $ F $ = $ l $ O% /% i% 9 $ rDj5A $ B $ 7 $? $ H $ - $ N ruby_cref $ B! J% /% i% 9 $ N% M% 9% H> pJs! K $ G $ "$ k! # $ 3 $ N> pJs $ O8e $ GDj? T $ d $ B% /% i% 9JQ? T $ N; 2> H $ N $ H $ - $ K; H $ o $ l $ k! #

rb_add_method ()

$ B rb_add_method () $ B $ @! #

$ B " ' rb_add_method ()

 
  237 void 
  238 rb_add_method (klass, mid, node, noex) 
  239 VALUE klass; 
  240 ID mid; 
  241 NODE * node; 
  242 int noex; 
  243 ( 
  244 NODE * body; 
  245 
  246 if (NIL_P (klass)) klass = rb_cObject; 
  247 if (ruby_safe_level> = 4 & & 
               (klass == rb_cObject | |! OBJ_TAINTED (klass))) ( 
  248 rb_raise (rb_eSecurityError, "Insecure: can't define method"); 
  249) 
  250 if (OBJ_FROZEN (klass)) rb_error_frozen ( "class / module"); 
  251 rb_clear_cache_by_id (mid); 
  252 body = NEW_METHOD (node, noex); 
  253 st_insert (RCLASS (klass) -> m_tbl, mid, body); 
  254) 

(eval.c) 

NEW_METHOD () $ B $ O NODE $ B $ r @ 8 @. $ 9 $ k %^%/% m $ @! # rb_clear_cache_by_id () $ B $ O% a% =% C% I% -% c% C% 7% e $ rA `: n $ 9 $ k4X? t $ G $" $ k! # $ B O! X% a% =% C% I! Y $ G @ bL @ $ 9 $ k! #

$ B $ G $ O! ": G =* E * $ K% /% i% 9 $ N m_tbl $ B $ K3JG <$ 5 $ l $ k9 = J8LZ $ r8 + $ F $ _ $ h $ &! # $ B $ 3 $&$$$&$ H $ - $ N $? $ A $ KMQ0U $ 7 $ F $*$$$? nodedump-method \ footnote ( nodedump-method $ B! ' nodedump $ B $ KF1 :-!#< code> nodedump $ B $ OE: IUCD-ROM $ B $ N tools / nodedump.tar.gz ) $ B $ r $ B; H $ &! #

 
% Ruby-e ' 
class C 
   def m (a) 
     puts "ok" 
   end 
end 
require "nodedump-method" 
NodeDump.dump C,: m # $ B% /% i% 9C $ B $ N% a% =% C% Im $ B $ r% @% s% W $ 9 $ k 
' 
NODE_METHOD 
nd_noex = 0 (NOEX_PUBLIC) 
nd_cnt = 0 
nd_body: 
     NODE_SCOPE 
     nd_rval = Object <- C 
     nd_tbl = 3 [_ ~ a] 
     nd_next: 
         NODE_ARGS 
         nd_cnt = 1 
         nd_rest = -1 
         nd_opt = (null) 
         U $ B2g & n S $ BprCx 


** Unhandled ** 


$ B62 $ i $ /% a% =% C% I $ N% X% C% @ $ r0UL # $ 9 $ k $ N $ @ $ m $&!"< code> NODE_METHOD $ B $, @ hF, $ KIU $ $ $ F $ B $ * $ j !"$=$ N copy_node_scope () $ B $ G% 3% T! <$ 7 $? NODE_SCOPE $ B $, IU $ /! # $ B $$$/$ D $+%@% s% W $ 7 $ F $_$?$ H $ 3 $ mC $ B $ GDj5A $ 7 $?% A% =% C% I $ K $ O NODE_SCOPE $ B $ OIU $ $ $ F $ B $ $ $ J $ + $ C $? $ N $ G! "$ 3 $ l $, Ruby $ B% l% Y% k $ GDj5A $ 7 $?% A% =% C% I $ N0u $ i $ 7 $ $ #

$ B $^$?< code> NODE_SCOPE $ B $ N nd_tbl $ B $ K% a% =% C% I $ N% Q% i% a! <%? JQ? TL>! J a $ B! K $, EP> l $ 7 $ B $ F $ $ $ k! # 0JA0! "% Q% i% a! <%? JQ? T $ OIaDL $ N% m !<%+% kJQ? T $ HF1 $ 8 $ @ $ H8 @ $ C $?$,!"$= $ B $ l $, $ 3 $ 3 $ KC

NODE_ARGS $ B $ K $ D $ $ $ F $ O O! X% a% =% C% I! Y $ G07 $ & $ N $ G> JN , #

$ B $ = $ l $ H: G8e $ K NODE_METHOD $ B $ N nd_cnt $ B $@$,!"$ 3 $ l $ O: # 2s $ O $"$^$ j5 $ $ K $ 7 $ J $ / $ B $ F $$$$!#< code> alias $ B $,$+$ i $ s $ @ $ H $ - $ K; H $ & $ b $ N $ @! #

$ BBeF ~ $ H; 2> H

$ B9M $ ($ F $ _ $ l $ P% 9%?% C% / $ N $ [$ H $ s $ I $ O3F H $ B $ N% 3! <% I $ r8 + $ F $ $ $ 3 $ &! #

$ B% m !<%+% kJQ? t

$ B% m !<%+% kJQ? T $ NBeF ~! &; 2> H $ KI, MW $ J> pJs $ O $ 3 $ 3 $ ^ $ G $ GA4 $ F $ BEP> l $ 7 $ F $ $ $ k $ N $ GM = B, $, IU $/$@$ m $&!#%]%$% s% H $ O0J2 <$ NFsE$@!#

  1. $ B% m !<%+% kJQ? tNN0h $ O ruby_scope-> local_vars $ B $,; X $ 9G [Ns $ G $ "$ k! #
  2. $ B% m !<%+% kJQ? tL> $ HG [Ns% $% s% G% C% /% 9 $ NBP1 ~ $ O% Q! <% 5% l% Y% k $ G2r7h: Q $_!#

$ B $ H $$$&$ 3 $ H $ G% m !<%+% kJQ? T; 2> H $ N% N! <% I NODE_LVAR $ B $ N% 3! <% I $ O $ 3 $ & $ J $ k! #

$ B " ' rb_eval () $ B!] NODE_LVAR

2975 case NODE_LVAR: 
2976 if (ruby_scope-> local_vars == 0) ( 
2977 rb_bug ( "unexpected local variable"); 
2978) 
2979 result = ruby_scope-> local_vars [node-> nd_cnt]; 
2980 break; 

(eval.c) 

Needless to say I think node-> nd_cnt is Parser local_cnt () was value in return.

constant

full version

Chapter 6, and a constant variable in the constant format and store information about the API. Kula is a constant Su belong to the same method to inherit. It is all too real struct RClass - iv_tbl instance variable and variable with class registration In that.

But the constant search for the path out of first class, and then wonder, in the superclass To, rb_const_get () , was not the only super class. I'm It? It is constant talk about the hidden spoken about the final version The must-have. Look at the following code.

 
class A 
   C = 5 
   def A.new 
     puts C 
     super 
   end 
end 

A.new is A belonging to the specific method of class-specific classes are (A) . So if you interpret the rules as A belong to a constant C is not to win.

But if you write this nearly constant C want to see it's only natural. Ruby is therefore also refer to this. These specifications are "SOSUKO I looked for the de-emphasize "reflects the character of Ruby be said.

This rule, he generalize. That is about the method of constant internal field If the method definition of "writing" as a starting point to the location of the class outside of class constants About. And "Methods class where I wrote" Oh, is context-dependent Resona parser and evaluator of information unless handle both. That's rb_const_get () outside The search path is no reason for class.

cbase

So outside of class, including the constant references to look at the code. :: constant references are usually standing in the syntax tree NODE_CONST said. rb_eval () , said the code is……

rb_eval () - NODE_CONST

 
2994 case NODE_CONST: 
2995 result = ev_const_get (RNODE (ruby_frame-> cbase), node-> nd_vid, self); 
2996 break; 

(eval.c) 

First nd_vid is Variable ID a constant name. And ruby_frame-> cbase is "I wrote a method to define the location of the class." This is a method to start Will be set when the code is still have not appeared in the set Where the project is coming from, or even to say, this method is defined copy_node_scope () , came nd_rval for both sides. Come back and see a little head If the thing, but this method is to define when a member of ruby_cref will be .

In other words, first class and when the module definition ruby_cref links to Formed. Now a defined class C and out (Fig. 81).

This method m to define and (probably C # m ), Then ruby_cref method is stored in the entry (Fig. 82).

After the subsequent statement class ruby_cref points to a different node, but will not, node-> nd_rval is of course continue the same points (Fig. 83).

And methods C # m is when you start node-> nd_rval , retrieve, Just loaded ruby_frame-> cbase to Cart (Fig. 84).

…… Of the mechanism. Confusing.

(cbase)
Figure 8: CREF transfer

ev_const_get ()

, NODE_CONST back to the code. The rest are ev_const_get () just to see it.

ev_const_get ()

 
1550 static VALUE 
1551 ev_const_get (cref, id, self) 
1552 NODE * cref; 
1553 ID id; 
1554 VALUE self; 
(1555 
1556 NODE * cbase = cref; 
1557 VALUE result; 
1558 
1559 while (cbase & & cbase-> nd_next) ( 
1560 VALUE klass = cbase-> nd_clss; 
1561 
1562 if (NIL_P (klass)) return rb_const_get (CLASS_OF (self), id); 
1563 if (RCLASS (klass) -> iv_tbl & & 
                   st_lookup (RCLASS (klass) -> iv_tbl, id, & result)) ( 
1564 return result; 
1565) 
1566 cbase = cbase-> nd_next; 
1567) 
1568 return rb_const_get (cref-> nd_clss, id); 
1569) 

(eval.c) 

Arguments cref , that is the original ruby_cref , is NODE of a linked list. The list of the direct Tasoritsuku st_lookup () , iv_tbl to find out. Suu outside of class 調べないpar until the class because of their specifications, rb_const_get () does not.

And klass is nil …… So when a top-level lights and other nesting Because the class to determine the direction of the superclass. This is rb_const_get () the first time.

Moreover, when the super class examine a reversal in the direction of the self is a starting point. Really confusing.

class variable

Class at a variable ruby_cref . However, of course, constant as the outside And looking for the next class because they do not use the first one. Class variable References node, NODE_CVAR , let's take a look at the code.

rb_eval () - NODE_CVAR

 
2998 case NODE_CVAR: 
2999 result = rb_cvar_get (cvar_cbase (), node-> nd_vid); 
3000 break; 

(eval.c) 

cvar_cbase () What is it? cbase and know where to look ruby_frame-> cbase and the relationship is going to happen, how different? Let's see.

cvar_cbase ()

 
1571 static VALUE 
1572 cvar_cbase () 
(1573 
1574 NODE * cref = RNODE (ruby_frame-> cbase); 
1575 
1576 while (cref & & cref-> nd_next & & 
                  FL_TEST (cref-> nd_clss, FL_SINGLETON)) ( 
1577 cref = cref-> nd_next; 
1578 if (! Cref-> nd_next) ( 
1579 rb_warn ( "class variable access from toplevel singleton method"); 
1580) 
1581) 
1582 return cref-> nd_clss; 
1583) 

(eval.c) 

Class is not specific to cbase traced back to the picture. This is following a number of measures added.

 
class C class C 
   @ @ cvar = 1 @ @ cvar = 1 
   class < 

This program is both right and left to write the same methods are also defined. But an increasing number of right書きかたmethod is often the class to write: Yes Not only pain in the neck. So when you define more specific method to the left Class-specific definitions in one place, many of them.

However, the two is how to write ruby_cref values are different. Define a specific use It is ruby_cref = (C) and dismembered-specific methods, it is ruby_cref = C . This class is variable at the inconvenience it has changed.

So, class, class-specific variables can not and will not judge The specific class is it that leap. Here again inconsistent. Resona's designed to emphasize ease of use that way.

By the way, if the constant references to find out from all classes and both書きかた C path into the search, so no problem. The assignment of more method in the first place This is unrelated to write.

multiple assignment

Ruby, Where's the most complex specifications, and immediately asked if I have to answer multiple assignment. The multiple assignment It's impossible to grasp the whole picture. I think so thin. YOUSURUNI, Multiple assignment of the entire design specifications are designed to clean out an involuntary not the God PAKASHIMO Being made. The new standards will always be "some typical use PERTH In turn would be useful behavior. " This is true of the entire Ruby, multi - That is particularly noticeable weight assignment.

Then how do you choose a dense forest in order to spare code? This is a state with a scanner I like to read, seen as a whole. It is not the whole picture, but , The overall picture you can not. To cut the number thingy, the Caux - This is a specification for the design of this code is here to be a…… Respond point by point the way to getting on it.

But this is ruby comprehensive understanding of the structure of the book, even though the Ruby programming Advanced level, not too little thing you do not have no choice. So here Multiple assignment, the fundamental structure and a very simple "many-to-many" if only to consider Especially now.

First of all street construction staple will be able to see from a tree.

▼ source program

 
a, b = 7, 8 

▼ corresponding syntax tree

 
NODE_MASGN 
nd_head: 
     NODE_ARRAY [ 
     0: 
         NODE_LASGN 
         nd_cnt = 2 
         nd_value: 
     1: 
         NODE_LASGN 
         nd_cnt = 3 
         nd_value: 
     ] 
nd_value: 
     NODE_REXPAND 
     nd_head: 
         NODE_ARRAY [ 
         0: 
             NODE_LIT 
             nd_lit = 7: Fixnum 
         1: 
             NODE_LIT 
             nd_lit = 8: Fixnum 
         ] 

Both are left-hand right-hand NODE_ARRAY list, The right side NODE_REXPAND even know. REXPAND is Right value EXPAND? The nodes are doing or what to worry about it. Let's see.

rb_eval () - NODE_REXPAND

 
2575 case NODE_REXPAND: 
2576 result = avalue_to_svalue (rb_eval (self, node-> nd_head)); 
2577 break; 

(eval.c) 

avalue_to_svalue () ignore the good. rb_eval () , NODE_ARRAY is evaluated by the (literal array of nodes it is so) Ruby's return to the array. So before you handle the left side are all evaluated by the right side It's not. That is why the following can be.

 
a, b = b, a # write a single line variable swap 

Left-hand side, NODE_MASGN also look at.

rb_eval () - NODE_MASGN

 
2923 case NODE_MASGN: 
2924 result = massign (self, node, rb_eval (self, node-> nd_value), 0); 
2925 break; 

(eval.c) 

This is the right term rating is the only remaining massign () delegates.

massign ()

massi ……

 
3917 static VALUE 
3918 massign (self, node, val, pcall) 
3919 VALUE self; 
3920 NODE * node; 
3921 VALUE val; 
3922 int pcall; 
(3923 

(eval.c) 

I'm sorry, in the middle of the list, but here it stopped paying attention to the fourth argument. pcall is Proc CALL , means that this function is Proc calls for the use of objects We have to see if the host country. Proc and other calls for the multiple assignment Check the severity is somewhat different, so I ask them to check the flags of the The reason. Naturally, the value is either 0 or 1 reason.

So recalled massign () number of calls, but I'd like to see, pcall = 0 . Resona In the meantime it is pcall = 0 beat and decided to expand the variables are already a構わ INO to be. That's because, pcall it behaves like a subtle change to the argument And the two have always read the scenario and thinking but also in very面倒く And. Even if the actual function massign () is one thing, even when it is read pcall = 0 and pcall = 1 if the two functions have thought that it is much easier to read.

When the program is是非ともduplication should be avoided, but when you read Only to have nothing to do with the principle. If the pattern is rather limited copy Redundant and it is correct. "Optimized for speed," "code of size Optimization "of the word, but in this case" optimized for readability " .

So pcall = 0 as shaving all of his削れるbelow.

massign () (condensed version)

 
static VALUE 
massign (self, node, val / *, pcall = 0 * /) 
     VALUE self; 
     NODE * node; 
     VALUE val; 
( 
     NODE * list; 
     long i = 0, len; 

     val = svalue_to_mvalue (val); 
     len = RARRAY (val) -> len; 
     list = node-> nd_head; 
     / * (A) * / 
     for (i = 0; list & & i  nd_head, RARRAY (val) -> ptr [i], pcall); 
         list = list-> nd_next; 
     ) 
     / * (B) * / 
     if (node-> nd_args) ( 
         if (node-> nd_args == (NODE *) -1) ( 
             / * No check for mere `* '* / 
         ) 
         else if (! list & & i  nd_args, 
                    rb_ary_new4 (len-i, RARRAY (val) -> ptr + i), pcall); 
         ) 
         else ( 
             assign (self, node-> nd_args, rb_ary_new2 (0), pcall); 
         ) 
     ) 

     / * (C) * / 
     while (list) ( 
         i + +; 
         assign (self, list-> nd_head, Qnil, pcall); 
         list = list-> nd_next; 
     ) 
     return val; 
) 

val value to the right side. Also svalue_to_mvalue () converted to a suspicious fire that the We are mvalue_to_svalue () , this is svalue_to_mvalue () So, "I'm sure rejoined It should be "considered. Therefore, both away at once. The next line RARRAY () from using the right side of the value of Ruby Array and I heard a Feel frisky. Meanwhile the left side node-> nd_head , means that local variables list has been assigned to Value. This list also node ( NODE_ARRAY ).

The following is a code to follow every clause.

(A) assign () name of the street, one-on-one assignment of functions. Is no left-hand Mode of expression that, for example NODE_IASGN (Variable instance) And rb_ivar_set () in the assignment, so I do. Ie, list and val it to meet one-on-one short of the assignment (Fig. 9).

(massign)
Figure 9: response to the assignment

(B) if the right side on one's hands rest on an array of Ruby node-> nd_args (of expression To the left side) assignment.

(C) If the left side on one's hands all nil is assigned.

By the way, pcall = 0 to cut back on the work of compiler optimization phase Use data-flow analysis / convolution and the constant look-alike. That is automated to some extent I think you can.


The original work is Copyright © 2002 - 2004 Minero AOKI.
Translations,  additions,  and graphics by C.E. Thornton
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike2.5 License.