voodoo 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  require 'voodoo/config'
2
2
  require 'voodoo/code_generator'
3
3
  require 'voodoo/compiler'
4
+ require 'voodoo/error'
4
5
  require 'voodoo/parser'
5
6
 
6
7
  # = Voodoo - Code Generation for Multiple Target Platforms
@@ -1,4 +1,5 @@
1
1
  require 'voodoo/config'
2
+ require 'voodoo/error'
2
3
 
3
4
  module Voodoo
4
5
  # Module for selecting code generators.
@@ -64,6 +65,32 @@ module Voodoo
64
65
  def formats architecture
65
66
  @@generators[architecture.to_sym].keys
66
67
  end
68
+
69
+ # Base class for errors raised by code generators.
70
+ class Error < Voodoo::Error
71
+ end
72
+
73
+ # Error raised when a symbol is exported after it has been used.
74
+ class SymbolsExportedAfterUseError < Error
75
+ def initialize symbols
76
+ @symbols = symbols
77
+ super("Symbols exported after they have been used: " +
78
+ symbols.to_a.join(" "))
79
+ end
80
+
81
+ attr_reader :symbols
82
+ end
83
+
84
+ # Error raised when a symbol is imported after it has been used.
85
+ class SymbolsImportedAfterUseError < Error
86
+ def initialize symbols
87
+ @symbols = symbols
88
+ super("Symbols imported after they have been used: " +
89
+ symbols.to_a.join(" "))
90
+ end
91
+
92
+ attr_reader :symbols
93
+ end
67
94
  end
68
95
  end
69
96
 
@@ -1,3 +1,4 @@
1
+ require 'voodoo/error'
1
2
  require 'voodoo/parser'
2
3
 
3
4
  module Voodoo
@@ -9,7 +10,7 @@ module Voodoo
9
10
  # An example of its usage can be found on the main page for the
10
11
  # Voodoo module.
11
12
  class Compiler
12
- class Error < StandardError
13
+ class Error < Voodoo::Error
13
14
  def initialize errors
14
15
  @errors = errors
15
16
  end
@@ -54,6 +55,9 @@ module Voodoo
54
55
  @generator.add section, statement
55
56
  end
56
57
 
58
+ rescue CodeGenerator::Error => e
59
+ errors << e
60
+
57
61
  rescue Parser::MultipleErrors => e
58
62
  errors.concat e.errors
59
63
 
@@ -2,7 +2,7 @@ module Voodoo
2
2
  # Methods to get and set configuration parameters
3
3
  module Config
4
4
  IMPLEMENTATION_NAME = 'Voodoo Compiler'
5
- IMPLEMENTATION_VERSION = '1.1.2'
5
+ IMPLEMENTATION_VERSION = '1.1.3'
6
6
 
7
7
  # Class that holds configuration parameters
8
8
  class Configuration
@@ -38,7 +38,7 @@ module Voodoo
38
38
  case arch
39
39
  when 'x86_64', 'amd64'
40
40
  :amd64
41
- when 'arm'
41
+ when /^arm/
42
42
  :arm
43
43
  when 'i386', 'i686'
44
44
  :i386
@@ -0,0 +1,5 @@
1
+ module Voodoo
2
+ # Base class of errors raised by the Voodoo Compiler.
3
+ class Error < StandardError
4
+ end
5
+ end
@@ -167,7 +167,7 @@ module Voodoo
167
167
  # If value_ref is a symbol, use PLT-relative addressing
168
168
  if global?(func)
169
169
  @symbol_tracker.use func
170
- emit "call #{value_ref} wrt ..plt\n"
170
+ emit "call #{func} wrt ..plt\n"
171
171
  else
172
172
  emit "call #{value_ref}\n"
173
173
  end
@@ -99,7 +99,6 @@ module Voodoo
99
99
  @frame_offset = 0
100
100
  @frame_size = 0
101
101
  @function_end_label = nil
102
- @imports = Set.new
103
102
  @if_labels = []
