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 | |
Jakob Kummerow
2015/11/17 12:12:35
The spec for various internal methods keeps checki
| |
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 3810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4729 } | 4738 } |
4730 | 4739 |
4731 int attributes = NONE; | 4740 int attributes = NONE; |
4732 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; | 4741 if (!enumerable->BooleanValue()) attributes |= DONT_ENUM; |
4733 if (!configurable->BooleanValue()) attributes |= DONT_DELETE; | 4742 if (!configurable->BooleanValue()) attributes |= DONT_DELETE; |
4734 if (!writable->BooleanValue()) attributes |= READ_ONLY; | 4743 if (!writable->BooleanValue()) attributes |= READ_ONLY; |
4735 return Just(static_cast<PropertyAttributes>(attributes)); | 4744 return Just(static_cast<PropertyAttributes>(attributes)); |
4736 } | 4745 } |
4737 | 4746 |
4738 | 4747 |
4748 MaybeHandle<Object> JSProxy::GetTrap(Handle<JSProxy> proxy, | |
4749 Handle<String> trap) { | |
4750 DCHECK(!IsRevoked(proxy)); | |
4751 Isolate* isolate = proxy->GetIsolate(); | |
Camillo Bruni
2015/11/17 08:57:17
I would pass the isolate along, since we kept it i
| |
4752 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); | |
4753 return Object::GetMethod(handler, trap); | |
4754 } | |
4755 | |
4756 | |
4739 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, | 4757 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, |
4740 const char* name, | 4758 const char* name, |
4741 Handle<Object> derived, | 4759 Handle<Object> derived, |
4742 int argc, | 4760 int argc, |
4743 Handle<Object> argv[]) { | 4761 Handle<Object> argv[]) { |
4744 Isolate* isolate = proxy->GetIsolate(); | 4762 Isolate* isolate = proxy->GetIsolate(); |
4745 Handle<Object> handler(proxy->handler(), isolate); | 4763 Handle<Object> handler(proxy->handler(), isolate); |
4746 | |
4747 Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name); | 4764 Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name); |
4748 Handle<Object> trap; | 4765 Handle<Object> trap; |
4749 ASSIGN_RETURN_ON_EXCEPTION( | 4766 ASSIGN_RETURN_ON_EXCEPTION(isolate, trap, GetTrap(proxy, trap_name), Object); |
4750 isolate, trap, | |
4751 Object::GetPropertyOrElement(handler, trap_name), | |
4752 Object); | |
4753 | 4767 |
4754 if (trap->IsUndefined()) { | 4768 if (trap->IsUndefined()) { |
4755 if (derived.is_null()) { | 4769 if (derived.is_null()) { |
4756 THROW_NEW_ERROR(isolate, | 4770 THROW_NEW_ERROR(isolate, |
4757 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, | 4771 NewTypeError(MessageTemplate::kProxyHandlerTrapMissing, |
4758 handler, trap_name), | 4772 handler, trap_name), |
4759 Object); | 4773 Object); |
4760 } | 4774 } |
4761 trap = Handle<Object>(derived); | 4775 trap = Handle<Object>(derived); |
4762 } | 4776 } |
(...skipping 2266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7029 } | 7043 } |
7030 } | 7044 } |
7031 | 7045 |
7032 // No references to object. | 7046 // No references to object. |
7033 return false; | 7047 return false; |
7034 } | 7048 } |
7035 | 7049 |
7036 | 7050 |
7037 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, | 7051 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, |
7038 ShouldThrow should_throw) { | 7052 ShouldThrow should_throw) { |
7039 if (!object->IsJSObject()) return Just(false); | 7053 if (object->IsJSProxy()) { |
7040 // TODO(neis): Deal with proxies. | 7054 return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object), |
7055 should_throw); | |
7056 } | |
7057 DCHECK(object->IsJSObject()); | |
7041 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), | 7058 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), |
7042 should_throw); | 7059 should_throw); |
7043 } | 7060 } |
7044 | 7061 |
7045 | 7062 |
Camillo Bruni
2015/11/17 08:57:16
Please add a tiny header:
// ES6 9.5.?
// static
neis
2015/11/17 23:19:03
Added spec reference to the header file.
| |
7063 Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy, | |
7064 ShouldThrow should_throw) { | |
Camillo Bruni
2015/11/17 08:57:17
Could you copy in the spec steps? (see the other p
neis
2015/11/17 23:19:03
I don't know what others think about this, but for
Jakob Kummerow
2015/11/18 13:58:27
I'm strongly in favor of adding the spec steps as
| |
7065 Isolate* isolate = proxy->GetIsolate(); | |
7066 Factory* factory = isolate->factory(); | |
7067 Handle<String> trap_name = factory->preventExtensions_string(); | |
7068 | |
7069 if (IsRevoked(proxy)) { | |
Camillo Bruni
2015/11/17 08:57:17
nice ;) we were too lazy so far to introduce this
| |
7070 isolate->Throw( | |
7071 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); | |
7072 return Nothing<bool>(); | |
7073 } | |
7074 | |
7075 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); | |
7076 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); | |
7077 | |
7078 Handle<Object> trap; | |
7079 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, trap, GetTrap(proxy, trap_name), | |
7080 Nothing<bool>()); | |
7081 if (trap->IsUndefined()) { | |
7082 return JSReceiver::PreventExtensions(target, should_throw); | |
7083 } | |
7084 | |
7085 Handle<Object> trap_result; | |
7086 Handle<Object> args[] = {target}; | |
7087 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
7088 isolate, trap_result, | |
7089 Execution::Call(isolate, trap, handler, arraysize(args), args), | |
7090 Nothing<bool>()); | |
7091 if (!trap_result->BooleanValue()) { | |
7092 RETURN_FAILURE(isolate, should_throw, | |
7093 NewTypeError(MessageTemplate::kProxyHandlerReturned, handler, | |
7094 factory->false_string(), | |
7095 factory->preventExtensions_string())); | |
Camillo Bruni
2015/11/17 08:57:16
you could use trap_name here.
neis
2015/11/17 23:19:02
Done.
| |
7096 } | |
7097 | |
7098 // Enforce the invariant. | |
7099 Maybe<bool> target_result = JSReceiver::IsExtensible(target); | |
7100 MAYBE_RETURN(target_result, Nothing<bool>()); | |
7101 if (target_result.FromJust()) { | |
7102 isolate->Throw(*factory->NewTypeError( | |
7103 MessageTemplate::kProxyPreventExtensionsViolatesInvariant)); | |
7104 return Nothing<bool>(); | |
7105 } | |
7106 return Just(true); | |
7107 } | |
7108 | |
7109 | |
7046 Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, | 7110 Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, |
7047 ShouldThrow should_throw) { | 7111 ShouldThrow should_throw) { |
7048 Isolate* isolate = object->GetIsolate(); | 7112 Isolate* isolate = object->GetIsolate(); |
7049 | 7113 |
7050 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { | 7114 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { |
7051 return PreventExtensionsWithTransition<NONE>(object, should_throw); | 7115 return PreventExtensionsWithTransition<NONE>(object, should_throw); |
7052 } | 7116 } |
7053 | 7117 |
7054 if (object->IsAccessCheckNeeded() && | 7118 if (object->IsAccessCheckNeeded() && |
7055 !isolate->MayAccess(handle(isolate->context()), object)) { | 7119 !isolate->MayAccess(handle(isolate->context()), object)) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7093 RETURN_ON_EXCEPTION_VALUE( | 7157 RETURN_ON_EXCEPTION_VALUE( |
7094 isolate, | 7158 isolate, |
7095 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 7159 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
7096 isolate->factory()->the_hole_value()), | 7160 isolate->factory()->the_hole_value()), |
7097 Nothing<bool>()); | 7161 Nothing<bool>()); |
7098 } | 7162 } |
7099 return Just(true); | 7163 return Just(true); |
7100 } | 7164 } |
7101 | 7165 |
7102 | 7166 |
7103 // static | |
7104 Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) { | 7167 Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) { |
7105 if (object->IsJSProxy()) { | 7168 if (object->IsJSProxy()) { |
7106 // TODO(neis,cbruni): Redirect to the trap on JSProxy. | 7169 return JSProxy::IsExtensible(Handle<JSProxy>::cast(object)); |
7107 return Just(true); | |
7108 } | 7170 } |
7171 DCHECK(object->IsJSObject()); | |
rossberg
2015/11/17 13:29:09
Nit: this check is redundant, since it's implied b
neis
2015/11/17 23:19:03
Done.
| |
7109 return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object))); | 7172 return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object))); |
7110 } | 7173 } |
7111 | 7174 |
7112 | 7175 |
Camillo Bruni
2015/11/17 08:57:16
ditto: missing spec chapter comment.
neis
2015/11/17 23:19:03
Done.
| |
7176 Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) { | |
Camillo Bruni
2015/11/17 08:57:17
ditto: spec steps.
| |
7177 Isolate* isolate = proxy->GetIsolate(); | |
7178 Factory* factory = isolate->factory(); | |
7179 Handle<String> trap_name = factory->isExtensible_string(); | |
7180 | |
7181 if (IsRevoked(proxy)) { | |
7182 isolate->Throw( | |
7183 *factory->NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); | |
7184 return Nothing<bool>(); | |
7185 } | |
7186 | |
7187 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate); | |
7188 Handle<JSReceiver> handler(JSReceiver::cast(proxy->handler()), isolate); | |
7189 | |
7190 Handle<Object> trap; | |
7191 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, trap, GetTrap(proxy, trap_name), | |
7192 Nothing<bool>()); | |
7193 if (trap->IsUndefined()) { | |
7194 return JSReceiver::IsExtensible(target); | |
7195 } | |
7196 | |
7197 Handle<Object> trap_result; | |
7198 Handle<Object> args[] = {target}; | |
7199 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
7200 isolate, trap_result, | |
7201 Execution::Call(isolate, trap, handler, arraysize(args), args), | |
7202 Nothing<bool>()); | |
7203 | |
7204 // Enforce the invariant. | |
7205 Maybe<bool> target_result = JSReceiver::IsExtensible(target); | |
7206 MAYBE_RETURN(target_result, Nothing<bool>()); | |
7207 if (target_result.FromJust() != trap_result->BooleanValue()) { | |
7208 isolate->Throw(*factory->NewTypeError( | |
7209 MessageTemplate::kProxyIsExtensibleViolatesInvariant)); | |
7210 return Nothing<bool>(); | |
7211 } | |
7212 return target_result; | |
7213 } | |
7214 | |
7215 | |
7113 bool JSObject::IsExtensible(Handle<JSObject> object) { | 7216 bool JSObject::IsExtensible(Handle<JSObject> object) { |
7114 Isolate* isolate = object->GetIsolate(); | 7217 Isolate* isolate = object->GetIsolate(); |
7115 if (object->IsAccessCheckNeeded() && | 7218 if (object->IsAccessCheckNeeded() && |
7116 !isolate->MayAccess(handle(isolate->context()), object)) { | 7219 !isolate->MayAccess(handle(isolate->context()), object)) { |
7117 return true; | 7220 return true; |
7118 } | 7221 } |
7119 if (object->IsJSGlobalProxy()) { | 7222 if (object->IsJSGlobalProxy()) { |
7120 PrototypeIterator iter(isolate, *object); | 7223 PrototypeIterator iter(isolate, *object); |
7121 if (iter.IsAtEnd()) return false; | 7224 if (iter.IsAtEnd()) return false; |
7122 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 7225 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
(...skipping 10999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
18122 if (cell->value() != *new_value) { | 18225 if (cell->value() != *new_value) { |
18123 cell->set_value(*new_value); | 18226 cell->set_value(*new_value); |
18124 Isolate* isolate = cell->GetIsolate(); | 18227 Isolate* isolate = cell->GetIsolate(); |
18125 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18228 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
18126 isolate, DependentCode::kPropertyCellChangedGroup); | 18229 isolate, DependentCode::kPropertyCellChangedGroup); |
18127 } | 18230 } |
18128 } | 18231 } |
18129 | 18232 |
18130 } // namespace internal | 18233 } // namespace internal |
18131 } // namespace v8 | 18234 } // namespace v8 |
OLD | NEW |