summaryrefslogtreecommitdiff
path: root/src/3rdparty/v8/src/property.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/v8/src/property.h')
-rw-r--r--src/3rdparty/v8/src/property.h348
1 files changed, 348 insertions, 0 deletions
diff --git a/src/3rdparty/v8/src/property.h b/src/3rdparty/v8/src/property.h
new file mode 100644
index 0000000..fa3916e
--- /dev/null
+++ b/src/3rdparty/v8/src/property.h
@@ -0,0 +1,348 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PROPERTY_H_
+#define V8_PROPERTY_H_
+
+namespace v8 {
+namespace internal {
+
+
+// Abstraction for elements in instance-descriptor arrays.
+//
+// Each descriptor has a key, property attributes, property type,
+// property index (in the actual instance-descriptor array) and
+// optionally a piece of data.
+//
+
+class Descriptor BASE_EMBEDDED {
+ public:
+ static int IndexFromValue(Object* value) {
+ return Smi::cast(value)->value();
+ }
+
+ MUST_USE_RESULT MaybeObject* KeyToSymbol() {
+ if (!StringShape(key_).IsSymbol()) {
+ Object* result;
+ { MaybeObject* maybe_result = HEAP->LookupSymbol(key_);
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ key_ = String::cast(result);
+ }
+ return key_;
+ }
+
+ String* GetKey() { return key_; }
+ Object* GetValue() { return value_; }
+ PropertyDetails GetDetails() { return details_; }
+
+#ifdef OBJECT_PRINT
+ void Print(FILE* out);
+#endif
+
+ void SetEnumerationIndex(int index) {
+ ASSERT(PropertyDetails::IsValidIndex(index));
+ details_ = PropertyDetails(details_.attributes(), details_.type(), index);
+ }
+
+ private:
+ String* key_;
+ Object* value_;
+ PropertyDetails details_;
+
+ protected:
+ Descriptor() : details_(Smi::FromInt(0)) {}
+
+ void Init(String* key, Object* value, PropertyDetails details) {
+ key_ = key;
+ value_ = value;
+ details_ = details;
+ }
+
+ Descriptor(String* key, Object* value, PropertyDetails details)
+ : key_(key),
+ value_(value),
+ details_(details) { }
+
+ Descriptor(String* key,
+ Object* value,
+ PropertyAttributes attributes,
+ PropertyType type,
+ int index = 0)
+ : key_(key),
+ value_(value),
+ details_(attributes, type, index) { }
+
+ friend class DescriptorArray;
+};
+
+// A pointer from a map to the new map that is created by adding
+// a named property. These are key to the speed and functioning of V8.
+// The two maps should always have the same prototype, since
+// MapSpace::CreateBackPointers depends on this.
+class MapTransitionDescriptor: public Descriptor {
+ public:
+ MapTransitionDescriptor(String* key, Map* map, PropertyAttributes attributes)
+ : Descriptor(key, map, attributes, MAP_TRANSITION) { }
+};
+
+class ExternalArrayTransitionDescriptor: public Descriptor {
+ public:
+ ExternalArrayTransitionDescriptor(String* key,
+ Map* map,
+ ExternalArrayType array_type)
+ : Descriptor(key, map, PropertyDetails(NONE,
+ EXTERNAL_ARRAY_TRANSITION,
+ array_type)) { }
+};
+
+// Marks a field name in a map so that adding the field is guaranteed
+// to create a FIELD descriptor in the new map. Used after adding
+// a constant function the first time, creating a CONSTANT_FUNCTION
+// descriptor in the new map. This avoids creating multiple maps with
+// the same CONSTANT_FUNCTION field.
+class ConstTransitionDescriptor: public Descriptor {
+ public:
+ explicit ConstTransitionDescriptor(String* key, Map* map)
+ : Descriptor(key, map, NONE, CONSTANT_TRANSITION) { }
+};
+
+
+class FieldDescriptor: public Descriptor {
+ public:
+ FieldDescriptor(String* key,
+ int field_index,
+ PropertyAttributes attributes,
+ int index = 0)
+ : Descriptor(key, Smi::FromInt(field_index), attributes, FIELD, index) {}
+};
+
+
+class ConstantFunctionDescriptor: public Descriptor {
+ public:
+ ConstantFunctionDescriptor(String* key,
+ JSFunction* function,
+ PropertyAttributes attributes,
+ int index = 0)
+ : Descriptor(key, function, attributes, CONSTANT_FUNCTION, index) {}
+};
+
+
+class CallbacksDescriptor: public Descriptor {
+ public:
+ CallbacksDescriptor(String* key,
+ Object* proxy,
+ PropertyAttributes attributes,
+ int index = 0)
+ : Descriptor(key, proxy, attributes, CALLBACKS, index) {}
+};
+
+
+class LookupResult BASE_EMBEDDED {
+ public:
+ // Where did we find the result;
+ enum {
+ NOT_FOUND,
+ DESCRIPTOR_TYPE,
+ DICTIONARY_TYPE,
+ INTERCEPTOR_TYPE,
+ CONSTANT_TYPE
+ } lookup_type_;
+
+ LookupResult()
+ : lookup_type_(NOT_FOUND),
+ cacheable_(true),
+ details_(NONE, NORMAL) {}
+
+ void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
+ lookup_type_ = DESCRIPTOR_TYPE;
+ holder_ = holder;
+ details_ = details;
+ number_ = number;
+ }
+
+ void ConstantResult(JSObject* holder) {
+ lookup_type_ = CONSTANT_TYPE;
+ holder_ = holder;
+ details_ =
+ PropertyDetails(static_cast<PropertyAttributes>(DONT_ENUM |
+ DONT_DELETE),
+ CALLBACKS);
+ number_ = -1;
+ }
+
+ void DictionaryResult(JSObject* holder, int entry) {
+ lookup_type_ = DICTIONARY_TYPE;
+ holder_ = holder;
+ details_ = holder->property_dictionary()->DetailsAt(entry);
+ number_ = entry;
+ }
+
+ void InterceptorResult(JSObject* holder) {
+ lookup_type_ = INTERCEPTOR_TYPE;
+ holder_ = holder;
+ details_ = PropertyDetails(NONE, INTERCEPTOR);
+ }
+
+ void NotFound() {
+ lookup_type_ = NOT_FOUND;
+ }
+
+ JSObject* holder() {
+ ASSERT(IsFound());
+ return holder_;
+ }
+
+ PropertyType type() {
+ ASSERT(IsFound());
+ return details_.type();
+ }
+
+ PropertyAttributes GetAttributes() {
+ ASSERT(IsFound());
+ return details_.attributes();
+ }
+
+ PropertyDetails GetPropertyDetails() {
+ return details_;
+ }
+
+ bool IsReadOnly() { return details_.IsReadOnly(); }
+ bool IsDontDelete() { return details_.IsDontDelete(); }
+ bool IsDontEnum() { return details_.IsDontEnum(); }
+ bool IsDeleted() { return details_.IsDeleted(); }
+ bool IsFound() { return lookup_type_ != NOT_FOUND; }
+
+ // Is the result is a property excluding transitions and the null
+ // descriptor?
+ bool IsProperty() {
+ return IsFound() && (type() < FIRST_PHANTOM_PROPERTY_TYPE);
+ }
+
+ // Is the result a property or a transition?
+ bool IsPropertyOrTransition() {
+ return IsFound() && (type() != NULL_DESCRIPTOR);
+ }
+
+ bool IsCacheable() { return cacheable_; }
+ void DisallowCaching() { cacheable_ = false; }
+
+ Object* GetLazyValue() {
+ switch (type()) {
+ case FIELD:
+ return holder()->FastPropertyAt(GetFieldIndex());
+ case NORMAL: {
+ Object* value;
+ value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry());
+ if (holder()->IsGlobalObject()) {
+ value = JSGlobalPropertyCell::cast(value)->value();
+ }
+ return value;
+ }
+ case CONSTANT_FUNCTION:
+ return GetConstantFunction();
+ default:
+ return Smi::FromInt(0);
+ }
+ }
+
+ Map* GetTransitionMap() {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(type() == MAP_TRANSITION || type() == CONSTANT_TRANSITION ||
+ type() == EXTERNAL_ARRAY_TRANSITION);
+ return Map::cast(GetValue());
+ }
+
+ Map* GetTransitionMapFromMap(Map* map) {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(type() == MAP_TRANSITION);
+ return Map::cast(map->instance_descriptors()->GetValue(number_));
+ }
+
+ int GetFieldIndex() {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(type() == FIELD);
+ return Descriptor::IndexFromValue(GetValue());
+ }
+
+ int GetLocalFieldIndexFromMap(Map* map) {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(type() == FIELD);
+ return Descriptor::IndexFromValue(
+ map->instance_descriptors()->GetValue(number_)) -
+ map->inobject_properties();
+ }
+
+ int GetDictionaryEntry() {
+ ASSERT(lookup_type_ == DICTIONARY_TYPE);
+ return number_;
+ }
+
+ JSFunction* GetConstantFunction() {
+ ASSERT(type() == CONSTANT_FUNCTION);
+ return JSFunction::cast(GetValue());
+ }
+
+ JSFunction* GetConstantFunctionFromMap(Map* map) {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(type() == CONSTANT_FUNCTION);
+ return JSFunction::cast(map->instance_descriptors()->GetValue(number_));
+ }
+
+ Object* GetCallbackObject() {
+ if (lookup_type_ == CONSTANT_TYPE) {
+ // For now we only have the __proto__ as constant type.
+ return HEAP->prototype_accessors();
+ }
+ return GetValue();
+ }
+
+#ifdef OBJECT_PRINT
+ void Print(FILE* out);
+#endif
+
+ Object* GetValue() {
+ if (lookup_type_ == DESCRIPTOR_TYPE) {
+ DescriptorArray* descriptors = holder()->map()->instance_descriptors();
+ return descriptors->GetValue(number_);
+ }
+ // In the dictionary case, the data is held in the value field.
+ ASSERT(lookup_type_ == DICTIONARY_TYPE);
+ return holder()->GetNormalizedProperty(this);
+ }
+
+ private:
+ JSObject* holder_;
+ int number_;
+ bool cacheable_;
+ PropertyDetails details_;
+};
+
+
+} } // namespace v8::internal
+
+#endif // V8_PROPERTY_H_