104
103
  @saved_registers = [] # registers we've saved in the current frame
105
104
  @saved_size = 0 # bytes dedicated to saved registers
@@ -338,6 +337,11 @@ module Voodoo
338
337
  @constants = []
339
338
  end
340
339
 
340
+ # Declares symbols to be exported.
341
+ def emit_export *symbols
342
+ symbols.each { |sym| emit ".globl #{sym}\n" }
343
+ end
344
+
341
345
  # Emit function prologue.
342
346
  def emit_function_prologue formals = [], nlocals = 0
343
347
  # Calculate the number of arguments we were passed in
@@ -443,13 +447,13 @@ module Voodoo
443
447
  case op
444
448
  when :div
445
449
  func = :"__aeabi_idiv"
446
- import func unless @imports.member? func
450
+ import func unless @relocated_symbols.member? func
447
451
  call func, expr[1], expr[2]
448
452
  emit "cpy #{register}, r0\n" if register != :r0
449
453
  return
450
454
  when :mod
451
455
  func = :"__aeabi_idivmod"
452
- import func unless @imports.member? func
456
+ import func unless @relocated_symbols.member? func
453
457
  call func, expr[1], expr[2]
454
458
  emit "cpy #{register}, r1\n" if register != :r1
455
459
  return
@@ -543,11 +547,6 @@ module Voodoo
543
547
  end
544
548
  end
545
549
 
546
- # Export symbols from the current section
547
- def export *symbols
548
- symbols.each { |sym| emit ".globl #{sym}\n" }
549
- end
550
-
551
550
  # Load byte from _base_ + _offset_ into _register_
552
551
  def get_byte base, offset, register
553
552
  # If base is an integer, but offset isn't, swap them
@@ -656,13 +655,6 @@ module Voodoo
656
655
  common_if :ifne, x, y
657
656
  end
658
657
 
659
- # Import labels into the current section
660
- def import *symbols
661
- # Record imported labels in @imports and @symbol_tracker
662
- @imports.merge symbols
663
- @symbol_tracker.define *symbols
664
- end
665
-
666
658
  # Introduce a new local variable
667
659
  def let symbol, *expr
668
660
  n = @environment.locals
@@ -295,6 +295,13 @@ module Voodoo
295
295
  @sections[real_section_name(@section)] << code
296
296
  end
297
297
 
298
+ # Emits code for an import incantation. For some targets, no code actually
299
+ # need be emitted, so the default implementation of this method does
300
+ # nothing.
301
+ def emit_import *symbols
302
+ # No need to emit anything.
303
+ end
304
+
298
305
  # Emits a label.
299
306
  def emit_label name
300
307
  emit "#{name}:\n"
@@ -308,11 +315,21 @@ module Voodoo
308
315
  # Declares that the given symbols are to be externally visible.
309
316
  # Requires subclasses to implement emit_export.
310
317
  def export *symbols
311
- if real_section_name(section) == ".data"
312
- @relocated_symbols.merge symbols
318
+ used_earlier = symbols_used_unrelocated symbols
319
+ # Exporting symbols after they have been used is not allowed.
320
+ error = nil
321
+ unless used_earlier.empty?
322
+ error = CodeGenerator::SymbolsExportedAfterUseError.new(used_earlier)
323
+ end
324
+ begin
325
+ if real_section_name(section) == ".data"
326
+ @relocated_symbols.merge symbols
327
+ end
328
+ @symbol_tracker.use *symbols
329
+ emit_export *symbols
330
+ ensure
331
+ raise error unless error == nil
313
332
  end
314
- @symbol_tracker.use *symbols
315
- emit_export *symbols
316
333
  end
317
334
 
318
335
  # Adds a function to the current section.
@@ -330,13 +347,24 @@ module Voodoo
330
347
  end
331
348
 
332
349
  # Declares that the given symbols are imported from an external object.
