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 |