Class: SyntaxTree::YARV::InstructionSequence
- Inherits:
-
Object
- Object
- SyntaxTree::YARV::InstructionSequence
- Defined in:
- lib/syntax_tree/yarv/instruction_sequence.rb
Overview
This class is meant to mirror RubyVM::InstructionSequence. It contains a list of instructions along with the metadata pertaining to them. It also functions as a builder for the instruction sequence.
Defined Under Namespace
Classes: CatchBreak, CatchEnsure, CatchEntry, CatchNext, CatchRedo, CatchRescue, CatchRetry, InstructionList, Label, Stack
Constant Summary collapse
- MAGIC =
"YARVInstructionSequence/SimpleDataFormat"
Instance Attribute Summary collapse
-
#argument_options ⇒ Object
readonly
Returns the value of attribute argument_options.
-
#argument_size ⇒ Object
This is the list of information about the arguments to this instruction sequence.
-
#catch_table ⇒ Object
readonly
The catch table for this instruction sequence.
-
#file ⇒ Object
readonly
The source location of the instruction sequence.
-
#inline_storages ⇒ Object
readonly
The hash of names of instance and class variables pointing to the index of their associated inline storage.
-
#insns ⇒ Object
readonly
The list of instructions for this instruction sequence.
-
#line ⇒ Object
readonly
The source location of the instruction sequence.
-
#local_table ⇒ Object
readonly
The table of local variables.
-
#name ⇒ Object
readonly
The name of the instruction sequence.
-
#options ⇒ Object
readonly
These are various compilation options provided.
-
#parent_iseq ⇒ Object
readonly
The parent instruction sequence, if there is one.
-
#stack ⇒ Object
readonly
An object that will track the current size of the stack and the maximum size of the stack for this instruction sequence.
-
#storage_index ⇒ Object
readonly
The index of the next inline storage that will be created.
-
#type ⇒ Object
readonly
The type of the instruction sequence.
Class Method Summary collapse
-
.from(source, options = Compiler::Options.new, parent_iseq = nil) ⇒ Object
This method will create a new instruction sequence from a serialized RubyVM::InstructionSequence object.
-
.iseq_load(iseq) ⇒ Object
This provides a handle to the rb_iseq_load function, which allows you to pass a serialized iseq to Ruby and have it return a RubyVM::InstructionSequence object.
Instance Method Summary collapse
- #adjuststack(number) ⇒ Object
- #anytostring ⇒ Object
- #block_child_iseq(line) ⇒ Object
- #branchif(label) ⇒ Object
- #branchnil(label) ⇒ Object
- #branchunless(label) ⇒ Object
- #catch_break(iseq, begin_label, end_label, exit_label, restore_sp) ⇒ Object
- #catch_ensure(iseq, begin_label, end_label, exit_label, restore_sp) ⇒ Object
- #catch_next(begin_label, end_label, exit_label, restore_sp) ⇒ Object
- #catch_redo(begin_label, end_label, exit_label, restore_sp) ⇒ Object
- #catch_rescue(iseq, begin_label, end_label, exit_label, restore_sp) ⇒ Object
- #catch_retry(begin_label, end_label, exit_label, restore_sp) ⇒ Object
- #checkkeyword(keyword_bits_index, keyword_index) ⇒ Object
- #checkmatch(type) ⇒ Object
- #checktype(type) ⇒ Object
-
#child_iseq(name, line, type) ⇒ Object
Child instruction sequence methods.
- #class_child_iseq(name, line) ⇒ Object
-
#compile! ⇒ Object
This method converts our linked list of instructions into a final array and performs any other compilation steps necessary.
- #concatarray ⇒ Object
- #concatstrings(number) ⇒ Object
- #defineclass(name, class_iseq, flags) ⇒ Object
- #defined(type, name, message) ⇒ Object
- #definedivar(name, cache, message) ⇒ Object
- #definemethod(name, method_iseq) ⇒ Object
- #definesmethod(name, method_iseq) ⇒ Object
- #disasm ⇒ Object
- #dup ⇒ Object
- #duparray(object) ⇒ Object
- #duphash(object) ⇒ Object
- #dupn(number) ⇒ Object
- #eval ⇒ Object
- #event(name) ⇒ Object
- #expandarray(length, flags) ⇒ Object
- #getblockparam(index, level) ⇒ Object
- #getblockparamproxy(index, level) ⇒ Object
- #getclassvariable(name) ⇒ Object
- #getconstant(name) ⇒ Object
- #getglobal(name) ⇒ Object
- #getinstancevariable(name) ⇒ Object
- #getlocal(index, level) ⇒ Object
- #getspecial(key, type) ⇒ Object
-
#initialize(name, file, line, type, parent_iseq = nil, options = Compiler::Options.new) ⇒ InstructionSequence
constructor
A new instance of InstructionSequence.
- #inline_storage ⇒ Object
- #inline_storage_for(name) ⇒ Object
- #inspect ⇒ Object
- #intern ⇒ Object
- #invokeblock(calldata) ⇒ Object
- #invokesuper(calldata, block_iseq) ⇒ Object
- #jump(label) ⇒ Object
-
#label ⇒ Object
Instruction push methods.
- #leave ⇒ Object
- #length ⇒ Object
-
#local_variable(name, level = 0) ⇒ Object
Query methods.
- #method_child_iseq(name, line) ⇒ Object
- #module_child_iseq(name, line) ⇒ Object
- #newarray(number) ⇒ Object
- #newarraykwsplat(number) ⇒ Object
- #newhash(number) ⇒ Object
- #newrange(exclude_end) ⇒ Object
- #nop ⇒ Object
- #objtostring(calldata) ⇒ Object
- #once(iseq, cache) ⇒ Object
- #opt_aref_with(object, calldata) ⇒ Object
- #opt_aset_with(object, calldata) ⇒ Object
- #opt_case_dispatch(case_dispatch_hash, else_label) ⇒ Object
- #opt_getconstant_path(names) ⇒ Object
- #opt_getinlinecache(label, cache) ⇒ Object
- #opt_setinlinecache(cache) ⇒ Object
- #pop ⇒ Object
- #push(value) ⇒ Object
- #putnil ⇒ Object
- #putobject(object) ⇒ Object
- #putself ⇒ Object
- #putspecialobject(object) ⇒ Object
- #putstring(object) ⇒ Object
- #send(calldata, block_iseq = nil) ⇒ Object
- #setblockparam(index, level) ⇒ Object
- #setclassvariable(name) ⇒ Object
- #setconstant(name) ⇒ Object
- #setglobal(name) ⇒ Object
- #setinstancevariable(name) ⇒ Object
- #setlocal(index, level) ⇒ Object
- #setn(number) ⇒ Object
- #setspecial(key) ⇒ Object
- #singleton_class_child_iseq(line) ⇒ Object
- #specialize_instructions! ⇒ Object
- #splatarray(flag) ⇒ Object
- #swap ⇒ Object
- #throw(type) ⇒ Object
- #to_a ⇒ Object
- #to_cfg ⇒ Object
- #to_dfg ⇒ Object
- #to_son ⇒ Object
- #topn(number) ⇒ Object
- #toregexp(options, length) ⇒ Object
Constructor Details
#initialize(name, file, line, type, parent_iseq = nil, options = Compiler::Options.new) ⇒ InstructionSequence
Returns a new instance of InstructionSequence.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 168 def initialize( name, file, line, type, parent_iseq = nil, = Compiler::Options.new ) @name = name @file = file @line = line @type = type @parent_iseq = parent_iseq @argument_size = 0 @argument_options = {} @catch_table = [] @local_table = LocalTable.new @inline_storages = {} @insns = InstructionList.new @storage_index = 0 @stack = Stack.new @options = end |
Instance Attribute Details
#argument_options ⇒ Object (readonly)
Returns the value of attribute argument_options.
143 144 145 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 143 def @argument_options end |
#argument_size ⇒ Object
This is the list of information about the arguments to this instruction sequence.
142 143 144 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 142 def argument_size @argument_size end |
#catch_table ⇒ Object (readonly)
The catch table for this instruction sequence.
146 147 148 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 146 def catch_table @catch_table end |
#file ⇒ Object (readonly)
The source location of the instruction sequence.
132 133 134 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 132 def file @file end |
#inline_storages ⇒ Object (readonly)
The hash of names of instance and class variables pointing to the index of their associated inline storage.
156 157 158 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 156 def inline_storages @inline_storages end |
#insns ⇒ Object (readonly)
The list of instructions for this instruction sequence.
149 150 151 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 149 def insns @insns end |
#line ⇒ Object (readonly)
The source location of the instruction sequence.
132 133 134 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 132 def line @line end |
#local_table ⇒ Object (readonly)
The table of local variables.
152 153 154 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 152 def local_table @local_table end |
#name ⇒ Object (readonly)
The name of the instruction sequence.
129 130 131 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 129 def name @name end |
#options ⇒ Object (readonly)
These are various compilation options provided.
166 167 168 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 166 def @options end |
#parent_iseq ⇒ Object (readonly)
The parent instruction sequence, if there is one.
138 139 140 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 138 def parent_iseq @parent_iseq end |
#stack ⇒ Object (readonly)
An object that will track the current size of the stack and the maximum size of the stack for this instruction sequence.
163 164 165 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 163 def stack @stack end |
#storage_index ⇒ Object (readonly)
The index of the next inline storage that will be created.
159 160 161 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 159 def storage_index @storage_index end |
#type ⇒ Object (readonly)
The type of the instruction sequence.
135 136 137 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 135 def type @type end |
Class Method Details
.from(source, options = Compiler::Options.new, parent_iseq = nil) ⇒ Object
This method will create a new instruction sequence from a serialized RubyVM::InstructionSequence object.
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 1015 def self.from(source, = Compiler::Options.new, parent_iseq = nil) iseq = new(source[5], source[6], source[8], source[9], parent_iseq, ) # set up the labels object so that the labels are shared between the # location in the instruction sequence and the instructions that # reference them labels = Hash.new { |hash, name| hash[name] = Label.new(name) } # set up the correct argument size iseq.argument_size = source[4][:arg_size] # set up all of the locals source[10].each { |local| iseq.local_table.plain(local) } # set up the argument options iseq..merge!(source[11]) if iseq.[:opt] iseq.[:opt].map! { |opt| labels[opt] } end # track the child block iseqs so that our catch table can point to the # correctly created iseqs block_iseqs = [] # set up all of the instructions source[13].each do |insn| # add line numbers if insn.is_a?(Integer) iseq.push(insn) next end # add events and labels if insn.is_a?(Symbol) if insn.start_with?("label_") iseq.push(labels[insn]) else iseq.push(insn) end next end # add instructions, mapped to our own instruction classes type, *opnds = insn case type when :adjuststack iseq.adjuststack(opnds[0]) when :anytostring iseq.anytostring when :branchif iseq.branchif(labels[opnds[0]]) when :branchnil iseq.branchnil(labels[opnds[0]]) when :branchunless iseq.branchunless(labels[opnds[0]]) when :checkkeyword iseq.checkkeyword(iseq.local_table.size - opnds[0] + 2, opnds[1]) when :checkmatch iseq.checkmatch(opnds[0]) when :checktype iseq.checktype(opnds[0]) when :concatarray iseq.concatarray when :concatstrings iseq.concatstrings(opnds[0]) when :defineclass iseq.defineclass(opnds[0], from(opnds[1], , iseq), opnds[2]) when :defined iseq.defined(opnds[0], opnds[1], opnds[2]) when :definedivar iseq.definedivar(opnds[0], opnds[1], opnds[2]) when :definemethod iseq.definemethod(opnds[0], from(opnds[1], , iseq)) when :definesmethod iseq.definesmethod(opnds[0], from(opnds[1], , iseq)) when :dup iseq.dup when :duparray iseq.duparray(opnds[0]) when :duphash iseq.duphash(opnds[0]) when :dupn iseq.dupn(opnds[0]) when :expandarray iseq.(opnds[0], opnds[1]) when :getblockparam, :getblockparamproxy, :getlocal, :getlocal_WC_0, :getlocal_WC_1, :setblockparam, :setlocal, :setlocal_WC_0, :setlocal_WC_1 current = iseq level = 0 case type when :getlocal_WC_1, :setlocal_WC_1 level = 1 when :getblockparam, :getblockparamproxy, :getlocal, :setblockparam, :setlocal level = opnds[1] end level.times { current = current.parent_iseq } index = current.local_table.size - opnds[0] + 2 case type when :getblockparam iseq.getblockparam(index, level) when :getblockparamproxy iseq.getblockparamproxy(index, level) when :getlocal, :getlocal_WC_0, :getlocal_WC_1 iseq.getlocal(index, level) when :setblockparam iseq.setblockparam(index, level) when :setlocal, :setlocal_WC_0, :setlocal_WC_1 iseq.setlocal(index, level) end when :getclassvariable iseq.push(GetClassVariable.new(opnds[0], opnds[1])) when :getconstant iseq.getconstant(opnds[0]) when :getglobal iseq.getglobal(opnds[0]) when :getinstancevariable iseq.push(GetInstanceVariable.new(opnds[0], opnds[1])) when :getspecial iseq.getspecial(opnds[0], opnds[1]) when :intern iseq.intern when :invokeblock iseq.invokeblock(CallData.from(opnds[0])) when :invokesuper block_iseq = opnds[1] ? from(opnds[1], , iseq) : nil iseq.invokesuper(CallData.from(opnds[0]), block_iseq) when :jump iseq.jump(labels[opnds[0]]) when :leave iseq.leave when :newarray iseq.newarray(opnds[0]) when :newarraykwsplat iseq.newarraykwsplat(opnds[0]) when :newhash iseq.newhash(opnds[0]) when :newrange iseq.newrange(opnds[0]) when :nop iseq.nop when :objtostring iseq.objtostring(CallData.from(opnds[0])) when :once iseq.once(from(opnds[0], , iseq), opnds[1]) when :opt_and, :opt_aref, :opt_aset, :opt_div, :opt_empty_p, :opt_eq, :opt_ge, :opt_gt, :opt_le, :opt_length, :opt_lt, :opt_ltlt, :opt_minus, :opt_mod, :opt_mult, :opt_nil_p, :opt_not, :opt_or, :opt_plus, :opt_regexpmatch2, :opt_send_without_block, :opt_size, :opt_succ iseq.send(CallData.from(opnds[0]), nil) when :opt_aref_with iseq.opt_aref_with(opnds[0], CallData.from(opnds[1])) when :opt_aset_with iseq.opt_aset_with(opnds[0], CallData.from(opnds[1])) when :opt_case_dispatch hash = opnds[0] .each_slice(2) .to_h .transform_values { |value| labels[value] } iseq.opt_case_dispatch(hash, labels[opnds[1]]) when :opt_getconstant_path iseq.opt_getconstant_path(opnds[0]) when :opt_getinlinecache iseq.opt_getinlinecache(labels[opnds[0]], opnds[1]) when :opt_newarray_max iseq.newarray(opnds[0]) iseq.send(YARV.calldata(:max)) when :opt_newarray_min iseq.newarray(opnds[0]) iseq.send(YARV.calldata(:min)) when :opt_newarray_send iseq.newarray(opnds[0]) iseq.send(CallData.new(opnds[1])) when :opt_neq iseq.push( OptNEq.new(CallData.from(opnds[0]), CallData.from(opnds[1])) ) when :opt_setinlinecache iseq.opt_setinlinecache(opnds[0]) when :opt_str_freeze iseq.putstring(opnds[0]) iseq.send(YARV.calldata(:freeze)) when :opt_str_uminus iseq.putstring(opnds[0]) iseq.send(YARV.calldata(:-@)) when :pop iseq.pop when :putnil iseq.putnil when :putobject iseq.putobject(opnds[0]) when :putobject_INT2FIX_0_ iseq.putobject(0) when :putobject_INT2FIX_1_ iseq.putobject(1) when :putself iseq.putself when :putstring iseq.putstring(opnds[0]) when :putspecialobject iseq.putspecialobject(opnds[0]) when :send block_iseq = opnds[1] ? from(opnds[1], , iseq) : nil block_iseqs << block_iseq if block_iseq iseq.send(CallData.from(opnds[0]), block_iseq) when :setclassvariable iseq.push(SetClassVariable.new(opnds[0], opnds[1])) when :setconstant iseq.setconstant(opnds[0]) when :setglobal iseq.setglobal(opnds[0]) when :setinstancevariable iseq.push(SetInstanceVariable.new(opnds[0], opnds[1])) when :setn iseq.setn(opnds[0]) when :setspecial iseq.setspecial(opnds[0]) when :splatarray iseq.splatarray(opnds[0]) when :swap iseq.swap when :throw iseq.throw(opnds[0]) when :topn iseq.topn(opnds[0]) when :toregexp iseq.toregexp(opnds[0], opnds[1]) else raise "Unknown instruction type: #{type}" end end # set up the catch table source[12].each do |entry| case entry[0] when :break if entry[1] break_iseq = block_iseqs.find do |block_iseq| block_iseq.name == entry[1][5] && block_iseq.file == entry[1][6] && block_iseq.line == entry[1][8] end iseq.catch_break( break_iseq || from(entry[1], , iseq), labels[entry[2]], labels[entry[3]], labels[entry[4]], entry[5] ) else iseq.catch_break( nil, labels[entry[2]], labels[entry[3]], labels[entry[4]], entry[5] ) end when :ensure iseq.catch_ensure( from(entry[1], , iseq), labels[entry[2]], labels[entry[3]], labels[entry[4]], entry[5] ) when :next iseq.catch_next( labels[entry[2]], labels[entry[3]], labels[entry[4]], entry[5] ) when :rescue iseq.catch_rescue( from(entry[1], , iseq), labels[entry[2]], labels[entry[3]], labels[entry[4]], entry[5] ) when :redo iseq.catch_redo( labels[entry[2]], labels[entry[3]], labels[entry[4]], entry[5] ) when :retry iseq.catch_retry( labels[entry[2]], labels[entry[3]], labels[entry[4]], entry[5] ) else raise "unknown catch type: #{entry[0]}" end end iseq.compile! if iseq.type == :top iseq end |
.iseq_load(iseq) ⇒ Object
This provides a handle to the rb_iseq_load function, which allows you to pass a serialized iseq to Ruby and have it return a RubyVM::InstructionSequence object.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 13 def self.iseq_load(iseq) require "fiddle" @iseq_load_function ||= Fiddle::Function.new( Fiddle::Handle::DEFAULT["rb_iseq_load"], [Fiddle::TYPE_VOIDP] * 3, Fiddle::TYPE_VOIDP ) Fiddle.dlunwrap(@iseq_load_function.call(Fiddle.dlwrap(iseq), 0, nil)) rescue LoadError raise "Could not load the Fiddle library" rescue NameError raise "Unable to find rb_iseq_load" rescue Fiddle::DLError raise "Unable to perform a dynamic load" end |
Instance Method Details
#adjuststack(number) ⇒ Object
652 653 654 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 652 def adjuststack(number) push(AdjustStack.new(number)) end |
#anytostring ⇒ Object
656 657 658 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 656 def anytostring push(AnyToString.new) end |
#block_child_iseq(line) ⇒ Object
472 473 474 475 476 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 472 def block_child_iseq(line) current = self current = current.parent_iseq while current.type == :block child_iseq("block in #{current.name}", line, :block) end |
#branchif(label) ⇒ Object
660 661 662 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 660 def branchif(label) push(BranchIf.new(label)) end |
#branchnil(label) ⇒ Object
664 665 666 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 664 def branchnil(label) push(BranchNil.new(label)) end |
#branchunless(label) ⇒ Object
668 669 670 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 668 def branchunless(label) push(BranchUnless.new(label)) end |
#catch_break(iseq, begin_label, end_label, exit_label, restore_sp) ⇒ Object
565 566 567 568 569 570 571 572 573 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 565 def catch_break(iseq, begin_label, end_label, exit_label, restore_sp) catch_table << CatchBreak.new( iseq, begin_label, end_label, exit_label, restore_sp ) end |
#catch_ensure(iseq, begin_label, end_label, exit_label, restore_sp) ⇒ Object
575 576 577 578 579 580 581 582 583 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 575 def catch_ensure(iseq, begin_label, end_label, exit_label, restore_sp) catch_table << CatchEnsure.new( iseq, begin_label, end_label, exit_label, restore_sp ) end |
#catch_next(begin_label, end_label, exit_label, restore_sp) ⇒ Object
585 586 587 588 589 590 591 592 593 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 585 def catch_next(begin_label, end_label, exit_label, restore_sp) catch_table << CatchNext.new( nil, begin_label, end_label, exit_label, restore_sp ) end |
#catch_redo(begin_label, end_label, exit_label, restore_sp) ⇒ Object
595 596 597 598 599 600 601 602 603 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 595 def catch_redo(begin_label, end_label, exit_label, restore_sp) catch_table << CatchRedo.new( nil, begin_label, end_label, exit_label, restore_sp ) end |
#catch_rescue(iseq, begin_label, end_label, exit_label, restore_sp) ⇒ Object
605 606 607 608 609 610 611 612 613 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 605 def catch_rescue(iseq, begin_label, end_label, exit_label, restore_sp) catch_table << CatchRescue.new( iseq, begin_label, end_label, exit_label, restore_sp ) end |
#catch_retry(begin_label, end_label, exit_label, restore_sp) ⇒ Object
615 616 617 618 619 620 621 622 623 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 615 def catch_retry(begin_label, end_label, exit_label, restore_sp) catch_table << CatchRetry.new( nil, begin_label, end_label, exit_label, restore_sp ) end |
#checkkeyword(keyword_bits_index, keyword_index) ⇒ Object
672 673 674 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 672 def checkkeyword(keyword_bits_index, keyword_index) push(CheckKeyword.new(keyword_bits_index, keyword_index)) end |
#checkmatch(type) ⇒ Object
676 677 678 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 676 def checkmatch(type) push(CheckMatch.new(type)) end |
#checktype(type) ⇒ Object
680 681 682 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 680 def checktype(type) push(CheckType.new(type)) end |
#child_iseq(name, line, type) ⇒ Object
Child instruction sequence methods
468 469 470 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 468 def child_iseq(name, line, type) InstructionSequence.new(name, file, line, type, self, ) end |
#class_child_iseq(name, line) ⇒ Object
478 479 480 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 478 def class_child_iseq(name, line) child_iseq("<class:#{name}>", line, :class) end |
#compile! ⇒ Object
This method converts our linked list of instructions into a final array and performs any other compilation steps necessary.
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 305 def compile! specialize_instructions! if .specialized_instruction? catch_table.each do |catch_entry| if !catch_entry.is_a?(CatchBreak) && catch_entry.iseq catch_entry.iseq.compile! end end length = 0 insns.each do |insn| case insn when Integer, Symbol # skip when Label insn.patch!(:"label_#{length}") when DefineClass insn.class_iseq.compile! length += insn.length when DefineMethod, DefineSMethod insn.method_iseq.compile! length += insn.length when InvokeSuper, Send insn.block_iseq.compile! if insn.block_iseq length += insn.length when Once insn.iseq.compile! length += insn.length else length += insn.length end end @insns = insns.to_a end |
#concatarray ⇒ Object
684 685 686 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 684 def concatarray push(ConcatArray.new) end |
#concatstrings(number) ⇒ Object
688 689 690 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 688 def concatstrings(number) push(ConcatStrings.new(number)) end |
#defineclass(name, class_iseq, flags) ⇒ Object
692 693 694 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 692 def defineclass(name, class_iseq, flags) push(DefineClass.new(name, class_iseq, flags)) end |
#defined(type, name, message) ⇒ Object
696 697 698 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 696 def defined(type, name, ) push(Defined.new(type, name, )) end |
#definedivar(name, cache, message) ⇒ Object
700 701 702 703 704 705 706 707 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 700 def definedivar(name, cache, ) if RUBY_VERSION < "3.3" push(PutNil.new) push(Defined.new(Defined::TYPE_IVAR, name, )) else push(DefinedIVar.new(name, cache, )) end end |
#definemethod(name, method_iseq) ⇒ Object
709 710 711 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 709 def definemethod(name, method_iseq) push(DefineMethod.new(name, method_iseq)) end |
#definesmethod(name, method_iseq) ⇒ Object
713 714 715 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 713 def definesmethod(name, method_iseq) push(DefineSMethod.new(name, method_iseq)) end |
#disasm ⇒ Object
292 293 294 295 296 297 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 292 def disasm fmt = Disassembler.new fmt.enqueue(self) fmt.format! fmt.string end |
#dup ⇒ Object
717 718 719 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 717 def dup push(Dup.new) end |
#duparray(object) ⇒ Object
721 722 723 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 721 def duparray(object) push(DupArray.new(object)) end |
#duphash(object) ⇒ Object
725 726 727 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 725 def duphash(object) push(DupHash.new(object)) end |
#dupn(number) ⇒ Object
729 730 731 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 729 def dupn(number) push(DupN.new(number)) end |
#eval ⇒ Object
232 233 234 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 232 def eval InstructionSequence.iseq_load(to_a).eval end |
#event(name) ⇒ Object
648 649 650 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 648 def event(name) push(name) end |
#expandarray(length, flags) ⇒ Object
733 734 735 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 733 def (length, flags) push(ExpandArray.new(length, flags)) end |
#getblockparam(index, level) ⇒ Object
737 738 739 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 737 def getblockparam(index, level) push(GetBlockParam.new(index, level)) end |
#getblockparamproxy(index, level) ⇒ Object
741 742 743 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 741 def getblockparamproxy(index, level) push(GetBlockParamProxy.new(index, level)) end |
#getclassvariable(name) ⇒ Object
745 746 747 748 749 750 751 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 745 def getclassvariable(name) if RUBY_VERSION < "3.0" push(Legacy::GetClassVariable.new(name)) else push(GetClassVariable.new(name, inline_storage_for(name))) end end |
#getconstant(name) ⇒ Object
753 754 755 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 753 def getconstant(name) push(GetConstant.new(name)) end |
#getglobal(name) ⇒ Object
757 758 759 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 757 def getglobal(name) push(GetGlobal.new(name)) end |
#getinstancevariable(name) ⇒ Object
761 762 763 764 765 766 767 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 761 def getinstancevariable(name) if RUBY_VERSION < "3.2" push(GetInstanceVariable.new(name, inline_storage_for(name))) else push(GetInstanceVariable.new(name, inline_storage)) end end |
#getlocal(index, level) ⇒ Object
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 769 def getlocal(index, level) if .operands_unification? # Specialize the getlocal instruction based on the level of the # local variable. If it's 0 or 1, then there's a specialized # instruction that will look at the current scope or the parent # scope, respectively, and requires fewer operands. case level when 0 push(GetLocalWC0.new(index)) when 1 push(GetLocalWC1.new(index)) else push(GetLocal.new(index, level)) end else push(GetLocal.new(index, level)) end end |
#getspecial(key, type) ⇒ Object
788 789 790 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 788 def getspecial(key, type) push(GetSpecial.new(key, type)) end |
#inline_storage ⇒ Object
207 208 209 210 211 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 207 def inline_storage storage = storage_index @storage_index += 1 storage end |
#inline_storage_for(name) ⇒ Object
213 214 215 216 217 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 213 def inline_storage_for(name) inline_storages[name] = inline_storage unless inline_storages.key?(name) inline_storages[name] end |
#inspect ⇒ Object
299 300 301 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 299 def inspect "#<ISeq:#{name}@<compiled>:1 (#{line},0)-(#{line},0)>" end |
#intern ⇒ Object
792 793 794 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 792 def intern push(Intern.new) end |
#invokeblock(calldata) ⇒ Object
796 797 798 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 796 def invokeblock(calldata) push(InvokeBlock.new(calldata)) end |
#invokesuper(calldata, block_iseq) ⇒ Object
800 801 802 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 800 def invokesuper(calldata, block_iseq) push(InvokeSuper.new(calldata, block_iseq)) end |
#jump(label) ⇒ Object
804 805 806 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 804 def jump(label) push(Jump.new(label)) end |
#label ⇒ Object
Instruction push methods
629 630 631 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 629 def label Label.new end |
#leave ⇒ Object
808 809 810 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 808 def leave push(Leave.new) end |
#length ⇒ Object
219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 219 def length insns .each .inject(0) do |sum, insn| case insn when Integer, Label, Symbol sum else sum + insn.length end end end |
#local_variable(name, level = 0) ⇒ Object
Query methods
199 200 201 202 203 204 205 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 199 def local_variable(name, level = 0) if (lookup = local_table.find(name, level)) lookup elsif parent_iseq parent_iseq.local_variable(name, level + 1) end end |
#method_child_iseq(name, line) ⇒ Object
482 483 484 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 482 def method_child_iseq(name, line) child_iseq(name, line, :method) end |
#module_child_iseq(name, line) ⇒ Object
486 487 488 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 486 def module_child_iseq(name, line) child_iseq("<module:#{name}>", line, :class) end |
#newarray(number) ⇒ Object
812 813 814 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 812 def newarray(number) push(NewArray.new(number)) end |
#newarraykwsplat(number) ⇒ Object
816 817 818 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 816 def newarraykwsplat(number) push(NewArrayKwSplat.new(number)) end |
#newhash(number) ⇒ Object
820 821 822 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 820 def newhash(number) push(NewHash.new(number)) end |
#newrange(exclude_end) ⇒ Object
824 825 826 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 824 def newrange(exclude_end) push(NewRange.new(exclude_end)) end |
#nop ⇒ Object
828 829 830 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 828 def nop push(Nop.new) end |
#objtostring(calldata) ⇒ Object
832 833 834 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 832 def objtostring(calldata) push(ObjToString.new(calldata)) end |
#once(iseq, cache) ⇒ Object
836 837 838 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 836 def once(iseq, cache) push(Once.new(iseq, cache)) end |
#opt_aref_with(object, calldata) ⇒ Object
840 841 842 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 840 def opt_aref_with(object, calldata) push(OptArefWith.new(object, calldata)) end |
#opt_aset_with(object, calldata) ⇒ Object
844 845 846 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 844 def opt_aset_with(object, calldata) push(OptAsetWith.new(object, calldata)) end |
#opt_case_dispatch(case_dispatch_hash, else_label) ⇒ Object
848 849 850 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 848 def opt_case_dispatch(case_dispatch_hash, else_label) push(OptCaseDispatch.new(case_dispatch_hash, else_label)) end |
#opt_getconstant_path(names) ⇒ Object
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 852 def opt_getconstant_path(names) if RUBY_VERSION < "3.2" || !.inline_const_cache? cache = nil cache_filled_label = nil if .inline_const_cache? cache = inline_storage cache_filled_label = label opt_getinlinecache(cache_filled_label, cache) if names[0] == :"" names.shift pop putobject(Object) end elsif names[0] == :"" names.shift putobject(Object) else putnil end names.each_with_index do |name, index| putobject(index == 0) getconstant(name) end if .inline_const_cache? opt_setinlinecache(cache) push(cache_filled_label) end else push(OptGetConstantPath.new(names)) end end |
#opt_getinlinecache(label, cache) ⇒ Object
888 889 890 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 888 def opt_getinlinecache(label, cache) push(Legacy::OptGetInlineCache.new(label, cache)) end |
#opt_setinlinecache(cache) ⇒ Object
892 893 894 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 892 def opt_setinlinecache(cache) push(Legacy::OptSetInlineCache.new(cache)) end |
#pop ⇒ Object
896 897 898 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 896 def pop push(Pop.new) end |
#push(value) ⇒ Object
633 634 635 636 637 638 639 640 641 642 643 644 645 646 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 633 def push(value) node = insns.push(value) case value when Array, Integer, Symbol value when Label value.node = node value else stack.change_by(-value.pops + value.pushes) value end end |
#putnil ⇒ Object
900 901 902 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 900 def putnil push(PutNil.new) end |
#putobject(object) ⇒ Object
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 904 def putobject(object) if .operands_unification? # Specialize the putobject instruction based on the value of the # object. If it's 0 or 1, then there's a specialized instruction # that will push the object onto the stack and requires fewer # operands. if object.eql?(0) push(PutObjectInt2Fix0.new) elsif object.eql?(1) push(PutObjectInt2Fix1.new) else push(PutObject.new(object)) end else push(PutObject.new(object)) end end |
#putself ⇒ Object
922 923 924 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 922 def putself push(PutSelf.new) end |
#putspecialobject(object) ⇒ Object
926 927 928 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 926 def putspecialobject(object) push(PutSpecialObject.new(object)) end |
#putstring(object) ⇒ Object
930 931 932 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 930 def putstring(object) push(PutString.new(object)) end |
#send(calldata, block_iseq = nil) ⇒ Object
934 935 936 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 934 def send(calldata, block_iseq = nil) push(Send.new(calldata, block_iseq)) end |
#setblockparam(index, level) ⇒ Object
938 939 940 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 938 def setblockparam(index, level) push(SetBlockParam.new(index, level)) end |
#setclassvariable(name) ⇒ Object
942 943 944 945 946 947 948 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 942 def setclassvariable(name) if RUBY_VERSION < "3.0" push(Legacy::SetClassVariable.new(name)) else push(SetClassVariable.new(name, inline_storage_for(name))) end end |
#setconstant(name) ⇒ Object
950 951 952 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 950 def setconstant(name) push(SetConstant.new(name)) end |
#setglobal(name) ⇒ Object
954 955 956 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 954 def setglobal(name) push(SetGlobal.new(name)) end |
#setinstancevariable(name) ⇒ Object
958 959 960 961 962 963 964 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 958 def setinstancevariable(name) if RUBY_VERSION < "3.2" push(SetInstanceVariable.new(name, inline_storage_for(name))) else push(SetInstanceVariable.new(name, inline_storage)) end end |
#setlocal(index, level) ⇒ Object
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 966 def setlocal(index, level) if .operands_unification? # Specialize the setlocal instruction based on the level of the # local variable. If it's 0 or 1, then there's a specialized # instruction that will write to the current scope or the parent # scope, respectively, and requires fewer operands. case level when 0 push(SetLocalWC0.new(index)) when 1 push(SetLocalWC1.new(index)) else push(SetLocal.new(index, level)) end else push(SetLocal.new(index, level)) end end |
#setn(number) ⇒ Object
985 986 987 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 985 def setn(number) push(SetN.new(number)) end |
#setspecial(key) ⇒ Object
989 990 991 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 989 def setspecial(key) push(SetSpecial.new(key)) end |
#singleton_class_child_iseq(line) ⇒ Object
490 491 492 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 490 def singleton_class_child_iseq(line) child_iseq("singleton class", line, :class) end |
#specialize_instructions! ⇒ Object
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 341 def specialize_instructions! insns.each_node do |node, value| case value when NewArray next unless node.next_node next_node = node.next_node next unless next_node.value.is_a?(Send) next if next_node.value.block_iseq calldata = next_node.value.calldata next unless calldata.flags == CallData::CALL_ARGS_SIMPLE next unless calldata.argc == 0 case calldata.method when :min node.value = if RUBY_VERSION < "3.3" Legacy::OptNewArrayMin.new(value.number) else OptNewArraySend.new(value.number, :min) end node.next_node = next_node.next_node when :max node.value = if RUBY_VERSION < "3.3" Legacy::OptNewArrayMax.new(value.number) else OptNewArraySend.new(value.number, :max) end node.next_node = next_node.next_node when :hash next if RUBY_VERSION < "3.3" node.value = OptNewArraySend.new(value.number, :hash) node.next_node = next_node.next_node end when PutObject, PutString next unless node.next_node next if value.is_a?(PutObject) && !value.object.is_a?(String) next_node = node.next_node next unless next_node.value.is_a?(Send) next if next_node.value.block_iseq calldata = next_node.value.calldata next unless calldata.flags == CallData::CALL_ARGS_SIMPLE next unless calldata.argc == 0 case calldata.method when :freeze node.value = OptStrFreeze.new(value.object, calldata) node.next_node = next_node.next_node when :-@ node.value = OptStrUMinus.new(value.object, calldata) node.next_node = next_node.next_node end when Send calldata = value.calldata if !value.block_iseq && !calldata.flag?(CallData::CALL_ARGS_BLOCKARG) # Specialize the send instruction. If it doesn't have a block # attached, then we will replace it with an opt_send_without_block # and do further specializations based on the called method and # the number of arguments. node.value = case [calldata.method, calldata.argc] when [:length, 0] OptLength.new(calldata) when [:size, 0] OptSize.new(calldata) when [:empty?, 0] OptEmptyP.new(calldata) when [:nil?, 0] OptNilP.new(calldata) when [:succ, 0] OptSucc.new(calldata) when [:!, 0] OptNot.new(calldata) when [:+, 1] OptPlus.new(calldata) when [:-, 1] OptMinus.new(calldata) when [:*, 1] OptMult.new(calldata) when [:/, 1] OptDiv.new(calldata) when [:%, 1] OptMod.new(calldata) when [:==, 1] OptEq.new(calldata) when [:!=, 1] OptNEq.new(YARV.calldata(:==, 1), calldata) when [:=~, 1] OptRegExpMatch2.new(calldata) when [:<, 1] OptLT.new(calldata) when [:<=, 1] OptLE.new(calldata) when [:>, 1] OptGT.new(calldata) when [:>=, 1] OptGE.new(calldata) when [:<<, 1] OptLTLT.new(calldata) when [:[], 1] OptAref.new(calldata) when [:&, 1] OptAnd.new(calldata) when [:|, 1] OptOr.new(calldata) when [:[]=, 2] OptAset.new(calldata) else OptSendWithoutBlock.new(calldata) end end end end end |
#splatarray(flag) ⇒ Object
993 994 995 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 993 def splatarray(flag) push(SplatArray.new(flag)) end |
#swap ⇒ Object
997 998 999 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 997 def swap push(Swap.new) end |
#throw(type) ⇒ Object
1001 1002 1003 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 1001 def throw(type) push(Throw.new(type)) end |
#to_a ⇒ Object
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 236 def to_a versions = RUBY_VERSION.split(".").map(&:to_i) # Dump all of the instructions into a flat list. dumped = insns.map do |insn| case insn when Integer, Symbol insn when Label insn.name else insn.to_a(self) end end = .dup [:opt].map!(&:name) if [:opt] # Next, return the instruction sequence as an array. [ MAGIC, versions[0], versions[1], 1, { arg_size: argument_size, local_size: local_table.size, stack_max: stack.maximum_size, node_id: -1, node_ids: [-1] * insns.length }, name, file, "<compiled>", line, type, local_table.names, , catch_table.map(&:to_a), dumped ] end |
#to_cfg ⇒ Object
280 281 282 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 280 def to_cfg ControlFlowGraph.compile(self) end |
#to_dfg ⇒ Object
284 285 286 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 284 def to_dfg to_cfg.to_dfg end |
#to_son ⇒ Object
288 289 290 |
# File 'lib/syntax_tree/yarv/instruction_sequence.rb', line 288 def to_son to_dfg.to_son end |