5 #include "src/builtins/builtins-utils-inl.h" 6 #include "src/builtins/builtins.h" 7 #include "src/code-factory.h" 8 #include "src/code-stub-assembler.h" 9 #include "src/counters.h" 11 #include "src/lookup.h" 12 #include "src/message-template.h" 13 #include "src/objects-inl.h" 14 #include "src/property-descriptor.h" 23 BUILTIN(ObjectPrototypePropertyIsEnumerable) {
24 HandleScope scope(isolate);
25 Handle<JSReceiver> object;
27 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
28 isolate, name, Object::ToName(isolate, args.atOrUndefined(isolate, 1)));
29 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
30 isolate,
object, JSReceiver::ToObject(isolate, args.receiver()));
31 Maybe<PropertyAttributes> maybe =
32 JSReceiver::GetOwnPropertyAttributes(
object, name);
33 if (maybe.IsNothing())
return ReadOnlyRoots(isolate).exception();
34 if (maybe.FromJust() == ABSENT)
return ReadOnlyRoots(isolate).false_value();
35 return isolate->heap()->ToBoolean((maybe.FromJust() & DONT_ENUM) == 0);
39 BUILTIN(ObjectDefineProperties) {
40 HandleScope scope(isolate);
41 DCHECK_EQ(3, args.length());
42 Handle<Object> target = args.at(1);
43 Handle<Object> properties = args.at(2);
45 RETURN_RESULT_OR_FAILURE(
46 isolate, JSReceiver::DefineProperties(isolate, target, properties));
50 BUILTIN(ObjectDefineProperty) {
51 HandleScope scope(isolate);
52 DCHECK_EQ(4, args.length());
53 Handle<Object> target = args.at(1);
54 Handle<Object> key = args.at(2);
55 Handle<Object> attributes = args.at(3);
57 return JSReceiver::DefineProperty(isolate, target, key, attributes);
62 template <AccessorComponent which_accessor>
63 Object* ObjectDefineAccessor(Isolate* isolate, Handle<Object>
object,
64 Handle<Object> name, Handle<Object> accessor) {
66 Handle<JSReceiver> receiver;
67 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
68 Object::ToObject(isolate,
object));
70 if (!accessor->IsCallable()) {
71 MessageTemplate message =
72 which_accessor == ACCESSOR_GETTER
73 ? MessageTemplate::kObjectGetterExpectingFunction
74 : MessageTemplate::kObjectSetterExpectingFunction;
75 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(message));
79 PropertyDescriptor desc;
80 if (which_accessor == ACCESSOR_GETTER) {
81 desc.set_get(accessor);
83 DCHECK(which_accessor == ACCESSOR_SETTER);
84 desc.set_set(accessor);
86 desc.set_enumerable(
true);
87 desc.set_configurable(
true);
89 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
90 Object::ToPropertyKey(isolate, name));
94 Maybe<bool> success = JSReceiver::DefineOwnProperty(isolate, receiver, name,
95 &desc, kThrowOnError);
96 MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
97 if (!success.FromJust()) {
98 isolate->CountUsage(v8::Isolate::kDefineGetterOrSetterWouldThrow);
101 return ReadOnlyRoots(isolate).undefined_value();
104 Object* ObjectLookupAccessor(Isolate* isolate, Handle<Object>
object,
105 Handle<Object> key, AccessorComponent component) {
106 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate,
object,
107 Object::ToObject(isolate,
object));
108 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
109 Object::ToPropertyKey(isolate, key));
110 bool success =
false;
111 LookupIterator it = LookupIterator::PropertyOrElement(
112 isolate,
object, key, &success,
113 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
116 for (; it.IsFound(); it.Next()) {
117 switch (it.state()) {
118 case LookupIterator::INTERCEPTOR:
119 case LookupIterator::NOT_FOUND:
120 case LookupIterator::TRANSITION:
123 case LookupIterator::ACCESS_CHECK:
124 if (it.HasAccess())
continue;
125 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
126 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
127 return ReadOnlyRoots(isolate).undefined_value();
129 case LookupIterator::JSPROXY: {
130 PropertyDescriptor desc;
131 Maybe<bool> found = JSProxy::GetOwnPropertyDescriptor(
132 isolate, it.GetHolder<JSProxy>(), it.GetName(), &desc);
133 MAYBE_RETURN(found, ReadOnlyRoots(isolate).exception());
134 if (found.FromJust()) {
135 if (component == ACCESSOR_GETTER && desc.has_get()) {
138 if (component == ACCESSOR_SETTER && desc.has_set()) {
141 return ReadOnlyRoots(isolate).undefined_value();
143 Handle<Object> prototype;
144 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
145 isolate, prototype, JSProxy::GetPrototype(it.GetHolder<JSProxy>()));
146 if (prototype->IsNull(isolate)) {
147 return ReadOnlyRoots(isolate).undefined_value();
149 return ObjectLookupAccessor(isolate, prototype, key, component);
152 case LookupIterator::INTEGER_INDEXED_EXOTIC:
153 case LookupIterator::DATA:
154 return ReadOnlyRoots(isolate).undefined_value();
156 case LookupIterator::ACCESSOR: {
157 Handle<Object> maybe_pair = it.GetAccessors();
158 if (maybe_pair->IsAccessorPair()) {
159 return *AccessorPair::GetComponent(
160 isolate, Handle<AccessorPair>::cast(maybe_pair), component);
166 return ReadOnlyRoots(isolate).undefined_value();
173 BUILTIN(ObjectDefineGetter) {
174 HandleScope scope(isolate);
175 Handle<Object>
object = args.at(0);
176 Handle<Object> name = args.at(1);
177 Handle<Object> getter = args.at(2);
178 return ObjectDefineAccessor<ACCESSOR_GETTER>(isolate, object, name, getter);
183 BUILTIN(ObjectDefineSetter) {
184 HandleScope scope(isolate);
185 Handle<Object>
object = args.at(0);
186 Handle<Object> name = args.at(1);
187 Handle<Object> setter = args.at(2);
188 return ObjectDefineAccessor<ACCESSOR_SETTER>(isolate, object, name, setter);
193 BUILTIN(ObjectLookupGetter) {
194 HandleScope scope(isolate);
195 Handle<Object>
object = args.at(0);
196 Handle<Object> name = args.at(1);
197 return ObjectLookupAccessor(isolate,
object, name, ACCESSOR_GETTER);
202 BUILTIN(ObjectLookupSetter) {
203 HandleScope scope(isolate);
204 Handle<Object>
object = args.at(0);
205 Handle<Object> name = args.at(1);
206 return ObjectLookupAccessor(isolate,
object, name, ACCESSOR_SETTER);
210 BUILTIN(ObjectFreeze) {
211 HandleScope scope(isolate);
212 Handle<Object>
object = args.atOrUndefined(isolate, 1);
213 if (object->IsJSReceiver()) {
214 MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(
object),
215 FROZEN, kThrowOnError),
216 ReadOnlyRoots(isolate).exception());
222 BUILTIN(ObjectGetPrototypeOf) {
223 HandleScope scope(isolate);
224 Handle<Object>
object = args.atOrUndefined(isolate, 1);
226 Handle<JSReceiver> receiver;
227 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
228 Object::ToObject(isolate,
object));
230 RETURN_RESULT_OR_FAILURE(isolate,
231 JSReceiver::GetPrototype(isolate, receiver));
235 BUILTIN(ObjectSetPrototypeOf) {
236 HandleScope scope(isolate);
239 Handle<Object>
object = args.atOrUndefined(isolate, 1);
240 if (object->IsNullOrUndefined(isolate)) {
241 THROW_NEW_ERROR_RETURN_FAILURE(
242 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
243 isolate->factory()->NewStringFromAsciiChecked(
244 "Object.setPrototypeOf")));
248 Handle<Object> proto = args.atOrUndefined(isolate, 2);
249 if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
250 THROW_NEW_ERROR_RETURN_FAILURE(
251 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto));
255 if (!object->IsJSReceiver())
return *
object;
256 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(
object);
260 MAYBE_RETURN(JSReceiver::SetPrototype(receiver, proto,
true, kThrowOnError),
261 ReadOnlyRoots(isolate).exception());
268 BUILTIN(ObjectPrototypeGetProto) {
269 HandleScope scope(isolate);
271 Handle<JSReceiver> receiver;
272 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
273 isolate, receiver, Object::ToObject(isolate, args.receiver()));
276 RETURN_RESULT_OR_FAILURE(isolate,
277 JSReceiver::GetPrototype(isolate, receiver));
281 BUILTIN(ObjectPrototypeSetProto) {
282 HandleScope scope(isolate);
284 Handle<Object>
object = args.receiver();
285 if (object->IsNullOrUndefined(isolate)) {
286 THROW_NEW_ERROR_RETURN_FAILURE(
287 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
288 isolate->factory()->NewStringFromAsciiChecked(
289 "set Object.prototype.__proto__")));
293 Handle<Object> proto = args.at(1);
294 if (!proto->IsNull(isolate) && !proto->IsJSReceiver()) {
295 return ReadOnlyRoots(isolate).undefined_value();
299 if (!object->IsJSReceiver())
return ReadOnlyRoots(isolate).undefined_value();
300 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(
object);
304 MAYBE_RETURN(JSReceiver::SetPrototype(receiver, proto,
true, kThrowOnError),
305 ReadOnlyRoots(isolate).exception());
308 return ReadOnlyRoots(isolate).undefined_value();
313 Object* GetOwnPropertyKeys(Isolate* isolate, BuiltinArguments args,
315 HandleScope scope(isolate);
316 Handle<Object>
object = args.atOrUndefined(isolate, 1);
317 Handle<JSReceiver> receiver;
318 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
319 Object::ToObject(isolate,
object));
320 Handle<FixedArray> keys;
321 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
323 KeyAccumulator::GetKeys(receiver, KeyCollectionMode::kOwnOnly, filter,
324 GetKeysConversion::kConvertToString));
325 return *isolate->factory()->NewJSArrayWithElements(keys);
331 BUILTIN(ObjectGetOwnPropertySymbols) {
332 return GetOwnPropertyKeys(isolate, args, SKIP_STRINGS);
336 BUILTIN(ObjectIsExtensible) {
337 HandleScope scope(isolate);
338 Handle<Object>
object = args.atOrUndefined(isolate, 1);
340 object->IsJSReceiver()
341 ? JSReceiver::IsExtensible(Handle<JSReceiver>::cast(
object))
343 MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
344 return isolate->heap()->ToBoolean(result.FromJust());
348 BUILTIN(ObjectIsFrozen) {
349 HandleScope scope(isolate);
350 Handle<Object>
object = args.atOrUndefined(isolate, 1);
351 Maybe<bool> result =
object->IsJSReceiver()
352 ? JSReceiver::TestIntegrityLevel(
353 Handle<JSReceiver>::cast(
object), FROZEN)
355 MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
356 return isolate->heap()->ToBoolean(result.FromJust());
360 BUILTIN(ObjectIsSealed) {
361 HandleScope scope(isolate);
362 Handle<Object>
object = args.atOrUndefined(isolate, 1);
363 Maybe<bool> result =
object->IsJSReceiver()
364 ? JSReceiver::TestIntegrityLevel(
365 Handle<JSReceiver>::cast(
object), SEALED)
367 MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
368 return isolate->heap()->ToBoolean(result.FromJust());
371 BUILTIN(ObjectGetOwnPropertyDescriptors) {
372 HandleScope scope(isolate);
373 Handle<Object>
object = args.atOrUndefined(isolate, 1);
375 Handle<JSReceiver> receiver;
376 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
377 Object::ToObject(isolate,
object));
379 Handle<FixedArray> keys;
380 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
381 isolate, keys, KeyAccumulator::GetKeys(
382 receiver, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
383 GetKeysConversion::kConvertToString));
385 Handle<JSObject> descriptors =
386 isolate->factory()->NewJSObject(isolate->object_function());
388 for (
int i = 0;
i < keys->length(); ++
i) {
389 Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys,
i, isolate));
390 PropertyDescriptor descriptor;
391 Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
392 isolate, receiver, key, &descriptor);
393 MAYBE_RETURN(did_get_descriptor, ReadOnlyRoots(isolate).exception());
395 if (!did_get_descriptor.FromJust())
continue;
396 Handle<Object> from_descriptor = descriptor.ToObject(isolate);
398 Maybe<bool> success = JSReceiver::CreateDataProperty(
399 isolate, descriptors, key, from_descriptor, kDontThrow);
400 CHECK(success.FromJust());
407 BUILTIN(ObjectPreventExtensions) {
408 HandleScope scope(isolate);
409 Handle<Object>
object = args.atOrUndefined(isolate, 1);
410 if (object->IsJSReceiver()) {
411 MAYBE_RETURN(JSReceiver::PreventExtensions(Handle<JSReceiver>::cast(
object),
413 ReadOnlyRoots(isolate).exception());
419 BUILTIN(ObjectSeal) {
420 HandleScope scope(isolate);
421 Handle<Object>
object = args.atOrUndefined(isolate, 1);
422 if (object->IsJSReceiver()) {
423 MAYBE_RETURN(JSReceiver::SetIntegrityLevel(Handle<JSReceiver>::cast(
object),
424 SEALED, kThrowOnError),
425 ReadOnlyRoots(isolate).exception());