Class: CastOff::Compiler::Instruction::InsnInfo

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/cast_off/compile/instruction.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

#bug, #dlog, #todo, #vlog

Constructor Details

#initialize(insn, iseq, pc = -1,, line = -1,, safe = false, depth = nil) ⇒ InsnInfo

pc > 0 : standard instruction pc == -1: cast_off instruction safe = true : should not be generate guard safe = false: should be generate guard



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/cast_off/compile/instruction.rb', line 94

def initialize(insn, iseq, pc = -1, line = -1, safe = false, depth = nil)
  @op, *@argv = *insn
  bug() unless iseq.is_a?(Iseq)
  @iseq = iseq
  @pc = pc
  @ic_class = class_information_in_ic(@iseq.iseq)
  @line = line
  @safe = safe
  if pc == -1 && !safe
    bug(op) if TypeInfoUser.include?(op)
  end
  @depth = depth
  @guard_label = "guard_#{self.hash.to_s.gsub(/-/, "_")}"
end

Instance Attribute Details

#argvObject (readonly)

Returns the value of attribute argv.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def argv
  @argv
end

#depthObject (readonly)

Returns the value of attribute depth.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def depth
  @depth
end

#guard_labelObject (readonly)

Returns the value of attribute guard_label.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def guard_label
  @guard_label
end

#ic_classObject (readonly)

Returns the value of attribute ic_class.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def ic_class
  @ic_class
end

#iseqObject (readonly)

Returns the value of attribute iseq.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def iseq
  @iseq
end

#lineObject (readonly)

Returns the value of attribute line.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def line
  @line
end

#opObject (readonly)

Returns the value of attribute op.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def op
  @op
end

#pcObject (readonly)

Returns the value of attribute pc.



88
89
90
# File 'lib/cast_off/compile/instruction.rb', line 88

def pc
  @pc
end

Instance Method Details

#dupObject



136
137
138
139
140
# File 'lib/cast_off/compile/instruction.rb', line 136

def dup()
  ret = InsnInfo.new(insn(), @iseq, @pc, @line, @safe)
  ret.set_stack_depth(@depth)
  ret
end

#get_iseqObject



198
199
200
201
# File 'lib/cast_off/compile/instruction.rb', line 198

def get_iseq()
  index = get_iseq_index()
  index ? @argv[index] : nil
end

#get_labelObject



209
210
211
212
# File 'lib/cast_off/compile/instruction.rb', line 209

def get_label()
  index = get_label_index()
  index ? @argv[index] : nil
end

#get_throw_infoObject



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
# File 'lib/cast_off/compile/instruction.rb', line 360

def get_throw_info()
  bug() unless @op == :throw
  # 1.9.2 and 1.9.3 compatible
  throw_state = @argv[0]
  state = throw_state & 0xff;
  flag = throw_state & 0x8000;
  level = throw_state >> 16;
  case state
  when THROW_TAG_RETURN
    type = :return
  when THROW_TAG_BREAK
    type = :break
  when THROW_TAG_NEXT
    type = :next
  when THROW_TAG_RETRY
    type = :retry
  when THROW_TAG_REDO
    type = :redo
  when THROW_TAG_RAISE
    type = :raise
  when THROW_TAG_THROW
    type = :throw
  when THROW_TAG_FATAL
    type = :fatal
  else
    bug()
  end
  [type, state, flag, level]
end

#get_unsupport_messageObject



168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/cast_off/compile/instruction.rb', line 168

def get_unsupport_message()
  case @op
  when :defineclass
    "Currently, CastOff cannot handle class definition"
  when :putspecialobject, :putiseq
    "Currently, CastOff cannot handle #{@op} instruction which is used for method definition"
  when :invokesuper
    "Currently, CastOff cannot handle super"
  else
    "Currently, CastOff cannot handle #{@op} instruction"
  end
end

#ignore?Boolean

Returns:

  • (Boolean)


194
195
196
# File 'lib/cast_off/compile/instruction.rb', line 194

def ignore?
  IgnoreInstruction.index(@op)
end

#need_guard?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/cast_off/compile/instruction.rb', line 117

def need_guard?
  @safe ? false : true
end

#popnumObject



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
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
279
280
281
282
283
284
285
286
# File 'lib/cast_off/compile/instruction.rb', line 220

def popnum()
  case @op
  when :leave, :throw
    return 1
  when :dup
    return 1
  when :dupn
    n = @argv[0]
    return n
  when :setn
    n = @argv[0]
    return n + 1
  when :topn
    n = @argv[0]
    return n + 1
  end
  begin
    return instruction_popnum(insn())
  rescue ArgumentError => e
    case @op
    when :cast_off_prep
      return @argv.last.popnum()
    when :cast_off_loop
      return 0 # push true(continue loop) or false(not continue loop)
    when :cast_off_cont
      return 0
    when :cast_off_finl
      return 0
    when :cast_off_getlvar
      return 0
    when :cast_off_setlvar
      return 1
    when :cast_off_getivar
      return 0
    when :cast_off_setivar
      return 1
    when :cast_off_getcvar
      return 0
    when :cast_off_setcvar
      return 1
    when :cast_off_getgvar
      return 0
    when :cast_off_setgvar
      return 1
    when :cast_off_getdvar
      return 0
    when :cast_off_setdvar
      return 1
    when :cast_off_handle_optional_args
      return 1
    when :cast_off_fetch_args
      return 0
    when :cast_off_decl_arg, :cast_off_decl_var
      return 0
    when :cast_off_getconst
      return 0
    when :cast_off_enter_block, :cast_off_leave_block
      return 0
    when :cast_off_break_block
      return 1
    when :cast_off_continue_loop
      return 1
    else
      bug("unsupported instruction #{@op}, #{@argv}")
    end
  end
