| Differences between
and this patch
- a/Source/JavaScriptCore/CMakeLists.txt +7 lines
Lines 219-224 ADD_CUSTOM_COMMAND( a/Source/JavaScriptCore/CMakeLists.txt_sec1
219
ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/yarr/YarrPattern.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/RegExpJitTables.h)
219
ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/yarr/YarrPattern.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/RegExpJitTables.h)
220
220
221
221
222
#GENERATOR: "KeywordLookup.h": keyword decision tree used by the lexer
223
ADD_CUSTOM_COMMAND(
224
    OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
225
    MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/KeywordLookupGenerator.py
226
    COMMAND ${PYTHON_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/KeywordLookupGenerator.py ${JAVASCRIPTCORE_DIR}/parser/Keywords.table > ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h
227
    VERBATIM)
228
ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/parser/Lexer.cpp ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/KeywordLookup.h)
222
229
223
IF (WTF_CPU_ARM)
230
IF (WTF_CPU_ARM)
224
    LIST(APPEND JavaScriptCore_SOURCES
231
    LIST(APPEND JavaScriptCore_SOURCES
- a/Source/JavaScriptCore/ChangeLog +28 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2011-06-03  Oliver Hunt  <oliver@apple.com>
2
3
        Reviewed by NOBODY (OOPS!).
4
5
        Improve keyword lookup
6
        https://bugs.webkit.org/show_bug.cgi?id=61913
7
8
        Rather than doing multiple hash lookups as we currently
9
        do when trying to identify keywords we now use an 
10
        automatically generated decision tree (essentially it's
11
        a hard coded patricia trie).  We still use the regular
12
        lookup table for the last few characters of an input as
13
        this allows us to completely skip all bounds checks.
14
15
        * CMakeLists.txt:
16
        * DerivedSources.make:
17
        * DerivedSources.pro:
18
        * GNUmakefile.am:
19
        * JavaScriptCore.gyp/JavaScriptCore.gyp:
20
        * JavaScriptCore.xcodeproj/project.pbxproj:
21
        * KeywordLookupGenerator.py: Added.
22
        * make-generated-sources.sh:
23
        * parser/Lexer.cpp:
24
        (JSC::Lexer::internalShift):
25
        (JSC::Lexer::shift):
26
        (JSC::Lexer::parseIdentifier):
27
        * parser/Lexer.h:
28
1
2011-06-03  Siddharth Mathur  <siddharth.mathur@nokia.com>
29
2011-06-03  Siddharth Mathur  <siddharth.mathur@nokia.com>
2
30
3
        Reviewed by Benjamin Poulain.
31
        Reviewed by Benjamin Poulain.
- a/Source/JavaScriptCore/DerivedSources.make +4 lines
Lines 46-51 all : \ a/Source/JavaScriptCore/DerivedSources.make_sec1
46
    JavaScriptCore.JSVALUE32_64.exp \
46
    JavaScriptCore.JSVALUE32_64.exp \
47
    JavaScriptCore.JSVALUE64.exp \
47
    JavaScriptCore.JSVALUE64.exp \
48
    JSGlobalObject.lut.h \
48
    JSGlobalObject.lut.h \
49
    KeywordLookup.h \
49
    Lexer.lut.h \
50
    Lexer.lut.h \
50
    MathObject.lut.h \
51
    MathObject.lut.h \
51
    NumberConstructor.lut.h \
52
    NumberConstructor.lut.h \
Lines 76-81 docs/bytecode.html: make-bytecode-docs.pl Interpreter.cpp a/Source/JavaScriptCore/DerivedSources.make_sec2
76
RegExpJitTables.h: create_regex_tables
77
RegExpJitTables.h: create_regex_tables
77
	python $^ > $@
78
	python $^ > $@
78
79
80
KeywordLookup.h: KeywordLookupGenerator.py Keywords.table
81
	python $^ > $@
82
79
# export files
83
# export files
80
84
81
JavaScriptCore.JSVALUE32_64.exp: JavaScriptCore.exp JavaScriptCore.JSVALUE32_64only.exp
85
JavaScriptCore.JSVALUE32_64.exp: JavaScriptCore.exp JavaScriptCore.JSVALUE32_64only.exp
- a/Source/JavaScriptCore/DerivedSources.pro +7 lines
Lines 99-101 retgen.wkScript = $$PWD/create_regex_tables a/Source/JavaScriptCore/DerivedSources.pro_sec1
99
retgen.input = retgen.wkScript
99
retgen.input = retgen.wkScript
100
retgen.commands = python $$retgen.wkScript > ${QMAKE_FILE_OUT}
100
retgen.commands = python $$retgen.wkScript > ${QMAKE_FILE_OUT}
101
addExtraCompiler(retgen)
101
addExtraCompiler(retgen)
102
103
#GENERATOR: "KeywordLookup.h": decision tree used by the lexer
104
klgen.output = $$JSC_GENERATED_SOURCES_DIR/KeywordLookup.h
105
klgen.wkScript = $$PWD/KeywordLookupGenerator.py 
106
klgen.input = KEYWORDLUT_FILES
107
klgen.commands = python $$klgen.wkScript ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT}
108
addExtraCompiler(klgen)
- a/Source/JavaScriptCore/GNUmakefile.am +3 lines
Lines 79-84 Source/JavaScriptCore/%.lut.h: $(srcdir)/Source/JavaScriptCore/create_hash_table a/Source/JavaScriptCore/GNUmakefile.am_sec1
79
Source/JavaScriptCore/RegExpJitTables.h: $(srcdir)/Source/JavaScriptCore/create_regex_tables
79
Source/JavaScriptCore/RegExpJitTables.h: $(srcdir)/Source/JavaScriptCore/create_regex_tables
80
	$(AM_V_GEN)$(PYTHON) $^ > $@
80
	$(AM_V_GEN)$(PYTHON) $^ > $@
81
81
82
Source/JavaScriptCore/KeywordLookup.h: $(srcdir)/Source/JavaScriptCore/KeywordLookupGenerator.py $(srcdir)/Source/JavaScriptCore/parser/Keywords.table
83
	$(AM_V_GEN)$(PYTHON) $^ > $@
84
82
jsc: $(javascriptcore_built_nosources) Programs/jsc$(EXEEXT)
85
jsc: $(javascriptcore_built_nosources) Programs/jsc$(EXEEXT)
83
86
84
bin_PROGRAMS += \
87
bin_PROGRAMS += \
- a/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp +13 lines
Lines 214-219 a/Source/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp_sec1
214
          ],