333
- # Requires subclasses to implement emit_import.
350
+ # This function calls emit_import to actually emit code for the import
351
+ # statements. The default implementation of emit_import does nothing,
352
+ # so targets where code is required for imports will want to override
353
+ # emit_import.
334
354
  def import *symbols
335
- if real_section_name(section) == ".data"
355
+ used_earlier = symbols_used_unrelocated symbols
356
+ # Importing symbols after they have been used is not allowed.
357
+ error = nil
358
+ unless used_earlier.empty?
359
+ error = CodeGenerator::SymbolsImportedAfterUseError.new(used_earlier)
360
+ end
361
+ begin
336
362
  @relocated_symbols.merge symbols
363
+ @symbol_tracker.define *symbols
364
+ emit_import *symbols
365
+ ensure
366
+ raise error unless error == nil
337
367
  end
338
- @symbol_tracker.define *symbols
339
- emit_import *symbols
340
368
  end
341
369
 
342
370
  # Executes a block of code using the given section as the current section.
@@ -722,5 +750,13 @@ module Voodoo
722
750
  end
723
751
  max
724
752
  end
753
+
754
+ # Given symbols, returns the set of symbols among those that
755
+ # have been used without relocation.
756
+ def symbols_used_unrelocated symbols
757
+ symbols_set = symbols.kind_of?(Set) ? symbols : Set.new(symbols)
758
+ new_symbols = symbols_set - @relocated_symbols
759
+ @symbol_tracker.used_symbols & new_symbols
760
+ end
725
761
  end
726
762
  end
@@ -136,7 +136,6 @@ module Voodoo
136
136
  @TEMPORARIES = [:'$8', :'$9', :'$10', :'$11',
137
137
  :'$12', :'$13', :'$14', :'$15']
138
138
  @function_end_label = nil
139
- @imports = {}
140
139
  @if_labels = []
141
140
  super params
142
141
  @output_file_suffix = '.s'
@@ -282,7 +281,7 @@ module Voodoo
282
281
  # Load function address
283
282
  if global? func
284
283
  @symbol_tracker.use func
285
- if @imports.has_key? func
284
+ if @relocated_symbols.include? func
286
285
  # Load address from global offset table
287
286
  emit "lw #{@FUNCTION}, %call16(#{func})(#{@GOT})\n"
288
287
  else
@@ -395,12 +394,6 @@ module Voodoo
395
394
  end
396
395
  end
397
396
 
398
- # Imports labels into the current section.
399
- def emit_import *symbols
400
- # Record imported labels in @imports
401
- symbols.each { |sym| @imports[sym] = sym }
402
- end
403
-
404
397
  # Emits a label type annotation.
405
398
  def emit_label_type name, type
