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

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: Rebase. Created 5 years 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
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698