Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added generated opcode methods instead of #method_missing on Generator.

  • Loading branch information...
commit af8a5cd2ae46131f52a2ccbec98bc680b26521b2 1 parent 653c40f
Brian Shirai authored
1  .gitignore
@@ -64,6 +64,7 @@ tmtags
64 64
 /kernel/signature.rb
65 65
 
66 66
 /lib/compiler/opcodes.rb
  67
+/lib/compiler/generator_methods.rb
67 68
 
68 69
 /lib/etc.rb
69 70
 /lib/kernel.rb
1  lib/compiler.rb
@@ -6,6 +6,7 @@
6 6
 require base + "/compiler/stages"
7 7
 require base + "/compiler/locals"
8 8
 require base + "/compiler/ast"
  9
+require base + "/compiler/generator_methods"
9 10
 require base + "/compiler/generator"
10 11
 require base + "/compiler/stack_calculator"
11 12
 require base + "/compiler/iseq"
4  lib/compiler/ast/transforms.rb
@@ -196,7 +196,7 @@ def bytecode(g)
196 196
         @receiver.bytecode(g)
197 197
         @arguments.bytecode(g)
198 198
 
199  
-        g.add @operator, g.find_literal(@name)
  199
+        g.__send__ @operator, g.find_literal(@name)
200 200
       end
201 201
     end
202 202
 
@@ -309,7 +309,7 @@ def bytecode(g)
309 309
         @arguments.bytecode(g)
310 310
         @receiver.bytecode(g)
311 311
 
312  
-        g.add @name
  312
+        g.__send__ @name
313 313
       end
314 314
     end
315 315
 
185  lib/compiler/generator.rb
@@ -11,6 +11,7 @@ def self.from(opcodes)
11 11
   end
12 12
 
13 13
   class Generator
  14
+    include GeneratorMethods
14 15
 
15 16
     CALL_FLAG_PRIVATE = 1
16 17
     CALL_FLAG_CONCAT = 2
@@ -160,48 +161,6 @@ def package(klass)
160 161
     end
161 162
 
162 163
 
163  
-    # Helpers
164  
-
165  
-    def new_stack_local
166  
-      idx = @stack_locals
167  
-      @stack_locals += 1
168  
-      return idx
169  
-    end
170  
-
171  
-    def add(instruction, arg1=nil, arg2=nil)
172  
-      @stream << InstructionSet[instruction].bytecode
173  
-      length = 1
174  
-
175  
-      if arg1
176  
-        @stream << arg1
177  
-        length = 2
178  
-
179  
-        if arg2
180  
-          @stream << arg2
181  
-          length = 3
182  
-        end
183  
-      end
184  
-
185  
-      @ip += length
186  
-
187  
-      @instruction = instruction
188  
-    end
189  
-
190  
-    # Find the index for the specified literal, or create a new slot if the
191  
-    # literal has not been encountered previously.
192  
-    def find_literal(literal)
193  
-      @literals_map[literal]
194  
-    end
195  
-
196  
-    # Add literal exists to allow RegexLiteral's to create a new regex literal
197  
-    # object at run-time. All other literals should be added via find_literal,
198  
-    # which re-use an existing matching literal if one exists.
199  
-    def add_literal(literal)
200  
-      index = @literals.size
201  
-      @literals << literal
202  
-      return index
203  
-    end
204  
-
205 164
     # Commands (these don't generate data in the stream)
206 165
 
207 166
     def state
@@ -275,7 +234,13 @@ def new_label
275 234
     end
276 235
 
277 236
 
278  
-    # Operations
  237
+    # Helpers and overrides
  238
+
  239
+    def new_stack_local
  240
+      idx = @stack_locals
  241
+      @stack_locals += 1
  242
+      return idx
  243
+    end
279 244
 
280 245
     def push(what)
281 246
       case what
@@ -288,32 +253,26 @@ def push(what)
288 253
       when :nil
289 254
         push_nil
290 255
       when Integer
291  
-        push_int(what)
  256
+        push_int what
292 257
       else
293 258
         raise Error, "Unknown push argument '#{what.inspect}'"
294 259
       end
295 260
     end
296 261
 
