diff options
Diffstat (limited to 'Source/JavaScriptCore/Scripts/builtins')
13 files changed, 1722 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..a9aff2b1c --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins.py @@ -0,0 +1,15 @@ +# 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 * +from builtins_generate_wrapper_header import * +from builtins_generate_wrapper_implementation import * +from builtins_generate_internals_wrapper_header import * +from builtins_generate_internals_wrapper_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 100755 index 000000000..42334ff3d --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_header.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014-2016 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'), + 'macroPrefix': self.model().framework.setting('macro_prefix'), + } + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + sections.append(Template(Templates.HeaderIncludeGuard).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(self.generate_section_for_global_private_code_name_macro()) + sections.append(Template(Templates.CombinedHeaderStaticMacros).substitute(args)) + sections.append(Template(Templates.NamespaceBottom).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) + + def generate_section_for_global_private_code_name_macro(self): + args = { + 'macroPrefix': self.model().framework.setting('macro_prefix'), + } + + lines = [] + lines.append("#define %(macroPrefix)s_FOREACH_BUILTIN_FUNCTION_PRIVATE_GLOBAL_NAME(macro) \\" % args) + functions = filter(lambda function: function.is_global_private, self.model().all_functions()) + functions.sort(key=lambda x: x.function_name) + for function in functions: + function_args = { + 'funcName': function.function_name, + 'codeName': BuiltinsGenerator.mangledNameForFunction(function), + } + + lines.append(" macro(%(funcName)s, %(codeName)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..728beba79 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_implementation.py @@ -0,0 +1,97 @@ +#!/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", "heap/HeapInlines.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/UnlinkedFunctionExecutable.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/JSCellInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/StructureInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/JSCJSValueInlines.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/VM.h"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/Intrinsic.h"), + ), + ] + + return '\n'.join(self.generate_includes_from_entries(header_includes)) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_header.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_header.py new file mode 100755 index 000000000..dbcd5b55a --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_header.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016 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 +from string import Template + +from builtins_generator import BuiltinsGenerator, WK_lcfirst, WK_ucfirst +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsInternalsWrapperHeaderGenerator(BuiltinsGenerator): + def __init__(self, model): + BuiltinsGenerator.__init__(self, model) + self.internals = filter(lambda object: 'internal' in object.annotations, model.objects) + + def output_filename(self): + return "%sJSBuiltinInternals.h" % self.model().framework.setting('namespace') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + } + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + sections.append(Template(Templates.HeaderIncludeGuard).substitute(args)) + sections.append(self.generate_secondary_header_includes()) + + sections.append(Template(Templates.NamespaceTop).substitute(args)) + sections.append(self.generate_section_for_object()) + sections.append(Template(Templates.NamespaceBottom).substitute(args)) + + return "\n\n".join(sections) + + def generate_secondary_header_includes(self): + header_includes = [ + (["WebCore"], ("JavaScriptCore", "heap/WeakInlines.h")), + (["WebCore"], ("JavaScriptCore", "runtime/VM.h")) + ] + for object in self.internals: + header_includes.append((["WebCore"], ("WebCore", object.object_name + "Builtins.h"))) + + return '\n'.join(self.generate_includes_from_entries(header_includes)) + + def generate_section_for_object(self): + lines = ["class JSDOMGlobalObject;", + "", + "class JSBuiltinInternalFunctions {", + "public:"] + + lines.append(" explicit JSBuiltinInternalFunctions(JSC::VM&);") + lines.append(self.generate_methods()) + lines.append(self.generate_accessors()) + lines.append("private:") + lines.append(self.generate_members()) + lines.append("};") + return '\n'.join(lines) + + def accessor_name(self, object): + return WK_lcfirst(object.object_name) + + def member_name(self, object): + return "m_" + self.accessor_name(object) + + def member_type(self, object): + return WK_ucfirst(object.object_name) + "BuiltinFunctions" + + def generate_methods(self): + return """ + void visit(JSC::SlotVisitor&); + void initialize(JSDOMGlobalObject&); +""" + + def generate_accessors(self): + lines = [] + for object in self.internals: + accessor = " %s& %s() { return %s; }" % (self.member_type(object), self.accessor_name(object), self.member_name(object)) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), accessor)) + lines.append("") + return '\n'.join(lines) + + def generate_members(self): + guards = set([object.annotations.get('conditional') for object in self.internals if 'conditional' in object.annotations]) + lines = [BuiltinsGenerator.wrap_with_guard(" || ".join(guards), " JSC::VM& m_vm;")] + for object in self.internals: + member = " %s %s;" % (self.member_type(object), self.member_name(object)) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), member)) + return '\n'.join(lines) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_implementation.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_implementation.py new file mode 100755 index 000000000..d2d09c58a --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_implementation.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016 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 +from string import Template + +from builtins_generator import BuiltinsGenerator, WK_lcfirst, WK_ucfirst +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsInternalsWrapperImplementationGenerator(BuiltinsGenerator): + def __init__(self, model): + BuiltinsGenerator.__init__(self, model) + self.internals = filter(lambda object: 'internal' in object.annotations, model.objects) + + def output_filename(self): + return "%sJSBuiltinInternals.cpp" % self.model().framework.setting('namespace') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + } + + 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)) + sections.append(self.generate_section_for_object()) + sections.append(Template(Templates.NamespaceBottom).substitute(args)) + + return "\n\n".join(sections) + + def generate_secondary_header_includes(self): + header_includes = [ + (["WebCore"], + ("WebCore", "JSDOMGlobalObject.h"), + ), + (["WebCore"], + ("WebCore", "WebCoreJSClientData.h"), + ), + (["WebCore"], + ("JavaScriptCore", "heap/HeapInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "heap/SlotVisitorInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/JSCJSValueInlines.h"), + ), + (["WebCore"], + ("JavaScriptCore", "runtime/StructureInlines.h"), + ), + ] + return '\n'.join(self.generate_includes_from_entries(header_includes)) + + def generate_section_for_object(self): + lines = [] + + lines.append(self.generate_constructor()) + lines.append(self.generate_visit_method()) + lines.append(self.generate_initialize_method()) + return '\n'.join(lines) + + def accessor_name(self, object): + return WK_lcfirst(object.object_name) + + def member_name(self, object): + return "m_" + self.accessor_name(object) + + def member_type(self, object): + return WK_ucfirst(object.object_name) + "BuiltinFunctions" + + def generate_constructor(self): + guards = set([object.annotations.get('conditional') for object in self.internals if 'conditional' in object.annotations]) + lines = ["JSBuiltinInternalFunctions::JSBuiltinInternalFunctions(JSC::VM& vm)", + BuiltinsGenerator.wrap_with_guard(" || ".join(guards), " : m_vm(vm)")] + for object in self.internals: + initializer = " , %s(m_vm)" % self.member_name(object) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), initializer)) + lines.append("{") + lines.append(" UNUSED_PARAM(vm);") + lines.append("}\n") + return '\n'.join(lines) + + def property_macro(self, object): + lines = [] + lines.append("#define DECLARE_GLOBAL_STATIC(name) \\") + lines.append(" JSDOMGlobalObject::GlobalPropertyInfo( \\") + lines.append(" clientData.builtinFunctions().%sBuiltins().name##PrivateName(), %s().m_##name##Function.get() , JSC::DontDelete | JSC::ReadOnly)," % (self.accessor_name(object), self.accessor_name(object))) + lines.append(" WEBCORE_FOREACH_%s_BUILTIN_FUNCTION_NAME(DECLARE_GLOBAL_STATIC)" % object.object_name.upper()) + lines.append("#undef DECLARE_GLOBAL_STATIC") + return '\n'.join(lines) + + def generate_visit_method(self): + lines = ["void JSBuiltinInternalFunctions::visit(JSC::SlotVisitor& visitor)", + "{"] + for object in self.internals: + visit = " %s.visit(visitor);" % self.member_name(object) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), visit)) + lines.append(" UNUSED_PARAM(visitor);") + lines.append("}\n") + return '\n'.join(lines) + + def _generate_initialize_static_globals(self): + lines = [" JSVMClientData& clientData = *static_cast<JSVMClientData*>(m_vm.clientData);", + " JSDOMGlobalObject::GlobalPropertyInfo staticGlobals[] = {"] + for object in self.internals: + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), self.property_macro(object))) + lines.append(" };") + lines.append(" globalObject.addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));") + lines.append(" UNUSED_PARAM(clientData);") + return '\n'.join(lines) + + def generate_initialize_method(self): + lines = ["void JSBuiltinInternalFunctions::initialize(JSDOMGlobalObject& globalObject)", + "{", + " UNUSED_PARAM(globalObject);"] + + for object in self.internals: + init = " %s.init(globalObject);" % self.member_name(object) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), init)) + lines.append("") + + guards = set([object.annotations.get('conditional') for object in self.internals if 'conditional' in object.annotations]) + lines.append(BuiltinsGenerator.wrap_with_guard(" || ".join(guards), self._generate_initialize_static_globals())) + + lines.append("}") + return '\n'.join(lines) 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 100755 index 000000000..9058367a0 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_header.py @@ -0,0 +1,197 @@ +#!/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'), + '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.HeaderIncludeGuard).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) + + 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..d5362bd4b --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_implementation.py @@ -0,0 +1,109 @@ +#!/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", "heap/HeapInlines.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"), + ), + (["JavaScriptCore", "WebCore"], + ("JavaScriptCore", "runtime/Intrinsic.h"), + ), + ] + + return '\n'.join(self.generate_includes_from_entries(header_includes)) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_wrapper_header.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_wrapper_header.py new file mode 100755 index 000000000..04abe5678 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_wrapper_header.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016 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 +from string import Template + +from builtins_generator import BuiltinsGenerator, WK_lcfirst, WK_ucfirst +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsWrapperHeaderGenerator(BuiltinsGenerator): + def __init__(self, model): + BuiltinsGenerator.__init__(self, model) + + def output_filename(self): + return "%sJSBuiltins.h" % self.model().framework.setting('namespace') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + } + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + sections.append(Template(Templates.HeaderIncludeGuard).substitute(args)) + sections.append(self.generate_secondary_header_includes()) + + sections.append(Template(Templates.NamespaceTop).substitute(args)) + sections.append(self.generate_section_for_object()) + sections.append(Template(Templates.NamespaceBottom).substitute(args)) + + return "\n\n".join(sections) + + def generate_secondary_header_includes(self): + header_includes = [ + (["WebCore"], + ("JavaScriptCore", "runtime/VM.h"), + ), + ] + for object in self.model().objects: + header_includes.append((["WebCore"], ("WebCore", object.object_name + "Builtins.h"))) + + return '\n'.join(self.generate_includes_from_entries(header_includes)) + + def generate_section_for_object(self): + lines = ["class JSBuiltinFunctions {", + "public:"] + + lines.append(self.generate_constructor()) + lines.append(self.generate_accessors()) + lines.append("private:") + lines.append(self.generate_members()) + lines.append("};") + return '\n'.join(lines) + + def accessor_name(self, object): + return WK_lcfirst(object.object_name) + "Builtins" + + def member_name(self, object): + return "m_" + self.accessor_name(object) + + def member_type(self, object): + return WK_ucfirst(object.object_name) + "BuiltinsWrapper" + + def generate_constructor(self): + lines = [" explicit JSBuiltinFunctions(JSC::VM& vm)", + " : m_vm(vm)"] + for object in self.model().objects: + member_init = " , %s(&m_vm)" % self.member_name(object) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), member_init)) + lines.append(" {") + for object in self.model().objects: + if not 'internal' in object.annotations: + continue + internal_export_names = " %s.exportNames();" % self.member_name(object) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), internal_export_names)) + lines.append(" }\n") + return '\n'.join(lines) + + def generate_accessors(self): + lines = [] + for object in self.model().objects: + accessor = " %s& %s() { return %s; }" % (self.member_type(object), self.accessor_name(object), self.member_name(object)) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), accessor)) + lines.append("") + return '\n'.join(lines) + + def generate_members(self): + lines = [" JSC::VM& m_vm;"] + for object in self.model().objects: + member = " %s %s;" % (self.member_type(object), self.member_name(object)) + lines.append(BuiltinsGenerator.wrap_with_guard(object.annotations.get('conditional'), member)) + return '\n'.join(lines) diff --git a/Source/JavaScriptCore/Scripts/builtins/builtins_generate_wrapper_implementation.py b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_wrapper_implementation.py new file mode 100755 index 000000000..0055917fd --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generate_wrapper_implementation.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# Copyright (c) 2016 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 +from string import Template + +from builtins_generator import BuiltinsGenerator +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + + +class BuiltinsWrapperImplementationGenerator(BuiltinsGenerator): + def __init__(self, model): + BuiltinsGenerator.__init__(self, model) + + def output_filename(self): + return "%sJSBuiltins.cpp" % self.model().framework.setting('namespace') + + def generate_output(self): + args = { + 'namespace': self.model().framework.setting('namespace'), + } + + sections = [] + sections.append(self.generate_license()) + sections.append(Template(Templates.DoNotEditWarning).substitute(args)) + + sections.append(self.generate_section_for_object()) + + return "\n\n".join(sections) + + def generate_section_for_object(self): + header_includes = [] + for object in self.model().objects: + header_includes.append((["WebCore"], ("WebCore", object.object_name + "Builtins.cpp"))) + + 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..4950113ca --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_generator.py @@ -0,0 +1,181 @@ +#!/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('dOM', 'dom') + 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, + 'intrinsic': function.intrinsic + } + + 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("static const JSC::Intrinsic s_%(codeName)sIntrinsic = JSC::%(intrinsic)s;" % args); + lines.append("const char* s_%(codeName)s =\n%(embeddedSource)s\n;" % args); + return '\n'.join(lines) + + # Helper methods. + + @staticmethod + def wrap_with_guard(guard, text): + if not guard: + return text + return '\n'.join([ + '#if %s' % guard, + text, + '#endif // %s' % guard, + ]) + + @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..c35bd3e84 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_model.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python +# +# Copyright (c) 2015-2016 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 + +from builtins_templates import BuiltinsGeneratorTemplates as Templates + +log = logging.getLogger('global') + +_FRAMEWORK_CONFIG_MAP = { + "JavaScriptCore": { + "macro_prefix": "JSC", + "namespace": "JSC", + }, + "WebCore": { + "macro_prefix": "WEBCORE", + "namespace": "WebCore", + }, +} + +functionHeadRegExp = re.compile(r"(?:@[\w|=]+\s*\n)*function\s+\w+\s*\(.*?\)", re.MULTILINE | re.DOTALL) +functionGlobalPrivateRegExp = re.compile(r".*^@globalPrivate", re.MULTILINE | re.DOTALL) +functionIntrinsicRegExp = re.compile(r".*^@intrinsic=(\w+)", re.MULTILINE | re.DOTALL) +functionIsConstructorRegExp = re.compile(r".*^@constructor", re.MULTILINE | re.DOTALL) +functionNameRegExp = re.compile(r"function\s+(\w+)\s*\(", re.MULTILINE | re.DOTALL) +functionParameterFinder = re.compile(r"^function\s+(?:\w+)\s*\(((?:\s*\w+)?\s*(?:\s*,\s*\w+)*)?\s*\)", re.MULTILINE | re.DOTALL) + +multilineCommentRegExp = re.compile(r"\/\*.*?\*\/", re.MULTILINE | re.DOTALL) +singleLineCommentRegExp = re.compile(r"\/\/.*?\n", re.MULTILINE | re.DOTALL) +keyValueAnnotationCommentRegExp = re.compile(r"^\/\/ @(\w+)=([^=]+?)\n", re.MULTILINE | re.DOTALL) +flagAnnotationCommentRegExp = re.compile(r"^\/\/ @(\w+)[^=]*?\n", re.MULTILINE | re.DOTALL) +lineWithOnlySingleLineCommentRegExp = re.compile(r"^\s*\/\/\n", re.MULTILINE | re.DOTALL) +lineWithTrailingSingleLineCommentRegExp = re.compile(r"\s*\/\/\n", re.MULTILINE | re.DOTALL) +multipleEmptyLinesRegExp = re.compile(r"\n{2,}", re.MULTILINE | re.DOTALL) + +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, parameters, is_constructor, is_global_private, intrinsic): + self.function_name = function_name + self.function_source = function_source + self.parameters = parameters + self.is_constructor = is_constructor + self.is_global_private = is_global_private + self.intrinsic = intrinsic + self.object = None # Set by the owning BuiltinObject + + @staticmethod + def fromString(function_string): + function_source = multilineCommentRegExp.sub("", function_string) + + intrinsic = "NoIntrinsic" + intrinsicMatch = functionIntrinsicRegExp.search(function_source) + if intrinsicMatch: + intrinsic = intrinsicMatch.group(1) + function_source = functionIntrinsicRegExp.sub("", function_source) + + 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 + is_global_private = functionGlobalPrivateRegExp.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, parameters, is_constructor, is_global_private, intrinsic) + + 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 = [Templates.DefaultCopyright] + 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..f84868008 --- /dev/null +++ b/Source/JavaScriptCore/Scripts/builtins/builtins_templates.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python +# +# Copyright (c) 2014-2016 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: + + DefaultCopyright = "2016 Apple Inc. All rights reserved." + 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""") + + HeaderIncludeGuard = ( + """#pragma once""") + + 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(), std::nullopt, s_##codeName##Intrinsic); \ +} +${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(), std::nullopt, s_##codeName##Intrinsic); \ +} +${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(), std::nullopt, s_##codeName##Intrinsic); \\ +} +${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(), std::nullopt, s_##codeName##Intrinsic); \\ +} +${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 +} +""") |