Changeset 172176 in webkit for trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
- Timestamp:
- Aug 6, 2014, 2:32:55 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r172129 r172176 1506 1506 emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1507 1507 generator.emitMove(local.get(), result.get()); 1508 generator.invalidateForInContextForLocal(local.get()); 1508 1509 if (generator.isProfilingTypesWithHighFidelity()) 1509 1510 generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd()); … … 1512 1513 1513 1514 RegisterID* result = emitReadModifyAssignment(generator, local.get(), local.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1515 generator.invalidateForInContextForLocal(local.get()); 1514 1516 return generator.moveToDestinationIfNeeded(dst, result); 1515 1517 } … … 1541 1543 generator.emitNode(tempDst.get(), m_right); 1542 1544 generator.emitMove(local.get(), tempDst.get()); 1545 generator.invalidateForInContextForLocal(local.get()); 1543 1546 if (generator.isProfilingTypesWithHighFidelity()) 1544 1547 generator.emitHighFidelityTypeProfilingExpressionInfo(divotStart(), divotEnd()); … … 1546 1549 } 1547 1550 RegisterID* result = generator.emitNode(local.get(), m_right); 1551 generator.invalidateForInContextForLocal(local.get()); 1548 1552 return generator.moveToDestinationIfNeeded(dst, result); 1549 1553 } … … 1921 1925 // ------------------------------ ForInNode ------------------------------------ 1922 1926 1923 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1924 { 1925 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 1926 1927 if (!m_lexpr->isAssignmentLocation()) { 1928 emitThrowReferenceError(generator, "Left side of for-in statement is not a reference."); 1929 return; 1930 } 1931 1932 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset()); 1933 1934 RefPtr<RegisterID> base = generator.newTemporary(); 1935 generator.emitNode(base.get(), m_expr); 1936 RefPtr<RegisterID> i = generator.newTemporary(); 1937 RefPtr<RegisterID> size = generator.newTemporary(); 1938 RefPtr<RegisterID> expectedSubscript; 1939 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); 1940 generator.emitJump(scope->continueTarget()); 1941 1942 RefPtr<Label> loopStart = generator.newLabel(); 1943 generator.emitLabel(loopStart.get()); 1944 generator.emitLoopHint(); 1945 1946 RegisterID* propertyName; 1947 bool optimizedForinAccess = false; 1927 RegisterID* ForInNode::tryGetBoundLocal(BytecodeGenerator& generator) 1928 { 1948 1929 if (m_lexpr->isResolveNode()) { 1949 1930 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); 1950 1931 Local local = generator.local(ident); 1951 if (!local.get()) { 1952 propertyName = generator.newTemporary(); 1953 RefPtr<RegisterID> protect = propertyName; 1932 if (local.isCaptured()) 1933 return nullptr; 1934 return local.get(); 1935 } 1936 1937 if (m_lexpr->isDeconstructionNode()) { 1938 DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr); 1939 auto binding = assignNode->bindings(); 1940 if (!binding->isBindingNode()) 1941 return nullptr; 1942 1943 auto simpleBinding = static_cast<BindingNode*>(binding); 1944 const Identifier& ident = simpleBinding->boundProperty(); 1945 Local local = generator.local(ident); 1946 if (local.isCaptured()) 1947 return nullptr; 1948 return local.get(); 1949 } 1950 1951 return nullptr; 1952 } 1953 1954 void ForInNode::emitLoopHeader(BytecodeGenerator& generator, RegisterID* propertyName) 1955 { 1956 if (m_lexpr->isResolveNode()) { 1957 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); 1958 Local local = generator.local(ident); 1959 if (local.get()) 1960 generator.emitMove(local.get(), propertyName); 1961 else { 1954 1962 if (generator.isStrictMode()) 1955 1963 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); … … 1957 1965 generator.emitExpressionInfo(divot(), divotStart(), divotEnd()); 1958 1966 generator.emitPutToScope(scope, ident, propertyName, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound); 1959 } else { 1960 expectedSubscript = generator.newTemporary(); 1961 propertyName = expectedSubscript.get(); 1962 generator.emitMove(local.get(), propertyName); 1963 generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), local.get()); 1964 optimizedForinAccess = true; 1965 } 1966 } else if (m_lexpr->isDotAccessorNode()) { 1967 } 1968 return; 1969 } 1970 if (m_lexpr->isDotAccessorNode()) { 1967 1971 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr); 1968 1972 const Identifier& ident = assignNode->identifier(); 1969 propertyName = generator.newTemporary();1970 RefPtr<RegisterID> protect = propertyName;1971 1973 RegisterID* base = generator.emitNode(assignNode->base()); 1972 1973 1974 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd()); 1974 1975 generator.emitPutById(base, ident, propertyName); 1975 } else if (m_lexpr->isBracketAccessorNode()) { 1976 return; 1977 } 1978 if (m_lexpr->isBracketAccessorNode()) { 1976 1979 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr); 1977 propertyName = generator.newTemporary();1978 RefPtr<RegisterID> protect = propertyName;1979 1980 RefPtr<RegisterID> base = generator.emitNode(assignNode->base()); 1980 1981 RegisterID* subscript = generator.emitNode(assignNode->subscript()); 1981 1982 1982 generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStart(), assignNode->divotEnd()); 1983 1983 generator.emitPutByVal(base.get(), subscript, propertyName); 1984 } else { 1985 ASSERT(m_lexpr->isDeconstructionNode()); 1984 return; 1985 } 1986 1987 if (m_lexpr->isDeconstructionNode()) { 1986 1988 DeconstructingAssignmentNode* assignNode = static_cast<DeconstructingAssignmentNode*>(m_lexpr); 1987 1989 auto binding = assignNode->bindings(); 1988 if (binding->isBindingNode()) { 1989 auto simpleBinding = static_cast<BindingNode*>(binding); 1990 Identifier ident = simpleBinding->boundProperty(); 1991 Local local = generator.local(ident); 1992 propertyName = local.get(); 1993 // FIXME: Should I emit expression info here? 1994 if (!propertyName || local.isCaptured() || generator.isProfilingTypesWithHighFidelity()) 1995 goto genericBinding; 1996 expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName); 1997 generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName); 1998 optimizedForinAccess = true; 1999 goto completedSimpleBinding; 2000 } else { 2001 genericBinding: 2002 propertyName = generator.newTemporary(); 2003 RefPtr<RegisterID> protect(propertyName); 1990 if (!binding->isBindingNode()) { 2004 1991 assignNode->bindings()->bindValue(generator, propertyName); 2005 } 2006 completedSimpleBinding: 2007 ; 2008 } 2009 2010 generator.emitNode(dst, m_statement); 2011 2012 if (optimizedForinAccess) 2013 generator.popOptimisedForIn(); 2014 2015 generator.emitLabel(scope->continueTarget()); 2016 generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get()); 1992 return; 1993 } 1994 1995 auto simpleBinding = static_cast<BindingNode*>(binding); 1996 const Identifier& ident = simpleBinding->boundProperty(); 1997 Local local = generator.local(ident); 1998 if (!local.get() || local.isCaptured()) { 1999 assignNode->bindings()->bindValue(generator, propertyName); 2000 return; 2001 } 2002 generator.emitMove(local.get(), propertyName); 2003 return; 2004 } 2005 2006 RELEASE_ASSERT_NOT_REACHED(); 2007 } 2008 2009 void ForInNode::emitMultiLoopBytecode(BytecodeGenerator& generator, RegisterID* dst) 2010 { 2011 if (!m_lexpr->isAssignmentLocation()) { 2012 emitThrowReferenceError(generator, "Left side of for-in statement is not a reference."); 2013 return; 2014 } 2015 2016 RefPtr<Label> end = generator.newLabel(); 2017 2017 2018 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset()); 2018 generator.emitLabel(scope->breakTarget()); 2019 2020 RefPtr<RegisterID> base = generator.newTemporary(); 2021 RefPtr<RegisterID> length; 2022 RefPtr<RegisterID> structureEnumerator; 2023 generator.emitNode(base.get(), m_expr); 2024 RefPtr<RegisterID> local = this->tryGetBoundLocal(generator); 2025 2026 // Indexed property loop. 2027 { 2028 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 2029 RefPtr<Label> loopStart = generator.newLabel(); 2030 RefPtr<Label> loopEnd = generator.newLabel(); 2031 2032 length = generator.emitGetEnumerableLength(generator.newTemporary(), base.get()); 2033 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0)); 2034 RefPtr<RegisterID> propertyName = generator.newTemporary(); 2035 2036 generator.emitLabel(loopStart.get()); 2037 generator.emitLoopHint(); 2038 2039 RefPtr<RegisterID> result = generator.emitEqualityOp(op_less, generator.newTemporary(), i.get(), length.get()); 2040 generator.emitJumpIfFalse(result.get(), loopEnd.get()); 2041 generator.emitHasIndexedProperty(result.get(), base.get(), i.get()); 2042 generator.emitJumpIfFalse(result.get(), scope->continueTarget()); 2043 2044 generator.emitToIndexString(propertyName.get(), i.get()); 2045 this->emitLoopHeader(generator, propertyName.get()); 2046 2047 generator.pushIndexedForInScope(local.get(), i.get()); 2048 generator.emitNode(dst, m_statement); 2049 generator.popIndexedForInScope(local.get()); 2050 2051 generator.emitLabel(scope->continueTarget()); 2052 generator.emitInc(i.get()); 2053 generator.emitJump(loopStart.get()); 2054 2055 generator.emitLabel(scope->breakTarget()); 2056 generator.emitJump(end.get()); 2057 generator.emitLabel(loopEnd.get()); 2058 } 2059 2060 // Structure property loop. 2061 { 2062 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 2063 RefPtr<Label> loopStart = generator.newLabel(); 2064 RefPtr<Label> loopEnd = generator.newLabel(); 2065 2066 structureEnumerator = generator.emitGetStructurePropertyEnumerator(generator.newTemporary(), base.get(), length.get()); 2067 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0)); 2068 RefPtr<RegisterID> propertyName = generator.newTemporary(); 2069 generator.emitNextEnumeratorPropertyName(propertyName.get(), structureEnumerator.get(), i.get()); 2070 2071 generator.emitLabel(loopStart.get()); 2072 generator.emitLoopHint(); 2073 2074 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get()); 2075 generator.emitJumpIfTrue(result.get(), loopEnd.get()); 2076 generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), structureEnumerator.get()); 2077 generator.emitJumpIfFalse(result.get(), scope->continueTarget()); 2078 2079 this->emitLoopHeader(generator, propertyName.get()); 2080 2081 generator.pushStructureForInScope(local.get(), i.get(), propertyName.get(), structureEnumerator.get()); 2082 generator.emitNode(dst, m_statement); 2083 generator.popStructureForInScope(local.get()); 2084 2085 generator.emitLabel(scope->continueTarget()); 2086 generator.emitInc(i.get()); 2087 generator.emitNextEnumeratorPropertyName(propertyName.get(), structureEnumerator.get(), i.get()); 2088 generator.emitJump(loopStart.get()); 2089 2090 generator.emitLabel(scope->breakTarget()); 2091 generator.emitJump(end.get()); 2092 generator.emitLabel(loopEnd.get()); 2093 } 2094 2095 // Generic property loop. 2096 { 2097 LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop); 2098 RefPtr<Label> loopStart = generator.newLabel(); 2099 RefPtr<Label> loopEnd = generator.newLabel(); 2100 2101 RefPtr<RegisterID> genericEnumerator = generator.emitGetGenericPropertyEnumerator(generator.newTemporary(), base.get(), length.get(), structureEnumerator.get()); 2102 RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0)); 2103 RefPtr<RegisterID> propertyName = generator.newTemporary(); 2104 2105 generator.emitNextEnumeratorPropertyName(propertyName.get(), genericEnumerator.get(), i.get()); 2106 RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get()); 2107 generator.emitJumpIfTrue(result.get(), loopEnd.get()); 2108 2109 generator.emitLabel(loopStart.get()); 2110 generator.emitLoopHint(); 2111 2112 this->emitLoopHeader(generator, propertyName.get()); 2113 2114 generator.emitNode(dst, m_statement); 2115 2116 generator.emitLabel(scope->continueTarget()); 2117 generator.emitInc(i.get()); 2118 generator.emitNextEnumeratorPropertyName(propertyName.get(), genericEnumerator.get(), i.get()); 2119 generator.emitUnaryOp(op_eq_null, result.get(), propertyName.get()); 2120 generator.emitJumpIfTrue(result.get(), loopEnd.get()); 2121 2122 generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get()); 2123 generator.emitJumpIfTrue(result.get(), loopStart.get()); 2124 generator.emitJump(scope->continueTarget()); 2125 2126 generator.emitLabel(scope->breakTarget()); 2127 generator.emitJump(end.get()); 2128 generator.emitLabel(loopEnd.get()); 2129 } 2130 2131 generator.emitDebugHook(WillExecuteStatement, firstLine(), startOffset(), lineStartOffset()); 2132 generator.emitLabel(end.get()); 2133 } 2134 2135 void ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 2136 { 2137 this->emitMultiLoopBytecode(generator, dst); 2019 2138 } 2020 2139
Note:
See TracChangeset
for help on using the changeset viewer.