1 require File.dirname(__FILE__) + '/../../spec_helper'
2 require File.dirname(__FILE__) + '/fixtures/classes'
4 describe "CompiledMethod#decode" do
6 @cm = CompiledMethodSpecs.instance_method(:simple_puts).compiled_method
9 it "returns an array of Instruction objects representing the instruction sequence" do
11 dc.kind_of?(Array).should == true
13 inst.kind_of?(CompiledMethod::Instruction).should == true
18 describe "CompiledMethod::Instruction" do
20 @cm = CompiledMethodSpecs.instance_method(:simple_puts).compiled_method
21 @code = [[:check_argcount, 0, 0], [:push_literal, 'hello'],
22 [:string_dup], [:set_local, :a], [:pop], [:push_local, :a],
23 [:push_self], [:set_call_flags, 1],
24 #[:set_cache_index, 0],
25 [:send_stack, :puts, 1], [:sret]]
28 it "#opcode returns a symbol representing the opcode for the corresponding instruction" do
29 @cm.decode.each_with_index do |inst,i|
30 inst.opcode.should == @code[i].first
34 it "#args returns an array containing the opcode arguments" do
35 @cm.decode.each_with_index do |inst,i|
36 inst.args.size.should == @code[i].size - 1
40 it "#args returns literal values, rather than the index into the literals tuple" do
41 @cm.decode[1].args.first.should == 'hello'
44 it "#args returns local variable names, rather than the index into the locals tuple" do
45 @cm.decode.each_with_index do |inst,i|
46 if inst.instruction.args.include? :slot_local
47 inst.args.first.inspect.should == @code[i][1].inspect
52 it "#stack_consumed returns a count of the stack operands consumed by the instruction" do
53 inst = CompiledMethod::Instruction.new([InstructionSet[:noop]], @cm, 0, 0)
54 inst.stack_consumed.should == [0, true]
55 inst = CompiledMethod::Instruction.new([InstructionSet[:swap_stack]], @cm, 0, 0)
56 inst.stack_consumed.should == [1, true]
57 inst = CompiledMethod::Instruction.new([InstructionSet[:make_hash], 2], @cm, 0, 0)
58 inst.stack_consumed.should == [4, true]
59 inst = CompiledMethod::Instruction.new([InstructionSet[:send_stack],0,2], @cm, 0, 0)
60 inst.stack_consumed.should == [3, true]
61 inst = CompiledMethod::Instruction.new([InstructionSet[:send_with_arg_register],0], @cm, 0, 0)
62 inst.stack_consumed.should == [2, false]
63 inst = CompiledMethod::Instruction.new([InstructionSet[:send_with_arg_register],0], @cm, 0, 2)
64 inst.stack_consumed.should == [4, false]
65 inst = CompiledMethod::Instruction.new([InstructionSet[:push_array]], @cm, 0, 0)
66 inst.stack_consumed.should == [1, true]
69 it "#stack_produced returns a count of the stack operands produced by the instruction" do
70 inst = CompiledMethod::Instruction.new([InstructionSet[:noop]], @cm, 0, 0)
71 inst.stack_produced.should == [0, true]
72 inst = CompiledMethod::Instruction.new([InstructionSet[:swap_stack]], @cm, 0, 0)
73 inst.stack_produced.should == [1, true]
74 inst = CompiledMethod::Instruction.new([InstructionSet[:make_hash], 2], @cm, 0, 0)
75 inst.stack_produced.should == [1, true]
76 inst = CompiledMethod::Instruction.new([InstructionSet[:send_stack],0,2], @cm, 0, 0)
77 inst.stack_produced.should == [1, true]
78 inst = CompiledMethod::Instruction.new([InstructionSet[:send_with_arg_register],0], @cm, 0, 0)
79 inst.stack_produced.should == [1, true]
80 inst = CompiledMethod::Instruction.new([InstructionSet[:send_with_arg_register],0], @cm, 0, 2)
81 inst.stack_produced.should == [1, true]
82 inst = CompiledMethod::Instruction.new([InstructionSet[:push_array]], @cm, 0, 0)
83 inst.stack_produced.should == [0, false]