Hi,

Paul Brannan wrote:
> irb(main):001:0> is = VM::InstructionSequence.compile('foo.bar = 42')
> => ISeq:maincompiled
> irb(main):003:0> puts is.disasm
> == disasm: <ISeq:<main>@<compiled>>=====================================
> 0000 putnil                                                           (   1)
> 0001 putnil           
> 0002 send             :foo, 0, nil, 24, <ic>
> 0008 putobject        42
> 0010 setn             2
> 0012 send             :bar=, 1, nil, 0, <ic>
> 0018 pop              
> 0019 leave            
> => nil
> 
> I'm a little confused about how the opcodes manipulate the stack.  This is what
> I have written on paper:
> 
> putnil               #=> [ nil ]
> putnil               #=> [ nil, nil ]
> send :foo, 0         #=> [ nil, nil, result of 1st send ]
consume "recv" value. if funcall (when receiver is not specified), nil
is pushed (and consumed when send insn).
so, stack will be :    #=> [ nil, result of 1st send ]

putobject 42         #=> [ nil, result of 1st send, 42 ]
setn 2               #=> [ 42, result of 1st send, 42 ]
#=> means: sp[-2] = sp[0]
send :bar=, 1        #=> [ 42, result of 2nd send ]
pop                  #=> [ 42 ]


regards,
Koichi

> 
> But if I try this in irb:
> 
> irb(main):008:0> is = VM::InstructionSequence.compile('foo = OpenStruct.new; foo.bar = 42')
> => ISeq:maincompiled
> irb(main):009:0> is.eval
> => 42
> 
> The answer is 42, not nil.  Where is my misunderstanding?
> 
> Thanks,
> 
> Paul
> 
> 


-- 
// SASADA Koichi at atdot dot net