406
399
  type_map = {
@@ -689,6 +682,7 @@ module Voodoo
689
682
  return register
690
683
  else
691
684
  # Assume global
685
+ @symbol_tracker.use x
692
686
  if @relocated_symbols.include? x
693
687
  emit "lw #{register}, %got(#{x})(#{@GOT})\n"
694
688
  else
@@ -920,7 +914,7 @@ module Voodoo
920
914
 
921
915
  # Load function address
922
916
  if global? func
923
- if @imports.has_key? func
917
+ if @relocated_symbols.include? func
924
918
  # Load address from global offset table
925
919
  emit "lw #{@FUNCTION}, %call16(#{func})(#{@GOT})\n"
926
920
  else
@@ -35,12 +35,11 @@ module Voodoo
35
35
  #
36
36
 
37
37
  # Export symbols from the current section
38
- def export *symbols
38
+ def emit_export *symbols
39
39
  case real_section_name(section)
40
40
  when ".text"
41
41
  symbols.each { |sym| emit "global #{sym}:function\n" }
42
42
  else
43
- @relocated_symbols.merge symbols
44
43
  symbols.each { |sym| emit "global #{sym}:data #{sym}.end-#{sym}\n" }
45
44
  end
46
45
  end
@@ -53,12 +52,8 @@ module Voodoo
53
52
  end
54
53
  end
55
54
 
56
- # Import labels into the current section
57
- def import *symbols
58
- @symbol_tracker.define *symbols
59
- if real_section_name(section) != ".text"
60
- @relocated_symbols.merge symbols
61
- end
55
+ # Emits code to declare symbols as imported from an external object.
56
+ def emit_import *symbols
62
57
  emit "extern #{symbols.join ', '}\n"
63
58
  end
64
59
 
@@ -22,7 +22,7 @@ module Voodoo
22
22
  class Parser
23
23
  NUMBER_STARTER = /\d|-/
24
24
  STRING_STARTER = '"'
25
- SYMBOL_STARTER = /[[:alpha:]]|\\/
25
+ SYMBOL_STARTER = /[[:alpha:]]|_|\\/
26
26
 
27
27
  # Creates a parser using the specified object as input.
28
28
  # The input object must support a method +getc+, which must
@@ -41,7 +41,7 @@ module Voodoo
41
41
  # This provides methods to get the name of the input being processed,
42
42
  # as well as the start_line, start_column, and text of the code
43
43
  # that triggered the error.
44
- class Error < StandardError
44
+ class Error < Voodoo::Error
45
45
  def initialize message, input_name, start_line, start_column, text
46
46
  super message
47
47
  @input_name = input_name
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: voodoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-21 00:00:00.000000000 Z
12
+ date: 2013-12-01 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'The Voodoo compiler is an implementation of the Voodoo programming
15
15
 
@@ -30,27 +30,28 @@ extensions: []
30
30
  extra_rdoc_files: []
31
31
  files:
32
32
  - bin/voodooc
33
- - lib/voodoo.rb
34
- - lib/voodoo/parser.rb
35
- - lib/voodoo/generators/mips_elf_generator.rb
36
- - lib/voodoo/generators/common_code_generator.rb
37
- - lib/voodoo/generators/nasm_elf_generator.rb
38
- - lib/voodoo/generators/amd64_nasm_generator.rb
39
- - lib/voodoo/generators/gas_elf_generator.rb
40
- - lib/voodoo/generators/i386_nasm_generator.rb
33
+ - lib/voodoo/symbol_tracker.rb
41
34
  - lib/voodoo/generators/arm_gas_generator.rb
42
- - lib/voodoo/generators/nasm_generator.rb
43
35
  - lib/voodoo/generators/mips_gas_generator.rb
36
+ - lib/voodoo/generators/common_code_generator.rb
37
+ - lib/voodoo/generators/mips_elf_generator.rb
44
38
  - lib/voodoo/generators/dummy_generator.rb
45
- - lib/voodoo/generators/arm_elf_generator.rb
46
39
  - lib/voodoo/generators/amd64_elf_generator.rb
40
+ - lib/voodoo/generators/arm_elf_generator.rb
47
41
  - lib/voodoo/generators/i386_elf_generator.rb
42
+ - lib/voodoo/generators/i386_nasm_generator.rb
43
+ - lib/voodoo/generators/amd64_nasm_generator.rb
44
+ - lib/voodoo/generators/nasm_generator.rb
48
45
  - lib/voodoo/generators/command_postprocessor.rb
46
+ - lib/voodoo/generators/gas_elf_generator.rb
47
+ - lib/voodoo/generators/nasm_elf_generator.rb
48
+ - lib/voodoo/parser.rb
49
+ - lib/voodoo/config.rb
50
+ - lib/voodoo/error.rb
51
+ - lib/voodoo/validator.rb
49
52
  - lib/voodoo/code_generator.rb
50
53
  - lib/voodoo/compiler.rb
51
- - lib/voodoo/validator.rb
52
- - lib/voodoo/config.rb
53
- - lib/voodoo/symbol_tracker.rb
54
+ - lib/voodoo.rb
54
55
  homepage: http://inglorion.net/software/voodoo/
55
56
  licenses: []
56
57
  post_install_message: