diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-09-21 10:40:37 -0500 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-09-23 14:33:24 -0700 |
commit | 9fbb6068043818ea38764492fffb3d65ad4cd6dd (patch) | |
tree | 7c8d4a160e62ee22c3762bd24a850bd625360ed1 | |
parent | 5de096548065d5e4e9992bd4791997eca145a524 (diff) |
deframeworkify the rest of intertyper
-rw-r--r-- | src/intertyper.js | 1245 |
1 files changed, 591 insertions, 654 deletions
diff --git a/src/intertyper.js b/src/intertyper.js index b6d96482..a00846d0 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -256,7 +256,7 @@ function intertyper(lines, sidePass, baseLineNums) { if (mainPass && /^}.*/.test(line)) { inFunction = false; if (mainPass) { - var func = funcHeader.processItem(tokenizer.processItem({ lineText: currFunctionLines[0], lineNum: currFunctionLineNum }, true))[0]; + var func = funcHeaderHandler(tokenizer.processItem({ lineText: currFunctionLines[0], lineNum: currFunctionLineNum }, true)); if (SKIP_STACK_IN_SMALL && /emscripten_autodebug/.exec(func.ident)) { warnOnce('Disabling SKIP_STACK_IN_SMALL because we are apparently processing autodebugger data'); @@ -285,399 +285,372 @@ function intertyper(lines, sidePass, baseLineNums) { return ret.filter(function(item) { return item.lineText && (item.lineText[0] != ';' || !mainPass); }); } - substrate.addActor('Triager', { - processItem: function _triager(item) { - function triage() { - assert(!item.intertype); - var token0Text = item.tokens[0].text; - var token1Text = item.tokens[1] ? item.tokens[1].text : null; - var tokensLength = item.tokens.length; - if (item.indent === 2) { - if (tokensLength >= 5 && - (token0Text == 'store' || token1Text == 'store')) - return 'Store'; - if (tokensLength >= 3 && token0Text == 'br') - return 'Branch'; - if (tokensLength >= 2 && token0Text == 'ret') - return 'Return'; - if (tokensLength >= 2 && token0Text == 'switch') - return 'Switch'; - if (token0Text == 'unreachable') - return 'Unreachable'; - if (tokensLength >= 3 && token0Text == 'indirectbr') - return 'IndirectBr'; - if (tokensLength >= 2 && token0Text == 'resume') - return 'Resume'; - if (tokensLength >= 3 && - (token0Text == 'load' || token1Text == 'load')) - return 'Load'; - if (tokensLength >= 3 && - token0Text in MATHOPS) - return 'Mathops'; - if (tokensLength >= 3 && token0Text == 'bitcast') - return 'Bitcast'; - if (tokensLength >= 3 && token0Text == 'getelementptr') - return 'GEP'; - if (tokensLength >= 2 && token0Text == 'alloca') - return 'Alloca'; - if (tokensLength >= 3 && token0Text == 'extractvalue') - return 'ExtractValue'; - if (tokensLength >= 3 && token0Text == 'insertvalue') - return 'InsertValue'; - if (tokensLength >= 3 && token0Text == 'phi') - return 'Phi'; - if (tokensLength >= 3 && token0Text == 'va_arg') - return 'va_arg'; - if (tokensLength >= 3 && token0Text == 'landingpad') - return 'Landingpad'; - if (token0Text == 'fence') - return '/dev/null'; - } else if (item.indent === 0) { - if ((tokensLength >= 1 && token0Text.substr(-1) == ':') || - (tokensLength >= 3 && token1Text == '<label>') || - (tokensLength >= 2 && token1Text == ':')) - return 'Label'; - if (tokensLength >= 4 && token0Text == 'declare') - return 'External'; - if (tokensLength >= 3 && token1Text == '=') - return 'Global'; - if (tokensLength >= 4 && token0Text == 'define' && - item.tokens.slice(-1)[0].text == '{') - return 'FuncHeader'; - if (tokensLength >= 1 && token0Text == '}') - return 'FuncEnd'; - if (token0Text == 'module' && token1Text == 'asm') { - warn('Ignoring module asm: ' + item.tokens[2].text); - return '/dev/null'; - } - if (token0Text == 'attributes') - return '/dev/null'; - } - if (tokensLength >= 3 && (token0Text == 'call' || token1Text == 'call')) - return 'Call'; - if (token0Text == 'target') { - if (token1Text == 'triple') { - var triple = item.tokens[3].text; - triple = triple.substr(1, triple.length-2); - var expected = TARGET_LE32 ? 'le32-unknown-nacl' : 'i386-pc-linux-gnu'; - if (triple !== expected) { - warn('using an unexpected LLVM triple: ' + [triple, ' !== ', expected] + ' (are you using emcc for everything and not clang?)'); - } - } - return '/dev/null'; - } - if (token0Text == ';') - return '/dev/null'; - if (tokensLength >= 3 && token0Text == 'invoke') - return 'Invoke'; - if (tokensLength >= 3 && token0Text == 'atomicrmw' || token0Text == 'cmpxchg') - return 'Atomic'; - throw 'Invalid token, cannot triage: ' + dump(item); + 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; + if (item.indent === 2) { + if (tokensLength >= 5 && + (token0Text == 'store' || token1Text == 'store')) + return storeHandler(item); + if (tokensLength >= 3 && token0Text == 'br') + return branchHandler(item); + if (tokensLength >= 2 && token0Text == 'ret') + return returnHandler(item); + if (tokensLength >= 2 && token0Text == 'switch') + return switchHandler(item); + if (token0Text == 'unreachable') + return unreachableHandler(item); + if (tokensLength >= 3 && token0Text == 'indirectbr') + return indirectBrHandler(item); + if (tokensLength >= 2 && token0Text == 'resume') + return resumeHandler(item); + if (tokensLength >= 3 && + (token0Text == 'load' || token1Text == 'load')) + return loadHandler(item); + if (tokensLength >= 3 && + token0Text in MATHOPS) + return mathopsHandler(item); + if (tokensLength >= 3 && token0Text == 'bitcast') + return bitcastHandler(item); + if (tokensLength >= 3 && token0Text == 'getelementptr') + return GEPHandler(item); + if (tokensLength >= 2 && token0Text == 'alloca') + return allocaHandler(item); + if (tokensLength >= 3 && token0Text == 'extractvalue') + return extractValueHandler(item); + if (tokensLength >= 3 && token0Text == 'insertvalue') + return insertValueHandler(item); + if (tokensLength >= 3 && token0Text == 'phi') + return phiHandler(item); + if (tokensLength >= 3 && token0Text == 'va_arg') + return va_argHandler(item); + if (tokensLength >= 3 && token0Text == 'landingpad') + return landingpadHandler(item); + if (token0Text == 'fence') + return null; + } else if (item.indent === 0) { + if ((tokensLength >= 1 && token0Text.substr(-1) == ':') || + (tokensLength >= 3 && token1Text == '<label>') || + (tokensLength >= 2 && token1Text == ':')) + return labelHandler(item); + if (tokensLength >= 4 && token0Text == 'declare') + return externalHandler(item); + if (tokensLength >= 3 && token1Text == '=') + return globalHandler(item); + if (tokensLength >= 4 && token0Text == 'define' && + item.tokens.slice(-1)[0].text == '{') + return funcHeaderHandler(item); + if (tokensLength >= 1 && token0Text == '}') + return funcEndHandler(item); + if (token0Text == 'module' && token1Text == 'asm') { + warn('Ignoring module asm: ' + item.tokens[2].text); + return null; } - var eq; - 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); + if (token0Text == 'attributes') + return null; + } + if (tokensLength >= 3 && (token0Text == 'call' || token1Text == 'call')) + return callHandler(item); + if (token0Text == 'target') { + if (token1Text == 'triple') { + var triple = item.tokens[3].text; + triple = triple.substr(1, triple.length-2); + var expected = TARGET_LE32 ? 'le32-unknown-nacl' : 'i386-pc-linux-gnu'; + if (triple !== expected) { + warn('using an unexpected LLVM triple: ' + [triple, ' !== ', expected] + ' (are you using emcc for everything and not clang?)'); + } } - this.forwardItem(item, triage()); - } - }); + return null; + } + if (token0Text == ';') + return null; + if (tokensLength >= 3 && token0Text == 'invoke') + return invokeHandler(item); + if (tokensLength >= 3 && token0Text == 'atomicrmw' || token0Text == 'cmpxchg') + return atomicHandler(item); + throw 'Invalid token, cannot triage: ' + dump(item); + } + + var extraResults = []; // Line parsers to intermediate form // globals: type or variable - substrate.addActor('Global', { - processItem: function _global(item) { - function scanConst(value, type) { - // Gets an array of constant items, separated by ',' tokens - function handleSegments(tokens) { - // Handle a single segment (after comma separation) - function handleSegment(segment) { - if (segment[1].text == 'null') { - return { intertype: 'value', ident: '0', type: 'i32' }; - } else if (segment[1].text == 'zeroinitializer') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'emptystruct', type: segment[0].text }; - } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) { - return parseLLVMFunctionCall(segment); - } else if (segment[1].type && segment[1].type == '{') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].tokens) }; - } else if (segment[1].type && segment[1].type == '<') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].item.tokens[0].tokens) }; - } else if (segment[1].type && segment[1].type == '[') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'list', type: segment[0].text, contents: handleSegments(segment[1].item.tokens) }; - } else if (segment.length == 2) { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'value', type: segment[0].text, ident: toNiceIdent(segment[1].text) }; - } else if (segment[1].text === 'c') { - // string - var text = segment[2].text; - text = text.substr(1, text.length-2); - return { intertype: 'string', text: text, type: 'i8*' }; - } else if (segment[1].text === 'blockaddress') { - return parseBlockAddress(segment); - } else { - throw 'Invalid segment: ' + dump(segment); - } - }; - return splitTokenList(tokens).map(handleSegment); - } - - Types.needAnalysis[type] = 0; - if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) { - return { value: toNiceIdent(value.text), type: type }; - } else if (value.text in ZEROINIT_UNDEF) { // undef doesn't really need initting, but why not - return { intertype: 'emptystruct', type: type }; - } else if (value.text && value.text[0] == '"') { - return { intertype: 'string', text: value.text.substr(1, value.text.length-2) }; - } else { - if (value.type == '<') { // <{ i8 }> etc. - value = value.item.tokens; - } - var contents; - if (value.item) { - // list of items - contents = value.item.tokens; - } else if (value.type == '{') { - // struct - contents = value.tokens; - } else if (value[0]) { - contents = value[0]; + function globalHandler(item) { + function scanConst(value, type) { + // Gets an array of constant items, separated by ',' tokens + function handleSegments(tokens) { + // Handle a single segment (after comma separation) + function handleSegment(segment) { + if (segment[1].text == 'null') { + return { intertype: 'value', ident: '0', type: 'i32' }; + } else if (segment[1].text == 'zeroinitializer') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'emptystruct', type: segment[0].text }; + } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) { + return parseLLVMFunctionCall(segment); + } else if (segment[1].type && segment[1].type == '{') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].tokens) }; + } else if (segment[1].type && segment[1].type == '<') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].item.tokens[0].tokens) }; + } else if (segment[1].type && segment[1].type == '[') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'list', type: segment[0].text, contents: handleSegments(segment[1].item.tokens) }; + } else if (segment.length == 2) { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'value', type: segment[0].text, ident: toNiceIdent(segment[1].text) }; + } else if (segment[1].text === 'c') { + // string + var text = segment[2].text; + text = text.substr(1, text.length-2); + return { intertype: 'string', text: text, type: 'i8*' }; + } else if (segment[1].text === 'blockaddress') { + return parseBlockAddress(segment); } else { - throw '// interfailzzzzzzzzzzzzzz ' + dump(value.item) + ' ::: ' + dump(value); + throw 'Invalid segment: ' + dump(segment); } - return { intertype: 'segments', contents: handleSegments(contents) }; - } + }; + return splitTokenList(tokens).map(handleSegment); } - cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 2); - if (item.tokens[2].text == 'alias') { - cleanOutTokens(LLVM.LINKAGES, item.tokens, 3); - cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 3); - var last = getTokenIndexByText(item.tokens, ';'); - var ret = { - intertype: 'alias', - ident: toNiceIdent(item.tokens[0].text), - value: parseLLVMSegment(item.tokens.slice(3, last)), - lineNum: item.lineNum - }; - ret.type = ret.value.type; - Types.needAnalysis[ret.type] = 0; - if (!NAMED_GLOBALS) { - Variables.globals[ret.ident].type = ret.type; + Types.needAnalysis[type] = 0; + if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) { + return { value: toNiceIdent(value.text), type: type }; + } else if (value.text in ZEROINIT_UNDEF) { // undef doesn't really need initting, but why not + return { intertype: 'emptystruct', type: type }; + } else if (value.text && value.text[0] == '"') { + return { intertype: 'string', text: value.text.substr(1, value.text.length-2) }; + } else { + if (value.type == '<') { // <{ i8 }> etc. + value = value.item.tokens; + } + var contents; + if (value.item) { + // list of items + contents = value.item.tokens; + } else if (value.type == '{') { + // struct + contents = value.tokens; + } else if (value[0]) { + contents = value[0]; + } else { + throw '// interfailzzzzzzzzzzzzzz ' + dump(value.item) + ' ::: ' + dump(value); } - return [ret]; + return { intertype: 'segments', contents: handleSegments(contents) }; } - if (item.tokens[2].text == 'type') { - var fields = []; - var packed = false; - if (Runtime.isNumberType(item.tokens[3].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 == '<') { - packed = true; - item.tokens[3] = item.tokens[3].item.tokens[0]; - } - var subTokens = item.tokens[3].tokens; - if (subTokens) { - subTokens.push({text:','}); - while (subTokens[0]) { - var stop = 1; - while ([','].indexOf(subTokens[stop].text) == -1) stop ++; - fields.push(combineTokens(subTokens.slice(0, stop)).text); - subTokens.splice(0, stop+1); - } - } + } + + cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 2); + if (item.tokens[2].text == 'alias') { + cleanOutTokens(LLVM.LINKAGES, item.tokens, 3); + cleanOutTokens(LLVM.VISIBILITIES, item.tokens, 3); + var last = getTokenIndexByText(item.tokens, ';'); + var ret = { + intertype: 'alias', + ident: toNiceIdent(item.tokens[0].text), + value: parseLLVMSegment(item.tokens.slice(3, last)), + lineNum: item.lineNum + }; + ret.type = ret.value.type; + Types.needAnalysis[ret.type] = 0; + if (!NAMED_GLOBALS) { + Variables.globals[ret.ident].type = ret.type; + } + return ret; + } + if (item.tokens[2].text == 'type') { + var fields = []; + var packed = false; + if (Runtime.isNumberType(item.tokens[3].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 == '<') { + packed = true; + item.tokens[3] = item.tokens[3].item.tokens[0]; } - return [{ - intertype: 'type', - name_: item.tokens[0].text, - fields: fields, - packed: packed, - lineNum: item.lineNum - }]; - } else { - // variable - var ident = item.tokens[0].text; - 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]); - var external = false; - if (item.tokens[2].text === 'external') { - external = true; - item.tokens.splice(2, 1); + var subTokens = item.tokens[3].tokens; + if (subTokens) { + subTokens.push({text:','}); + while (subTokens[0]) { + var stop = 1; + while ([','].indexOf(subTokens[stop].text) == -1) stop ++; + fields.push(combineTokens(subTokens.slice(0, stop)).text); + subTokens.splice(0, stop+1); + } } - Types.needAnalysis[item.tokens[2].text] = 0; - var ret = { - intertype: 'globalVariable', - ident: toNiceIdent(ident), - type: item.tokens[2].text, - external: external, - private_: private_, - named: named, - lineNum: item.lineNum - }; - if (!NAMED_GLOBALS) { - Variables.globals[ret.ident].type = ret.type; - Variables.globals[ret.ident].external = external; + } + return { + intertype: 'type', + name_: item.tokens[0].text, + fields: fields, + packed: packed, + lineNum: item.lineNum + }; + } else { + // variable + var ident = item.tokens[0].text; + 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]); + var external = false; + if (item.tokens[2].text === 'external') { + external = true; + item.tokens.splice(2, 1); + } + Types.needAnalysis[item.tokens[2].text] = 0; + var ret = { + intertype: 'globalVariable', + ident: toNiceIdent(ident), + type: item.tokens[2].text, + external: external, + private_: private_, + named: named, + lineNum: item.lineNum + }; + if (!NAMED_GLOBALS) { + Variables.globals[ret.ident].type = ret.type; + Variables.globals[ret.ident].external = external; + } + Types.needAnalysis[ret.type] = 0; + if (ident == '@llvm.global_ctors') { + ret.ctors = []; + if (item.tokens[3].item) { + var subTokens = item.tokens[3].item.tokens; + splitTokenList(subTokens).forEach(function(segment) { + var ctor = toNiceIdent(segment[1].tokens.slice(-1)[0].text); + ret.ctors.push(ctor); + if (ASM_JS) { // must export the global constructors from asm.js module, so mark as implemented and exported + Functions.implementedFunctions[ctor] = 'v'; + EXPORTED_FUNCTIONS[ctor] = 1; + } + }); } - Types.needAnalysis[ret.type] = 0; - if (ident == '@llvm.global_ctors') { - ret.ctors = []; - if (item.tokens[3].item) { - var subTokens = item.tokens[3].item.tokens; - splitTokenList(subTokens).forEach(function(segment) { - var ctor = toNiceIdent(segment[1].tokens.slice(-1)[0].text); - ret.ctors.push(ctor); - if (ASM_JS) { // must export the global constructors from asm.js module, so mark as implemented and exported - Functions.implementedFunctions[ctor] = 'v'; - EXPORTED_FUNCTIONS[ctor] = 1; - } - }); + } else if (!external) { + if (item.tokens[3] && item.tokens[3].text != ';') { + if (item.tokens[3].text == 'c') { + item.tokens.splice(3, 1); } - } 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[3].text in PARSABLE_LLVM_FUNCTIONS) { - ret.value = parseLLVMFunctionCall(item.tokens.slice(2)); - } else { - ret.value = scanConst(item.tokens[3], ret.type); - } + if (item.tokens[3].text in PARSABLE_LLVM_FUNCTIONS) { + ret.value = parseLLVMFunctionCall(item.tokens.slice(2)); } else { - ret.value = { intertype: 'value', ident: '0', value: '0', type: ret.type }; + ret.value = scanConst(item.tokens[3], ret.type); } + } else { + ret.value = { intertype: 'value', ident: '0', value: '0', type: ret.type }; } - return [ret]; } + return ret; } - }); + } // function header - var funcHeader = substrate.addActor('FuncHeader', { - processItem: function(item) { - item.tokens = item.tokens.filter(function(token) { - return !(token.text in LLVM.LINKAGES || token.text in LLVM.PARAM_ATTR || token.text in LLVM.FUNC_ATTR || token.text in LLVM.CALLING_CONVENTIONS); - }); - var params = parseParamTokens(item.tokens[2].item.tokens); - if (sidePass) dprint('unparsedFunctions', 'Processing function: ' + item.tokens[1].text); - return [{ - intertype: 'function', - ident: toNiceIdent(item.tokens[1].text), - returnType: item.tokens[0].text, - params: params, - hasVarArgs: hasVarArgs(params), - lineNum: item.lineNum, - }]; - } - }); + function funcHeaderHandler(item) { + item.tokens = item.tokens.filter(function(token) { + return !(token.text in LLVM.LINKAGES || token.text in LLVM.PARAM_ATTR || token.text in LLVM.FUNC_ATTR || token.text in LLVM.CALLING_CONVENTIONS); + }); + var params = parseParamTokens(item.tokens[2].item.tokens); + if (sidePass) dprint('unparsedFunctions', 'Processing function: ' + item.tokens[1].text); + return { + intertype: 'function', + ident: toNiceIdent(item.tokens[1].text), + returnType: item.tokens[0].text, + params: params, + hasVarArgs: hasVarArgs(params), + lineNum: item.lineNum, + }; + } // label - substrate.addActor('Label', { - processItem: function(item) { - var rawLabel = item.tokens[0].text.substr(-1) == ':' ? - '%' + item.tokens[0].text.substr(0, item.tokens[0].text.length-1) : - (item.tokens[1].text == '<label>' ? - '%' + item.tokens[2].text.substr(1) : - '%' + item.tokens[0].text) - var niceLabel = toNiceIdent(rawLabel); - return [{ - intertype: 'label', - ident: niceLabel, - lineNum: item.lineNum - }]; - } - }); - - // TODO: remove dis - substrate.addActor('Reintegrator', { - processItem: function(item) { - this.forwardItem(item, '/dev/stdout'); - } - }); + function labelHandler(item) { + var rawLabel = item.tokens[0].text.substr(-1) == ':' ? + '%' + item.tokens[0].text.substr(0, item.tokens[0].text.length-1) : + (item.tokens[1].text == '<label>' ? + '%' + item.tokens[2].text.substr(1) : + '%' + item.tokens[0].text) + var niceLabel = toNiceIdent(rawLabel); + return { + intertype: 'label', + ident: niceLabel, + lineNum: item.lineNum + }; + } // 'load' - substrate.addActor('Load', { - processItem: function(item) { - item.intertype = 'load'; - cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]); - item.pointerType = item.tokens[1].text; - item.valueType = item.type = removePointing(item.pointerType); - Types.needAnalysis[item.type] = 0; - var last = getTokenIndexByText(item.tokens, ';'); - var segments = splitTokenList(item.tokens.slice(1, last)); - item.pointer = parseLLVMSegment(segments[0]); - if (segments.length > 1) { - assert(segments[1][0].text == 'align'); - item.align = parseInt(segments[1][1].text) || QUANTUM_SIZE; // 0 means preferred arch align - } else { - item.align = QUANTUM_SIZE; - } - item.ident = item.pointer.ident || null; - this.forwardItem(item, 'Reintegrator'); + function loadHandler(item) { + item.intertype = 'load'; + cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]); + item.pointerType = item.tokens[1].text; + item.valueType = item.type = removePointing(item.pointerType); + Types.needAnalysis[item.type] = 0; + var last = getTokenIndexByText(item.tokens, ';'); + var segments = splitTokenList(item.tokens.slice(1, last)); + item.pointer = parseLLVMSegment(segments[0]); + if (segments.length > 1) { + assert(segments[1][0].text == 'align'); + item.align = parseInt(segments[1][1].text) || QUANTUM_SIZE; // 0 means preferred arch align + } else { + item.align = QUANTUM_SIZE; } - }); + item.ident = item.pointer.ident || null; + return item; + } // 'extractvalue' - substrate.addActor('ExtractValue', { - processItem: function(item) { - var last = getTokenIndexByText(item.tokens, ';'); - item.intertype = 'extractvalue'; - item.type = item.tokens[1].text; // Of the origin aggregate - not what we extract from it. For that, can only infer it later - Types.needAnalysis[item.type] = 0; - item.ident = toNiceIdent(item.tokens[2].text); - item.indexes = splitTokenList(item.tokens.slice(4, last)); - this.forwardItem(item, 'Reintegrator'); - } - }); + function extractValueHandler(item) { + var last = getTokenIndexByText(item.tokens, ';'); + item.intertype = 'extractvalue'; + item.type = item.tokens[1].text; // Of the origin aggregate - not what we extract from it. For that, can only infer it later + Types.needAnalysis[item.type] = 0; + item.ident = toNiceIdent(item.tokens[2].text); + item.indexes = splitTokenList(item.tokens.slice(4, last)); + return item; + } // 'insertvalue' - substrate.addActor('InsertValue', { - processItem: function(item) { - var last = getTokenIndexByText(item.tokens, ';'); - item.intertype = 'insertvalue'; - item.type = item.tokens[1].text; // Of the origin aggregate, as well as the result - Types.needAnalysis[item.type] = 0; - item.ident = toNiceIdent(item.tokens[2].text); - var segments = splitTokenList(item.tokens.slice(4, last)); - item.value = parseLLVMSegment(segments[0]); - item.indexes = segments.slice(1); - this.forwardItem(item, 'Reintegrator'); - } - }); + function insertValueHandler(item) { + var last = getTokenIndexByText(item.tokens, ';'); + item.intertype = 'insertvalue'; + item.type = item.tokens[1].text; // Of the origin aggregate, as well as the result + Types.needAnalysis[item.type] = 0; + item.ident = toNiceIdent(item.tokens[2].text); + var segments = splitTokenList(item.tokens.slice(4, last)); + item.value = parseLLVMSegment(segments[0]); + item.indexes = segments.slice(1); + return item; + } // 'bitcast' - substrate.addActor('Bitcast', { - processItem: function(item) { - item.intertype = 'bitcast'; - item.type = item.tokens[4].text; // The final type - Types.needAnalysis[item.type] = 0; - var to = getTokenIndexByText(item.tokens, 'to'); - item.params = [parseLLVMSegment(item.tokens.slice(1, to))]; - item.ident = item.params[0].ident; - item.type2 = item.tokens[1].text; // The original type - Types.needAnalysis[item.type2] = 0; - this.forwardItem(item, 'Reintegrator'); - } - }); + function bitcastHandler(item) { + item.intertype = 'bitcast'; + item.type = item.tokens[4].text; // The final type + Types.needAnalysis[item.type] = 0; + var to = getTokenIndexByText(item.tokens, 'to'); + item.params = [parseLLVMSegment(item.tokens.slice(1, to))]; + item.ident = item.params[0].ident; + item.type2 = item.tokens[1].text; // The original type + Types.needAnalysis[item.type2] = 0; + return item; + } // 'getelementptr' - substrate.addActor('GEP', { - processItem: function(item) { - var first = 0; - while (!isType(item.tokens[first].text)) first++; - Types.needAnalysis[item.tokens[first].text] = 0; - var last = getTokenIndexByText(item.tokens, ';'); - var segment = [ item.tokens[first], { text: 'getelementptr' }, null, { item: { - tokens: item.tokens.slice(first, last) - } } ]; - var data = parseLLVMFunctionCall(segment); - item.intertype = 'getelementptr'; - item.type = '*'; // We need type info to determine this - all we know is it's a pointer - item.params = data.params; - item.ident = data.ident; - this.forwardItem(item, 'Reintegrator'); - } - }); + function GEPHandler(item) { + var first = 0; + while (!isType(item.tokens[first].text)) first++; + Types.needAnalysis[item.tokens[first].text] = 0; + var last = getTokenIndexByText(item.tokens, ';'); + var segment = [ item.tokens[first], { text: 'getelementptr' }, null, { item: { + tokens: item.tokens.slice(first, last) + } } ]; + var data = parseLLVMFunctionCall(segment); + item.intertype = 'getelementptr'; + item.type = '*'; // We need type info to determine this - all we know is it's a pointer + item.params = data.params; + item.ident = data.ident; + return item; + } // 'call', 'invoke' function makeCall(item, type) { item.intertype = type; @@ -740,328 +713,292 @@ function intertyper(lines, sidePass, baseLineNums) { if (item.indent == 2) { // standalone call - not in assign item.standalone = true; - return { forward: null, ret: [item], item: item }; + return { forward: null, ret: item, item: item }; } - return { forward: item, ret: [], item: item }; + return { forward: item, ret: null, item: item }; } - substrate.addActor('Call', { - processItem: function(item) { - var result = makeCall.call(this, item, 'call'); - if (result.forward) this.forwardItem(result.forward, 'Reintegrator'); - return result.ret; - } - }); - substrate.addActor('Invoke', { - processItem: function(item) { - var result = makeCall.call(this, item, 'invoke'); - if (DISABLE_EXCEPTION_CATCHING == 1) { - result.item.intertype = 'call'; - result.ret.push({ - intertype: 'branch', - label: result.item.toLabel, - lineNum: (result.forward ? item.parentLineNum : item.lineNum) + 0.5 - }); - } - if (result.forward) this.forwardItem(result.forward, 'Reintegrator'); - return result.ret; - } - }); - substrate.addActor('Atomic', { - processItem: function(item) { - item.intertype = 'atomic'; - if (item.tokens[0].text == 'atomicrmw') { - if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1); - item.op = item.tokens[1].text; - item.tokens.splice(1, 1); - } else { - assert(item.tokens[0].text == 'cmpxchg') - if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1); - item.op = 'cmpxchg'; - } - var last = getTokenIndexByText(item.tokens, ';'); - item.params = splitTokenList(item.tokens.slice(1, last)).map(parseLLVMSegment); - item.type = item.params[1].type; - this.forwardItem(item, 'Reintegrator'); + function callHandler(item) { + var result = makeCall.call(this, item, 'call'); + if (result.forward) this.forwardItem(result.forward, 'Reintegrator'); + return result.ret; + } + function invokeHandler(item) { + var result = makeCall.call(this, item, 'invoke'); + if (DISABLE_EXCEPTION_CATCHING == 1) { + result.item.intertype = 'call'; + extraResults.push({ + intertype: 'branch', + label: result.item.toLabel, + lineNum: (result.forward ? item.parentLineNum : item.lineNum) + 0.5 + }); } - }); + if (result.forward) this.forwardItem(result.forward, 'Reintegrator'); + return result.ret; + } + function atomicHandler(item) { + item.intertype = 'atomic'; + if (item.tokens[0].text == 'atomicrmw') { + if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1); + item.op = item.tokens[1].text; + item.tokens.splice(1, 1); + } else { + assert(item.tokens[0].text == 'cmpxchg') + if (item.tokens[1].text == 'volatile') item.tokens.splice(1, 1); + item.op = 'cmpxchg'; + } + var last = getTokenIndexByText(item.tokens, ';'); + item.params = splitTokenList(item.tokens.slice(1, last)).map(parseLLVMSegment); + item.type = item.params[1].type; + return item; + } // 'landingpad' - substrate.addActor('Landingpad', { - processItem: function(item) { - item.intertype = 'landingpad'; - item.type = item.tokens[1].text; - item.catchables = []; - var catchIdx = findTokenText(item, "catch"); - if (catchIdx != -1) { - do { - var nextCatchIdx = findTokenTextAfter(item, "catch", catchIdx+1); - if (nextCatchIdx == -1) - nextCatchIdx = item.tokens.length; - item.catchables.push(parseLLVMSegment(item.tokens.slice(catchIdx+2, nextCatchIdx))); - catchIdx = nextCatchIdx; - } while (catchIdx != item.tokens.length); - } - Types.needAnalysis[item.type] = 0; - this.forwardItem(item, 'Reintegrator'); + function landingpadHandler(item) { + item.intertype = 'landingpad'; + item.type = item.tokens[1].text; + item.catchables = []; + var catchIdx = findTokenText(item, "catch"); + if (catchIdx != -1) { + do { + var nextCatchIdx = findTokenTextAfter(item, "catch", catchIdx+1); + if (nextCatchIdx == -1) + nextCatchIdx = item.tokens.length; + item.catchables.push(parseLLVMSegment(item.tokens.slice(catchIdx+2, nextCatchIdx))); + catchIdx = nextCatchIdx; + } while (catchIdx != item.tokens.length); } - }); + Types.needAnalysis[item.type] = 0; + return item; + } // 'alloca' var allocaPossibleVars = ['allocatedNum']; - substrate.addActor('Alloca', { - processItem: function(item) { - item.intertype = 'alloca'; - item.allocatedType = item.tokens[1].text; - if (item.tokens.length > 3 && Runtime.isNumberType(item.tokens[3].text)) { - item.allocatedNum = toNiceIdent(item.tokens[4].text); - item.possibleVars = allocaPossibleVars; - } else { - item.allocatedNum = 1; - } - item.type = addPointing(item.tokens[1].text); // type of pointer we will get - Types.needAnalysis[item.type] = 0; - item.type2 = item.tokens[1].text; // value we will create, and get a pointer to - Types.needAnalysis[item.type2] = 0; - this.forwardItem(item, 'Reintegrator'); + function allocaHandler(item) { + item.intertype = 'alloca'; + item.allocatedType = item.tokens[1].text; + if (item.tokens.length > 3 && Runtime.isNumberType(item.tokens[3].text)) { + item.allocatedNum = toNiceIdent(item.tokens[4].text); + item.possibleVars = allocaPossibleVars; + } else { + item.allocatedNum = 1; } - }); + item.type = addPointing(item.tokens[1].text); // type of pointer we will get + Types.needAnalysis[item.type] = 0; + item.type2 = item.tokens[1].text; // value we will create, and get a pointer to + Types.needAnalysis[item.type2] = 0; + return item; + } // 'phi' - substrate.addActor('Phi', { - processItem: function(item) { - item.intertype = 'phi'; - item.type = item.tokens[1].text; - var typeToken = [item.tokens[1]]; - Types.needAnalysis[item.type] = 0; - var last = getTokenIndexByText(item.tokens, ';'); - item.params = splitTokenList(item.tokens.slice(2, last)).map(function(segment) { - var subSegments = splitTokenList(segment[0].item.tokens); - var ret = { - intertype: 'phiparam', - label: toNiceIdent(subSegments[1][0].text), - value: parseLLVMSegment(typeToken.concat(subSegments[0])) - }; - return ret; - }).filter(function(param) { return param.value && param.value.ident != 'undef' }); - this.forwardItem(item, 'Reintegrator'); - } - }); + function phiHandler(item) { + item.intertype = 'phi'; + item.type = item.tokens[1].text; + var typeToken = [item.tokens[1]]; + Types.needAnalysis[item.type] = 0; + var last = getTokenIndexByText(item.tokens, ';'); + item.params = splitTokenList(item.tokens.slice(2, last)).map(function(segment) { + var subSegments = splitTokenList(segment[0].item.tokens); + var ret = { + intertype: 'phiparam', + label: toNiceIdent(subSegments[1][0].text), + value: parseLLVMSegment(typeToken.concat(subSegments[0])) + }; + return ret; + }).filter(function(param) { return param.value && param.value.ident != 'undef' }); + return item; + } // 'phi' - substrate.addActor('va_arg', { - processItem: function(item) { - item.intertype = 'va_arg'; - var segments = splitTokenList(item.tokens.slice(1)); - item.type = segments[1][0].text; - item.value = parseLLVMSegment(segments[0]); - this.forwardItem(item, 'Reintegrator'); - } - }); + function va_argHandler(item) { + item.intertype = 'va_arg'; + var segments = splitTokenList(item.tokens.slice(1)); + item.type = segments[1][0].text; + item.value = parseLLVMSegment(segments[0]); + return item; + } // mathops - substrate.addActor('Mathops', { - processItem: function(item) { - item.intertype = 'mathop'; - item.op = item.tokens[0].text; - item.variant = null; - while (item.tokens[1].text in NSW_NUW) item.tokens.splice(1, 1); - if (['icmp', 'fcmp'].indexOf(item.op) != -1) { - item.variant = item.tokens[1].text; - item.tokens.splice(1, 1); - } - if (item.tokens[1].text == 'exact') item.tokens.splice(1, 1); // TODO: Implement trap values - var segments = splitTokenList(item.tokens.slice(1)); - item.params = []; - for (var i = 1; i <= 4; i++) { - if (segments[i-1]) { - if (i > 1 && segments[i-1].length == 1 && segments[0].length > 1 && !isType(segments[i-1][0].text)) { - segments[i-1].unshift(segments[0][0]); // Add the type from the first segment, they are all alike - } - item.params[i-1] = parseLLVMSegment(segments[i-1]); - } - } - var setParamTypes = true; - if (item.op === 'select') { - assert(item.params[1].type === item.params[2].type); - item.type = item.params[1].type; - } else if (item.op in LLVM.CONVERSIONS) { - item.type = item.params[1].type; - setParamTypes = false; - } else { - item.type = item.params[0].type; - } - if (setParamTypes) { - for (var i = 0; i < 4; i++) { - if (item.params[i]) item.params[i].type = item.type; // All params have the same type, normally + function mathopsHandler(item) { + item.intertype = 'mathop'; + item.op = item.tokens[0].text; + item.variant = null; + while (item.tokens[1].text in NSW_NUW) item.tokens.splice(1, 1); + if (['icmp', 'fcmp'].indexOf(item.op) != -1) { + item.variant = item.tokens[1].text; + item.tokens.splice(1, 1); + } + if (item.tokens[1].text == 'exact') item.tokens.splice(1, 1); // TODO: Implement trap values + var segments = splitTokenList(item.tokens.slice(1)); + item.params = []; + for (var i = 1; i <= 4; i++) { + if (segments[i-1]) { + if (i > 1 && segments[i-1].length == 1 && segments[0].length > 1 && !isType(segments[i-1][0].text)) { + segments[i-1].unshift(segments[0][0]); // Add the type from the first segment, they are all alike } + item.params[i-1] = parseLLVMSegment(segments[i-1]); } - if (item.op in LLVM.EXTENDS) { - item.type = item.params[1].ident; - item.params[0].type = item.params[1].type; - // TODO: also remove 2nd param? - } else if (item.op in LLVM.COMPS) { - item.type = 'i1'; + } + var setParamTypes = true; + if (item.op === 'select') { + assert(item.params[1].type === item.params[2].type); + item.type = item.params[1].type; + } else if (item.op in LLVM.CONVERSIONS) { + item.type = item.params[1].type; + setParamTypes = false; + } else { + item.type = item.params[0].type; + } + if (setParamTypes) { + for (var i = 0; i < 4; i++) { + if (item.params[i]) item.params[i].type = item.type; // All params have the same type, normally } - if (USE_TYPED_ARRAYS == 2) { - // Some specific corrections, since 'i64' is special - if (item.op in LLVM.SHIFTS) { - item.params[1].type = 'i32'; - } else if (item.op == 'select') { - item.params[0].type = 'i1'; - } + } + if (item.op in LLVM.EXTENDS) { + item.type = item.params[1].ident; + item.params[0].type = item.params[1].type; + // TODO: also remove 2nd param? + } else if (item.op in LLVM.COMPS) { + item.type = 'i1'; + } + if (USE_TYPED_ARRAYS == 2) { + // Some specific corrections, since 'i64' is special + if (item.op in LLVM.SHIFTS) { + item.params[1].type = 'i32'; + } else if (item.op == 'select') { + item.params[0].type = 'i1'; } - Types.needAnalysis[item.type] = 0; - this.forwardItem(item, 'Reintegrator'); } - }); + Types.needAnalysis[item.type] = 0; + return item; + } // 'store' - substrate.addActor('Store', { - processItem: function(item) { - cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]); - var segments = splitTokenList(item.tokens.slice(1)); - var ret = { - intertype: 'store', - valueType: item.tokens[1].text, - value: parseLLVMSegment(segments[0]), - pointer: parseLLVMSegment(segments[1]), - lineNum: item.lineNum - }; - Types.needAnalysis[ret.valueType] = 0; - ret.ident = toNiceIdent(ret.pointer.ident); - ret.pointerType = ret.pointer.type; - Types.needAnalysis[ret.pointerType] = 0; - if (segments.length > 2) { - assert(segments[2][0].text == 'align'); - ret.align = parseInt(segments[2][1].text) || QUANTUM_SIZE; // 0 means preferred arch align - } else { - ret.align = QUANTUM_SIZE; - } - return [ret]; + function storeHandler(item) { + cleanOutTokens(LLVM.ACCESS_OPTIONS, item.tokens, [0, 1]); + var segments = splitTokenList(item.tokens.slice(1)); + var ret = { + intertype: 'store', + valueType: item.tokens[1].text, + value: parseLLVMSegment(segments[0]), + pointer: parseLLVMSegment(segments[1]), + lineNum: item.lineNum + }; + Types.needAnalysis[ret.valueType] = 0; + ret.ident = toNiceIdent(ret.pointer.ident); + ret.pointerType = ret.pointer.type; + Types.needAnalysis[ret.pointerType] = 0; + if (segments.length > 2) { + assert(segments[2][0].text == 'align'); + ret.align = parseInt(segments[2][1].text) || QUANTUM_SIZE; // 0 means preferred arch align + } else { + ret.align = QUANTUM_SIZE; } - }); + return ret; + } // 'br' - substrate.addActor('Branch', { - processItem: function(item) { - if (item.tokens[1].text == 'label') { - return [{ - intertype: 'branch', - label: toNiceIdent(item.tokens[2].text), - lineNum: item.lineNum - }]; - } else { - var commaIndex = findTokenText(item, ','); - return [{ - intertype: 'branch', - value: parseLLVMSegment(item.tokens.slice(1, commaIndex)), - labelTrue: toNiceIdent(item.tokens[commaIndex+2].text), - labelFalse: toNiceIdent(item.tokens[commaIndex+5].text), - lineNum: item.lineNum - }]; - } - } - }); - // 'ret' - substrate.addActor('Return', { - processItem: function(item) { - var type = item.tokens[1].text; - Types.needAnalysis[type] = 0; - return [{ - intertype: 'return', - type: type, - value: (item.tokens[2] && type !== 'void') ? parseLLVMSegment(item.tokens.slice(1)) : null, + function branchHandler(item) { + if (item.tokens[1].text == 'label') { + return { + intertype: 'branch', + label: toNiceIdent(item.tokens[2].text), lineNum: item.lineNum - }]; - } - }); - // 'resume' - partial implementation - substrate.addActor('Resume', { - processItem: function(item) { - return [{ - intertype: 'resume', - ident: toNiceIdent(item.tokens[2].text), + }; + } else { + var commaIndex = findTokenText(item, ','); + return { + intertype: 'branch', + value: parseLLVMSegment(item.tokens.slice(1, commaIndex)), + labelTrue: toNiceIdent(item.tokens[commaIndex+2].text), + labelFalse: toNiceIdent(item.tokens[commaIndex+5].text), lineNum: item.lineNum - }]; + }; } - }); + } + // 'ret' + function returnHandler(item) { + var type = item.tokens[1].text; + Types.needAnalysis[type] = 0; + return { + intertype: 'return', + type: type, + value: (item.tokens[2] && type !== 'void') ? parseLLVMSegment(item.tokens.slice(1)) : null, + lineNum: item.lineNum + }; + } + // 'resume' - partial implementation + function resumeHandler(item) { + return { + intertype: 'resume', + ident: toNiceIdent(item.tokens[2].text), + lineNum: item.lineNum + }; + } // 'switch' - substrate.addActor('Switch', { - processItem: function(item) { - function parseSwitchLabels(item) { - var ret = []; - var tokens = item.item.tokens; - while (tokens.length > 0) { - ret.push({ - value: tokens[1].text, - label: toNiceIdent(tokens[4].text) - }); - tokens = tokens.slice(5); - } - return ret; + function switchHandler(item) { + function parseSwitchLabels(item) { + var ret = []; + var tokens = item.item.tokens; + while (tokens.length > 0) { + ret.push({ + value: tokens[1].text, + label: toNiceIdent(tokens[4].text) + }); + tokens = tokens.slice(5); } - var type = item.tokens[1].text; - Types.needAnalysis[type] = 0; - return [{ - intertype: 'switch', - type: type, - ident: toNiceIdent(item.tokens[2].text), - defaultLabel: toNiceIdent(item.tokens[5].text), - switchLabels: parseSwitchLabels(item.tokens[6]), - lineNum: item.lineNum - }]; - } - }); + return ret; + } + var type = item.tokens[1].text; + Types.needAnalysis[type] = 0; + return { + intertype: 'switch', + type: type, + ident: toNiceIdent(item.tokens[2].text), + defaultLabel: toNiceIdent(item.tokens[5].text), + switchLabels: parseSwitchLabels(item.tokens[6]), + lineNum: item.lineNum + }; + } // function end - substrate.addActor('FuncEnd', { - processItem: function(item) { - return [{ - intertype: 'functionEnd', - lineNum: item.lineNum - }]; - } - }); + function funcEndHandler(item) { + return { + intertype: 'functionEnd', + lineNum: item.lineNum + }; + } // external function stub - substrate.addActor('External', { - processItem: function(item) { - while (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.VISIBILITIES || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) { - item.tokens.splice(1, 1); - } - var params = parseParamTokens(item.tokens[3].item.tokens); - return [{ - intertype: 'functionStub', - ident: toNiceIdent(item.tokens[2].text), - returnType: item.tokens[1], - params: params, - hasVarArgs: hasVarArgs(params), - lineNum: item.lineNum - }]; + function externalHandler(item) { + while (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.VISIBILITIES || item.tokens[1].text in LLVM.CALLING_CONVENTIONS) { + item.tokens.splice(1, 1); } - }); + var params = parseParamTokens(item.tokens[3].item.tokens); + return { + intertype: 'functionStub', + ident: toNiceIdent(item.tokens[2].text), + returnType: item.tokens[1], + params: params, + hasVarArgs: hasVarArgs(params), + lineNum: item.lineNum + }; + } // 'unreachable' - substrate.addActor('Unreachable', { - processItem: function(item) { - return [{ - intertype: 'unreachable', - lineNum: item.lineNum - }]; - } - }); + function unreachableHandler(item) { + return { + intertype: 'unreachable', + lineNum: item.lineNum + }; + } // 'indirectbr' - substrate.addActor('IndirectBr', { - processItem: function(item) { - var ret = { - intertype: 'indirectbr', - value: parseLLVMSegment(splitTokenList(item.tokens.slice(1))[0]), - type: item.tokens[1].text, - lineNum: item.lineNum - }; - Types.needAnalysis[ret.type] = 0; - return [ret]; - } - }); + function indirectBrHandler(item) { + var ret = { + intertype: 'indirectbr', + value: parseLLVMSegment(splitTokenList(item.tokens.slice(1))[0]), + type: item.tokens[1].text, + lineNum: item.lineNum + }; + Types.needAnalysis[ret.type] = 0; + return ret; + } // Input - substrate.addItems(lineSplitter().map(tokenizer.processItem).filter(function(item) { return item }), 'Triager'); - - substrate.onResult = function(result) { + return lineSplitter().map(tokenizer.processItem).filter(function(item) { return item }).map(triager).filter(function(result) { + if (!result) return false; if (result.tokens) result.tokens = null; // We do not need tokens, past the intertyper. Clean them up as soon as possible here. - }; - - return substrate.solve().concat(unparsedBundles); + return true; + }).concat(unparsedBundles).concat(extraResults); } |