Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(609)

Side by Side Diff: src/objects.cc

Issue 1441043002: [proxies] Implement [[PreventExtensions]] and [[IsExtensible]]. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Various changes. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698