Commit 85eb7df9 authored by fpizlo@apple.com's avatar fpizlo@apple.com

It should be possible to hijack IndexingHeader for things other than lengths

https://bugs.webkit.org/show_bug.cgi?id=119065

Reviewed by Mark Hahnenberg.
        
Made the body of IndexingHeader be a union.
        
Modified the offlineasm so that you can say IndexingHeader::u.lengths.publicLength.
Previously those dots would cause parse errors. Now an identifier in offlineasm can
have a dot anywhere except the first character.

* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/parser.rb:
* runtime/IndexingHeader.h:
(JSC::IndexingHeader::offsetOfPublicLength):
(JSC::IndexingHeader::offsetOfVectorLength):
(JSC::IndexingHeader::IndexingHeader):
(JSC::IndexingHeader::vectorLength):
(JSC::IndexingHeader::setVectorLength):
(JSC::IndexingHeader::publicLength):
(JSC::IndexingHeader::setPublicLength):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153104 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 7e9bb4ce
2013-07-24 Filip Pizlo <fpizlo@apple.com>
It should be possible to hijack IndexingHeader for things other than lengths
https://bugs.webkit.org/show_bug.cgi?id=119065
Reviewed by Mark Hahnenberg.
Made the body of IndexingHeader be a union.
Modified the offlineasm so that you can say IndexingHeader::u.lengths.publicLength.
Previously those dots would cause parse errors. Now an identifier in offlineasm can
have a dot anywhere except the first character.
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/parser.rb:
* runtime/IndexingHeader.h:
(JSC::IndexingHeader::offsetOfPublicLength):
(JSC::IndexingHeader::offsetOfVectorLength):
(JSC::IndexingHeader::IndexingHeader):
(JSC::IndexingHeader::vectorLength):
(JSC::IndexingHeader::setVectorLength):
(JSC::IndexingHeader::publicLength):
(JSC::IndexingHeader::setPublicLength):
2013-07-24 Mark Hahnenberg <mhahnenberg@apple.com>
JIT::updateTopCallFrame doesn't update the CallFrame's bytecodeOffset if bytecodeOffset == 0
......
......@@ -1047,7 +1047,7 @@ _llint_op_get_array_length:
loadi 4[PC], t1
loadp 32[PC], t2
loadp JSObject::m_butterfly[t3], t0
loadi -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], t0
loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
bilt t0, 0, .opGetArrayLengthSlow
valueProfile(Int32Tag, t0, t2)
storep t0, PayloadOffset[cfr, t1, 8]
......@@ -1182,14 +1182,14 @@ _llint_op_get_by_val:
bineq t2, ContiguousShape, .opGetByValNotContiguous
.opGetByValIsContiguous:
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValOutOfBounds
biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadi TagOffset[t3, t1, 8], t2
loadi PayloadOffset[t3, t1, 8], t1
jmp .opGetByValDone
.opGetByValNotContiguous:
bineq t2, DoubleShape, .opGetByValNotDouble
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValOutOfBounds
biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadd [t3, t1, 8], ft0
bdnequn ft0, ft0, .opGetByValSlow
# FIXME: This could be massively optimized.
......@@ -1200,7 +1200,7 @@ _llint_op_get_by_val:
.opGetByValNotDouble:
subi ArrayStorageShape, t2
bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValOutOfBounds
biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t3], .opGetByValOutOfBounds
loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
......@@ -1282,20 +1282,20 @@ _llint_op_get_by_pname:
macro contiguousPutByVal(storeCallback)
biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds
biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
.storeResult:
loadi 12[PC], t2
storeCallback(t2, t1, t0, t3)
dispatch(5)
.outOfBounds:
biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValOutOfBounds
biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
if VALUE_PROFILER
loadp 16[PC], t2
storeb 1, ArrayProfile::m_mayStoreToHole[t2]
end
addi 1, t3, t2
storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .storeResult
end
......@@ -1349,7 +1349,7 @@ _llint_op_put_by_val:
.opPutByValNotContiguous:
bineq t2, ArrayStorageShape, .opPutByValSlow
biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValOutOfBounds
biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
bieq ArrayStorage::m_vector + TagOffset[t0, t3, 8], EmptyValueTag, .opPutByValArrayStorageEmpty
.opPutByValArrayStorageStoreResult:
loadi 12[PC], t2
......@@ -1365,9 +1365,9 @@ _llint_op_put_by_val:
storeb 1, ArrayProfile::m_mayStoreToHole[t1]
end
addi 1, ArrayStorage::m_numValuesInVector[t0]
bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult
bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
addi 1, t3, t1
storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
storei t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .opPutByValArrayStorageStoreResult
.opPutByValOutOfBounds:
......
......@@ -889,7 +889,7 @@ _llint_op_get_array_length:
loadisFromInstruction(1, t1)
loadpFromInstruction(8, t2)
loadp JSObject::m_butterfly[t3], t0
loadi -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], t0
loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
bilt t0, 0, .opGetArrayLengthSlow
orq tagTypeNumber, t0
valueProfile(t0, t2)
......@@ -1022,7 +1022,7 @@ _llint_op_get_by_val:
bineq t2, ContiguousShape, .opGetByValNotContiguous
.opGetByValIsContiguous:
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValOutOfBounds
biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadisFromInstruction(1, t0)
loadq [t3, t1, 8], t2
btqz t2, .opGetByValOutOfBounds
......@@ -1030,7 +1030,7 @@ _llint_op_get_by_val:
.opGetByValNotContiguous:
bineq t2, DoubleShape, .opGetByValNotDouble
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValOutOfBounds
biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
loadis 8[PB, PC, 8], t0
loadd [t3, t1, 8], ft0
bdnequn ft0, ft0, .opGetByValOutOfBounds
......@@ -1041,7 +1041,7 @@ _llint_op_get_by_val:
.opGetByValNotDouble:
subi ArrayStorageShape, t2
bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValOutOfBounds
biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t3], .opGetByValOutOfBounds
loadisFromInstruction(1, t0)
loadq ArrayStorage::m_vector[t3, t1, 8], t2
btqz t2, .opGetByValOutOfBounds
......@@ -1120,20 +1120,20 @@ _llint_op_get_by_pname:
macro contiguousPutByVal(storeCallback)
biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds
biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .outOfBounds
.storeResult:
loadisFromInstruction(3, t2)
storeCallback(t2, t1, [t0, t3, 8])
dispatch(5)
.outOfBounds:
biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValOutOfBounds
biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
if VALUE_PROFILER
loadp 32[PB, PC, 8], t2
storeb 1, ArrayProfile::m_mayStoreToHole[t2]
end
addi 1, t3, t2
storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
storei t2, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .storeResult
end
......@@ -1184,7 +1184,7 @@ _llint_op_put_by_val:
.opPutByValNotContiguous:
bineq t2, ArrayStorageShape, .opPutByValSlow
biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValOutOfBounds
biaeq t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t0], .opPutByValOutOfBounds
btqz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty
.opPutByValArrayStorageStoreResult:
loadisFromInstruction(3, t2)
......@@ -1199,9 +1199,9 @@ _llint_op_put_by_val:
storeb 1, ArrayProfile::m_mayStoreToHole[t1]
end
addi 1, ArrayStorage::m_numValuesInVector[t0]
bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult
bib t3, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], .opPutByValArrayStorageStoreResult
addi 1, t3, t1
storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
storei t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0]
jmp .opPutByValArrayStorageStoreResult
.opPutByValOutOfBounds:
......
......@@ -114,7 +114,7 @@ def lex(str, fileName)
end
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
lineNumber += 1
when /\A[a-zA-Z]([a-zA-Z0-9_]*)/
when /\A[a-zA-Z]([a-zA-Z0-9_.]*)/
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
when /\A\.([a-zA-Z0-9_]*)/
result << Token.new(CodeOrigin.new(fileName, lineNumber), $&)
......@@ -163,7 +163,7 @@ def isKeyword(token)
end
def isIdentifier(token)
token =~ /\A[a-zA-Z]([a-zA-Z0-9_]*)\Z/ and not isKeyword(token)
token =~ /\A[a-zA-Z]([a-zA-Z0-9_.]*)\Z/ and not isKeyword(token)
end
def isLabel(token)
......
......@@ -44,25 +44,25 @@ public:
static ptrdiff_t offsetOfIndexingHeader() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); }
static ptrdiff_t offsetOfPublicLength() { return OBJECT_OFFSETOF(IndexingHeader, m_publicLength); }
static ptrdiff_t offsetOfVectorLength() { return OBJECT_OFFSETOF(IndexingHeader, m_vectorLength); }
static ptrdiff_t offsetOfPublicLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.publicLength); }
static ptrdiff_t offsetOfVectorLength() { return OBJECT_OFFSETOF(IndexingHeader, u.lengths.vectorLength); }
IndexingHeader()
: m_publicLength(0)
, m_vectorLength(0)
{
u.lengths.publicLength = 0;
u.lengths.vectorLength = 0;
}
uint32_t vectorLength() const { return m_vectorLength; }
uint32_t vectorLength() const { return u.lengths.vectorLength; }
void setVectorLength(uint32_t length)
{
RELEASE_ASSERT(length <= maximumLength);
m_vectorLength = length;
u.lengths.vectorLength = length;
}
uint32_t publicLength() { return m_publicLength; }
void setPublicLength(uint32_t auxWord) { m_publicLength = auxWord; }
uint32_t publicLength() { return u.lengths.publicLength; }
void setPublicLength(uint32_t auxWord) { u.lengths.publicLength = auxWord; }
static IndexingHeader* from(Butterfly* butterfly)
{
......@@ -111,9 +111,13 @@ public:
private:
friend class LLIntOffsetsExtractor;
uint32_t m_publicLength; // The meaning of this field depends on the array type, but for all JSArrays we rely on this being the publicly visible length (array.length).
uint32_t m_vectorLength; // The length of the indexed property storage. The actual size of the storage depends on this, and the type.
union {
struct {
uint32_t publicLength; // The meaning of this field depends on the array type, but for all JSArrays we rely on this being the publicly visible length (array.length).
uint32_t vectorLength; // The length of the indexed property storage. The actual size of the storage depends on this, and the type.
} lengths;
} u;
};
} // namespace JSC
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment