diff options
-rw-r--r-- | src/compiler.js | 1 | ||||
-rw-r--r-- | src/intertyper.js | 143 | ||||
-rw-r--r-- | tests/test_core.py | 3 | ||||
-rw-r--r-- | tests/test_other.py | 4 | ||||
-rw-r--r-- | tools/autodebugger.py | 4 |
5 files changed, 81 insertions, 74 deletions
diff --git a/src/compiler.js b/src/compiler.js index d490f454..ac1b0ec8 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -318,4 +318,5 @@ if (ll_file) { //var M = keys(tokenCacheMisses).map(function(m) { return [m, misses[m]] }).sort(function(a, b) { return a[1] - b[1] }); //printErr(dump(M.slice(M.length-10))); +//printErr('hits: ' + hits); diff --git a/src/intertyper.js b/src/intertyper.js index 94a096f3..9414a1d4 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -6,12 +6,12 @@ var fastPaths = 0, slowPaths = 0; var tokenCache = {}; -['=', 'i32', 'label', ';', '4', '0', '1', '2', '255', 'align', 'i8*', 'i8', 'i16', 'getelementptr', 'inbounds', 'unnamed_addr', 'x', 'load', 'preds', 'br', 'i32*', 'i1', 'store', '<label>', 'constant', 'c', 'private', 'null', 'internal', 'to', 'bitcast', 'define', 'nounwind', 'nocapture', '%this', 'call', '...'].forEach(function(text) { tokenCache[text] = { text: text } }); +[',', 'i32', 'label', ';', '4', '0', '1', '2', '255', 'align', 'i8*', 'i8', 'i16', 'getelementptr', 'inbounds', 'unnamed_addr', 'x', 'load', 'preds', 'br', 'i32*', 'i1', 'store', '<label>', 'constant', 'c', 'private', 'null', 'internal', 'to', 'bitcast', 'define', 'nounwind', 'nocapture', '%this', 'call', '...'].forEach(function(text) { tokenCache[text] = { text: text } }); //var tokenCacheMisses = {}; // Line tokenizer -function tokenize(text, lineNum) { +function tokenize(text, lineNum, indent) { var tokens = []; var quotes = 0; var lastToken = null; @@ -63,12 +63,7 @@ function tokenize(text, lineNum) { tokens.splice(openBrace, tokens.length-openBrace+1); tokens.push(token); token.type = '{'; - token.text = '{ ' + token.text + ' }'; - var pointingLevelsToAdd = pointingLevels(text) - pointingLevels(token.text); - while (pointingLevelsToAdd > 0) { - token.text += '*'; - pointingLevelsToAdd--; - } + token.text = '{ ' + token.text + ' ' + text; lastToken = token; } else { tokens.push(token); @@ -82,78 +77,67 @@ function tokenize(text, lineNum) { segments.pop(); var len = segments.length; var i = -1; - var curr = ''; + var start = 0; var segment, letter; for (var s = 0; s < len; s++) { segment = segments[s]; i += segment.length + 1; letter = lineText[i]; - curr += segment; switch (letter) { case ' ': if (totalEnclosing == 0 && quotes == 0) { - makeToken(curr); - curr = ''; + makeToken(lineText.substring(start, i)); + start = i+1; } else { - curr += ' '; } break; case '"': if (totalEnclosing == 0) { if (quotes == 0) { - if (curr == '@' || curr == '%') { - curr += '"'; + if (start === i-1 && (lineText[start] == '@' || lineText[start] == '%')) { } else { - makeToken(curr); - curr = '"'; + makeToken(lineText.substring(start, i)); + start = i; } } else { - makeToken(curr + '"'); - curr = ''; + makeToken(lineText.substring(start, i+1)); + start = i+1; } - } else { - curr += '"'; } quotes = 1-quotes; break; case ',': if (totalEnclosing == 0 && quotes == 0) { - makeToken(curr); - curr = ''; - tokens.push({ text: ',' }); - } else { - curr += ','; + makeToken(lineText.substring(start, i)); + start = i+1; + tokens.push(tokenCache[',']); } break; default: assert(letter in enclosers); if (quotes) { - curr += letter; break; } if (letter in ENCLOSER_STARTERS) { if (totalEnclosing == 0) { - makeToken(curr); - curr = ''; + makeToken(lineText.substring(start, i)); + start = i; } - curr += letter; enclosers[letter]++; totalEnclosing++; } else { enclosers[enclosers[letter]]--; totalEnclosing--; if (totalEnclosing == 0) { - makeToken(curr + letter); - curr = ''; - } else { - curr += letter; + makeToken(lineText.substring(start, i+1)); + start = i+1; } } } } var newItem = { tokens: tokens, - indent: lineText.search(/[^ ]/), + indent: indent || lineText.search(/[^ ]/), lineNum: lineNum || 0 }; return newItem; @@ -291,10 +275,6 @@ function intertyper(lines, sidePass, baseLineNums) { function triager(item) { assert(!item.intertype); - if (item.indent == 2 && (eq = findTokenText(item, '=')) >= 0) { - item.assignTo = toNiceIdent(combineTokens(item.tokens.slice(0, eq)).text); - item.tokens = item.tokens.slice(eq+1); - } var token0Text = item.tokens[0].text; var token1Text = item.tokens[1] ? item.tokens[1].text : null; var tokensLength = item.tokens.length; @@ -345,7 +325,7 @@ function intertyper(lines, sidePass, baseLineNums) { return labelHandler(item); if (tokensLength >= 4 && token0Text == 'declare') return externalHandler(item); - if (tokensLength >= 3 && token1Text == '=') + if (item.assignTo) return globalHandler(item); if (tokensLength >= 4 && token0Text == 'define' && item.tokens.slice(-1)[0].text == '{') @@ -458,15 +438,15 @@ function intertyper(lines, sidePass, baseLineNums) { } } - cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 2); - if (item.tokens[2].text == 'alias') { - cleanOutTokens(LLVM.LINKAGES, item.tokens, 3); - cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 3); + cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 0); + if (item.tokens[0].text == 'alias') { + cleanOutTokens(LLVM.LINKAGES, item.tokens, 1); + cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 1); var last = getTokenIndexByText(item.tokens, ';'); var ret = { intertype: 'alias', - ident: toNiceIdent(item.tokens[0].text), - value: parseLLVMSegment(item.tokens.slice(3, last)), + ident: item.assignTo, + value: parseLLVMSegment(item.tokens.slice(1, last)), lineNum: item.lineNum }; ret.type = ret.value.type; @@ -476,18 +456,18 @@ function intertyper(lines, sidePass, baseLineNums) { } return ret; } - if (item.tokens[2].text == 'type') { + if (item.tokens[0].text == 'type') { var fields = []; var packed = false; - if (Runtime.isNumberType(item.tokens[3].text)) { + if (Runtime.isNumberType(item.tokens[1].text)) { // Clang sometimes has |= i32| instead of |= { i32 }| - fields = [item.tokens[3].text]; - } else if (item.tokens[3].text != 'opaque') { - if (item.tokens[3].type == '<') { + fields = [item.tokens[1].text]; + } else if (item.tokens[1].text != 'opaque') { + if (item.tokens[1].type == '<') { packed = true; - item.tokens[3] = item.tokens[3].item.tokens[0]; + item.tokens[1] = item.tokens[1].item.tokens[0]; } - var subTokens = item.tokens[3].tokens; + var subTokens = item.tokens[1].tokens; if (subTokens) { subTokens.push({text:','}); while (subTokens[0]) { @@ -500,36 +480,36 @@ function intertyper(lines, sidePass, baseLineNums) { } return { intertype: 'type', - name_: item.tokens[0].text, + name_: item.assignTo, fields: fields, packed: packed, lineNum: item.lineNum }; } else { // variable - var ident = item.tokens[0].text; + var ident = item.assignTo; var private_ = findTokenText(item, 'private') >= 0 || findTokenText(item, 'internal') >= 0; var named = findTokenText(item, 'unnamed_addr') < 0; - cleanOutTokens(LLVM.GLOBAL_MODIFIERS, item.tokens, [2, 3]); + cleanOutTokens(LLVM.GLOBAL_MODIFIERS, item.tokens, [0, 1]); var external = false; - if (item.tokens[2].text === 'external') { + if (item.tokens[0].text === 'external') { external = true; - item.tokens.splice(2, 1); + item.tokens.splice(0, 1); } var ret = { intertype: 'globalVariable', - ident: toNiceIdent(ident), - type: item.tokens[2].text, + ident: ident, + type: item.tokens[0].text, external: external, private_: private_, named: named, lineNum: item.lineNum }; noteGlobalVariable(ret); - if (ident == '@llvm.global_ctors') { + if (ident == '_llvm_global_ctors') { ret.ctors = []; - if (item.tokens[3].item) { - var subTokens = item.tokens[3].item.tokens; + if (item.tokens[1].item) { + var subTokens = item.tokens[1].item.tokens; splitTokenList(subTokens).forEach(function(segment) { var parsed = parseLLVMSegment(segment); assert(parsed.intertype === 'structvalue'); @@ -542,14 +522,14 @@ function intertyper(lines, sidePass, baseLineNums) { }); } } else if (!external) { - if (item.tokens[3] && item.tokens[3].text != ';') { - if (item.tokens[3].text == 'c') { - item.tokens.splice(3, 1); + if (item.tokens[1] && item.tokens[1].text != ';') { + if (item.tokens[1].text == 'c') { + item.tokens.splice(1, 1); } - if (item.tokens[3].text in PARSABLE_LLVM_FUNCTIONS) { - ret.value = parseLLVMFunctionCall(item.tokens.slice(2)); + if (item.tokens[1].text in PARSABLE_LLVM_FUNCTIONS) { + ret.value = parseLLVMFunctionCall(item.tokens); } else { - ret.value = scanConst(item.tokens[3], ret.type); + ret.value = scanConst(item.tokens[1], ret.type); } } else { ret.value = { intertype: 'value', ident: '0', value: '0', type: ret.type }; @@ -1133,7 +1113,27 @@ function intertyper(lines, sidePass, baseLineNums) { //var time = Date.now(); - var t = tokenize(line.lineText, line.lineNum); + // parse out the assignment + var indent = 0, assignTo = null; + if (phase === 'pre') { + var m = /^([%@\w\d\._\-]+|[%@]"[^"]+") = (.*)/.exec(line.lineText); + if (m) { + assignTo = m[1]; + line.lineText = m[2]; + } + } else if (phase === 'funcs') { + var m = /^ ([%@\w\d\._\-]+|[%@]"[^"]+") = (.*)/.exec(line.lineText); + if (m) { + indent = 2; + assignTo = m[1]; + line.lineText = m[2]; + } + } + + var t = tokenize(line.lineText, line.lineNum, indent); + if (assignTo) { + t.assignTo = t.tokens[0].text !== 'type' ? toNiceIdent(assignTo) : assignTo; + } item = triager(t); /* @@ -1150,7 +1150,7 @@ function intertyper(lines, sidePass, baseLineNums) { return finalResults; } -// intertyper profiler +// intertyper profiling /* var interProf = {}; @@ -1158,4 +1158,5 @@ function dumpInterProf() { printErr('\nintertyper/' + phase + ' (ms | n): ' + JSON.stringify(keys(interProf).sort(function(x, y) { return interProf[y].ms - interProf[x].ms }).map(function(x) { return x + ' : ' + interProf[x].ms + ' | ' + interProf[x].n }), null, ' ') + '\n'); } */ +//var hits = 0; diff --git a/tests/test_core.py b/tests/test_core.py index 87925082..c3e6421b 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -7826,6 +7826,7 @@ def process(filename): self.do_run(src, expected) def test_unistd_unlink(self): + self.clear() if self.emcc_args is None: return self.skip('requires emcc') if not self.is_le32(): return self.skip('le32 needed for inline js') for fs in ['MEMFS', 'NODEFS']: @@ -7834,6 +7835,7 @@ def process(filename): self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS]) def test_unistd_links(self): + self.clear() if not self.is_le32(): return self.skip('le32 needed for inline js') for fs in ['MEMFS', 'NODEFS']: src = open(path_from_root('tests', 'unistd', 'links.c'), 'r').read() @@ -7847,6 +7849,7 @@ def process(filename): self.do_run(src, expected) def test_unistd_io(self): + self.clear() if not self.is_le32(): return self.skip('le32 needed for inline js') if self.run_name == 'o2': return self.skip('non-asm optimized builds can fail with inline js') if self.emcc_args is None: return self.skip('requires emcc') diff --git a/tests/test_other.py b/tests/test_other.py index c38a35d8..c8b6d4b1 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -31,8 +31,8 @@ Most normal gcc/g++ options will work, for example: --version Display compiler version information Options that are modified or new in %s include: - -O0 No optimizations (default) -''' % (shortcompiler, shortcompiler), output[0].replace('\r', ''), output[1].replace('\r', '')) + + -O0 No optimizations (default)''' % (shortcompiler, shortcompiler), output[0].replace('\r', ''), output[1].replace('\r', '')) # emcc src.cpp ==> writes a.out.js self.clear() diff --git a/tools/autodebugger.py b/tools/autodebugger.py index c74e56d2..df9594b3 100644 --- a/tools/autodebugger.py +++ b/tools/autodebugger.py @@ -282,7 +282,9 @@ for i in range(len(lines)): lines_added += 1 f = open(ofilename, 'w') -f.write('\n'.join(lines) + '\n' + POSTAMBLE + '\n') +ll = '\n'.join(lines) +meta_start = ll.find('\n!') +f.write(ll[:meta_start] + '\n' + POSTAMBLE + '\n' + ll[meta_start:]) f.close() print 'Success.' |