diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/Scripts/builtins/builtins_generator.py | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/Scripts/builtins/builtins_generator.py')
-rw-r--r-- | Source/JavaScriptCore/Scripts/builtins/builtins_generator.py | 181 |
1 files changed, 181 insertions, 0 deletions
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) |