end

#pushnumObject



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/cast_off/compile/instruction.rb', line 288

def pushnum()
  case @op
  when :leave, :throw
    return 0
  when :dup
    return 2
  when :dupn
    n = @argv[0]
    return n * 2
  when :setn
    n = @argv[0]
    return n + 1
  when :topn
    n = @argv[0]
    return n + 2
  end
  begin
    return instruction_pushnum(insn())
  rescue ArgumentError => e
    case @op
    when :cast_off_prep
      return @argv.last.pushnum()
    when :cast_off_loop
      return 0 # push true(continue loop) or false(not continue loop)
    when :cast_off_cont
      return 0
    when :cast_off_finl
      return 1
    when :cast_off_getlvar
      return 1
    when :cast_off_setlvar
      return 0
    when :cast_off_getivar
      return 1
    when :cast_off_setivar
      return 0
    when :cast_off_getcvar
      return 1
    when :cast_off_setcvar
      return 0
    when :cast_off_getgvar
      return 1
    when :cast_off_setgvar
      return 0
    when :cast_off_getdvar
      return 1
    when :cast_off_setdvar
      return 0
    when :cast_off_handle_optional_args
      return 0
    when :cast_off_fetch_args
      return 1
    when :cast_off_decl_arg, :cast_off_decl_var
      return 0
    when :cast_off_getconst
      return 1
    when :cast_off_enter_block, :cast_off_leave_block
      return 0
    when :cast_off_break_block
      return 1
    when :cast_off_continue_loop
      return 0
    else
      bug("unsupported instruction #{@op}, #{@argv}")
    end
  end
end

#set_iseq(iseq) ⇒ Object



203
204
205
206
207
# File 'lib/cast_off/compile/instruction.rb', line 203

def set_iseq(iseq)
  index = get_iseq_index()
  bug() unless index
  @argv[index] = iseq
end

#set_label(label) ⇒ Object



214
215
216
217
218
# File 'lib/cast_off/compile/instruction.rb', line 214

def set_label(label)
  index = get_label_index()
  bug() unless index
  @argv[index] = label
end

#set_stack_depth(depth) ⇒ Object



113
114
115
# File 'lib/cast_off/compile/instruction.rb', line 113

def set_stack_depth(depth)
  @depth = depth
end

#sizeObject



109
110
111
# File 'lib/cast_off/compile/instruction.rb', line 109

def size
  @argv.size + 1
end

#sourceObject



125
126
127
128
129
130
131
132
133
134
# File 'lib/cast_off/compile/instruction.rb', line 125

def source()
  bug() unless @iseq
  src = @iseq.source
  if @line > 0 && src
    src = src[@line - 1]
    src ? src.sub(/^[\s]+/, '').chomp : ''
  else
    ''
  end
end

#stack_usageObject



356
357
358
# File 'lib/cast_off/compile/instruction.rb', line 356

def stack_usage()
  pushnum() - popnum()
end

#support?Boolean

Returns:

  • (Boolean)


181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/cast_off/compile/instruction.rb', line 181

def support?
  if SupportInstruction.index(@op)
    case @op
    when :throw
      support_throw_instruction?
    else
      true
    end
  else
    false
  end
end

#to_sObject



121
122
123
# File 'lib/cast_off/compile/instruction.rb', line 121

def to_s
  "line[#{@line}]: #{source()}"
end

#update(n_insn) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/cast_off/compile/instruction.rb', line 142

def update(n_insn)
  n_op, *n_argv = *n_insn
  case @op
  when :getdynamic, :getlocal
    bug() unless n_op == :cast_off_getlvar || n_op == :cast_off_getdvar
  when :setdynamic, :setlocal
    bug() unless n_op == :cast_off_setlvar || n_op == :cast_off_setdvar
  when :getinstancevariable
    bug() unless n_op == :cast_off_getivar
  when :setinstancevariable
    bug() unless n_op == :cast_off_setivar
  when :getclassvariable
    bug() unless n_op == :cast_off_getcvar
  when :setclassvariable
    bug() unless n_op == :cast_off_setcvar
  when :getglobal
    bug() unless n_op == :cast_off_getgvar
  when :setglobal
    bug() unless n_op == :cast_off_setgvar
  else
    bug()
  end
  @op = n_op
  @argv = n_argv
end