A stack overflow in the parsing of a builtin (called by createExecutable) cause a...
[WebKit-https.git] / Source / JavaScriptCore / Scripts / builtins / builtins_generate_separate_header.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2014, 2015 Apple Inc. All rights reserved.
4 # Copyright (c) 2014 University of Washington. All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 # THE POSSIBILITY OF SUCH DAMAGE.
26
27
28 import logging
29 import re
30 import string
31 from string import Template
32
33 from builtins_generator import BuiltinsGenerator
34 from builtins_model import Frameworks
35 from builtins_templates import BuiltinsGeneratorTemplates as Templates
36
37 log = logging.getLogger('global')
38
39
40 class BuiltinsSeparateHeaderGenerator(BuiltinsGenerator):
41     def __init__(self, model, object):
42         BuiltinsGenerator.__init__(self, model)
43         self.object = object
44
45     def output_filename(self):
46         return "%sBuiltins.h" % BuiltinsGenerator.mangledNameForObject(self.object)
47
48     def macro_prefix(self):
49         return self.model().framework.setting('macro_prefix')
50
51     def generate_output(self):
52         args = {
53             'namespace': self.model().framework.setting('namespace'),
54             'macroPrefix': self.macro_prefix(),
55             'objectName': self.object.object_name,
56             'objectMacro': self.object.object_name.upper(),
57         }
58
59         conditional_guard = self.object.annotations.get('conditional')
60
61         sections = []
62         sections.append(self.generate_license())
63         sections.append(Template(Templates.DoNotEditWarning).substitute(args))
64         sections.append(Template(Templates.HeaderIncludeGuard).substitute(args))
65         if conditional_guard is not None:
66             sections.append("#if %s" % conditional_guard)
67         sections.append(self.generate_secondary_header_includes())
68         sections.append(self.generate_forward_declarations())
69         sections.append(Template(Templates.NamespaceTop).substitute(args))
70         sections.append(self.generate_section_for_object(self.object))
71         sections.append(self.generate_section_for_code_table_macro())
72         sections.append(self.generate_section_for_code_name_macro())
73         sections.append(Template(Templates.SeparateHeaderStaticMacros).substitute(args))
74         if self.model().framework is Frameworks.WebCore:
75             sections.append(Template(Templates.SeparateHeaderWrapperBoilerplate).substitute(args))
76             if self.object.annotations.get('internal'):
77                 sections.append(Template(Templates.SeparateHeaderInternalFunctionsBoilerplate).substitute(args))
78         sections.append(Template(Templates.NamespaceBottom).substitute(args))
79         if conditional_guard is not None:
80             sections.append("#endif // %s" % conditional_guard)
81
82         return "\n\n".join(sections)
83
84     def generate_forward_declarations(self):
85         return """namespace JSC {
86 class FunctionExecutable;
87 }"""
88
89     def generate_secondary_header_includes(self):
90         header_includes = [
91             (["WebCore"],
92                 ("JavaScriptCore", "bytecode/UnlinkedFunctionExecutable.h"),
93             ),
94
95             (["WebCore"],
96                 ("JavaScriptCore", "parser/ParserError.h"),
97             ),
98
99             (["WebCore"],
100                 ("JavaScriptCore", "builtins/BuiltinUtils.h"),
101             ),
102
103             (["WebCore"],
104                 ("JavaScriptCore", "runtime/Identifier.h"),
105             ),
106
107             (["WebCore"],
108                 ("JavaScriptCore", "runtime/JSFunction.h"),
109             ),
110         ]
111
112         return '\n'.join(self.generate_includes_from_entries(header_includes))
113
114     def generate_section_for_object(self, object):
115         lines = []
116         lines.append('/* %s */' % object.object_name)
117         lines.extend(self.generate_externs_for_object(object))
118         lines.append("")
119         lines.extend(self.generate_macros_for_object(object))
120         lines.append("")
121         lines.extend(self.generate_defines_for_object(object))
122         return '\n'.join(lines)
123
124     def generate_externs_for_object(self, object):
125         lines = []
126
127         for function in object.functions:
128             function_args = {
129                 'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code',
130             }
131
132             lines.append("""extern const char* s_%(codeName)s;
133 extern const int s_%(codeName)sLength;
134 extern const JSC::ConstructAbility s_%(codeName)sConstructAbility;""" % function_args)
135
136         return lines
137
138     def generate_macros_for_object(self, object):
139         args = {
140             'macroPrefix': self.macro_prefix(),
141             'objectMacro': object.object_name.replace('.', '_').upper(),
142         }
143
144         lines = []
145         lines.append("#define %(macroPrefix)s_FOREACH_%(objectMacro)s_BUILTIN_DATA(macro) \\" % args)
146         for function in object.functions:
147             function_args = {
148                 'funcName': function.function_name,
149                 'mangledName': BuiltinsGenerator.mangledNameForFunction(function),
150                 'paramCount': len(function.parameters),
151             }
152
153             lines.append("    macro(%(funcName)s, %(mangledName)s, %(paramCount)d) \\" % function_args)
154         return lines
155
156     def generate_defines_for_object(self, object):
157         lines = []
158         for function in object.functions:
159             args = {
160                 'macroPrefix': self.macro_prefix(),
161                 'objectMacro': object.object_name.replace('.', '_').upper(),
162                 'functionMacro': function.function_name.upper(),
163             }
164             lines.append("#define %(macroPrefix)s_BUILTIN_%(objectMacro)s_%(functionMacro)s 1" % args)
165
166         return lines
167
168     def generate_section_for_code_table_macro(self):
169         args = {
170             'macroPrefix': self.model().framework.setting('macro_prefix'),
171             'objectMacro': self.object.object_name.upper(),
172         }
173
174         lines = []
175         lines.append("#define %(macroPrefix)s_FOREACH_%(objectMacro)s_BUILTIN_CODE(macro) \\" % args)
176         for function in self.object.functions:
177             function_args = {
178                 'funcName': function.function_name,
179                 'overriddenName': function.overridden_name,
180                 'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code',
181             }
182
183             lines.append("    macro(%(codeName)s, %(funcName)s, %(overriddenName)s, s_%(codeName)sLength) \\" % function_args)
184         return '\n'.join(lines)
185
186     def generate_section_for_code_name_macro(self):
187         args = {
188             'macroPrefix': self.macro_prefix(),
189             'objectMacro': self.object.object_name.upper(),
190         }
191
192         lines = []
193         lines.append("#define %(macroPrefix)s_FOREACH_%(objectMacro)s_BUILTIN_FUNCTION_NAME(macro) \\" % args)
194         unique_names = list(set([function.function_name for function in self.object.functions]))
195         unique_names.sort()
196         for function_name in unique_names:
197             function_args = {
198                 'funcName': function_name,
199             }
200
201             lines.append("    macro(%(funcName)s) \\" % function_args)
202         return '\n'.join(lines)