3 # Copyright (C) 2011 Apple Inc. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
8 # 1. Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 # notice, this list of conditions and the following disclaimer in the
12 # documentation and/or other materials provided with the distribution.
14 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 # THE POSSIBILITY OF SUCH DAMAGE.
26 $
: << File
.dirname(__FILE__
)
37 IncludeFile
.processIncludeOptions()
39 inputFlnm
= ARGV.shift
40 outputFlnm
= ARGV.shift
42 $stderr.puts
"offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}."
45 OFFSET_MAGIC_NUMBERS
.each
{
47 $output.puts
"unsigned(#{number}),"
51 inputHash
= "// offlineasm input hash: #{parseHash(inputFlnm)} #{selfHash}"
53 if FileTest
.exist
? outputFlnm
54 File
.open(outputFlnm
, "r") {
57 if firstLine
and firstLine
.chomp
== inputHash
58 $stderr.puts
"offlineasm: Nothing changed."
64 originalAST
= parse(inputFlnm
)
67 # Optimize the AST to make configuration extraction faster. This reduces the AST to a form
68 # that only contains the things that matter for our purposes: offsets, sizes, and if
73 def offsetsPruneTo(sequence
)
76 child
.offsetsPruneTo(sequence
)
81 result
= Sequence
.new(codeOrigin
, [])
82 offsetsPruneTo(result
)
88 def offsetsPruneTo(sequence
)
89 ifThenElse
= IfThenElse
.new(codeOrigin
, predicate
, thenCase
.offsetsPrune
)
90 ifThenElse
.elseCase
= elseCase
.offsetsPrune
91 sequence
.list
<< ifThenElse
96 def offsetsPruneTo(sequence
)
102 def offsetsPruneTo(sequence
)
103 sequence
.list
<< self
107 prunedAST
= originalAST
.offsetsPrune
109 File
.open(outputFlnm
, "w") {
114 emitCodeInAllConfigurations(prunedAST
) {
115 | settings
, ast
, backend
, index
|
116 offsetsList
= ast
.filter(StructOffset
).uniq
.sort
117 sizesList
= ast
.filter(Sizeof
).uniq
.sort
118 length +
= OFFSET_HEADER_MAGIC_NUMBERS
.size +
(OFFSET_MAGIC_NUMBERS
.size +
1) * (1 + offsetsList
.size + sizesList
.size
)
120 outp
.puts
"static const unsigned extractorTable[#{length}] = {"
121 emitCodeInAllConfigurations(prunedAST
) {
122 | settings
, ast
, backend
, index
|
123 OFFSET_HEADER_MAGIC_NUMBERS
.each
{
125 $output.puts
"unsigned(#{number}),"
128 offsetsList
= ast
.filter(StructOffset
).uniq
.sort
129 sizesList
= ast
.filter(Sizeof
).uniq
.sort
132 outp
.puts
"#{index},"
136 outp
.puts
"OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
141 outp
.puts
"sizeof(#{offset.struct}),"
147 $stderr.puts
"offlineasm: offset extractor #{outputFlnm} successfully generated."