214
          ],
215
          'action': ['python', '<@(_inputs)', '<@(_arguments)', '<@(_outputs)'],
215
          'action': ['python', '<@(_inputs)', '<@(_arguments)', '<@(_outputs)'],
216
        },
216
        },
217
        {
218
          'action_name': 'klgen',
219
          'inputs': [
220
            '../KeywordLookupGenerator.py',
221
            '../parser/Keywords.table'
222
          ],
223
          'arguments': [
224
          ],
225
          'outputs': [
226
            '<(INTERMEDIATE_DIR)/KeywordLookup.h',
227
          ],
228
          'action': ['python', '<@(_inputs)', '<@(_arguments)', '<@(_outputs)'],
229
        },
217
      ],
230
      ],
218
      'include_dirs': [
231
      'include_dirs': [
219
        '<(INTERMEDIATE_DIR)',
232
        '<(INTERMEDIATE_DIR)',
- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +6 lines
Lines 381-386 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
381
		A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
381
		A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
382
		A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
382
		A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
383
		A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
383
		A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
384
		A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C225CD1399849C00FF1662 /* KeywordLookup.h */; };
384
		A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = A730B6101250068F009D25B1 /* StrictEvalActivation.h */; };
385
		A730B6121250068F009D25B1 /* StrictEvalActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = A730B6101250068F009D25B1 /* StrictEvalActivation.h */; };
385
		A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */; };
386
		A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */; };
386
		A731B25A130093880040A7FA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
387
		A731B25A130093880040A7FA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
Lines 1119-1124 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
1119
		A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocator.h; sourceTree = "<group>"; };
1120
		A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocator.h; sourceTree = "<group>"; };
1120
		A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
1121
		A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
1121
		A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess32_64.cpp; sourceTree = "<group>"; };
1122
		A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess32_64.cpp; sourceTree = "<group>"; };
1123
		A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = KeywordLookupGenerator.py; sourceTree = "<group>"; };
