Updated RubySpec submodule to 9f66d0b1.
[rbx.git] / spec / core / compiledmethod / decode_spec.rb
blobe533247b500a437f859e03254bc5d72022adf651
1 require File.dirname(__FILE__) + '/../../spec_helper'
2 require File.dirname(__FILE__) + '/fixtures/classes'
4 describe "CompiledMethod#decode" do
5   before do
6     @cm = CompiledMethodSpecs.instance_method(:simple_puts).compiled_method
7   end
9   it "returns an array of Instruction objects representing the instruction sequence" do
10     dc = @cm.decode
11     dc.kind_of?(Array).should == true
12     dc.each do |inst|
13       inst.kind_of?(CompiledMethod::Instruction).should == true
14     end
15   end
16 end
18 describe "CompiledMethod::Instruction" do
19   before 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]]
26   end
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
31     end
32   end
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
37     end
38   end
40   it "#args returns literal values, rather than the index into the literals tuple" do
41     @cm.decode[1].args.first.should == 'hello'
42   end
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
48       end
49     end
50   end
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]
67   end
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]
84   end
85 end