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__
)
36 inputFlnm
= ARGV.shift
37 outputFlnm
= ARGV.shift
39 $stderr.puts
"offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}."
42 OFFSET_MAGIC_NUMBERS
.each
{
44 $output.puts
"#{number},"
48 inputHash
= "// offlineasm input hash: #{parseHash(inputFlnm)} #{selfHash}"
50 if FileTest
.exist
? outputFlnm
51 File
.open(outputFlnm
, "r") {
54 if firstLine
and firstLine
.chomp
== inputHash
55 $stderr.puts
"offlineasm: Nothing changed."
61 originalAST
= parse(inputFlnm
)
64 # Optimize the AST to make configuration extraction faster. This reduces the AST to a form
65 # that only contains the things that matter for our purposes: offsets, sizes, and if
70 def offsetsPruneTo(sequence
)
73 child
.offsetsPruneTo(sequence
)
78 result
= Sequence
.new(codeOrigin
, [])
79 offsetsPruneTo(result
)
85 def offsetsPruneTo(sequence
)
86 ifThenElse
= IfThenElse
.new(codeOrigin
, predicate
, thenCase
.offsetsPrune
)
87 ifThenElse
.elseCase
= elseCase
.offsetsPrune
88 sequence
.list
<< ifThenElse
93 def offsetsPruneTo(sequence
)
99 def offsetsPruneTo(sequence
)
100 sequence
.list
<< self
104 prunedAST
= originalAST
.offsetsPrune
106 File
.open(outputFlnm
, "w") {
111 emitCodeInAllConfigurations(prunedAST
) {
112 | settings
, ast
, backend
, index
|
113 offsetsList
= ast
.filter(StructOffset
).uniq
.sort
114 sizesList
= ast
.filter(Sizeof
).uniq
.sort
115 length +
= OFFSET_HEADER_MAGIC_NUMBERS
.size +
(OFFSET_MAGIC_NUMBERS
.size +
1) * (1 + offsetsList
.size + sizesList
.size
)
117 outp
.puts
"static const unsigned extractorTable[#{length}] = {"
118 emitCodeInAllConfigurations(prunedAST
) {
119 | settings
, ast
, backend
, index
|
120 OFFSET_HEADER_MAGIC_NUMBERS
.each
{
122 $output.puts
"#{number},"
125 offsetsList
= ast
.filter(StructOffset
).uniq
.sort
126 sizesList
= ast
.filter(Sizeof
).uniq
.sort
129 outp
.puts
"#{index},"
133 outp
.puts
"OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
138 outp
.puts
"sizeof(#{offset.struct}),"
144 $stderr.puts
"offlineasm: offset extractor #{outputFlnm} successfully generated."