1124
		A7C225CD1399849C00FF1662 /* KeywordLookup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeywordLookup.h; sourceTree = "<group>"; };
1122
		A7C40C07130B057D00D002A1 /* BlockStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockStack.h; sourceTree = "<group>"; };
1125
		A7C40C07130B057D00D002A1 /* BlockStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockStack.h; sourceTree = "<group>"; };
1123
		A7C40C08130B057D00D002A1 /* SentinelLinkedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentinelLinkedList.h; sourceTree = "<group>"; };
1126
		A7C40C08130B057D00D002A1 /* SentinelLinkedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentinelLinkedList.h; sourceTree = "<group>"; };
1124
		A7C40C09130B057D00D002A1 /* SinglyLinkedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinglyLinkedList.h; sourceTree = "<group>"; };
1127
		A7C40C09130B057D00D002A1 /* SinglyLinkedList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinglyLinkedList.h; sourceTree = "<group>"; };
Lines 1374-1379 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
1374
			children = (
1377
			children = (
1375
				A718F8211178EB4B002465A7 /* create_regex_tables */,
1378
				A718F8211178EB4B002465A7 /* create_regex_tables */,
1376
				937B63CC09E766D200A671DD /* DerivedSources.make */,
1379
				937B63CC09E766D200A671DD /* DerivedSources.make */,
1380
				A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */,
1377
				F692A8540255597D01FF60F7 /* create_hash_table */,
1381
				F692A8540255597D01FF60F7 /* create_hash_table */,
1378
				14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */,
1382
				14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */,
1379
				867FC35F11B763950025105E /* JavaScriptCore.JSVALUE32_64only.exp */,
1383
				867FC35F11B763950025105E /* JavaScriptCore.JSVALUE32_64only.exp */,
Lines 1608-1613 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
1608
				BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */,
1612
				BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */,
1609
				BC8149AF12F89F53007B2C32 /* HeaderDetection.h */,
1613
				BC8149AF12F89F53007B2C32 /* HeaderDetection.h */,
1610
				BC87CDB810712ACA000614CF /* JSONObject.lut.h */,
1614
				BC87CDB810712ACA000614CF /* JSONObject.lut.h */,
1615
				A7C225CD1399849C00FF1662 /* KeywordLookup.h */,
1611
				BC18C52D0E16FCE100B34460 /* Lexer.lut.h */,
1616
				BC18C52D0E16FCE100B34460 /* Lexer.lut.h */,
1612
				BC18C5290E16FCC200B34460 /* MathObject.lut.h */,
1617
				BC18C5290E16FCC200B34460 /* MathObject.lut.h */,
1613
				BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */,
1618
				BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */,
Lines 2547-2552 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec5
2547
				651DCA04136A6FEF00F74194 /* PassTraits.h in Headers */,
2552
				651DCA04136A6FEF00F74194 /* PassTraits.h in Headers */,
2548
				14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
2553
				14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
2549
				86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */,
2554
				86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */,
2555
				A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */,
2550
			);
2556
			);
2551
			runOnlyForDeploymentPostprocessing = 0;
2557
			runOnlyForDeploymentPostprocessing = 0;
2552
		};
2558
		};
- a/Source/JavaScriptCore/KeywordLookupGenerator.py +180 lines
Line 0 a/Source/JavaScriptCore/KeywordLookupGenerator.py_sec1
1
# Copyright (C) 2010 Apple Inc. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
5
# are met:
6
# 1. Redistributions of source code must retain the above copyright
7
#    notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
#    notice, this list of conditions and the following disclaimer in the
10
#    documentation and/or other materials provided with the distribution.
11
#
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
13
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
16
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
17
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
18
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
20
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24
import sys
25
import string
26
import operator
27
28
keywordsText = open(sys.argv[1]).read()
29
30
# Observed weights of the most common keywords, rounded to 2.s.d
31
keyWordWeights = {
32
    "catch": 0.01,
33
    "try": 0.01,
34
    "while": 0.01,
35
    "case": 0.01,
36
    "break": 0.01,
37
    "new": 0.01,
38
    "in": 0.01,
39
    "typeof": 0.02,
40
    "true": 0.02,
41
    "false": 0.02,
42
    "for": 0.03,
43
    "null": 0.03,
44
    "else": 0.03,
45
    "return": 0.13,
46
    "var": 0.13,
47
    "if": 0.16,
48
    "function": 0.18,
49
    "this": 0.18,
50
}
51
52
53
def allWhitespace(str):
54
    for c in str:
55
        if not(c in string.whitespace):
56
            return False
57
    return True
58
59
60
def parseKeywords(keywordsText):
61
    lines = keywordsText.split("\n")
62
    lines = [line.split("#")[0] for line in lines]
63
    lines = [line for line in lines if (not allWhitespace(line))]
64
    name = lines[0].split()
