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.
- data/lib/voodoo.rb +1 -0
- data/lib/voodoo/code_generator.rb +27 -0
- data/lib/voodoo/compiler.rb +5 -1
- data/lib/voodoo/config.rb +2 -2
- data/lib/voodoo/error.rb +5 -0
- data/lib/voodoo/generators/amd64_nasm_generator.rb +1 -1
- data/lib/voodoo/generators/arm_gas_generator.rb +7 -15
- data/lib/voodoo/generators/common_code_generator.rb +44 -8
- data/lib/voodoo/generators/mips_gas_generator.rb +3 -9
- data/lib/voodoo/generators/nasm_generator.rb +3 -8
- data/lib/voodoo/parser.rb +2 -2
- metadata +16 -15
data/lib/voodoo.rb
CHANGED
@@ -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
|
|
data/lib/voodoo/compiler.rb
CHANGED
@@ -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 <
|
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
|
|
data/lib/voodoo/config.rb
CHANGED
@@ -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.
|
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
|
41
|
+
when /^arm/
|
42
42
|
:arm
|
43
43
|
when 'i386', 'i686'
|
44
44
|
:i386
|
data/lib/voodoo/error.rb
ADDED
@@ -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 @
|
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 @
|
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
|
-
|
312
|
-
|
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
|
-
#
|
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
|
-
|
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 @
|
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 @
|
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
|
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
|
-
#
|
57
|
-
def
|
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
|
|
data/lib/voodoo/parser.rb
CHANGED
@@ -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 <
|
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.
|
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-
|
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
|
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:
|