297  
-    def push_symbol(what)
298  
-      push_literal what
299  
-    end
300  
-
301 262
     def push_int(int)
302  
-      case int
303  
-      when -1
304  
-        add :meta_push_neg_1
305  
-      when 0
306  
-        add :meta_push_0
307  
-      when 1
308  
-        add :meta_push_1
309  
-      when 2
310  
-        add :meta_push_2
  263
+      # Integers greater than 256 are stored in the literals tuple.
  264
+      if int > 2 and int < 256
  265
+        super int
311 266
       else
312  
-        # The max value we use for inline ints. Above this, they're
313  
-        # stored in the literals tuple.
314  
-        inline_cutoff = 256
315  
-        if int > 0 and int < inline_cutoff
316  
-          add :push_int, int
  267
+        case int
  268
+        when -1
  269
+          meta_push_neg_1
  270
+        when 0
  271
+          meta_push_0
  272
+        when 1
  273
+          meta_push_1
  274
+        when 2
  275
+          meta_push_2
317 276
         else
318 277
           push_literal int
319 278
         end
@@ -325,10 +284,25 @@ def push_generator(generator)
325 284
       push_literal generator
326 285
     end
327 286
 
  287
+    # Find the index for the specified literal, or create a new slot if the
  288
+    # literal has not been encountered previously.
  289
+    def find_literal(literal)
  290
+      @literals_map[literal]
  291
+    end
  292
+
  293
+    # Add literal exists to allow RegexLiteral's to create a new regex literal
  294
+    # object at run-time. All other literals should be added via find_literal,
  295
+    # which re-use an existing matching literal if one exists.
  296
+    def add_literal(literal)
  297
+      index = @literals.size
  298
+      @literals << literal
  299
+      return index
  300
+    end
  301
+
328 302
     # Pushes the specified literal value into the literal's tuple
329  
-    def push_literal(literal)
330  
-      index = find_literal literal
331  
-      add :push_literal, index
  303
+    def push_literal(literal_or_index, search=true)
  304
+      index = search ? find_literal(literal_or_index) : literal_or_index
  305
+      super index
332 306
       return index
333 307
     end
334 308
 
@@ -336,7 +310,7 @@ def push_literal(literal)
336 310
     # something that is like +what+ is already there.
337 311
     def push_unique_literal(literal)
338 312
       index = add_literal literal
339  
-      add :push_literal, index
  313
+      push_literal index, false
340 314
       return index
341 315
     end
342 316
 
@@ -345,83 +319,62 @@ def push_unique_literal(literal)
345 319
     # method exists to support RegexLiteral, where the compiled literal value
346 320
     # (a Regex object) does not exist until runtime.
347 321
     def push_literal_at(index)
348  
-      add :push_literal, index
  322
+      push_literal index, false
349 323
       return index
350 324
     end
351 325
 
352  
-    def set_literal(index)
353  
-      add :set_literal, index
354  
-    end
355  
-
356 326
     def push_ivar(name)
357  
-      add :push_ivar, find_literal(name)
  327
+      super find_literal(name)
358 328
     end
359 329
 
360 330
     def set_ivar(name)
361  
-      add :set_ivar, find_literal(name)
  331
+      super find_literal(name)
362 332
     end
363 333
 
364 334
     def push_const(name)
365  
-      add :push_const_fast, find_literal(name), add_literal(nil)
  335
+      push_const_fast find_literal(name), add_literal(nil)
366 336
     end
367 337
 
368 338
     def find_const(name)
369  
-      add :find_const, find_literal(name)
  339
+      super find_literal(name)
370 340
     end
371 341
 
372 342
     def dup
373  
-      add :dup_top
  343
+      dup_top
374 344
     end
375 345
 
376 346
     def swap
377  
-      add :swap_stack
  347
+      swap_stack
378 348
     end
379 349
 
380 350
     def gif(label)
381  
-      add :goto_if_false, label
  351
+      goto_if_false label
382 352
       label.used_at @ip - 1
383 353
     end
384 354
 
385 355
     def git(label)
386  
-      add :goto_if_true, label
  356
+      goto_if_true label
387 357
       label.used_at @ip - 1
388 358
     end
389 359
 