65
    terminator = lines[-1]
66
    if not name[0] == "@begin":
67
        raise Exception("expected description beginning with @begin")
68
    if not terminator == "@end":
69
        raise Exception("expected description ending with @end")
70
71
    lines = lines[1:-1]  # trim off the old heading
72
    return [line.split() for line in lines]
73
74
75
def makePadding(size):
76
    str = ""
77
    for i in range(size):
78
        str = str + " "
79
    return str
80
81
82
class Trie:
83
    def __init__(self, prefix):
84
        self.prefix = prefix
85
        self.keys = {}
86
        self.value = None
87
88
    def insert(self, key, value):
89
        if len(key) == 0:
90
            self.value = value
91
            return
92
        if not (key[0] in self.keys):
93
            self.keys[key[0]] = Trie(key[0])
94
        self.keys[key[0]].insert(key[1:], value)
95
96
    def coalesce(self):
97
        keys = {}
98
        for k, v in self.keys.items():
99
            t = v.coalesce()
100
            keys[t.prefix] = t
101
        self.keys = keys
102
        if self.value != None:
103
            return self
104
        if len(self.keys) != 1:
105
            return self
106
        (prefix, suffix) = self.keys.items()[0]
107
        res = Trie(self.prefix + prefix)
108
        res.value = suffix.value
109
        res.keys = suffix.keys
110
        return res
111
112
    def fillOut(self, prefix=""):
113
        self.fullPrefix = prefix + self.prefix
114
        weight = 0
115
        if self.fullPrefix in keyWordWeights:
116
            weight = weight + keyWordWeights[self.fullPrefix]
117
        self.selfWeight = weight
118
        for trie in self.keys.values():
119
            trie.fillOut(self.fullPrefix)
120
            weight = weight + trie.weight
121
        self.keys = [(trie.prefix, trie) for trie in sorted(self.keys.values(), key=operator.attrgetter('weight'), reverse=True)]
122
        self.weight = weight
123
124
    def printSubTreeAsC(self, indent):
125
        str = makePadding(indent)
126
127
        if self.value != None:
128
            print(str + "if (!isIdentPart(code[%d])) {" % (len(self.fullPrefix)))
129
            print(str + "    internalShift<%d, false>();" % len(self.fullPrefix))
130
            print(str + "    return " + self.value + ";")
131
            print(str + "}")
132
        rootIndex = len(self.fullPrefix)
133
        itemCount = 0
134
        for k, trie in self.keys:
135
            baseIndex = rootIndex
136
            if (baseIndex > 0) and ((len(k) % 2) == 1) and (len(k) > 2) and (len(k) != 5):
137
                baseIndex = baseIndex - 1
138
                k = trie.fullPrefix[baseIndex] + k
139
            test = [("'%s'" % c) for c in k]
140
            if len(test) == 1:
141
                comparison = "code[%d] == %s" % (baseIndex, test[0])
142
            else:
143
                base = "code"
144
                if baseIndex > 0:
145
                    base = "code + %d" % baseIndex
146
                comparison = ("COMPARE_CHARACTERS%d(%s, " % (len(test), base)) + ", ".join(test) + ")"
147
            if itemCount == 0:
148
                print(str + "if (" + comparison + ") {")
149
            else:
150
                print(str + "else if (" + comparison + ") {")
151
152
            trie.printSubTreeAsC(indent + 4)
153
            itemCount = itemCount + 1
154
            print(str + "}")
155
156
    def maxLength(self):
157
        max = len(self.fullPrefix)
158
        for (_, trie) in self.keys:
159
            l = trie.maxLength()
160
            if l > max:
161
                max = l
162
        return max
163
164
    def printAsC(self):
165
        # max length + 1 so we don't need to do any bounds checking at all
166
        print("static const int maxTokenLength = %d;" % (self.maxLength() + 1))
167
        print("const ptrdiff_t remaining = m_codeEnd - m_code;")
168
        print("if ((remaining >= maxTokenLength) && !(lexType & IgnoreReservedWords)) {")
169
        print("    const UChar* code = m_code;")
170
        self.printSubTreeAsC(4)
171
        print("}")
172
173
keywords = parseKeywords(keywordsText)
174
trie = Trie("")
175
for k, v in keywords:
176
    trie.insert(k, v)
