Chromium Code Reviews| 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 |