diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/Scripts/builtins | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz |
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f
Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/Scripts/builtins')
9 files changed, 1221 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/Scripts/builtins/__init__.py b/Source/JavaScriptCore/Scripts/builtins/__init__.py new file mode 100644 index 000000000..fdfcba981 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/__init__.py @@ -0,0 +1,3 @@ +# Required for Python to search this directory for module files + +from builtins import * diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins.py b/Source/JavaScriptCore/Scripts/builtins/builtins.py new file mode 100644 index 000000000..9349eeef6 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins.py @@ -0,0 +1,11 @@ +# This file is used to simulate the builtins/ directory when generate-js-builtins.py +# is run from JavaScriptCore framework's private headers directory, which is flattened. + +from builtins_model import * +from builtins_templates import * + +from builtins_generator import * +from builtins_generate_combined_header import * +from builtins_generate_combined_implementation import * +from builtins_generate_separate_header import * +from builtins_generate_separate_implementation import * diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_header.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_header.py new file mode 100644 index 000000000..891bd3cb4 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_header.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014, 2015 Apple Inc. All rights reserved. +# Copyright (c) 2014 University of Washington. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + + +import logging +import re +import string +from string import Template + +from builtins_generator import BuiltinsGenerator +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsCombinedHeaderGenerator(BuiltinsGenerator): + def __init__(self, model): + BuiltinsGenerator.__init__(self, model) + + def output_filename(self): + return "%sBuiltins.h" % self.model().framework.setting('namespace') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + 'headerGuard': self.output_filename().replace('.', '_'), + 'macroPrefix': self.model().framework.setting('macro_prefix'), + } + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + sections.append(Template(Templates.HeaderIncludeGuardTop).substitute(args)) + sections.append(self.generate_forward_declarations()) + sections.append(Template(Templates.NamespaceTop).substitute(args)) + for object in self.model().objects: + sections.append(self.generate_section_for_object(object)) + sections.append(self.generate_section_for_code_table_macro()) + sections.append(self.generate_section_for_code_name_macro()) + sections.append(Template(Templates.CombinedHeaderStaticMacros).substitute(args)) + sections.append(Template(Templates.NamespaceBottom).substitute(args)) + sections.append(Template(Templates.HeaderIncludeGuardBottom).substitute(args)) + + return "\n\n".join(sections) + + def generate_forward_declarations(self): + return """namespace JSC { +class FunctionExecutable; +class VM; + +enum class ConstructAbility : unsigned; +}""" + + def generate_section_for_object(self, object): + lines = [] + lines.append('/* %s */' % object.object_name) + lines.extend(self.generate_externs_for_object(object)) + lines.append("") + lines.extend(self.generate_macros_for_object(object)) + return '\n'.join(lines) + + def generate_externs_for_object(self, object): + lines = [] + + for function in object.functions: + function_args = { + 'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code', + } + + lines.append("""extern const char* s_%(codeName)s; +extern const int s_%(codeName)sLength; +extern const JSC::ConstructAbility s_%(codeName)sConstructAbility;""" % function_args) + + return lines + + def generate_macros_for_object(self, object): + args = { + 'macroPrefix': self.model().framework.setting('macro_prefix'), + 'objectMacro': object.object_name.replace('.', '').upper(), + } + + lines = [] + lines.append("#define %(macroPrefix)s_FOREACH_%(objectMacro)s_BUILTIN_DATA(macro) \\" % args) + for function in object.functions: + function_args = { + 'funcName': function.function_name, + 'mangledName': BuiltinsGenerator.mangledNameForFunction(function), + 'paramCount': len(function.parameters), + } + + lines.append(" macro(%(funcName)s, %(mangledName)s, %(paramCount)d) \\" % function_args) + return lines + + def generate_section_for_code_table_macro(self): + args = { + 'macroPrefix': self.model().framework.setting('macro_prefix'), + } + + lines = [] + lines.append("#define %(macroPrefix)s_FOREACH_BUILTIN_CODE(macro) \\" % args) + for function in self.model().all_functions(): + function_args = { + 'funcName': function.function_name, + 'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code', + } + + lines.append(" macro(%(codeName)s, %(funcName)s, s_%(codeName)sLength) \\" % function_args) + return '\n'.join(lines) + + def generate_section_for_code_name_macro(self): + args = { + 'macroPrefix': self.model().framework.setting('macro_prefix'), + } + + internal_function_names = [function.function_name for function in self.model().all_internal_functions()] + if len(internal_function_names) != len(set(internal_function_names)): + log.error("There are several internal functions with the same name. Private identifiers may clash.") + + lines = [] + lines.append("#define %(macroPrefix)s_FOREACH_BUILTIN_FUNCTION_NAME(macro) \\" % args) + unique_names = list(set([function.function_name for function in self.model().all_functions()])) + unique_names.sort() + for function_name in unique_names: + function_args = { + 'funcName': function_name, + } + + lines.append(" macro(%(funcName)s) \\" % function_args) + return '\n'.join(lines) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_implementation.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_implementation.py new file mode 100644 index 000000000..094434b64 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_implementation.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014, 2015 Apple Inc. All rights reserved. +# Copyright (c) 2014 University of Washington. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + + +import logging +import re +import string +from string import Template + +from builtins_generator import BuiltinsGenerator +from builtins_model import Framework, Frameworks +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsCombinedImplementationGenerator(BuiltinsGenerator): + def __init__(self, model): + BuiltinsGenerator.__init__(self, model) + + def output_filename(self): + return "%sBuiltins.cpp" % self.model().framework.setting('namespace') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + 'macroPrefix': self.model().framework.setting('macro_prefix'), + } + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + sections.append(self.generate_primary_header_includes()) + sections.append(self.generate_secondary_header_includes()) + sections.append(Template(Templates.NamespaceTop).substitute(args)) + for function in self.model().all_functions(): + sections.append(self.generate_embedded_code_string_section_for_function(function)) + if self.model().framework is Frameworks.JavaScriptCore: + sections.append(Template(Templates.CombinedJSCImplementationStaticMacros).substitute(args)) + elif self.model().framework is Frameworks.WebCore: + sections.append(Template(Templates.CombinedWebCoreImplementationStaticMacros).substitute(args)) + sections.append(Template(Templates.NamespaceBottom).substitute(args)) + + return "\n\n".join(sections) + + def generate_secondary_header_includes(self): + header_includes = [ + (["JavaScriptCore"], + ("JavaScriptCore", "builtins/BuiltinExecutables.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/Executable.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/JSCellInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/StructureInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/JSCJSValueInlines.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/VM.h"), + ), + ] + + return '\n'.join(self.generate_includes_from_entries(header_includes)) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_header.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_header.py new file mode 100644 index 000000000..b72a94bfe --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_header.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014, 2015 Apple Inc. All rights reserved. +# Copyright (c) 2014 University of Washington. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + + +import logging +import re +import string +from string import Template + +from builtins_generator import BuiltinsGenerator +from builtins_model import Frameworks +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsSeparateHeaderGenerator(BuiltinsGenerator): + def __init__(self, model, object): + BuiltinsGenerator.__init__(self, model) + self.object = object + + def output_filename(self): + return "%sBuiltins.h" % BuiltinsGenerator.mangledNameForObject(self.object) + + def macro_prefix(self): + return self.model().framework.setting('macro_prefix') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + 'headerGuard': self.output_filename().replace('.', '_'), + 'macroPrefix': self.macro_prefix(), + 'objectName': self.object.object_name, + 'objectMacro': self.object.object_name.upper(), + } + + conditional_guard = self.object.annotations.get('conditional') + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + sections.append(Template(Templates.HeaderIncludeGuardTop).substitute(args)) + if conditional_guard is not None: + sections.append("#if %s" % conditional_guard) + sections.append(self.generate_secondary_header_includes()) + sections.append(self.generate_forward_declarations()) + sections.append(Template(Templates.NamespaceTop).substitute(args)) + sections.append(self.generate_section_for_object(self.object)) + sections.append(self.generate_section_for_code_table_macro()) + sections.append(self.generate_section_for_code_name_macro()) + sections.append(Template(Templates.SeparateHeaderStaticMacros).substitute(args)) + if self.model().framework is Frameworks.WebCore: + sections.append(Template(Templates.SeparateHeaderWrapperBoilerplate).substitute(args)) + if self.object.annotations.get('internal'): + sections.append(Template(Templates.SeparateHeaderInternalFunctionsBoilerplate).substitute(args)) + sections.append(Template(Templates.NamespaceBottom).substitute(args)) + if conditional_guard is not None: + sections.append("#endif // %s" % conditional_guard) + sections.append(Template(Templates.HeaderIncludeGuardBottom).substitute(args)) + + return "\n\n".join(sections) + + def generate_forward_declarations(self): + return """namespace JSC { +class FunctionExecutable; +}""" + + def generate_secondary_header_includes(self): + header_includes = [ + (["WebCore"], + ("JavaScriptCore", "bytecode/UnlinkedFunctionExecutable.h"), + ), + + (["WebCore"], + ("JavaScriptCore", "builtins/BuiltinUtils.h"), + ), + + (["WebCore"], + ("JavaScriptCore", "runtime/Identifier.h"), + ), + + (["WebCore"], + ("JavaScriptCore", "runtime/JSFunction.h"), + ), + ] + + return '\n'.join(self.generate_includes_from_entries(header_includes)) + + def generate_section_for_object(self, object): + lines = [] + lines.append('/* %s */' % object.object_name) + lines.extend(self.generate_externs_for_object(object)) + lines.append("") + lines.extend(self.generate_macros_for_object(object)) + lines.append("") + lines.extend(self.generate_defines_for_object(object)) + return '\n'.join(lines) + + def generate_externs_for_object(self, object): + lines = [] + + for function in object.functions: + function_args = { + 'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code', + } + + lines.append("""extern const char* s_%(codeName)s; +extern const int s_%(codeName)sLength; +extern const JSC::ConstructAbility s_%(codeName)sConstructAbility;""" % function_args) + + return lines + + def generate_macros_for_object(self, object): + args = { + 'macroPrefix': self.macro_prefix(), + 'objectMacro': object.object_name.replace('.', '_').upper(), + } + + lines = [] + lines.append("#define %(macroPrefix)s_FOREACH_%(objectMacro)s_BUILTIN_DATA(macro) \\" % args) + for function in object.functions: + function_args = { + 'funcName': function.function_name, + 'mangledName': BuiltinsGenerator.mangledNameForFunction(function), + 'paramCount': len(function.parameters), + } + + lines.append(" macro(%(funcName)s, %(mangledName)s, %(paramCount)d) \\" % function_args) + return lines + + def generate_defines_for_object(self, object): + lines = [] + for function in object.functions: + args = { + 'macroPrefix': self.macro_prefix(), + 'objectMacro': object.object_name.replace('.', '_').upper(), + 'functionMacro': function.function_name.upper(), + } + lines.append("#define %(macroPrefix)s_BUILTIN_%(objectMacro)s_%(functionMacro)s 1" % args) + + return lines + + def generate_section_for_code_table_macro(self): + args = { + 'macroPrefix': self.model().framework.setting('macro_prefix'), + 'objectMacro': self.object.object_name.upper(), + } + + lines = [] + lines.append("#define %(macroPrefix)s_FOREACH_%(objectMacro)s_BUILTIN_CODE(macro) \\" % args) + for function in self.object.functions: + function_args = { + 'funcName': function.function_name, + 'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code', + } + + lines.append(" macro(%(codeName)s, %(funcName)s, s_%(codeName)sLength) \\" % function_args) + return '\n'.join(lines) + + def generate_section_for_code_name_macro(self): + args = { + 'macroPrefix': self.macro_prefix(), + 'objectMacro': self.object.object_name.upper(), + } + + lines = [] + lines.append("#define %(macroPrefix)s_FOREACH_%(objectMacro)s_BUILTIN_FUNCTION_NAME(macro) \\" % args) + unique_names = list(set([function.function_name for function in self.object.functions])) + unique_names.sort() + for function_name in unique_names: + function_args = { + 'funcName': function_name, + } + + lines.append(" macro(%(funcName)s) \\" % function_args) + return '\n'.join(lines) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_implementation.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_implementation.py new file mode 100644 index 000000000..0443975da --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_implementation.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014, 2015 Apple Inc. All rights reserved. +# Copyright (c) 2014 University of Washington. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + + +import logging +import re +import string +from string import Template + +from builtins_generator import BuiltinsGenerator, WK_lcfirst +from builtins_model import Framework, Frameworks +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsSeparateImplementationGenerator(BuiltinsGenerator): + def __init__(self, model, object): + BuiltinsGenerator.__init__(self, model) + self.object = object + + def output_filename(self): + return "%sBuiltins.cpp" % BuiltinsGenerator.mangledNameForObject(self.object) + + def macro_prefix(self): + return self.model().framework.setting('macro_prefix') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + 'macroPrefix': self.macro_prefix(), + 'objectMacro': self.object.object_name.upper(), + 'objectNameLC': WK_lcfirst(self.object.object_name), + } + + conditional_guard = self.object.annotations.get('conditional') + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + sections.append(self.generate_primary_header_includes()) + if conditional_guard is not None: + sections.append("#if %s" % conditional_guard) + sections.append(self.generate_secondary_header_includes()) + sections.append(Template(Templates.NamespaceTop).substitute(args)) + for function in self.object.functions: + sections.append(self.generate_embedded_code_string_section_for_function(function)) + if self.model().framework is Frameworks.JavaScriptCore: + sections.append(Template(Templates.SeparateJSCImplementationStaticMacros).substitute(args)) + elif self.model().framework is Frameworks.WebCore: + sections.append(Template(Templates.SeparateWebCoreImplementationStaticMacros).substitute(args)) + sections.append(Template(Templates.NamespaceBottom).substitute(args)) + if conditional_guard is not None: + sections.append("#endif // %s\n" % conditional_guard) + + return "\n\n".join(sections) + + def generate_secondary_header_includes(self): + header_includes = [ + (["JavaScriptCore"], + ("JavaScriptCore", "builtins/BuiltinExecutables.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/Executable.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/JSCellInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/StructureInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/JSCJSValueInlines.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/VM.h"), + ), + (["WebCore"], + ("WebCore", "bindings/js/WebCoreJSClientData.h"), + ), + ] + + return '\n'.join(self.generate_includes_from_entries(header_includes)) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generator.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generator.py new file mode 100644 index 000000000..21ac4c1d9 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generator.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014, 2015 Apple Inc. All rights reserved. +# Copyright (c) 2014 University of Washington. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +import logging +import os.path +import re +from string import Template +import json + +from builtins_model import BuiltinFunction, BuiltinObject +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + +# These match WK_lcfirst and WK_ucfirst defined in CodeGenerator.pm. +def WK_lcfirst(str): + str = str[:1].lower() + str[1:] + str = str.replace('hTML', 'html') + str = str.replace('uRL', 'url') + str = str.replace('jS', 'js') + str = str.replace('xML', 'xml') + str = str.replace('xSLT', 'xslt') + str = str.replace('cSS', 'css') + str = str.replace('rTC', 'rtc') + return str + +def WK_ucfirst(str): + str = str[:1].upper() + str[1:] + str = str.replace('Xml', 'XML') + str = str.replace('Svg', 'SVG') + return str + +class BuiltinsGenerator: + def __init__(self, model): + self._model = model + + def model(self): + return self._model + + # These methods are overridden by subclasses. + + def generate_output(self): + pass + + def output_filename(self): + pass + + + # Shared code generation methods. + def generate_license(self): + raw_license = Template(Templates.LicenseText).substitute(None) + copyrights = self._model.copyrights() + copyrights.sort() + + license_block = [] + license_block.append("/*") + for copyright in copyrights: + license_block.append(" * Copyright (c) %s" % copyright) + if len(copyrights) > 0: + license_block.append(" * ") + + for line in raw_license.split('\n'): + license_block.append(" * " + line) + + license_block.append(" */") + + return '\n'.join(license_block) + + def generate_includes_from_entries(self, entries): + includes = set() + for entry in entries: + (allowed_framework_names, data) = entry + (framework_name, header_path) = data + + if self.model().framework.name not in allowed_framework_names: + continue + if self.model().framework.name != framework_name: + includes.add("#include <%s>" % header_path) + else: + includes.add("#include \"%s\"" % os.path.basename(header_path)) + + return sorted(list(includes)) + + def generate_primary_header_includes(self): + name, _ = os.path.splitext(self.output_filename()) + return '\n'.join([ + "#include \"config.h\"", + "#include \"%s.h\"" % name, + ]) + + def generate_embedded_code_string_section_for_function(self, function): + text = function.function_source + # Wrap it in parens to avoid adding to global scope. + text = "(function " + text[text.index("("):] + ")" + embeddedSourceLength = len(text) + 1 # For extra \n. + # Lazy way to escape quotes, I think? + textLines = json.dumps(text)[1:-1].split("\\n") + # This looks scary because we need the JS source itself to have newlines. + embeddedSource = '\n'.join([' "%s\\n" \\' % line for line in textLines]) + + constructAbility = "CannotConstruct" + if function.is_constructor: + constructAbility = "CanConstruct" + + args = { + 'codeName': BuiltinsGenerator.mangledNameForFunction(function) + 'Code', + 'embeddedSource': embeddedSource, + 'embeddedSourceLength': embeddedSourceLength, + 'canConstruct': constructAbility + } + + lines = [] + lines.append("const JSC::ConstructAbility s_%(codeName)sConstructAbility = JSC::ConstructAbility::%(canConstruct)s;" % args); + lines.append("const int s_%(codeName)sLength = %(embeddedSourceLength)d;" % args); + lines.append("const char* s_%(codeName)s =\n%(embeddedSource)s\n;" % args); + return '\n'.join(lines) + + # Helper methods. + + @staticmethod + def mangledNameForObject(object): + if not isinstance(object, BuiltinObject): + raise Exception("Invalid argument passed to mangledNameForObject()") + + def toCamel(match): + str = match.group(0) + return str[1].upper() + return re.sub(r'\.[a-z]', toCamel, object.object_name, flags=re.IGNORECASE) + + + @staticmethod + def mangledNameForFunction(function): + if not isinstance(function, BuiltinFunction): + raise Exception("Invalid argument passed to mangledNameForFunction()") + + function_name = WK_ucfirst(function.function_name) + + def toCamel(match): + str = match.group(0) + return str[1].upper() + function_name = re.sub(r'\.[a-z]', toCamel, function_name, flags=re.IGNORECASE) + if function.is_constructor: + function_name = function_name + "Constructor" + + object_name = BuiltinsGenerator.mangledNameForObject(function.object) + return WK_lcfirst(object_name + function_name) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_model.py b/Source/JavaScriptCore/Scripts/builtins/builtins_model.py new file mode 100755 index 000000000..cdd5f9003 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_model.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python +# +# Copyright (c) 2015 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +import logging +import re +import os + +log = logging.getLogger('global') + +_FRAMEWORK_CONFIG_MAP = { + "JavaScriptCore": { + "macro_prefix": "JSC", + "namespace": "JSC", + }, + "WebCore": { + "macro_prefix": "WEBCORE", + "namespace": "WebCore", + }, +} + +functionHeadRegExp = re.compile(r"(?:function|constructor)\s+\w+\s*\(.*?\)", re.MULTILINE | re.S) +functionNameRegExp = re.compile(r"(?:function|constructor)\s+(\w+)\s*\(", re.MULTILINE | re.S) +functionIsConstructorRegExp = re.compile(r"^constructor", re.MULTILINE | re.S) +functionParameterFinder = re.compile(r"^(?:function|constructor)\s+(?:\w+)\s*\(((?:\s*\w+)?\s*(?:\s*,\s*\w+)*)?\s*\)", re.MULTILINE | re.S) + +multilineCommentRegExp = re.compile(r"\/\*.*?\*\/", re.MULTILINE | re.S) +singleLineCommentRegExp = re.compile(r"\/\/.*?\n", re.MULTILINE | re.S) +keyValueAnnotationCommentRegExp = re.compile(r"^\/\/ @(\w+)=([^=]+?)\n", re.MULTILINE | re.S) +flagAnnotationCommentRegExp = re.compile(r"^\/\/ @(\w+)[^=]*?\n", re.MULTILINE | re.S) +lineWithOnlySingleLineCommentRegExp = re.compile(r"^\s*\/\/\n", re.MULTILINE | re.S) +lineWithTrailingSingleLineCommentRegExp = re.compile(r"\s*\/\/\n", re.MULTILINE | re.S) +multipleEmptyLinesRegExp = re.compile(r"\n{2,}", re.MULTILINE | re.S) + +class ParseException(Exception): + pass + + +class Framework: + def __init__(self, name): + self._settings = _FRAMEWORK_CONFIG_MAP[name] + self.name = name + + def setting(self, key, default=''): + return self._settings.get(key, default) + + @staticmethod + def fromString(frameworkString): + if frameworkString == "JavaScriptCore": + return Frameworks.JavaScriptCore + + if frameworkString == "WebCore": + return Frameworks.WebCore + + raise ParseException("Unknown framework: %s" % frameworkString) + + +class Frameworks: + JavaScriptCore = Framework("JavaScriptCore") + WebCore = Framework("WebCore") + + +class BuiltinObject: + def __init__(self, object_name, annotations, functions): + self.object_name = object_name + self.annotations = annotations + self.functions = functions + self.collection = None # Set by the owning BuiltinsCollection + + for function in self.functions: + function.object = self + + +class BuiltinFunction: + def __init__(self, function_name, function_source, is_constructor, parameters): + self.function_name = function_name + self.function_source = function_source + self.is_constructor = is_constructor + self.parameters = parameters + self.object = None # Set by the owning BuiltinObject + + @staticmethod + def fromString(function_string): + function_source = multilineCommentRegExp.sub("", function_string) + if os.getenv("CONFIGURATION", "Debug").startswith("Debug"): + function_source = lineWithOnlySingleLineCommentRegExp.sub("", function_source) + function_source = lineWithTrailingSingleLineCommentRegExp.sub("\n", function_source) + function_source = multipleEmptyLinesRegExp.sub("\n", function_source) + + function_name = functionNameRegExp.findall(function_source)[0] + is_constructor = functionIsConstructorRegExp.match(function_source) != None + parameters = [s.strip() for s in functionParameterFinder.findall(function_source)[0].split(',')] + if len(parameters[0]) == 0: + parameters = [] + + return BuiltinFunction(function_name, function_source, is_constructor, parameters) + + def __str__(self): + interface = "%s(%s)" % (self.function_name, ', '.join(self.parameters)) + if self.is_constructor: + interface = interface + " [Constructor]" + + return interface + + +class BuiltinsCollection: + def __init__(self, framework_name): + self._copyright_lines = set() + self.objects = [] + self.framework = Framework.fromString(framework_name) + log.debug("Created new Builtins collection.") + + def parse_builtins_file(self, filename, text): + log.debug("Parsing builtins file: %s" % filename) + + parsed_copyrights = set(self._parse_copyright_lines(text)) + self._copyright_lines = self._copyright_lines.union(parsed_copyrights) + + log.debug("Found copyright lines:") + for line in self._copyright_lines: + log.debug(line) + log.debug("") + + object_annotations = self._parse_annotations(text) + + object_name, ext = os.path.splitext(os.path.basename(filename)) + log.debug("Parsing object: %s" % object_name) + + parsed_functions = self._parse_functions(text) + for function in parsed_functions: + function.object = object_name + + log.debug("Parsed functions:") + for func in parsed_functions: + log.debug(func) + log.debug("") + + new_object = BuiltinObject(object_name, object_annotations, parsed_functions) + new_object.collection = self + self.objects.append(new_object) + + def copyrights(self): + owner_to_years = dict() + copyrightYearRegExp = re.compile(r"(\d{4})[, ]{0,2}") + ownerStartRegExp = re.compile(r"[^\d, ]") + + # Returns deduplicated copyrights keyed on the owner. + for line in self._copyright_lines: + years = set(copyrightYearRegExp.findall(line)) + ownerIndex = ownerStartRegExp.search(line).start() + owner = line[ownerIndex:] + log.debug("Found years: %s and owner: %s" % (years, owner)) + if owner not in owner_to_years: + owner_to_years[owner] = set() + + owner_to_years[owner] = owner_to_years[owner].union(years) + + result = [] + + for owner, years in owner_to_years.items(): + sorted_years = list(years) + sorted_years.sort() + result.append("%s %s" % (', '.join(sorted_years), owner)) + + return result + + def all_functions(self): + result = [] + for object in self.objects: + result.extend(object.functions) + + result.sort() + return result + + def all_internal_functions(self): + result = [] + for object in [o for o in self.objects if 'internal' in o.annotations]: + result.extend(object.functions) + + result.sort() + return result + + # Private methods. + + def _parse_copyright_lines(self, text): + licenseBlock = multilineCommentRegExp.findall(text)[0] + licenseBlock = licenseBlock[:licenseBlock.index("Redistribution")] + + copyrightLines = [] + for line in licenseBlock.split("\n"): + line = line.replace("/*", "") + line = line.replace("*/", "") + line = line.replace("*", "") + line = line.replace("Copyright", "") + line = line.replace("copyright", "") + line = line.replace("(C)", "") + line = line.replace("(c)", "") + line = line.strip() + + if len(line) == 0: + continue + + copyrightLines.append(line) + + return copyrightLines + + def _parse_annotations(self, text): + annotations = {} + + for match in keyValueAnnotationCommentRegExp.finditer(text): + (key, value) = match.group(1, 2) + log.debug("Found annotation: '%s' => '%s'" % (key, value)) + if key in annotations: + raise ParseException("Duplicate annotation found: %s" % key) + + annotations[key] = value + + for match in flagAnnotationCommentRegExp.finditer(text): + key = match.group(1) + log.debug("Found annotation: '%s' => 'TRUE'" % key) + if key in annotations: + raise ParseException("Duplicate annotation found: %s" % key) + + annotations[key] = True + + return annotations + + def _parse_functions(self, text): + text = multilineCommentRegExp.sub("/**/", singleLineCommentRegExp.sub("//\n", text)) + + matches = [func for func in functionHeadRegExp.finditer(text)] + functionBounds = [] + start = 0 + end = 0 + for match in matches: + start = match.start() + if start < end: + continue + end = match.end() + while text[end] != '{': + end = end + 1 + depth = 1 + end = end + 1 + while depth > 0: + if text[end] == '{': + depth = depth + 1 + elif text[end] == '}': + depth = depth - 1 + end = end + 1 + functionBounds.append((start, end)) + + functionStrings = [text[start:end].strip() for (start, end) in functionBounds] + return map(BuiltinFunction.fromString, functionStrings) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_templates.py b/Source/JavaScriptCore/Scripts/builtins/builtins_templates.py new file mode 100644 index 000000000..67cdd5df7 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_templates.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014, 2015 Apple Inc. All rights reserved. +# Copyright (C) 2015 Canon Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. + +# Builtins generator templates, which can be filled with string.Template. + + +class BuiltinsGeneratorTemplates: + + LicenseText = ( + """Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. +""") + + DoNotEditWarning = ( + """// DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for +// builtins by the script: Source/JavaScriptCore/Scripts/generate-js-builtins.py""") + + HeaderIncludeGuardTop = ( + """#ifndef ${headerGuard} +#define ${headerGuard}""") + + HeaderIncludeGuardBottom = ( + """#endif // ${headerGuard} +""") + + NamespaceTop = ( + """namespace ${namespace} {""") + + NamespaceBottom = ( + """} // namespace ${namespace}""") + + CombinedHeaderStaticMacros = ( + """#define DECLARE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\ + JSC::FunctionExecutable* codeName##Generator(JSC::VM&); + +${macroPrefix}_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR) +#undef DECLARE_BUILTIN_GENERATOR""") + + SeparateHeaderStaticMacros = ( + """#define DECLARE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\ + JSC::FunctionExecutable* codeName##Generator(JSC::VM&); + +${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR) +#undef DECLARE_BUILTIN_GENERATOR""") + + CombinedJSCImplementationStaticMacros = ( + """ +#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\ +JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\ +{\\ + return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source()); \ +} +${macroPrefix}_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR) +#undef DEFINE_BUILTIN_GENERATOR +""") + + SeparateJSCImplementationStaticMacros = ( + """ +#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\ +JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\ +{\\ + return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source()); \ +} +${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR) +#undef DEFINE_BUILTIN_GENERATOR +""") + + CombinedWebCoreImplementationStaticMacros = ( + """ +#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\ +JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\ +{\\ + JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \\ + return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source()); \\ +} +${macroPrefix}_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR) +#undef DEFINE_BUILTIN_GENERATOR +""") + + SeparateWebCoreImplementationStaticMacros = ( + """ +#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \\ +JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\ +{\\ + JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \\ + return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source()); \\ +} +${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR) +#undef DEFINE_BUILTIN_GENERATOR +""") + + SeparateHeaderWrapperBoilerplate = ( + """class ${objectName}BuiltinsWrapper : private JSC::WeakHandleOwner { +public: + explicit ${objectName}BuiltinsWrapper(JSC::VM* vm) + : m_vm(*vm) + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_FUNCTION_NAME(INITIALIZE_BUILTIN_NAMES) +#define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) , m_##name##Source(JSC::makeSource(StringImpl::createFromLiteral(s_##name, length))) + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(INITIALIZE_BUILTIN_SOURCE_MEMBERS) +#undef INITIALIZE_BUILTIN_SOURCE_MEMBERS + { + } + +#define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, length) \\ + JSC::UnlinkedFunctionExecutable* name##Executable(); \\ + const JSC::SourceCode& name##Source() const { return m_##name##Source; } + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES) +#undef EXPOSE_BUILTIN_EXECUTABLES + + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR) + + void exportNames(); + +private: + JSC::VM& m_vm; + + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES) + +#define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) \\ + JSC::SourceCode m_##name##Source;\\ + JSC::Weak<JSC::UnlinkedFunctionExecutable> m_##name##Executable; + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS) +#undef DECLARE_BUILTIN_SOURCE_MEMBERS + +}; + +#define DEFINE_BUILTIN_EXECUTABLES(name, functionName, length) \\ +inline JSC::UnlinkedFunctionExecutable* ${objectName}BuiltinsWrapper::name##Executable() \\ +{\\ + if (!m_##name##Executable)\\ + m_##name##Executable = JSC::Weak<JSC::UnlinkedFunctionExecutable>(JSC::createBuiltinExecutable(m_vm, m_##name##Source, functionName##PublicName(), s_##name##ConstructAbility), this, &m_##name##Executable);\\ + return m_##name##Executable.get();\\ +} +${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DEFINE_BUILTIN_EXECUTABLES) +#undef DEFINE_BUILTIN_EXECUTABLES + +inline void ${objectName}BuiltinsWrapper::exportNames() +{ +#define EXPORT_FUNCTION_NAME(name) m_vm.propertyNames->appendExternalName(name##PublicName(), name##PrivateName()); + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_FUNCTION_NAME(EXPORT_FUNCTION_NAME) +#undef EXPORT_FUNCTION_NAME +}""") + + SeparateHeaderInternalFunctionsBoilerplate = ( + """class ${objectName}BuiltinFunctions { +public: + explicit ${objectName}BuiltinFunctions(JSC::VM& vm) : m_vm(vm) { } + + void init(JSC::JSGlobalObject&); + void visit(JSC::SlotVisitor&); + +public: + JSC::VM& m_vm; + +#define DECLARE_BUILTIN_SOURCE_MEMBERS(functionName) \\ + JSC::WriteBarrier<JSC::JSFunction> m_##functionName##Function; + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_SOURCE_MEMBERS) +#undef DECLARE_BUILTIN_SOURCE_MEMBERS +}; + +inline void ${objectName}BuiltinFunctions::init(JSC::JSGlobalObject& globalObject) +{ +#define EXPORT_FUNCTION(codeName, functionName, length)\\ + m_##functionName##Function.set(m_vm, &globalObject, JSC::JSFunction::createBuiltinFunction(m_vm, codeName##Generator(m_vm), &globalObject)); + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(EXPORT_FUNCTION) +#undef EXPORT_FUNCTION +} + +inline void ${objectName}BuiltinFunctions::visit(JSC::SlotVisitor& visitor) +{ +#define VISIT_FUNCTION(name) visitor.append(&m_##name##Function); + ${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_FUNCTION_NAME(VISIT_FUNCTION) +#undef VISIT_FUNCTION +} +""") |