177
trie.coalesce()
178
trie.fillOut()
179
print("// This file was generated by KeywordLookupGenerator.py.  Do not edit.")
180
trie.printAsC()
- a/Source/JavaScriptCore/make-generated-sources.sh +1 lines
Lines 4-9 export SRCROOT=$PWD a/Source/JavaScriptCore/make-generated-sources.sh_sec1
4
export WebCore=$PWD
4
export WebCore=$PWD
5
export CREATE_HASH_TABLE="$SRCROOT/create_hash_table"
5
export CREATE_HASH_TABLE="$SRCROOT/create_hash_table"
6
export CREATE_REGEXP_TABLES="$SRCROOT/create_regex_tables"
6
export CREATE_REGEXP_TABLES="$SRCROOT/create_regex_tables"
7
export CREATE_KEYWORD_LOOKUP="$SRCROOT/KeywordLookupGenerator.py"
7
8
8
mkdir -p DerivedSources/JavaScriptCore
9
mkdir -p DerivedSources/JavaScriptCore
9
cd DerivedSources/JavaScriptCore
10
cd DerivedSources/JavaScriptCore
- a/Source/JavaScriptCore/parser/Lexer.cpp -11 / +68 lines
Lines 221-226 static const unsigned short typesOfASCIICharacters[128] = { a/Source/JavaScriptCore/parser/Lexer.cpp_sec1
221
/* 127 - Delete             */ CharacterInvalid,
221
/* 127 - Delete             */ CharacterInvalid,
222
};
222
};
223
223
224
#if CPU(NEEDS_ALIGNED_ACCESS)
225
226
#define COMPARE_CHARACTERS2(address, char1, char2) \
227
    (((address)[0] == char1) && ((address)[1] == char2))
228
#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \
229
    (COMPARE_CHARACTERS2(address, char1, char2) && COMPARE_CHARACTERS2((address) + 2, char3, char4))
230
231
#else
232
233
#if CPU(BIG_ENDIAN)
234
#define CHARPAIR_TOUINT32(a, b) ((((uint32_t)(a)) << 16) + (uint32_t)(b))
235
#define CHARQUAD_TOUINT64(a, b, c, d) ((((uint64_t)(CHARPAIR_TOUINT32(a, b))) << 32) + CHARPAIR_TOUINT32(c, d))
236
#else
237
#define CHARPAIR_TOUINT32(a, b) ((((uint32_t)(b)) << 16) + (uint32_t)(a))
238
#define CHARQUAD_TOUINT64(a, b, c, d) ((((uint64_t)(CHARPAIR_TOUINT32(c, d))) << 32) + CHARPAIR_TOUINT32(a, b))
239
#endif
240
241
#define COMPARE_CHARACTERS2(address, char1, char2) \
242
    (((uint32_t*)(address))[0] == CHARPAIR_TOUINT32(char1, char2))
243
#if CPU(X86_64)
244
245
#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \
246
    (((uint64_t*)(address))[0] == CHARQUAD_TOUINT64(char1, char2, char3, char4))
247
#else
248
#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \
249
    (COMPARE_CHARACTERS2(address, char1, char2) && COMPARE_CHARACTERS2((address) + 2, char3, char4))
250
#endif
251
252
#endif
253
254
#define COMPARE_CHARACTERS3(address, char1, char2, char3) \
255
    (COMPARE_CHARACTERS2(address, char1, char2) && ((address)[2] == (char3)))
256
#define COMPARE_CHARACTERS5(address, char1, char2, char3, char4, char5) \
257
    (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && ((address)[4] == (char5)))
258
#define COMPARE_CHARACTERS6(address, char1, char2, char3, char4, char5, char6) \
259
    (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS2(address + 4, char5, char6))
260
#define COMPARE_CHARACTERS8(address, char1, char2, char3, char4, char5, char6, char7, char8) \
261
    (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS4(address + 4, char5, char6, char7, char8))
262
263
224
Lexer::Lexer(JSGlobalData* globalData)
264
Lexer::Lexer(JSGlobalData* globalData)
225
    : m_isReparsing(false)
265
    : m_isReparsing(false)
226
    , m_globalData(globalData)
266
    , m_globalData(globalData)
Lines 271-284 void Lexer::setCode(const SourceCode& source, ParserArena& arena) a/Source/JavaScriptCore/parser/Lexer.cpp_sec2
271
    ASSERT(currentOffset() == source.startOffset());
311
    ASSERT(currentOffset() == source.startOffset());
