voodoo 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: