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 inputFlnm
= ARGV.shift
38 outputFlnm
= ARGV.shift
40 $stderr.puts
"offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}."
43 OFFSET_MAGIC_NUMBERS
.each
{
45 $output.puts
"unsigned(#{number}),"
49 inputHash
= "// offlineasm input hash: #{parseHash(inputFlnm)} #{selfHash}"
51 if FileTest
.exist
? outputFlnm
52 File
.open(outputFlnm
, "r") {
55 if firstLine
and firstLine
.chomp
== inputHash
56 $stderr.puts
"offlineasm: Nothing changed."
62 originalAST
= parse(inputFlnm
)
65 # Optimize the AST to make configuration extraction faster. This reduces the AST to a form
66 # that only contains the things that matter for our purposes: offsets, sizes, and if
71 def offsetsPruneTo(sequence
)
74 child
.offsetsPruneTo(sequence
)
79 result
= Sequence
.new(codeOrigin
, [])
80 offsetsPruneTo(result
)
86 def offsetsPruneTo(sequence
)
87 ifThenElse
= IfThenElse
.new(codeOrigin
, predicate
, thenCase
.offsetsPrune
)
88 ifThenElse
.elseCase
= elseCase
.offsetsPrune
89 sequence
.list
<< ifThenElse
94 def offsetsPruneTo(sequence
)
100 def offsetsPruneTo(sequence
)
101 sequence
.list
<< self
105 prunedAST
= originalAST
.offsetsPrune
107 File
.open(outputFlnm
, "w") {
112 emitCodeInAllConfigurations(prunedAST
) {
113 | settings
, ast
, backend
, index
|
114 offsetsList
= ast
.filter(StructOffset
).uniq
.sort
115 sizesList
= ast
.filter(Sizeof
).uniq
.sort
116 length +
= OFFSET_HEADER_MAGIC_NUMBERS
.size +
(OFFSET_MAGIC_NUMBERS
.size +
1) * (1 + offsetsList
.size + sizesList
.size
)
118 outp
.puts
"static const unsigned extractorTable[#{length}] = {"
119 emitCodeInAllConfigurations(prunedAST
) {
120 | settings
, ast
, backend
, index
|
121 OFFSET_HEADER_MAGIC_NUMBERS
.each
{
123 $output.puts
"unsigned(#{number}),"
126 offsetsList
= ast
.filter(StructOffset
).uniq
.sort
127 sizesList
= ast
.filter(Sizeof
).uniq
.sort
130 outp
.puts
"#{index},"
134 outp
.puts
"OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
139 outp
.puts
"sizeof(#{offset.struct}),"
145 $stderr.puts
"offlineasm: offset extractor #{outputFlnm} successfully generated."