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.h"
6 : #include "src/builtins/builtins-utils.h"
7 :
8 : #include "src/counters.h"
9 : #include "src/keys.h"
10 : #include "src/lookup.h"
11 : #include "src/objects-inl.h"
12 : #include "src/property-descriptor.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // -----------------------------------------------------------------------------
18 : // ES6 section 26.1 The Reflect Object
19 :
20 : // ES6 section 26.1.3 Reflect.defineProperty
21 49620 : BUILTIN(ReflectDefineProperty) {
22 : HandleScope scope(isolate);
23 : DCHECK_EQ(4, args.length());
24 : Handle<Object> target = args.at(1);
25 16540 : Handle<Object> key = args.at(2);
26 16540 : Handle<Object> attributes = args.at(3);
27 :
28 16540 : if (!target->IsJSReceiver()) {
29 252 : THROW_NEW_ERROR_RETURN_FAILURE(
30 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
31 : isolate->factory()->NewStringFromAsciiChecked(
32 : "Reflect.defineProperty")));
33 : }
34 :
35 : Handle<Name> name;
36 32912 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
37 : Object::ToName(isolate, key));
38 :
39 : PropertyDescriptor desc;
40 16442 : if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
41 84 : return isolate->heap()->exception();
42 : }
43 :
44 : Maybe<bool> result =
45 : JSReceiver::DefineOwnProperty(isolate, Handle<JSReceiver>::cast(target),
46 16358 : name, &desc, Object::DONT_THROW);
47 16358 : MAYBE_RETURN(result, isolate->heap()->exception());
48 32716 : return *isolate->factory()->ToBoolean(result.FromJust());
49 : }
50 :
51 : // ES6 section 26.1.4 Reflect.deleteProperty
52 13413 : BUILTIN(ReflectDeleteProperty) {
53 : HandleScope scope(isolate);
54 : DCHECK_EQ(3, args.length());
55 : Handle<Object> target = args.at(1);
56 4471 : Handle<Object> key = args.at(2);
57 :
58 4471 : if (!target->IsJSReceiver()) {
59 126 : THROW_NEW_ERROR_RETURN_FAILURE(
60 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
61 : isolate->factory()->NewStringFromAsciiChecked(
62 : "Reflect.deleteProperty")));
63 : }
64 :
65 : Handle<Name> name;
66 8858 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
67 : Object::ToName(isolate, key));
68 :
69 : Maybe<bool> result = JSReceiver::DeletePropertyOrElement(
70 4415 : Handle<JSReceiver>::cast(target), name, SLOPPY);
71 4415 : MAYBE_RETURN(result, isolate->heap()->exception());
72 8186 : return *isolate->factory()->ToBoolean(result.FromJust());
73 : }
74 :
75 : // ES6 section 26.1.6 Reflect.get
76 46293 : BUILTIN(ReflectGet) {
77 : HandleScope scope(isolate);
78 : Handle<Object> target = args.atOrUndefined(isolate, 1);
79 15431 : Handle<Object> key = args.atOrUndefined(isolate, 2);
80 26937 : Handle<Object> receiver = args.length() > 3 ? args.at(3) : target;
81 :
82 15431 : if (!target->IsJSReceiver()) {
83 126 : THROW_NEW_ERROR_RETURN_FAILURE(
84 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
85 : isolate->factory()->NewStringFromAsciiChecked(
86 : "Reflect.get")));
87 : }
88 :
89 : Handle<Name> name;
90 30778 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
91 : Object::ToName(isolate, key));
92 :
93 46097 : RETURN_RESULT_OR_FAILURE(
94 : isolate, Object::GetPropertyOrElement(receiver, name,
95 : Handle<JSReceiver>::cast(target)));
96 : }
97 :
98 : // ES6 section 26.1.7 Reflect.getOwnPropertyDescriptor
99 8910 : BUILTIN(ReflectGetOwnPropertyDescriptor) {
100 : HandleScope scope(isolate);
101 : DCHECK_EQ(3, args.length());
102 : Handle<Object> target = args.at(1);
103 2970 : Handle<Object> key = args.at(2);
104 :
105 2970 : if (!target->IsJSReceiver()) {
106 126 : THROW_NEW_ERROR_RETURN_FAILURE(
107 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
108 : isolate->factory()->NewStringFromAsciiChecked(
109 : "Reflect.getOwnPropertyDescriptor")));
110 : }
111 :
112 : Handle<Name> name;
113 5856 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
114 : Object::ToName(isolate, key));
115 :
116 : PropertyDescriptor desc;
117 : Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor(
118 2914 : isolate, Handle<JSReceiver>::cast(target), name, &desc);
119 2914 : MAYBE_RETURN(found, isolate->heap()->exception());
120 2886 : if (!found.FromJust()) return isolate->heap()->undefined_value();
121 4086 : return *desc.ToObject(isolate);
122 : }
123 :
124 : // ES6 section 26.1.8 Reflect.getPrototypeOf
125 3723 : BUILTIN(ReflectGetPrototypeOf) {
126 : HandleScope scope(isolate);
127 : DCHECK_EQ(2, args.length());
128 : Handle<Object> target = args.at(1);
129 :
130 1241 : if (!target->IsJSReceiver()) {
131 420 : THROW_NEW_ERROR_RETURN_FAILURE(
132 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
133 : isolate->factory()->NewStringFromAsciiChecked(
134 : "Reflect.getPrototypeOf")));
135 : }
136 1101 : Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(target);
137 3275 : RETURN_RESULT_OR_FAILURE(isolate,
138 : JSReceiver::GetPrototype(isolate, receiver));
139 : }
140 :
141 : // ES6 section 26.1.9 Reflect.has
142 25845 : BUILTIN(ReflectHas) {
143 : HandleScope scope(isolate);
144 : DCHECK_EQ(3, args.length());
145 : Handle<Object> target = args.at(1);
146 8615 : Handle<Object> key = args.at(2);
147 :
148 8615 : if (!target->IsJSReceiver()) {
149 126 : THROW_NEW_ERROR_RETURN_FAILURE(
150 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
151 : isolate->factory()->NewStringFromAsciiChecked(
152 : "Reflect.has")));
153 : }
154 :
155 : Handle<Name> name;
156 17146 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
157 : Object::ToName(isolate, key));
158 :
159 : Maybe<bool> result =
160 8559 : JSReceiver::HasProperty(Handle<JSReceiver>::cast(target), name);
161 34124 : return result.IsJust() ? *isolate->factory()->ToBoolean(result.FromJust())
162 8671 : : isolate->heap()->exception();
163 : }
164 :
165 : // ES6 section 26.1.10 Reflect.isExtensible
166 4707 : BUILTIN(ReflectIsExtensible) {
167 : HandleScope scope(isolate);
168 : DCHECK_EQ(2, args.length());
169 : Handle<Object> target = args.at(1);
170 :
171 1569 : if (!target->IsJSReceiver()) {
172 126 : THROW_NEW_ERROR_RETURN_FAILURE(
173 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
174 : isolate->factory()->NewStringFromAsciiChecked(
175 : "Reflect.isExtensible")));
176 : }
177 :
178 : Maybe<bool> result =
179 1527 : JSReceiver::IsExtensible(Handle<JSReceiver>::cast(target));
180 1527 : MAYBE_RETURN(result, isolate->heap()->exception());
181 2858 : return *isolate->factory()->ToBoolean(result.FromJust());
182 : }
183 :
184 : // ES6 section 26.1.11 Reflect.ownKeys
185 2736 : BUILTIN(ReflectOwnKeys) {
186 : HandleScope scope(isolate);
187 : DCHECK_EQ(2, args.length());
188 : Handle<Object> target = args.at(1);
189 :
190 912 : if (!target->IsJSReceiver()) {
191 252 : THROW_NEW_ERROR_RETURN_FAILURE(
192 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
193 : isolate->factory()->NewStringFromAsciiChecked(
194 : "Reflect.ownKeys")));
195 : }
196 :
197 : Handle<FixedArray> keys;
198 1656 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
199 : isolate, keys,
200 : KeyAccumulator::GetKeys(Handle<JSReceiver>::cast(target),
201 : KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
202 : GetKeysConversion::kConvertToString));
203 : return *isolate->factory()->NewJSArrayWithElements(keys);
204 : }
205 :
206 : // ES6 section 26.1.12 Reflect.preventExtensions
207 1515 : BUILTIN(ReflectPreventExtensions) {
208 : HandleScope scope(isolate);
209 : DCHECK_EQ(2, args.length());
210 : Handle<Object> target = args.at(1);
211 :
212 505 : if (!target->IsJSReceiver()) {
213 126 : THROW_NEW_ERROR_RETURN_FAILURE(
214 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
215 : isolate->factory()->NewStringFromAsciiChecked(
216 : "Reflect.preventExtensions")));
217 : }
218 :
219 : Maybe<bool> result = JSReceiver::PreventExtensions(
220 463 : Handle<JSReceiver>::cast(target), Object::DONT_THROW);
221 463 : MAYBE_RETURN(result, isolate->heap()->exception());
222 786 : return *isolate->factory()->ToBoolean(result.FromJust());
223 : }
224 :
225 : // ES6 section 26.1.13 Reflect.set
226 40842 : BUILTIN(ReflectSet) {
227 : HandleScope scope(isolate);
228 : Handle<Object> target = args.atOrUndefined(isolate, 1);
229 13614 : Handle<Object> key = args.atOrUndefined(isolate, 2);
230 13614 : Handle<Object> value = args.atOrUndefined(isolate, 3);
231 21930 : Handle<Object> receiver = args.length() > 4 ? args.at(4) : target;
232 :
233 13614 : if (!target->IsJSReceiver()) {
234 126 : THROW_NEW_ERROR_RETURN_FAILURE(
235 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
236 : isolate->factory()->NewStringFromAsciiChecked(
237 : "Reflect.set")));
238 : }
239 :
240 : Handle<Name> name;
241 27144 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
242 : Object::ToName(isolate, key));
243 :
244 : LookupIterator it = LookupIterator::PropertyOrElement(
245 13558 : isolate, receiver, name, Handle<JSReceiver>::cast(target));
246 : Maybe<bool> result = Object::SetSuperProperty(
247 13558 : &it, value, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED);
248 13558 : MAYBE_RETURN(result, isolate->heap()->exception());
249 26220 : return *isolate->factory()->ToBoolean(result.FromJust());
250 : }
251 :
252 : // ES6 section 26.1.14 Reflect.setPrototypeOf
253 8994 : BUILTIN(ReflectSetPrototypeOf) {
254 : HandleScope scope(isolate);
255 : DCHECK_EQ(3, args.length());
256 : Handle<Object> target = args.at(1);
257 : Handle<Object> proto = args.at(2);
258 :
259 2998 : if (!target->IsJSReceiver()) {
260 378 : THROW_NEW_ERROR_RETURN_FAILURE(
261 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
262 : isolate->factory()->NewStringFromAsciiChecked(
263 : "Reflect.setPrototypeOf")));
264 : }
265 :
266 3797 : if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) {
267 1512 : THROW_NEW_ERROR_RETURN_FAILURE(
268 : isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
269 : }
270 :
271 : Maybe<bool> result = JSReceiver::SetPrototype(
272 2116 : Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW);
273 2116 : MAYBE_RETURN(result, isolate->heap()->exception());
274 4176 : return *isolate->factory()->ToBoolean(result.FromJust());
275 : }
276 :
277 : } // namespace internal
278 : } // namespace v8
|