Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
| 8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
| 9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
| 10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
| (...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1057 } | 1057 } |
| 1058 return HType.UNKNOWN; | 1058 return HType.UNKNOWN; |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 bool hasExpectedType() => builtinJsName != null; | 1061 bool hasExpectedType() => builtinJsName != null; |
| 1062 | 1062 |
| 1063 HInstruction fold() { | 1063 HInstruction fold() { |
| 1064 if (name == 'length' && inputs[1].isLiteralString()) { | 1064 if (name == 'length' && inputs[1].isLiteralString()) { |
| 1065 // TODO(lrn): Account for escapes in string. Currently we count characters | 1065 // TODO(lrn): Account for escapes in string. Currently we count characters |
| 1066 // in the uninterpreted (but unquoted) string. | 1066 // in the uninterpreted (but unquoted) string. |
| 1067 QuotedString string = inputs[1].value; | |
| 1068 int contentLength = string.contentEnd - string.contentStart; | |
| 1069 return new HLiteral(contentLength, HType.INTEGER); | |
| 1070 } | 1067 } |
| 1071 return this; | 1068 return this; |
| 1072 } | 1069 } |
| 1073 | 1070 |
| 1074 void prepareGvn() { | 1071 void prepareGvn() { |
| 1075 if (builtinJsName == 'length') { | 1072 if (builtinJsName == 'length') { |
| 1076 assert(!hasSideEffects()); | 1073 assert(!hasSideEffects()); |
| 1077 } else { | 1074 } else { |
| 1078 setAllSideEffects(); | 1075 setAllSideEffects(); |
| 1079 } | 1076 } |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1549 bool get isRaw() => (flags & RAW) != 0; | 1546 bool get isRaw() => (flags & RAW) != 0; |
| 1550 String get quoteChar() => ((flags & SINGLE_QUOTED) != 0) ? "'" : '"'; | 1547 String get quoteChar() => ((flags & SINGLE_QUOTED) != 0) ? "'" : '"'; |
| 1551 | 1548 |
| 1552 int get contentStart() => | 1549 int get contentStart() => |
| 1553 hasLeftQuote ? (isRaw ? 1 : 0) + (isMultiLine ? 3 : 1) : 0; | 1550 hasLeftQuote ? (isRaw ? 1 : 0) + (isMultiLine ? 3 : 1) : 0; |
| 1554 int get contentEnd() => | 1551 int get contentEnd() => |
| 1555 wrappedString.length - (hasRightQuote ? (isMultiLine ? 3 : 1) : 0); | 1552 wrappedString.length - (hasRightQuote ? (isMultiLine ? 3 : 1) : 0); |
| 1556 | 1553 |
| 1557 bool isEmpty() => contentStart == contentEnd; | 1554 bool isEmpty() => contentStart == contentEnd; |
| 1558 | 1555 |
| 1556 static int hexValue(int hexDigit) { | |
| 1557 // hexDigit is one of '0'..'9', 'A'..'F' and 'a'..'f'. | |
| 1558 if (hexDigit <= 0x39) { | |
| 1559 return hexDigit - 0x30; | |
|
floitsch
2012/01/12 12:30:28
Don't use random constants. I would prefer not to
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Now uses $9, etc.
| |
| 1560 } | |
| 1561 // Make letters lowercase. | |
| 1562 hexDigit |= 0x20; | |
| 1563 hexDigit -= 0x61 - 10; | |
| 1564 assert(0 <= hexDigit && hexDigit <= 15); | |
| 1565 return hexDigit; | |
| 1566 } | |
| 1567 | |
| 1568 /* Write the contents of the quoted string to a [StringBuffer] in | |
|
floitsch
2012/01/12 12:30:28
/**
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Done.
| |
| 1569 * a form that is valid as JavaScript string literal content. | |
| 1570 * The string is assumed quoted by [quote] characters. | |
| 1571 * This method doesn't try to make the shortest string, but rather | |
| 1572 * to be as close to the original string as possible. | |
| 1573 */ | |
| 1574 void writeEscaped(StringBuffer buffer, String quote) { | |
| 1575 bool raw = this.isRaw; | |
| 1576 int from = contentStart; | |
| 1577 int end = contentEnd; | |
| 1578 for (int i = from; i < end; i++) { | |
| 1579 String character = wrappedString[i]; | |
| 1580 if (character == quote) { | |
| 1581 // Insert backslash before unquoted quote character. | |
| 1582 wrappedString.printSubstringOn(buffer, from, i); | |
| 1583 buffer.add(@'\'); | |
| 1584 from = i; | |
| 1585 } else if (character == @'\') { | |
| 1586 if (raw) { | |
| 1587 wrappedString.printSubstringOn(buffer, from, i); | |
| 1588 buffer.add(@'\'); | |
|
floitsch
2012/01/12 12:30:28
Don't you need to update from?
Lasse Reichstein Nielsen
2012/01/16 13:30:23
I did. It's now completely rewritten.
| |
| 1589 } else { | |
| 1590 character = wrappedString[++i]; | |
|
floitsch
2012/01/12 12:30:28
I find it easier to i++; first:
i++;
character = w
Lasse Reichstein Nielsen
2012/01/16 13:30:23
In many cases I'd agree. In this, I actually read
| |
| 1591 if (character == 'u') { | |
| 1592 if (wrappedString[++i] == '{') { | |
|
floitsch
2012/01/12 12:30:28
ditto
floitsch
2012/01/12 12:30:28
Maybe move the \u{...} section into a (local/neste
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Moved.
| |
| 1593 // In Dart, \u{x+} is a valid escape, but not in | |
| 1594 // JS. Convert to a \uxxxx escape. | |
| 1595 wrappedString.printSubstringOn(buffer, from, i); | |
| 1596 int value = 0; | |
| 1597 int hexDigit = wrappedString.charCodeAt(++i); | |
|
floitsch
2012/01/12 12:30:28
ditto. (maybe also move i++ up, so that it is clea
Lasse Reichstein Nielsen
2012/01/16 13:30:23
gone.
| |
| 1598 do { | |
| 1599 value = value * 16 + hexValue(hexDigit); | |
| 1600 hexDigit = wrappedString.charCodeAt(++i); | |
|
floitsch
2012/01/12 12:30:28
use i++
| |
| 1601 } while (hexDigit !== 0x7d); // until '}'. | |
|
floitsch
2012/01/12 12:30:28
magic value.
| |
| 1602 // JavaScript only supports characters in the BMP. | |
|
floitsch
2012/01/12 12:30:28
That's not true. It allows for the full UTF-16. We
| |
| 1603 if (value > 0xffff) value = 0xfffd; | |
| 1604 | |
| 1605 for (int j = 12; j >= 0; j -= 4) { | |
| 1606 int digit = (value >> j) & 0xf; | |
| 1607 buffer.add("0123456789abcdef"[digit]); | |
| 1608 } | |
| 1609 from = i + 1; | |
| 1610 } | |
| 1611 } else if ('0' == character || | |
| 1612 '1' == character || | |
| 1613 '2' == character || | |
| 1614 '3' == character || | |
| 1615 '4' == character || | |
| 1616 '5' == character || | |
| 1617 '6' == character || | |
| 1618 '7' == character) { | |
| 1619 // In Dart "\[0-9]" are identity escapes. In JS, | |
| 1620 // they start an octal escape, so we need to remove the '\'. | |
| 1621 wrappedString.printSubstringOn(buffer, from, i - 1); | |
| 1622 from = i; | |
| 1623 } | |
| 1624 // All other valid Dart escapes are also valid JS escapes | |
| 1625 // with the same meaning, so we include them verbatim. | |
|
floitsch
2012/01/12 12:30:28
I would still prefer to have them explicitly handl
Lasse Reichstein Nielsen
2012/01/16 13:30:23
Done.
| |
| 1626 } | |
| 1627 } | |
| 1628 } | |
| 1629 wrappedString.printSubstringOn(buffer, from, end); | |
| 1630 } | |
| 1631 | |
| 1559 /** | 1632 /** |
| 1560 * Does a conservative test for equality between two quoted strings. | 1633 * Does a conservative test for equality between two quoted strings. |
| 1561 * Returns true if the two definitly have the same string. | 1634 * Returns true if the two definitly have the same string. |
| 1562 * Returns false if the strings are different, or if it's not possible | 1635 * Returns false if the strings are different, or if it's not possible |
| 1563 * to (quickly) determine whether they are equal. | 1636 * to (quickly) determine whether they are equal. |
| 1564 */ | 1637 */ |
| 1565 bool definitlyEquals(QuotedString other) { | 1638 bool definitlyEquals(QuotedString other) { |
| 1566 return flags == other.flags && wrappedString == other.wrappedString; | 1639 return flags == other.flags && wrappedString == other.wrappedString; |
| 1567 } | 1640 } |
| 1568 | 1641 |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1993 HInstruction first, | 2066 HInstruction first, |
| 1994 HInstruction second) | 2067 HInstruction second) |
| 1995 : super(<HInstruction>[first, second]); | 2068 : super(<HInstruction>[first, second]); |
| 1996 toString() => operation; | 2069 toString() => operation; |
| 1997 accept(HVisitor visitor) => visitor.visitLogicalOperator(this); | 2070 accept(HVisitor visitor) => visitor.visitLogicalOperator(this); |
| 1998 HInstruction get left() => inputs[0]; | 2071 HInstruction get left() => inputs[0]; |
| 1999 HInstruction get right() => inputs[1]; | 2072 HInstruction get right() => inputs[1]; |
| 2000 HType computeType() => HType.BOOLEAN; | 2073 HType computeType() => HType.BOOLEAN; |
| 2001 bool hasExpectedType() => true; | 2074 bool hasExpectedType() => true; |
| 2002 } | 2075 } |
| OLD | NEW |