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 71224 : BUILTIN(ReflectDefineProperty) {
21 : HandleScope scope(isolate);
22 : DCHECK_EQ(4, args.length());
23 : Handle<Object> target = args.at(1);
24 17806 : Handle<Object> key = args.at(2);
25 17806 : Handle<Object> attributes = args.at(3);
26 :
27 35612 : if (!target->IsJSReceiver()) {
28 162 : THROW_NEW_ERROR_RETURN_FAILURE(
29 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
30 : isolate->factory()->NewStringFromAsciiChecked(
31 : "Reflect.defineProperty")));
32 : }
33 :
34 : Handle<Name> name;
35 35513 : 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 17689 : isolate, Handle<JSReceiver>::cast(target), name, &desc, kDontThrow);
45 24812 : 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 37248 : BUILTIN(ReflectDeleteProperty) {
51 : HandleScope scope(isolate);
52 : DCHECK_EQ(3, args.length());
53 : Handle<Object> target = args.at(1);
54 9312 : Handle<Object> key = args.at(2);
55 :
56 18624 : if (!target->IsJSReceiver()) {
57 81 : THROW_NEW_ERROR_RETURN_FAILURE(
58 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
59 : isolate->factory()->NewStringFromAsciiChecked(
60 : "Reflect.deleteProperty")));
61 : }
62 :
63 : Handle<Name> name;
64 18579 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
65 : Object::ToName(isolate, key));
66 :
67 : Maybe<bool> result = JSReceiver::DeletePropertyOrElement(
68 9276 : Handle<JSReceiver>::cast(target), name, LanguageMode::kSloppy);
69 15888 : 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 65268 : BUILTIN(ReflectGet) {
75 : HandleScope scope(isolate);
76 : Handle<Object> target = args.atOrUndefined(isolate, 1);
77 16317 : Handle<Object> key = args.atOrUndefined(isolate, 2);
78 29912 : Handle<Object> receiver = args.length() > 3 ? args.at(3) : target;
79 :
80 32634 : if (!target->IsJSReceiver()) {
81 243 : THROW_NEW_ERROR_RETURN_FAILURE(
82 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
83 : isolate->factory()->NewStringFromAsciiChecked(
84 : "Reflect.get")));
85 : }
86 :
87 : Handle<Name> name;
88 32501 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
89 : Object::ToName(isolate, key));
90 :
91 38629 : 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 30392 : BUILTIN(ReflectGetOwnPropertyDescriptor) {
98 : HandleScope scope(isolate);
99 : DCHECK_EQ(3, args.length());
100 : Handle<Object> target = args.at(1);
101 7598 : Handle<Object> key = args.at(2);
102 :
103 15196 : if (!target->IsJSReceiver()) {
104 81 : THROW_NEW_ERROR_RETURN_FAILURE(
105 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
106 : isolate->factory()->NewStringFromAsciiChecked(
107 : "Reflect.getOwnPropertyDescriptor")));
108 : }
109 :
110 : Handle<Name> name;
111 15151 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
112 : Object::ToName(isolate, key));
113 :
114 : PropertyDescriptor desc;
115 : Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor(
116 7562 : isolate, Handle<JSReceiver>::cast(target), name, &desc);
117 13108 : MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
118 2556 : if (!found.FromJust()) return ReadOnlyRoots(isolate).undefined_value();
119 2952 : return *desc.ToObject(isolate);
120 : }
121 :
122 : // ES6 section 26.1.8 Reflect.getPrototypeOf
123 3320 : BUILTIN(ReflectGetPrototypeOf) {
124 : HandleScope scope(isolate);
125 : DCHECK_EQ(2, args.length());
126 : Handle<Object> target = args.at(1);
127 :
128 1660 : if (!target->IsJSReceiver()) {
129 351 : 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 43400 : BUILTIN(ReflectIsExtensible) {
141 : HandleScope scope(isolate);
142 : DCHECK_EQ(2, args.length());
143 : Handle<Object> target = args.at(1);
144 :
145 21700 : if (!target->IsJSReceiver()) {
146 81 : THROW_NEW_ERROR_RETURN_FAILURE(
147 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
148 : isolate->factory()->NewStringFromAsciiChecked(
149 : "Reflect.isExtensible")));
150 : }
151 :
152 : Maybe<bool> result =
153 10823 : JSReceiver::IsExtensible(Handle<JSReceiver>::cast(target));
154 20728 : 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 27984 : BUILTIN(ReflectOwnKeys) {
160 : HandleScope scope(isolate);
161 : DCHECK_EQ(2, args.length());
162 : Handle<Object> target = args.at(1);
163 :
164 13992 : if (!target->IsJSReceiver()) {
165 162 : THROW_NEW_ERROR_RETURN_FAILURE(
166 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
167 : isolate->factory()->NewStringFromAsciiChecked(
168 : "Reflect.ownKeys")));
169 : }
170 :
171 : Handle<FixedArray> keys;
172 19962 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
173 : isolate, keys,
174 : KeyAccumulator::GetKeys(Handle<JSReceiver>::cast(target),
175 : KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
176 : GetKeysConversion::kConvertToString));
177 1728 : return *isolate->factory()->NewJSArrayWithElements(keys);
178 : }
179 :
180 : // ES6 section 26.1.12 Reflect.preventExtensions
181 39976 : BUILTIN(ReflectPreventExtensions) {
182 : HandleScope scope(isolate);
183 : DCHECK_EQ(2, args.length());
184 : Handle<Object> target = args.at(1);
185 :
186 19988 : if (!target->IsJSReceiver()) {
187 81 : 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 9967 : Handle<JSReceiver>::cast(target), kDontThrow);
195 19682 : 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 56332 : BUILTIN(ReflectSet) {
201 : HandleScope scope(isolate);
202 : Handle<Object> target = args.atOrUndefined(isolate, 1);
203 14083 : Handle<Object> key = args.atOrUndefined(isolate, 2);
204 14083 : Handle<Object> value = args.atOrUndefined(isolate, 3);
205 24449 : Handle<Object> receiver = args.length() > 4 ? args.at(4) : target;
206 :
207 28166 : if (!target->IsJSReceiver()) {
208 81 : THROW_NEW_ERROR_RETURN_FAILURE(
209 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
210 : isolate->factory()->NewStringFromAsciiChecked(
211 : "Reflect.set")));
212 : }
213 :
214 : Handle<Name> name;
215 28121 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
216 : Object::ToName(isolate, key));
217 :
218 : LookupIterator it = LookupIterator::PropertyOrElement(
219 14047 : isolate, receiver, name, Handle<JSReceiver>::cast(target));
220 : Maybe<bool> result = Object::SetSuperProperty(
221 14047 : &it, value, LanguageMode::kSloppy, StoreOrigin::kMaybeKeyed);
222 19373 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
223 17442 : return *isolate->factory()->ToBoolean(result.FromJust());
224 : }
225 :
226 : // ES6 section 26.1.14 Reflect.setPrototypeOf
227 42268 : 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 21134 : if (!target->IsJSReceiver()) {
234 243 : THROW_NEW_ERROR_RETURN_FAILURE(
235 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
236 : isolate->factory()->NewStringFromAsciiChecked(
237 : "Reflect.setPrototypeOf")));
238 : }
239 :
240 22160 : 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 10000 : Handle<JSReceiver>::cast(target), proto, true, kDontThrow);
247 18659 : MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
248 2682 : return *isolate->factory()->ToBoolean(result.FromJust());
249 : }
250 :
251 : } // namespace internal
252 183867 : } // namespace v8
|