390 360
     def goto(label)
391  
-      add :goto, label
  361
+      super label
392 362
       label.used_at @ip - 1
393 363
     end
394 364
 
395 365
     def setup_unwind(label, type)
396  
-      add :setup_unwind, label, type
  366
+      super label, type
397 367
       label.used_at @ip - 2
398 368
     end
399 369
 
400  
-    def set_local(index)
401  
-      add :set_local, index
402  
-    end
403  
-
404  
-    def push_local(index)
405  
-      add :push_local, index
406  
-    end
407  
-
408  
-    def set_local_depth(depth, index)
409  
-      add :set_local_depth, depth, index
410  
-    end
411  
-
412  
-    def push_local_depth(depth, index)
413  
-      add :push_local_depth, depth, index
414  
-    end
415  
-
416 370
     def cast_array
417 371
       unless @instruction == :cast_array or @instruction == :make_array
418  
-        add :cast_array
  372
+        super()
419 373
       end
420 374
     end
421 375
 
422 376
     def invoke_primitive(name, count)
423  
-      idx = find_literal(name)
424  
-      add :invoke_primitive, idx, Integer(count)
  377
+      super find_literal(name), Integer(count)
425 378
     end
426 379
 
427 380
     def last_match(mode, which)
@@ -431,7 +384,7 @@ def last_match(mode, which)
431 384
     end
432 385
 
433 386
     def send(meth, count, priv=false)
434  
-      add :allow_private if priv
  387
+      allow_private if priv
435 388
 
436 389
       unless count.kind_of? Fixnum
437 390
         raise Error, "count must be a number"
@@ -440,14 +393,14 @@ def send(meth, count, priv=false)
440 393
       idx = find_literal(meth)
441 394
 
442 395
       if count == 0
443  
-        add :send_method, idx
  396
+        send_method idx
444 397
       else
445  
-        add :send_stack, idx, count
  398
+        send_stack idx, count
446 399
       end
447 400
     end
448 401
 
449 402
     def send_with_block(meth, count, priv=false)
450  
-      add :allow_private if priv
  403
+      allow_private if priv
451 404
 
452 405
       unless count.kind_of? Fixnum
453 406
         raise Error, "count must be a number"
@@ -455,50 +408,46 @@ def send_with_block(meth, count, priv=false)
455 408
 
456 409
       idx = find_literal(meth)
457 410
 
458  
-      add :send_stack_with_block, idx, count
  411
+      send_stack_with_block idx, count
459 412
     end
460 413
 
461 414
     def send_with_splat(meth, args, priv=false, concat=false)
462 415
       val = 0
463 416
       val |= CALL_FLAG_CONCAT  if concat
464  
-      add :set_call_flags, val unless val == 0
  417
+      set_call_flags val unless val == 0
465 418
 
466  
-      add :allow_private if priv
  419
+      allow_private if priv
467 420
 
468 421
       idx = find_literal(meth)
469  
-      add :send_stack_with_splat, idx, args
  422
+      send_stack_with_splat idx, args
470 423
     end
471 424
 
472 425
     def send_super(meth, args, splat=false)
473 426
       idx = find_literal(meth)
474 427
 
475 428
       if splat
476  
-        add :send_super_stack_with_splat, idx, args
  429
+        send_super_stack_with_splat idx, args
477 430
       else
478  
-        add :send_super_stack_with_block, idx, args
  431
+        send_super_stack_with_block idx, args
479 432
       end
480 433
     end
481 434
 
482 435
     def zsuper(meth)
483  
-      add :zsuper, find_literal(meth)
  436
+      super find_literal(meth)
484 437
     end
485 438
 
486 439
     def check_serial(sym, serial)
487  
-      add :check_serial, find_literal(sym), serial.to_i
  440
+      super find_literal(sym), serial.to_i
488 441
     end
489 442
 
490 443
     def check_serial_private(sym, serial)
491  
-      add :check_serial_private, find_literal(sym), serial.to_i
  444
+      super find_literal(sym), serial.to_i
492 445
     end
493 446
 
494 447
     def create_block(generator)
495 448
       @generators << generator
496 449
       index = add_literal generator
