1 | // Copyright 2014 the V8 project authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #include "src/property.h" |
6 | |
7 | #include "src/field-type.h" |
8 | #include "src/handles-inl.h" |
9 | #include "src/objects-inl.h" |
10 | #include "src/objects/name-inl.h" |
11 | #include "src/objects/smi.h" |
12 | #include "src/ostreams.h" |
13 | |
14 | namespace v8 { |
15 | namespace internal { |
16 | |
17 | std::ostream& operator<<(std::ostream& os, |
18 | const PropertyAttributes& attributes) { |
19 | os << "[" ; |
20 | os << (((attributes & READ_ONLY) == 0) ? "W" : "_" ); // writable |
21 | os << (((attributes & DONT_ENUM) == 0) ? "E" : "_" ); // enumerable |
22 | os << (((attributes & DONT_DELETE) == 0) ? "C" : "_" ); // configurable |
23 | os << "]" ; |
24 | return os; |
25 | } |
26 | |
27 | Descriptor::Descriptor() : details_(Smi::zero()) {} |
28 | |
29 | Descriptor::Descriptor(Handle<Name> key, const MaybeObjectHandle& value, |
30 | PropertyKind kind, PropertyAttributes attributes, |
31 | PropertyLocation location, PropertyConstness constness, |
32 | Representation representation, int field_index) |
33 | : key_(key), |
34 | value_(value), |
35 | details_(kind, attributes, location, constness, representation, |
36 | field_index) { |
37 | DCHECK(key->IsUniqueName()); |
38 | DCHECK_IMPLIES(key->IsPrivate(), !details_.IsEnumerable()); |
39 | } |
40 | |
41 | Descriptor::Descriptor(Handle<Name> key, const MaybeObjectHandle& value, |
42 | PropertyDetails details) |
43 | : key_(key), value_(value), details_(details) { |
44 | DCHECK(key->IsUniqueName()); |
45 | DCHECK_IMPLIES(key->IsPrivate(), !details_.IsEnumerable()); |
46 | } |
47 | |
48 | Descriptor Descriptor::DataField(Isolate* isolate, Handle<Name> key, |
49 | int field_index, PropertyAttributes attributes, |
50 | Representation representation) { |
51 | return DataField(key, field_index, attributes, PropertyConstness::kMutable, |
52 | representation, MaybeObjectHandle(FieldType::Any(isolate))); |
53 | } |
54 | |
55 | Descriptor Descriptor::DataField(Handle<Name> key, int field_index, |
56 | PropertyAttributes attributes, |
57 | PropertyConstness constness, |
58 | Representation representation, |
59 | const MaybeObjectHandle& wrapped_field_type) { |
60 | DCHECK(wrapped_field_type->IsSmi() || wrapped_field_type->IsWeak()); |
61 | PropertyDetails details(kData, attributes, kField, constness, representation, |
62 | field_index); |
63 | return Descriptor(key, wrapped_field_type, details); |
64 | } |
65 | |
66 | Descriptor Descriptor::DataConstant(Handle<Name> key, Handle<Object> value, |
67 | PropertyAttributes attributes) { |
68 | return Descriptor(key, MaybeObjectHandle(value), kData, attributes, |
69 | kDescriptor, PropertyConstness::kConst, |
70 | value->OptimalRepresentation(), 0); |
71 | } |
72 | |
73 | Descriptor Descriptor::DataConstant(Isolate* isolate, Handle<Name> key, |
74 | int field_index, Handle<Object> value, |
75 | PropertyAttributes attributes) { |
76 | if (FLAG_track_constant_fields) { |
77 | MaybeObjectHandle any_type(FieldType::Any(), isolate); |
78 | return DataField(key, field_index, attributes, PropertyConstness::kConst, |
79 | Representation::Tagged(), any_type); |
80 | |
81 | } else { |
82 | return Descriptor(key, MaybeObjectHandle(value), kData, attributes, |
83 | kDescriptor, PropertyConstness::kConst, |
84 | value->OptimalRepresentation(), field_index); |
85 | } |
86 | } |
87 | |
88 | Descriptor Descriptor::AccessorConstant(Handle<Name> key, |
89 | Handle<Object> foreign, |
90 | PropertyAttributes attributes) { |
91 | return Descriptor(key, MaybeObjectHandle(foreign), kAccessor, attributes, |
92 | kDescriptor, PropertyConstness::kConst, |
93 | Representation::Tagged(), 0); |
94 | } |
95 | |
96 | // Outputs PropertyDetails as a dictionary details. |
97 | void PropertyDetails::PrintAsSlowTo(std::ostream& os) { |
98 | os << "(" ; |
99 | if (constness() == PropertyConstness::kConst) os << "const " ; |
100 | os << (kind() == kData ? "data" : "accessor" ); |
101 | os << ", dict_index: " << dictionary_index(); |
102 | os << ", attrs: " << attributes() << ")" ; |
103 | } |
104 | |
105 | // Outputs PropertyDetails as a descriptor array details. |
106 | void PropertyDetails::PrintAsFastTo(std::ostream& os, PrintMode mode) { |
107 | os << "(" ; |
108 | if (constness() == PropertyConstness::kConst) os << "const " ; |
109 | os << (kind() == kData ? "data" : "accessor" ); |
110 | if (location() == kField) { |
111 | os << " field" ; |
112 | if (mode & kPrintFieldIndex) { |
113 | os << " " << field_index(); |
114 | } |
115 | if (mode & kPrintRepresentation) { |
116 | os << ":" << representation().Mnemonic(); |
117 | } |
118 | } else { |
119 | os << " descriptor" ; |
120 | } |
121 | if (mode & kPrintPointer) { |
122 | os << ", p: " << pointer(); |
123 | } |
124 | if (mode & kPrintAttributes) { |
125 | os << ", attrs: " << attributes(); |
126 | } |
127 | os << ")" ; |
128 | } |
129 | |
130 | #ifdef OBJECT_PRINT |
131 | void PropertyDetails::Print(bool dictionary_mode) { |
132 | StdoutStream os; |
133 | if (dictionary_mode) { |
134 | PrintAsSlowTo(os); |
135 | } else { |
136 | PrintAsFastTo(os, PrintMode::kPrintFull); |
137 | } |
138 | os << "\n" << std::flush; |
139 | } |
140 | #endif |
141 | |
142 | } // namespace internal |
143 | } // namespace v8 |
144 | |