| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 THROW_NEW_ERROR(isolate, | 899 THROW_NEW_ERROR(isolate, |
| 900 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, | 900 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, |
| 901 handler, trap_name), | 901 handler, trap_name), |
| 902 Object); | 902 Object); |
| 903 } | 903 } |
| 904 // 13. Return handlerProto. | 904 // 13. Return handlerProto. |
| 905 return handler_proto; | 905 return handler_proto; |
| 906 } | 906 } |
| 907 | 907 |
| 908 | 908 |
| 909 bool JSProxy::IsRevoked(Handle<JSProxy> proxy) { |
| 910 // TODO(neis): Decide on how to represent revocation. For now, revocation is |
| 911 // unsupported. |
| 912 DCHECK(proxy->target()->IsJSReceiver()); |
| 913 DCHECK(proxy->handler()->IsJSReceiver()); |
| 914 return false; |
| 915 } |
| 916 |
| 917 |
| 909 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, | 918 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, |
| 910 Handle<Object> receiver, | 919 Handle<Object> receiver, |
| 911 Handle<Name> name) { | 920 Handle<Name> name) { |
| 912 Isolate* isolate = proxy->GetIsolate(); | 921 Isolate* isolate = proxy->GetIsolate(); |
| 913 | 922 |
| 914 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 923 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 915 if (name->IsSymbol()) return isolate->factory()->undefined_value(); | 924 if (name->IsSymbol()) return isolate->factory()->undefined_value(); |
| 916 | 925 |
| 917 Handle<Object> args[] = { receiver, name }; | 926 Handle<Object> args[] = { receiver, name }; |
| 918 return CallTrap( | 927 return CallTrap( |
| (...skipping 3749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4668 Isolate* isolate = it->isolate(); | 4677 Isolate* isolate = it->isolate(); |
| 4669 HandleScope scope(isolate); | 4678 HandleScope scope(isolate); |
| 4670 PropertyDescriptor desc; | 4679 PropertyDescriptor desc; |
| 4671 bool found = JSProxy::GetOwnPropertyDescriptor(it, &desc); | 4680 bool found = JSProxy::GetOwnPropertyDescriptor(it, &desc); |
| 4672 if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>(); | 4681 if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>(); |
| 4673 if (!found) return Just(ABSENT); | 4682 if (!found) return Just(ABSENT); |
| 4674 return Just(desc.ToAttributes()); | 4683 return Just(desc.ToAttributes()); |
| 4675 } | 4684 } |
| 4676 | 4685 |
| 4677 | 4686 |
| 4687 MaybeHandle<Object> JSProxy::GetTrap(Handle<JSProxy> proxy, |
| 4688 Handle<String> trap) { |
| 4689 DCHECK(!IsRevoked(proxy)); |
| 4690 Isolate* isolate = proxy->GetIsolate(); |
| 4691 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); |
| 4692 return Object::GetMethod(handler, trap); |
| 4693 } |
| 4694 |
| 4695 |
| 4678 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, | 4696 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, |
| 4679 const char* name, | 4697 const char* name, |
| 4680 Handle<Object> derived, | 4698 Handle<Object> derived, |
| 4681 int argc, | 4699 int argc, |
| 4682 Handle<Object> argv[]) { | 4700 Handle<Object> argv[]) { |
| 4683 Isolate* isolate = proxy->GetIsolate(); | 4701 Isolate* isolate = proxy->GetIsolate(); |
| 4684 Handle<Object> handler(proxy->handler(), isolate); | 4702 Handle<Object> handler(proxy->handler(), isolate); |
| 4685 | |
| 4686 Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name); | 4703 Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name); |
| 4687 Handle<Object> trap; | 4704 Handle<Object> trap; |
| 4688 ASSIGN_RETURN_ON_EXCEPTION( | 4705 ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetTrap(proxy, trap_name), Object); |
| 4689 isolate, trap, | |
| 4690 Object::GetPropertyOrElement(handler, trap_name), | |
| 4691 Object); | |
| 4692 | 4706 |
| 4693 if (trap->IsUndefined()) { | 4707 if (trap->IsUndefined()) { |
| 4694 if (derived.is_null()) { | 4708 if (derived.is_null()) { |
| 4695 THROW_NEW_ERROR(isolate, | 4709 THROW_NEW_ERROR(isolate, |
| 4696 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, | 4710 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, |
| 4697 handler, trap_name), | 4711 handler, trap_name), |
| 4698 Object); | 4712 Object); |
| 4699 } | 4713 } |
| 4700 trap = Handle<Object>(derived); | 4714 trap = Handle<Object>(derived); |
| 4701 } | 4715 } |
| (...skipping 2374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7076 } | 7090 } |
| 7077 } | 7091 } |
| 7078 | 7092 |
| 7079 // No references to object. | 7093 // No references to object. |
| 7080 return false; | 7094 return false; |
| 7081 } | 7095 } |
| 7082 | 7096 |
| 7083 | 7097 |
| 7084 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, | 7098 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, |
| 7085 ShouldThrow should_throw) { | 7099 ShouldThrow should_throw) { |
| 7086 if (!object->IsJSObject()) return Just(false); | 7100 if (object->IsJSProxy()) { |
| 7087 // TODO(neis): Deal with proxies. | 7101 return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object), |
| 7102 should_throw); |
| 7103 } |
| 7104 DCHECK(object->IsJSObject()); |
| 7088 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), | 7105 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), |
| 7089 should_throw); | 7106 should_throw); |
| 7090 } | 7107 } |
| 7091 | 7108 |
| 7092 | 7109 |
| 7110 Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy, |
| 7111 ShouldThrow should_throw) { |
| 7112 Isolate* isolate = proxy->GetIsolate(); |
| 7113 Factory* factory = isolate->factory(); |
| 7114 Handle<String> trap_name = factory->preventExtensions_string(); |
| 7115 |
| 7116 if (IsRevoked(proxy)) { |
| 7117 isolate->Throw( |
| 7118 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); |
| 7119 return Nothing<bool>(); |
| 7120 } |
| 7121 |
| 7122 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 7123 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); |
| 7124 |
| 7125 Handle<Object> trap; |
| 7126 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, trap, GetTrap(proxy, trap_name), |
| 7127 Nothing<bool>()); |
| 7128 if (trap->IsUndefined()) { |
| 7129 return JSReceiver::PreventExtensions(target, should_throw); |
| 7130 } |
| 7131 |
| 7132 Handle<Object> trap_result; |
| 7133 Handle<Object> args[] = {target}; |
| 7134 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 7135 isolate, trap_result, |
| 7136 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 7137 Nothing<bool>()); |
| 7138 if (!trap_result->BooleanValue()) { |
| 7139 RETURN_FAILURE(isolate, should_throw, |
| 7140 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, |
| 7141 factory->false_string(), trap_name)); |
| 7142 } |
| 7143 |
| 7144 // Enforce the invariant. |
| 7145 Maybe<bool> target_result = JSReceiver::IsExtensible(target); |
| 7146 MAYBE_RETURN(target_result, Nothing<bool>()); |
| 7147 if (target_result.FromJust()) { |
| 7148 isolate->Throw(*factory->NewTypeError( |
| 7149 MessageTemplate::kProxyPreventExtensionsViolatesInvariant)); |
| 7150 return Nothing<bool>(); |
| 7151 } |
| 7152 return Just(true); |
| 7153 } |
| 7154 |
| 7155 |
| 7093 Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, | 7156 Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, |
| 7094 ShouldThrow should_throw) { | 7157 ShouldThrow should_throw) { |
| 7095 Isolate* isolate = object->GetIsolate(); | 7158 Isolate* isolate = object->GetIsolate(); |
| 7096 | 7159 |
| 7097 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { | 7160 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { |
| 7098 return PreventExtensionsWithTransition<NONE>(object, should_throw); | 7161 return PreventExtensionsWithTransition<NONE>(object, should_throw); |
| 7099 } | 7162 } |
| 7100 | 7163 |
| 7101 if (object->IsAccessCheckNeeded() && | 7164 if (object->IsAccessCheckNeeded() && |
| 7102 !isolate->MayAccess(handle(isolate->context()), object)) { | 7165 !isolate->MayAccess(handle(isolate->context()), object)) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7140 RETURN_ON_EXCEPTION_VALUE( | 7203 RETURN_ON_EXCEPTION_VALUE( |
| 7141 isolate, | 7204 isolate, |
| 7142 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 7205 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
| 7143 isolate->factory()->the_hole_value()), | 7206 isolate->factory()->the_hole_value()), |
| 7144 Nothing<bool>()); | 7207 Nothing<bool>()); |
| 7145 } | 7208 } |
| 7146 return Just(true); | 7209 return Just(true); |
| 7147 } | 7210 } |
| 7148 | 7211 |
| 7149 | 7212 |
| 7150 // static | |
| 7151 Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) { | 7213 Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) { |
| 7152 if (object->IsJSProxy()) { | 7214 if (object->IsJSProxy()) { |
| 7153 // TODO(neis,cbruni): Redirect to the trap on JSProxy. | 7215 return JSProxy::IsExtensible(Handle<JSProxy>::cast(object)); |
| 7154 return Just(true); | |
| 7155 } | 7216 } |
| 7156 return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object))); | 7217 return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object))); |
| 7157 } | 7218 } |
| 7158 | 7219 |
| 7159 | 7220 |
| 7221 Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) { |
| 7222 Isolate* isolate = proxy->GetIsolate(); |
| 7223 Factory* factory = isolate->factory(); |
| 7224 Handle<String> trap_name = factory->isExtensible_string(); |
| 7225 |
| 7226 if (IsRevoked(proxy)) { |
| 7227 isolate->Throw( |
| 7228 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); |
| 7229 return Nothing<bool>(); |
| 7230 } |
| 7231 |
| 7232 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); |
| 7233 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); |
| 7234 |
| 7235 Handle<Object> trap; |
| 7236 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, trap, GetTrap(proxy, trap_name), |
| 7237 Nothing<bool>()); |
| 7238 if (trap->IsUndefined()) { |
| 7239 return JSReceiver::IsExtensible(target); |
| 7240 } |
| 7241 |
| 7242 Handle<Object> trap_result; |
| 7243 Handle<Object> args[] = {target}; |
| 7244 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 7245 isolate, trap_result, |
| 7246 Execution::Call(isolate, trap, handler, arraysize(args), args), |
| 7247 Nothing<bool>()); |
| 7248 |
| 7249 // Enforce the invariant. |
| 7250 Maybe<bool> target_result = JSReceiver::IsExtensible(target); |
| 7251 MAYBE_RETURN(target_result, Nothing<bool>()); |
| 7252 if (target_result.FromJust() != trap_result->BooleanValue()) { |
| 7253 isolate->Throw(*factory->NewTypeError( |
| 7254 MessageTemplate::kProxyIsExtensibleViolatesInvariant)); |
| 7255 return Nothing<bool>(); |
| 7256 } |
| 7257 return target_result; |
| 7258 } |
| 7259 |
| 7260 |
| 7160 bool JSObject::IsExtensible(Handle<JSObject> object) { | 7261 bool JSObject::IsExtensible(Handle<JSObject> object) { |
| 7161 Isolate* isolate = object->GetIsolate(); | 7262 Isolate* isolate = object->GetIsolate(); |
| 7162 if (object->IsAccessCheckNeeded() && | 7263 if (object->IsAccessCheckNeeded() && |
| 7163 !isolate->MayAccess(handle(isolate->context()), object)) { | 7264 !isolate->MayAccess(handle(isolate->context()), object)) { |
| 7164 return true; | 7265 return true; |
| 7165 } | 7266 } |
| 7166 if (object->IsJSGlobalProxy()) { | 7267 if (object->IsJSGlobalProxy()) { |
| 7167 PrototypeIterator iter(isolate, *object); | 7268 PrototypeIterator iter(isolate, *object); |
| 7168 if (iter.IsAtEnd()) return false; | 7269 if (iter.IsAtEnd()) return false; |
| 7169 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 7270 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
| (...skipping 11260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18430 if (cell->value() != *new_value) { | 18531 if (cell->value() != *new_value) { |
| 18431 cell->set_value(*new_value); | 18532 cell->set_value(*new_value); |
| 18432 Isolate* isolate = cell->GetIsolate(); | 18533 Isolate* isolate = cell->GetIsolate(); |
| 18433 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18534 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18434 isolate, DependentCode::kPropertyCellChangedGroup); | 18535 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18435 } | 18536 } |
| 18436 } | 18537 } |
| 18437 | 18538 |
| 18438 } // namespace internal | 18539 } // namespace internal |
| 18439 } // namespace v8 | 18540 } // namespace v8 |
| OLD | NEW |