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 32016 : BUILTIN(ReflectDefineProperty) {
22 : HandleScope scope(isolate);
23 : DCHECK_EQ(4, args.length());
24 : Handle<Object> target = args.at(1);
25 10672 : Handle<Object> key = args.at(2);
26 10672 : Handle<Object> attributes = args.at(3);
27 :
28 10672 : if (!target->IsJSReceiver()) {
29 162 : THROW_NEW_ERROR_RETURN_FAILURE(
30 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
31 : isolate->factory()->NewStringFromAsciiChecked(
32 : "Reflect.defineProperty")));
33 : }
34 :
35 : Handle<Name> name;
36 21236 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
37 : Object::ToName(isolate, key));
38 :
39 : PropertyDescriptor desc;
40 10609 : if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
41 54 : return isolate->heap()->exception();
42 : }
43 :
44 : Maybe<bool> result =
45 : JSReceiver::DefineOwnProperty(isolate, Handle<JSReceiver>::cast(target),
46 10555 : name, &desc, Object::DONT_THROW);
47 10555 : MAYBE_RETURN(result, isolate->heap()->exception());
48 21110 : return *isolate->factory()->ToBoolean(result.FromJust());
49 : }
50 :
51 : // ES6 section 26.1.4 Reflect.deleteProperty
52 8628 : BUILTIN(ReflectDeleteProperty) {
53 : HandleScope scope(isolate);
54 : DCHECK_EQ(3, args.length());
55 : Handle<Object> target = args.at(1);
56 2876 : Handle<Object> key = args.at(2);
57 :
58 2876 : if (!target->IsJSReceiver()) {
59 81 : THROW_NEW_ERROR_RETURN_FAILURE(
60 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
61 : isolate->factory()->NewStringFromAsciiChecked(
62 : "Reflect.deleteProperty")));
63 : }
64 :
65 : Handle<Name> name;
66 5698 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
67 : Object::ToName(isolate, key));
68 :
69 : Maybe<bool> result = JSReceiver::DeletePropertyOrElement(
70 2840 : Handle<JSReceiver>::cast(target), name, LanguageMode::kSloppy);
71 2840 : MAYBE_RETURN(result, isolate->heap()->exception());
72 5266 : return *isolate->factory()->ToBoolean(result.FromJust());
73 : }
74 :
75 : // ES6 section 26.1.6 Reflect.get
76 29778 : BUILTIN(ReflectGet) {
77 : HandleScope scope(isolate);
78 : Handle<Object> target = args.atOrUndefined(isolate, 1);
79 9926 : Handle<Object> key = args.atOrUndefined(isolate, 2);
80 17327 : Handle<Object> receiver = args.length() > 3 ? args.at(3) : target;
81 :
82 9926 : if (!target->IsJSReceiver()) {
83 81 : THROW_NEW_ERROR_RETURN_FAILURE(
84 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
85 : isolate->factory()->NewStringFromAsciiChecked(
86 : "Reflect.get")));
87 : }
88 :
89 : Handle<Name> name;
90 19798 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
91 : Object::ToName(isolate, key));
92 :
93 29652 : 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 5745 : BUILTIN(ReflectGetOwnPropertyDescriptor) {
100 : HandleScope scope(isolate);
101 : DCHECK_EQ(3, args.length());
102 : Handle<Object> target = args.at(1);
103 1915 : Handle<Object> key = args.at(2);
104 :
105 1915 : if (!target->IsJSReceiver()) {
106 81 : THROW_NEW_ERROR_RETURN_FAILURE(
107 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
108 : isolate->factory()->NewStringFromAsciiChecked(
109 : "Reflect.getOwnPropertyDescriptor")));
110 : }
111 :
112 : Handle<Name> name;
113 3776 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
114 : Object::ToName(isolate, key));
115 :
116 : PropertyDescriptor desc;
117 : Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor(
118 1879 : isolate, Handle<JSReceiver>::cast(target), name, &desc);
119 1879 : MAYBE_RETURN(found, isolate->heap()->exception());
120 1861 : if (!found.FromJust()) return isolate->heap()->undefined_value();
121 2636 : return *desc.ToObject(isolate);
122 : }
123 :
124 : // ES6 section 26.1.8 Reflect.getPrototypeOf
125 2478 : BUILTIN(ReflectGetPrototypeOf) {
126 : HandleScope scope(isolate);
127 : DCHECK_EQ(2, args.length());
128 : Handle<Object> target = args.at(1);
129 :
130 826 : if (!target->IsJSReceiver()) {
131 360 : THROW_NEW_ERROR_RETURN_FAILURE(
132 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
133 : isolate->factory()->NewStringFromAsciiChecked(
134 : "Reflect.getPrototypeOf")));
135 : }
136 706 : Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(target);
137 2100 : RETURN_RESULT_OR_FAILURE(isolate,
138 : JSReceiver::GetPrototype(isolate, receiver));
139 : }
140 :
141 : // ES6 section 26.1.10 Reflect.isExtensible
142 3027 : BUILTIN(ReflectIsExtensible) {
143 : HandleScope scope(isolate);
144 : DCHECK_EQ(2, args.length());
145 : Handle<Object> target = args.at(1);
146 :
147 1009 : if (!target->IsJSReceiver()) {
148 81 : THROW_NEW_ERROR_RETURN_FAILURE(
149 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
150 : isolate->factory()->NewStringFromAsciiChecked(
151 : "Reflect.isExtensible")));
152 : }
153 :
154 : Maybe<bool> result =
155 982 : JSReceiver::IsExtensible(Handle<JSReceiver>::cast(target));
156 982 : MAYBE_RETURN(result, isolate->heap()->exception());
157 1838 : return *isolate->factory()->ToBoolean(result.FromJust());
158 : }
159 :
160 : // ES6 section 26.1.11 Reflect.ownKeys
161 1761 : BUILTIN(ReflectOwnKeys) {
162 : HandleScope scope(isolate);
163 : DCHECK_EQ(2, args.length());
164 : Handle<Object> target = args.at(1);
165 :
166 587 : if (!target->IsJSReceiver()) {
167 162 : THROW_NEW_ERROR_RETURN_FAILURE(
168 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
169 : isolate->factory()->NewStringFromAsciiChecked(
170 : "Reflect.ownKeys")));
171 : }
172 :
173 : Handle<FixedArray> keys;
174 1066 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
175 : isolate, keys,
176 : KeyAccumulator::GetKeys(Handle<JSReceiver>::cast(target),
177 : KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
178 : GetKeysConversion::kConvertToString));
179 : return *isolate->factory()->NewJSArrayWithElements(keys);
180 : }
181 :
182 : // ES6 section 26.1.12 Reflect.preventExtensions
183 975 : BUILTIN(ReflectPreventExtensions) {
184 : HandleScope scope(isolate);
185 : DCHECK_EQ(2, args.length());
186 : Handle<Object> target = args.at(1);
187 :
188 325 : if (!target->IsJSReceiver()) {
189 81 : THROW_NEW_ERROR_RETURN_FAILURE(
190 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
191 : isolate->factory()->NewStringFromAsciiChecked(
192 : "Reflect.preventExtensions")));
193 : }
194 :
195 : Maybe<bool> result = JSReceiver::PreventExtensions(
196 298 : Handle<JSReceiver>::cast(target), Object::DONT_THROW);
197 298 : MAYBE_RETURN(result, isolate->heap()->exception());
198 506 : return *isolate->factory()->ToBoolean(result.FromJust());
199 : }
200 :
201 : // ES6 section 26.1.13 Reflect.set
202 27153 : BUILTIN(ReflectSet) {
203 : HandleScope scope(isolate);
204 : Handle<Object> target = args.atOrUndefined(isolate, 1);
205 9051 : Handle<Object> key = args.atOrUndefined(isolate, 2);
206 9051 : Handle<Object> value = args.atOrUndefined(isolate, 3);
207 14397 : Handle<Object> receiver = args.length() > 4 ? args.at(4) : target;
208 :
209 9051 : if (!target->IsJSReceiver()) {
210 81 : THROW_NEW_ERROR_RETURN_FAILURE(
211 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
212 : isolate->factory()->NewStringFromAsciiChecked(
213 : "Reflect.set")));
214 : }
215 :
216 : Handle<Name> name;
217 18048 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
218 : Object::ToName(isolate, key));
219 :
220 : LookupIterator it = LookupIterator::PropertyOrElement(
221 9015 : isolate, receiver, name, Handle<JSReceiver>::cast(target));
222 : Maybe<bool> result = Object::SetSuperProperty(
223 9015 : &it, value, LanguageMode::kSloppy, Object::MAY_BE_STORE_FROM_KEYED);
224 9015 : MAYBE_RETURN(result, isolate->heap()->exception());
225 17454 : return *isolate->factory()->ToBoolean(result.FromJust());
226 : }
227 :
228 : // ES6 section 26.1.14 Reflect.setPrototypeOf
229 5784 : BUILTIN(ReflectSetPrototypeOf) {
230 : HandleScope scope(isolate);
231 : DCHECK_EQ(3, args.length());
232 : Handle<Object> target = args.at(1);
233 : Handle<Object> proto = args.at(2);
234 :
235 1928 : if (!target->IsJSReceiver()) {
236 243 : THROW_NEW_ERROR_RETURN_FAILURE(
237 : isolate, NewTypeError(MessageTemplate::kCalledOnNonObject,
238 : isolate->factory()->NewStringFromAsciiChecked(
239 : "Reflect.setPrototypeOf")));
240 : }
241 :
242 2442 : if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) {
243 972 : THROW_NEW_ERROR_RETURN_FAILURE(
244 : isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
245 : }
246 :
247 : Maybe<bool> result = JSReceiver::SetPrototype(
248 1361 : Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW);
249 1361 : MAYBE_RETURN(result, isolate->heap()->exception());
250 2686 : return *isolate->factory()->ToBoolean(result.FromJust());
251 : }
252 :
253 : } // namespace internal
254 : } // namespace v8
|