| 334 | } |
| 335 | |
| 336 | constructor(compilerProps?: PropertyGetter) { |
| 337 | super(); |
| 338 | |
| 339 | this.sourceLineHandler = new SourceLineHandler(); |
| 340 | this.labelProcessor = new LabelProcessor(); |
| 341 | this.parsingState = new ParsingState({}, null, '', false, false, []); |
| 342 | |
| 343 | this.labelFindNonMips = /[.A-Z_a-z][\w$.]*|"[.A-Z_a-z][\w$.]*"/g; |
| 344 | // MIPS labels can start with a $ sign, but other assemblers use $ to mean literal. |
| 345 | this.labelFindMips = /[$.A-Z_a-z][\w$.]*|"[$.A-Z_a-z][\w$.]*"/g; |
| 346 | this.mipsLabelDefinition = /^\$[\w$.]+:/; |
| 347 | this.dataDefn = |
| 348 | /^\s*\.(ascii|asciz|base64|[1248]?byte|dc(?:\.[abdlswx])?|dcb(?:\.[bdlswx])?|ds(?:\.[bdlpswx])?|double|dword|fill|float|half|hword|int|long|octa|quad|short|single|skip|space|string(?:8|16|32|64)?|value|word|xword|zero)/; |
| 349 | this.fileFind = /^\s*\.(?:cv_)?file\s+(\d+)\s+"([^"]+)"(\s+"([^"]+)")?.*/; |
| 350 | // Opcode expression here matches LLVM-style opcodes of the form `%blah = opcode` |
| 351 | this.hasOpcodeRe = /^\s*(%[$.A-Z_a-z][\w$.]*\s*=\s*)?[A-Za-z]/; |
| 352 | this.instructionRe = /^\s*[A-Za-z]+/; |
| 353 | this.identifierFindRe = /((?!\$\.)[$.@A-Z_a-z"][\w$.]*"?)(?:@\w+)*/g; |
| 354 | this.hasNvccOpcodeRe = /^\s*[@A-Za-z|]/; |
| 355 | this.definesFunction = /^\s*\.(type.*,\s*[#%@]function|proc\s+[.A-Z_a-z][\w$.]*:.*)$/; |
| 356 | this.definesGlobal = /^\s*\.(?:globa?l|GLB|export)\s*([.A-Z_a-z][\w$.]*|"[.A-Z_a-z][\w$.]*")/; |
| 357 | this.definesWeak = /^\s*\.(?:weakext|weak)\s*([.A-Z_a-z][\w$.]*|"[.A-Z_a-z][\w$.]*")/; |
| 358 | this.definesAlias = /^\s*\.set\s*((?:[.A-Z_a-z][\w$.]*|"[.A-Z_a-z][\w$.]*")\s*),\s*\.\s*(\+\s*0)?$/; |
| 359 | this.indentedLabelDef = /^\s*([$.A-Z_a-z][\w$.]*|"[$.A-Z_a-z][\w$.]*"):/; |
| 360 | this.assignmentDef = /^\s*([$.A-Z_a-z][\w$.]*)\s*=\s*(.*)/; |
| 361 | // ".set label, label" where "label" is `this.labelFindNonMips` |
| 362 | this.setDef = |
| 363 | /^\s*\.set\s+([.A-Z_a-z][\w$.]*|"[.A-Z_a-z][\w$.]*"),\s*(?:[.A-Z_a-z][\w$.]*|"[.A-Z_a-z][\w$.]*")\s*$/; |
| 364 | this.directive = /^\s*\..*$/; |
| 365 | // These four regexes when phrased as /\s*#APP.*/ etc exhibit costly polynomial backtracking. Instead use ^$ and |
| 366 | // test with regex.test(line.trim()), more robust anyway |
| 367 | this.startAppBlock = /^#APP.*$/; |
| 368 | this.endAppBlock = /^#NO_APP.*$/; |
| 369 | this.startAsmNesting = /^# Begin ASM.*$/; |
| 370 | this.endAsmNesting = /^# End ASM.*$/; |
| 371 | this.cudaBeginDef = /\.(entry|func)\s+(?:\([^)]*\)\s*)?([$.A-Z_a-z][\w$.]*)\($/; |
| 372 | this.cudaEndDef = /^\s*\)\s*$/; |
| 373 | |
| 374 | this.binaryHideFuncRe = null; |
| 375 | this.maxAsmLines = 5000; |
| 376 | if (compilerProps) { |
| 377 | const binaryHideFuncReValue = compilerProps('binaryHideFuncRe'); |
| 378 | if (binaryHideFuncReValue) { |
| 379 | assert(isString(binaryHideFuncReValue)); |
| 380 | this.binaryHideFuncRe = new RegExp(binaryHideFuncReValue); |
| 381 | } |
| 382 | |
| 383 | this.maxAsmLines = compilerProps('maxLinesOfAsm', this.maxAsmLines); |
| 384 | } |
| 385 | |
| 386 | this.asmOpcodeRe = /^\s*(?<address>[\da-f]+):\s*(?<opcodes>([\da-f]{2} ?)+)\s*(?<disasm>.*)/; |
| 387 | this.relocationRe = /^\s*(?<address>[\da-f]+):\s*(?<relocname>(R_[\dA-Z_]+))\s*(?<relocdata>.*)/; |
| 388 | this.relocDataSymNameRe = /^(?<symname>[^\d-+][\w.]*)?\s*(?<addend_or_value>.*)$/; |
| 389 | if (process.platform === 'win32') { |
| 390 | this.lineRe = /^([A-Z]:\/[^:]+):(?<line>\d+).*/; |
| 391 | } else { |
| 392 | this.lineRe = /^(\/[^:]+):(?<line>\d+).*/; |
| 393 | } |