497  
-      add :create_block, index
498  
-    end
499  
-
500  
-    def method_missing(instruction, arg1=nil, arg2=nil)
501  
-      add instruction, arg1, arg2
  450
+      super index
502 451
     end
503 452
   end
504 453
 end
37  rakelib/instruction_parser.rb
@@ -55,6 +55,9 @@ class Definition
55 55
     def opcode_definition(file)
56 56
     end
57 57
 
  58
+    def opcode_method(file)
  59
+    end
  60
+
58 61
     def opcode_name
59 62
     end
60 63
 
@@ -191,7 +194,25 @@ def opcode_definition(file)
191 194
       args = "[#{@arguments.map { |x| ":#{x}" }.join(", ")}],"
192 195
       file.print ":args => %-20s" % args
193 196
 
194  
-      file.puts  ":control_flow => :#{@control_flow}"
  197
+      file.puts  "              :control_flow => :#{@control_flow}"
  198
+    end
  199
+
  200
+    def opcode_method(file)
  201
+      case @arguments.size
  202
+      when 0
  203
+        file.puts "      def #{@name}"
  204
+        file.puts "        @stream << #{@bytecode}"
  205
+      when 1
  206
+        file.puts "      def #{@name}(arg)"
  207
+        file.puts "        @stream << #{@bytecode} << arg"
  208
+      when 2
  209
+        file.puts "      def #{@name}(arg1, arg2)"
  210
+        file.puts "        @stream << #{@bytecode} << arg1 << arg2"
  211
+      end
  212
+      file.puts "        @ip += #{@arguments.size + 1}"
  213
+      file.puts "        @instruction = :#{@name}"
  214
+      file.puts "      end"
  215
+      file.puts ""
195 216
     end
196 217
 
197 218
     def opcode_name
@@ -313,6 +334,20 @@ def generate_opcodes(filename)
313 334
     end
314 335
   end
315 336
 
  337
+  def generate_generator_methods(filename)
  338
+    File.open filename, "w" do |file|
  339
+      file.puts "# *** This file is generated by InstructionParser ***"
  340
+      file.puts
  341
+      file.puts "module Rubinius"
  342
+      file.puts "  module GeneratorMethods"
  343
+
  344
+      objects.each { |obj| obj.opcode_method file }
  345
+
  346
+      file.puts "  end"
  347
+      file.puts "end"
  348
+    end
  349
+  end
  350
+
316 351
   def generate_names(filename)
317 352
     File.open filename, "w" do |file|
318 353
       file.puts "const char *rubinius::InstructionSequence::get_instruction_name(int op) {"
1  rakelib/kernel.rake
@@ -82,6 +82,7 @@ compiler_files = FileList[
82 82
   "lib/compiler.rb",
83 83
   "lib/compiler/**/*.rb",
84 84
   opcodes,
  85
+  "lib/compiler/generator_methods.rb",
85 86
   "lib/melbourne.rb",
86 87
   "lib/melbourne/**/*.rb"
87 88
 ]
4  rakelib/vm.rake
@@ -527,6 +527,10 @@ file "lib/compiler/opcodes.rb" => insn_deps do |t|
527 527
   generate_instruction_file iparser, :generate_opcodes, t.name
528 528
 end
529 529
 
  530
+file "lib/compiler/generator_methods.rb" => insn_deps do |t|
  531
+  generate_instruction_file iparser, :generate_generator_methods, t.name
  532
+end
  533
+
530 534
 file "vm/gen/instruction_names.hpp" => insn_deps do |t|
531 535
   generate_instruction_file iparser, :generate_names_header, t.name
532 536
 end
2  vm/instructions.def
@@ -666,7 +666,7 @@ instruction raise_exc() [ -- ] => raise
666 666
   RUN_EXCEPTION();
667 667
 end
668 668
 
669  
-instruction setup_unwind(ip type) [ -- ]
  669
+instruction setup_unwind(ip type) [ -- ] => handler
670 670
   interp_assert(current_unwind < kMaxUnwindInfos);
671 671
   UnwindInfo& info = unwinds[current_unwind++];
672 672
   info.target_ip = ip;

0 notes on commit af8a5cd

Please sign in to comment.
Something went wrong with that request. Please try again.