X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/14957cd040308e3eeec43d26bae5d76da13fcd85..1981f5dfe8d77d97469d20652f712a09400c48ed:/KeywordLookupGenerator.py diff --git a/KeywordLookupGenerator.py b/KeywordLookupGenerator.py index 6ba7e34..748acf9 100644 --- a/KeywordLookupGenerator.py +++ b/KeywordLookupGenerator.py @@ -1,4 +1,5 @@ -# Copyright (C) 2010 Apple Inc. All rights reserved. +# Copyright (C) 2011 Apple Inc. All rights reserved. +# Copyright (C) 2012 Sony Network Entertainment. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -27,6 +28,15 @@ import operator keywordsText = open(sys.argv[1]).read() +# A second argument signifies that the output +# should be redirected to a file +redirect_to_file = len(sys.argv) > 2 + +# Change stdout to point to the file if requested +if redirect_to_file: + file_output = open(sys.argv[-1], "w") + sys.stdout = file_output + # Observed weights of the most common keywords, rounded to 2.s.d keyWordWeights = { "catch": 0.01, @@ -103,11 +113,12 @@ class Trie: return self if len(self.keys) != 1: return self - (prefix, suffix) = self.keys.items()[0] - res = Trie(self.prefix + prefix) - res.value = suffix.value - res.keys = suffix.keys - return res + # Python 3: for() loop for compatibility. Use next() when Python 2.6 is the baseline. + for (prefix, suffix) in self.keys.items(): + res = Trie(self.prefix + prefix) + res.value = suffix.value + res.keys = suffix.keys + return res def fillOut(self, prefix=""): self.fullPrefix = prefix + self.prefix @@ -121,12 +132,12 @@ class Trie: self.keys = [(trie.prefix, trie) for trie in sorted(self.keys.values(), key=operator.attrgetter('weight'), reverse=True)] self.weight = weight - def printSubTreeAsC(self, indent): + def printSubTreeAsC(self, typeName, indent): str = makePadding(indent) if self.value != None: print(str + "if (!isIdentPart(code[%d])) {" % (len(self.fullPrefix))) - print(str + " internalShift<%d, DoNotBoundsCheck>();" % len(self.fullPrefix)) + print(str + " internalShift<%d>();" % len(self.fullPrefix)) print(str + " if (shouldCreateIdentifier)") print(str + (" data->ident = &m_globalData->propertyNames->%sKeyword;" % self.fullPrefix)) print(str + " return " + self.value + ";") @@ -145,15 +156,17 @@ class Trie: base = "code" if baseIndex > 0: base = "code + %d" % baseIndex - comparison = ("COMPARE_CHARACTERS%d(%s, " % (len(test), base)) + ", ".join(test) + ")" + comparison = ("COMPARE_%d%sS(%s, " % (len(test), typeName, base)) + ", ".join(test) + ")" if itemCount == 0: print(str + "if (" + comparison + ") {") else: - print(str + "else if (" + comparison + ") {") + print(str + "} else if (" + comparison + ") {") - trie.printSubTreeAsC(indent + 4) + trie.printSubTreeAsC(typeName, indent + 4) itemCount = itemCount + 1 - print(str + "}") + + if itemCount == len(self.keys): + print(str + "}") def maxLength(self): max = len(self.fullPrefix) @@ -165,16 +178,33 @@ class Trie: def printAsC(self): print("namespace JSC {") - print("static ALWAYS_INLINE bool isIdentPart(int c);") + print("") + print("static ALWAYS_INLINE bool isIdentPart(LChar c);") + print("static ALWAYS_INLINE bool isIdentPart(UChar c);") # max length + 1 so we don't need to do any bounds checking at all print("static const int maxTokenLength = %d;" % (self.maxLength() + 1)) - print("template ALWAYS_INLINE JSTokenType Lexer::parseKeyword(JSTokenData* data) {") + print("") + print("template <>") + print("template ALWAYS_INLINE JSTokenType Lexer::parseKeyword(JSTokenData* data)") + print("{") print(" ASSERT(m_codeEnd - m_code >= maxTokenLength);") + print("") print(" const UChar* code = m_code;") - self.printSubTreeAsC(4) + self.printSubTreeAsC("UCHAR", 4) print(" return IDENT;") print("}") + print("") + print("template <>") + print("template ALWAYS_INLINE JSTokenType Lexer::parseKeyword(JSTokenData* data)") + print("{") + print(" ASSERT(m_codeEnd - m_code >= maxTokenLength);") + print("") + print(" const LChar* code = m_code;") + self.printSubTreeAsC("CHAR", 4) + print(" return IDENT;") print("}") + print("") + print("} // namespace JSC") keywords = parseKeywords(keywordsText) trie = Trie("") @@ -184,47 +214,92 @@ trie.coalesce() trie.fillOut() print("// This file was generated by KeywordLookupGenerator.py. Do not edit.") print(""" - #if CPU(NEEDS_ALIGNED_ACCESS) -#define COMPARE_CHARACTERS2(address, char1, char2) \ +#define COMPARE_2CHARS(address, char1, char2) \\ + (((address)[0] == char1) && ((address)[1] == char2)) +#define COMPARE_4CHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2CHARS(address, char1, char2) && COMPARE_2CHARS((address) + 2, char3, char4)) +#define COMPARE_2UCHARS(address, char1, char2) \\ (((address)[0] == char1) && ((address)[1] == char2)) -#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \ - (COMPARE_CHARACTERS2(address, char1, char2) && COMPARE_CHARACTERS2((address) + 2, char3, char4)) +#define COMPARE_4UCHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2UCHARS(address, char1, char2) && COMPARE_2UCHARS((address) + 2, char3, char4)) -#else +#else // CPU(NEEDS_ALIGNED_ACCESS) #if CPU(BIG_ENDIAN) -#define CHARPAIR_TOUINT32(a, b) ((((uint32_t)(a)) << 16) + (uint32_t)(b)) -#define CHARQUAD_TOUINT64(a, b, c, d) ((((uint64_t)(CHARPAIR_TOUINT32(a, b))) << 32) + CHARPAIR_TOUINT32(c, d)) -#else -#define CHARPAIR_TOUINT32(a, b) ((((uint32_t)(b)) << 16) + (uint32_t)(a)) -#define CHARQUAD_TOUINT64(a, b, c, d) ((((uint64_t)(CHARPAIR_TOUINT32(c, d))) << 32) + CHARPAIR_TOUINT32(a, b)) -#endif - -#define COMPARE_CHARACTERS2(address, char1, char2) \ - (((uint32_t*)(address))[0] == CHARPAIR_TOUINT32(char1, char2)) + +#define CHARPAIR_TOUINT16(a, b) \\ + ((((uint16_t)(a)) << 8) + (uint16_t)(b)) +#define CHARQUAD_TOUINT32(a, b, c, d) \\ + ((((uint32_t)(CHARPAIR_TOUINT16(a, b))) << 16) + CHARPAIR_TOUINT16(c, d)) +#define UCHARPAIR_TOUINT32(a, b) \\ + ((((uint32_t)(a)) << 16) + (uint32_t)(b)) +#define UCHARQUAD_TOUINT64(a, b, c, d) \\ + ((((uint64_t)(UCHARQUAD_TOUINT64(a, b))) << 32) + UCHARPAIR_TOUINT32(c, d)) + +#else // CPU(BIG_ENDIAN) + +#define CHARPAIR_TOUINT16(a, b) \\ + ((((uint16_t)(b)) << 8) + (uint16_t)(a)) +#define CHARQUAD_TOUINT32(a, b, c, d) \\ + ((((uint32_t)(CHARPAIR_TOUINT16(c, d))) << 16) + CHARPAIR_TOUINT16(a, b)) +#define UCHARPAIR_TOUINT32(a, b) \\ + ((((uint32_t)(b)) << 16) + (uint32_t)(a)) +#define UCHARQUAD_TOUINT64(a, b, c, d) \\ + ((((uint64_t)(UCHARPAIR_TOUINT32(c, d))) << 32) + UCHARPAIR_TOUINT32(a, b)) + +#endif // CPU(BIG_ENDIAN) + + +#define COMPARE_2CHARS(address, char1, char2) \\ + (((uint16_t*)(address))[0] == CHARPAIR_TOUINT16(char1, char2)) +#define COMPARE_2UCHARS(address, char1, char2) \\ + (((uint32_t*)(address))[0] == UCHARPAIR_TOUINT32(char1, char2)) + #if CPU(X86_64) -#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \ - (((uint64_t*)(address))[0] == CHARQUAD_TOUINT64(char1, char2, char3, char4)) -#else -#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \ - (COMPARE_CHARACTERS2(address, char1, char2) && COMPARE_CHARACTERS2((address) + 2, char3, char4)) -#endif - -#endif - -#define COMPARE_CHARACTERS3(address, char1, char2, char3) \ - (COMPARE_CHARACTERS2(address, char1, char2) && ((address)[2] == (char3))) -#define COMPARE_CHARACTERS5(address, char1, char2, char3, char4, char5) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && ((address)[4] == (char5))) -#define COMPARE_CHARACTERS6(address, char1, char2, char3, char4, char5, char6) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS2(address + 4, char5, char6)) -#define COMPARE_CHARACTERS7(address, char1, char2, char3, char4, char5, char6, char7) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS4(address + 3, char4, char5, char6, char7)) -#define COMPARE_CHARACTERS8(address, char1, char2, char3, char4, char5, char6, char7, char8) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS4(address + 4, char5, char6, char7, char8)) +#define COMPARE_4CHARS(address, char1, char2, char3, char4) \\ + (((uint32_t*)(address))[0] == CHARQUAD_TOUINT32(char1, char2, char3, char4)) +#define COMPARE_4UCHARS(address, char1, char2, char3, char4) \\ + (((uint64_t*)(address))[0] == UCHARQUAD_TOUINT64(char1, char2, char3, char4)) + +#else // CPU(X86_64) + +#define COMPARE_4CHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2CHARS(address, char1, char2) && COMPARE_2CHARS((address) + 2, char3, char4)) +#define COMPARE_4UCHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2UCHARS(address, char1, char2) && COMPARE_2UCHARS((address) + 2, char3, char4)) + +#endif // CPU(X86_64) + +#endif // CPU(NEEDS_ALIGNED_ACCESS) + +#define COMPARE_3CHARS(address, char1, char2, char3) \\ + (COMPARE_2CHARS(address, char1, char2) && ((address)[2] == (char3))) +#define COMPARE_3UCHARS(address, char1, char2, char3) \\ + (COMPARE_2UCHARS(address, char1, char2) && ((address)[2] == (char3))) +#define COMPARE_5CHARS(address, char1, char2, char3, char4, char5) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && ((address)[4] == (char5))) +#define COMPARE_5UCHARS(address, char1, char2, char3, char4, char5) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && ((address)[4] == (char5))) +#define COMPARE_6CHARS(address, char1, char2, char3, char4, char5, char6) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && COMPARE_2CHARS(address + 4, char5, char6)) +#define COMPARE_6UCHARS(address, char1, char2, char3, char4, char5, char6) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && COMPARE_2UCHARS(address + 4, char5, char6)) +#define COMPARE_7CHARS(address, char1, char2, char3, char4, char5, char6, char7) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && COMPARE_4CHARS(address + 3, char4, char5, char6, char7)) +#define COMPARE_7UCHARS(address, char1, char2, char3, char4, char5, char6, char7) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && COMPARE_4UCHARS(address + 3, char4, char5, char6, char7)) +#define COMPARE_8CHARS(address, char1, char2, char3, char4, char5, char6, char7, char8) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && COMPARE_4CHARS(address + 4, char5, char6, char7, char8)) +#define COMPARE_8UCHARS(address, char1, char2, char3, char4, char5, char6, char7, char8) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && COMPARE_4UCHARS(address + 4, char5, char6, char7, char8)) """) trie.printAsC() + +# Close the redirected file if requested +if (redirect_to_file): + file_output.close() + sys.stdout = sys.__stdout__