Version 3.5.9.
Made FromPropertyDescriptor not trigger inherited setters.
Fixed .gyp files to work on the ARM simulator.
Fixed shared library build warnings for MSVS.
git-svn-id: http://v8.googlecode.com/svn/trunk@9041 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 098bd7a..b4c6a3a 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -178,10 +178,14 @@
bool Object::IsConsString() {
- if (!this->IsHeapObject()) return false;
- uint32_t type = HeapObject::cast(this)->map()->instance_type();
- return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
- (kStringTag | kConsStringTag);
+ if (!IsString()) return false;
+ return StringShape(String::cast(this)).IsCons();
+}
+
+
+bool Object::IsSlicedString() {
+ if (!IsString()) return false;
+ return StringShape(String::cast(this)).IsSliced();
}
@@ -269,6 +273,38 @@
}
+bool String::IsAsciiRepresentationUnderneath() {
+ uint32_t type = map()->instance_type();
+ STATIC_ASSERT(kIsIndirectStringTag != 0);
+ STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
+ ASSERT(IsFlat());
+ switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
+ case kAsciiStringTag:
+ return true;
+ case kTwoByteStringTag:
+ return false;
+ default: // Cons or sliced string. Need to go deeper.
+ return GetUnderlying()->IsAsciiRepresentation();
+ }
+}
+
+
+bool String::IsTwoByteRepresentationUnderneath() {
+ uint32_t type = map()->instance_type();
+ STATIC_ASSERT(kIsIndirectStringTag != 0);
+ STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
+ ASSERT(IsFlat());
+ switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
+ case kAsciiStringTag:
+ return false;
+ case kTwoByteStringTag:
+ return true;
+ default: // Cons or sliced string. Need to go deeper.
+ return GetUnderlying()->IsTwoByteRepresentation();
+ }
+}
+
+
bool String::HasOnlyAsciiChars() {
uint32_t type = map()->instance_type();
return (type & kStringEncodingMask) == kAsciiStringTag ||
@@ -281,6 +317,16 @@
}
+bool StringShape::IsSliced() {
+ return (type_ & kStringRepresentationMask) == kSlicedStringTag;
+}
+
+
+bool StringShape::IsIndirect() {
+ return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
+}
+
+
bool StringShape::IsExternal() {
return (type_ & kStringRepresentationMask) == kExternalStringTag;
}
@@ -2075,6 +2121,7 @@
CAST_ACCESSOR(SeqString)
CAST_ACCESSOR(SeqAsciiString)
CAST_ACCESSOR(SeqTwoByteString)
+CAST_ACCESSOR(SlicedString)
CAST_ACCESSOR(ConsString)
CAST_ACCESSOR(ExternalString)
CAST_ACCESSOR(ExternalAsciiString)
@@ -2156,7 +2203,7 @@
MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
if (!StringShape(this).IsCons()) return this;
ConsString* cons = ConsString::cast(this);
- if (cons->second()->length() == 0) return cons->first();
+ if (cons->IsFlat()) return cons->first();
return SlowTryFlatten(pretenure);
}
@@ -2164,10 +2211,8 @@
String* String::TryFlattenGetString(PretenureFlag pretenure) {
MaybeObject* flat = TryFlatten(pretenure);
Object* successfully_flattened;
- if (flat->ToObject(&successfully_flattened)) {
- return String::cast(successfully_flattened);
- }
- return this;
+ if (!flat->ToObject(&successfully_flattened)) return this;
+ return String::cast(successfully_flattened);
}
@@ -2185,6 +2230,9 @@
return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
case kExternalStringTag | kTwoByteStringTag:
return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
+ case kSlicedStringTag | kAsciiStringTag:
+ case kSlicedStringTag | kTwoByteStringTag:
+ return SlicedString::cast(this)->SlicedStringGet(index);
default:
break;
}
@@ -2205,15 +2253,19 @@
bool String::IsFlat() {
- switch (StringShape(this).representation_tag()) {
- case kConsStringTag: {
- String* second = ConsString::cast(this)->second();
- // Only flattened strings have second part empty.
- return second->length() == 0;
- }
- default:
- return true;
- }
+ if (!StringShape(this).IsCons()) return true;
+ return ConsString::cast(this)->second()->length() == 0;
+}
+
+
+String* String::GetUnderlying() {
+ // Giving direct access to underlying string only makes sense if the
+ // wrapping string is already flattened.
+ ASSERT(this->IsFlat());
+ ASSERT(StringShape(this).IsIndirect());
+ STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
+ const int kUnderlyingOffset = SlicedString::kParentOffset;
+ return String::cast(READ_FIELD(this, kUnderlyingOffset));
}
@@ -2272,6 +2324,20 @@
}
+String* SlicedString::parent() {
+ return String::cast(READ_FIELD(this, kParentOffset));
+}
+
+
+void SlicedString::set_parent(String* parent) {
+ ASSERT(parent->IsSeqString());
+ WRITE_FIELD(this, kParentOffset, parent);
+}
+
+
+SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
+
+
String* ConsString::first() {
return String::cast(READ_FIELD(this, kFirstOffset));
}