Line data Source code
1 : // Copyright 2016 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/builtins/builtins-utils-inl.h"
6 : #include "src/builtins/builtins.h"
7 : #include "src/counters.h"
8 : #include "src/keys.h"
9 : #include "src/lookup.h"
10 : #include "src/objects-inl.h"
11 : #include "src/property-descriptor.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : // -----------------------------------------------------------------------------
17 : // ES6 section 26.1 The Reflect Object
18 :
19 : // ES6 section 26.1.3 Reflect.defineProperty
20 93640 : BUILTIN(ReflectDefineProperty) {
21 : HandleScope scope(isolate);
22 : DCHECK_EQ(4, args.length());
23 : Handle<Object> target = args.at(1);
24 18728 : Handle<Object> key = args.at(2);
25 18728 : Handle<Object> attributes = args.at(3);
26 :
27 18728 : if (!target->IsJSReceiver()) {
28 243 : THROW_NEW_ERROR_RETURN_FAILURE(
29 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
30 : isolate->factory()->NewStringFromAsciiChecked(
31 : "Reflect.defineProperty")));
32 : }
33 :
34 : Handle<Name> name;
35 37303 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
36 : Object::ToName(isolate, key));
37 :
38 : PropertyDescriptor desc;
39 : if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
40 54 : return ReadOnlyRoots(isolate).exception();
41 : }
42 :
43 : Maybe<bool> result = JSReceiver::DefineOwnProperty(
44 18584 : isolate, Handle<JSReceiver>::cast(target), name, &desc, Just(kDontThrow));
45 26602 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
46 21132 : return *isolate->factory()->ToBoolean(result.FromJust());
47 : }
48 :
49 : // ES6 section 26.1.4 Reflect.deleteProperty
50 49470 : BUILTIN(ReflectDeleteProperty) {
51 : HandleScope scope(isolate);
52 : DCHECK_EQ(3, args.length());
53 : Handle<Object> target = args.at(1);
54 9894 : Handle<Object> key = args.at(2);
55 :
56 9894 : if (!target->IsJSReceiver()) {
57 162 : THROW_NEW_ERROR_RETURN_FAILURE(
58 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
59 : isolate->factory()->NewStringFromAsciiChecked(
60 : "Reflect.deleteProperty")));
61 : }
62 :
63 : Handle<Name> name;
64 19689 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
65 : Object::ToName(isolate, key));
66 :
67 : Maybe<bool> result = JSReceiver::DeletePropertyOrElement(
68 9831 : Handle<JSReceiver>::cast(target), name, LanguageMode::kSloppy);
69 16998 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
70 5328 : return *isolate->factory()->ToBoolean(result.FromJust());
71 : }
72 :
73 : // ES6 section 26.1.6 Reflect.get
74 84160 : BUILTIN(ReflectGet) {
75 : HandleScope scope(isolate);
76 : Handle<Object> target = args.atOrUndefined(isolate, 1);
77 16832 : Handle<Object> key = args.atOrUndefined(isolate, 2);
78 31025 : Handle<Object> receiver = args.length() > 3 ? args.at(3) : target;
79 :
80 16832 : if (!target->IsJSReceiver()) {
81 324 : THROW_NEW_ERROR_RETURN_FAILURE(
82 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
83 : isolate->factory()->NewStringFromAsciiChecked(
84 : "Reflect.get")));
85 : }
86 :
87 : Handle<Name> name;
88 33476 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
89 : Object::ToName(isolate, key));
90 :
91 40205 : RETURN_RESULT_OR_FAILURE(
92 : isolate, Object::GetPropertyOrElement(receiver, name,
93 : Handle<JSReceiver>::cast(target)));
94 : }
95 :
96 : // ES6 section 26.1.7 Reflect.getOwnPropertyDescriptor
97 42335 : BUILTIN(ReflectGetOwnPropertyDescriptor) {
98 : HandleScope scope(isolate);
99 : DCHECK_EQ(3, args.length());
100 : Handle<Object> target = args.at(1);
101 8467 : Handle<Object> key = args.at(2);
102 :
103 8467 : if (!target->IsJSReceiver()) {
104 162 : THROW_NEW_ERROR_RETURN_FAILURE(
105 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
106 : isolate->factory()->NewStringFromAsciiChecked(
107 : "Reflect.getOwnPropertyDescriptor")));
108 : }
109 :
110 : Handle<Name> name;
111 16835 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
112 : Object::ToName(isolate, key));
113 :
114 : PropertyDescriptor desc;
115 : Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor(
116 8404 : isolate, Handle<JSReceiver>::cast(target), name, &desc);
117 14981 : MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
118 2367 : if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
119 2574 : return *desc.ToObject(isolate);
120 : }
121 :
122 : // ES6 section 26.1.8 Reflect.getPrototypeOf
123 4285 : BUILTIN(ReflectGetPrototypeOf) {
124 : HandleScope scope(isolate);
125 : DCHECK_EQ(2, args.length());
126 : Handle<Object> target = args.at(1);
127 :
128 857 : if (!target->IsJSReceiver()) {
129 432 : THROW_NEW_ERROR_RETURN_FAILURE(
130 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
131 : isolate->factory()->NewStringFromAsciiChecked(
132 : "Reflect.getPrototypeOf")));
133 : }
134 713 : Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(target);
135 1453 : RETURN_RESULT_OR_FAILURE(isolate,
136 : JSReceiver::GetPrototype(isolate, receiver));
137 : }
138 :
139 : // ES6 section 26.1.10 Reflect.isExtensible
140 57180 : BUILTIN(ReflectIsExtensible) {
141 : HandleScope scope(isolate);
142 : DCHECK_EQ(2, args.length());
143 : Handle<Object> target = args.at(1);
144 :
145 11436 : if (!target->IsJSReceiver()) {
146 162 : THROW_NEW_ERROR_RETURN_FAILURE(
147 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
148 : isolate->factory()->NewStringFromAsciiChecked(
149 : "Reflect.isExtensible")));
150 : }
151 :
152 : Maybe<bool> result =
153 11382 : JSReceiver::IsExtensible(Handle<JSReceiver>::cast(target));
154 21846 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
155 1836 : return *isolate->factory()->ToBoolean(result.FromJust());
156 : }
157 :
158 : // ES6 section 26.1.11 Reflect.ownKeys
159 40250 : BUILTIN(ReflectOwnKeys) {
160 : HandleScope scope(isolate);
161 : DCHECK_EQ(2, args.length());
162 : Handle<Object> target = args.at(1);
163 :
164 8050 : if (!target->IsJSReceiver()) {
165 243 : THROW_NEW_ERROR_RETURN_FAILURE(
166 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
167 : isolate->factory()->NewStringFromAsciiChecked(
168 : "Reflect.ownKeys")));
169 : }
170 :
171 : Handle<FixedArray> keys;
172 23070 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
173 : isolate, keys,
174 : KeyAccumulator::GetKeys(Handle<JSReceiver>::cast(target),
175 : KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
176 : GetKeysConversion::kConvertToString));
177 837 : return *isolate->factory()->NewJSArrayWithElements(keys);
178 : }
179 :
180 : // ES6 section 26.1.12 Reflect.preventExtensions
181 53760 : BUILTIN(ReflectPreventExtensions) {
182 : HandleScope scope(isolate);
183 : DCHECK_EQ(2, args.length());
184 : Handle<Object> target = args.at(1);
185 :
186 10752 : if (!target->IsJSReceiver()) {
187 162 : THROW_NEW_ERROR_RETURN_FAILURE(
188 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
189 : isolate->factory()->NewStringFromAsciiChecked(
190 : "Reflect.preventExtensions")));
191 : }
192 :
193 : Maybe<bool> result = JSReceiver::PreventExtensions(
194 10698 : Handle<JSReceiver>::cast(target), kDontThrow);
195 21144 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
196 504 : return *isolate->factory()->ToBoolean(result.FromJust());
197 : }
198 :
199 : // ES6 section 26.1.13 Reflect.set
200 72410 : BUILTIN(ReflectSet) {
201 : HandleScope scope(isolate);
202 : Handle<Object> target = args.atOrUndefined(isolate, 1);
203 14482 : Handle<Object> key = args.atOrUndefined(isolate, 2);
204 14482 : Handle<Object> value = args.atOrUndefined(isolate, 3);
205 25142 : Handle<Object> receiver = args.length() > 4 ? args.at(4) : target;
206 :
207 14482 : if (!target->IsJSReceiver()) {
208 162 : THROW_NEW_ERROR_RETURN_FAILURE(
209 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
210 : isolate->factory()->NewStringFromAsciiChecked(
211 : "Reflect.set")));
212 : }
213 :
214 : Handle<Name> name;
215 28865 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
216 : Object::ToName(isolate, key));
217 :
218 : LookupIterator it = LookupIterator::PropertyOrElement(
219 14419 : isolate, receiver, name, Handle<JSReceiver>::cast(target));
220 : Maybe<bool> result = Object::SetSuperProperty(
221 14419 : &it, value, StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kDontThrow));
222 20039 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
223 17598 : return *isolate->factory()->ToBoolean(result.FromJust());
224 : }
225 :
226 : // ES6 section 26.1.14 Reflect.setPrototypeOf
227 56645 : BUILTIN(ReflectSetPrototypeOf) {
228 : HandleScope scope(isolate);
229 : DCHECK_EQ(3, args.length());
230 : Handle<Object> target = args.at(1);
231 : Handle<Object> proto = args.at(2);
232 :
233 11329 : if (!target->IsJSReceiver()) {
234 324 : THROW_NEW_ERROR_RETURN_FAILURE(
235 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
236 : isolate->factory()->NewStringFromAsciiChecked(
237 : "Reflect.setPrototypeOf")));
238 : }
239 :
240 11815 : if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) {
241 972 : THROW_NEW_ERROR_RETURN_FAILURE(
242 : isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
243 : }
244 :
245 : Maybe<bool> result = JSReceiver::SetPrototype(
246 10735 : Handle<JSReceiver>::cast(target), proto, true, kDontThrow);
247 20129 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
248 2682 : return *isolate->factory()->ToBoolean(result.FromJust());
249 : }
250 :
251 : } // namespace internal
252 122036 : } // namespace v8
|