272
}
312
}
273
313
274
ALWAYS_INLINE void Lexer::shift()
314
template <int shiftAmount, bool shouldBoundsCheck> ALWAYS_INLINE void Lexer::internalShift()
275
{
315
{
276
    // Faster than an if-else sequence
316
    if (shouldBoundsCheck) {
277
    ASSERT(m_current != -1);
317
        // Faster than an if-else sequence
278
    m_current = -1;
318
        ASSERT(m_current != -1);
279
    ++m_code;
319
        m_current = -1;
280
    if (LIKELY(m_code < m_codeEnd))
320
        m_code += shiftAmount;
321
        if (LIKELY(m_code < m_codeEnd))
322
            m_current = *m_code;
323
    } else {
324
        m_code += shiftAmount;
281
        m_current = *m_code;
325
        m_current = *m_code;
326
    }
327
}
328
329
ALWAYS_INLINE void Lexer::shift()
330
{
331
    internalShift<1, true>();
282
}
332
}
283
333
284
ALWAYS_INLINE int Lexer::peek(int offset)
334
ALWAYS_INLINE int Lexer::peek(int offset)
Lines 401-409 inline void Lexer::record16(int c) a/Source/JavaScriptCore/parser/Lexer.cpp_sec3
401
451
402
template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer::parseIdentifier(JSTokenData* lvalp, unsigned lexType)
452
template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer::parseIdentifier(JSTokenData* lvalp, unsigned lexType)
403
{
453
{
404
    bool bufferRequired = false;
454
455
#include "KeywordLookup.h"
456
405
    const UChar* identifierStart = currentCharacter();
457
    const UChar* identifierStart = currentCharacter();
406
    int identifierLength;
458
    bool bufferRequired = false;
407
459
408
    while (true) {
460
    while (true) {
409
        if (LIKELY(isIdentPart(m_current))) {
461
        if (LIKELY(isIdentPart(m_current))) {
Lines 430-436 template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer::parseIde a/Source/JavaScriptCore/parser/Lexer.cpp_sec4
430
            record16(character);
482
            record16(character);
431
        identifierStart = currentCharacter();
483
        identifierStart = currentCharacter();
432
    }
484
    }
433
485
    
486
    int identifierLength;
434
    const Identifier* ident = 0;
487
    const Identifier* ident = 0;
435
    if (shouldCreateIdentifier) {
488
    if (shouldCreateIdentifier) {
436
        if (!bufferRequired)
489
        if (!bufferRequired)
Lines 452-459 template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer::parseIde a/Source/JavaScriptCore/parser/Lexer.cpp_sec5
452
    if (LIKELY(!bufferRequired && !(lexType & IgnoreReservedWords))) {
505
    if (LIKELY(!bufferRequired && !(lexType & IgnoreReservedWords))) {
453
        ASSERT(shouldCreateIdentifier);
506
        ASSERT(shouldCreateIdentifier);
454
        // Keywords must not be recognized if there was an \uXXXX in the identifier.
507
        // Keywords must not be recognized if there was an \uXXXX in the identifier.
455
        const HashEntry* entry = m_keywordTable.entry(m_globalData, *ident);
508
        if (remaining < maxTokenLength) {
456
        return entry ? static_cast<JSTokenType>(entry->lexerValue()) : IDENT;
509
            const HashEntry* entry = m_keywordTable.entry(m_globalData, *ident);
510
            ASSERT((remaining < maxTokenLength) || !entry);
511
            return entry ? static_cast<JSTokenType>(entry->lexerValue()) : IDENT;
512
        }
513
        return IDENT;
457
    }
514
    }
458
515
459
    m_buffer16.resize(0);
516
    m_buffer16.resize(0);
- a/Source/JavaScriptCore/parser/Lexer.h +1 lines
Lines 113-118 namespace JSC { a/Source/JavaScriptCore/parser/Lexer.h_sec1
113
113
114
        ALWAYS_INLINE bool lastTokenWasRestrKeyword() const;
114
        ALWAYS_INLINE bool lastTokenWasRestrKeyword() const;
115
115
116
        template <int shiftAmount, bool shouldBoundsCheck> void internalShift();
116
        template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned);
117
        template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned);
117
        template <bool shouldBuildStrings> ALWAYS_INLINE bool parseString(JSTokenData* lvalp, bool strictMode);
118
        template <bool shouldBuildStrings> ALWAYS_INLINE bool parseString(JSTokenData* lvalp, bool strictMode);
118
        ALWAYS_INLINE void parseHex(double& returnValue);
119
        ALWAYS_INLINE void parseHex(double& returnValue);

Return to Bug 61913