diff --git a/src/api.cc b/src/api.cc index 8b6f010363..5a4bfb47d9 100644 --- a/src/api.cc +++ b/src/api.cc @@ -4599,8 +4599,8 @@ Maybe v8::Object::SetIntegrityLevel(Local context, auto self = Utils::OpenHandle(this); i::JSReceiver::IntegrityLevel i_level = level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED; - Maybe result = - i::JSReceiver::SetIntegrityLevel(self, i_level, i::Object::DONT_THROW); + Maybe result = i::JSReceiver::SetIntegrityLevel( + self, i_level, i::Object::THROW_ON_ERROR); has_pending_exception = result.IsNothing(); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return result; diff --git a/src/messages.h b/src/messages.h index 8069d639a1..f180440162 100644 --- a/src/messages.h +++ b/src/messages.h @@ -280,8 +280,10 @@ class ErrorUtils : public AllStatic { T(CallSiteMethod, "CallSite method % expects CallSite as receiver") \ T(CannotConvertToPrimitive, "Cannot convert object to primitive value") \ T(CannotPreventExt, "Cannot prevent extensions") \ + T(CannotFreeze, "Cannot freeze") \ T(CannotFreezeArrayBufferView, \ "Cannot freeze array buffer views with elements") \ + T(CannotSeal, "Cannot seal") \ T(CircularStructure, "Converting circular structure to JSON") \ T(ConstructAbstractClass, "Abstract class % not directly constructable") \ T(ConstAssign, "Assignment to constant variable.") \ diff --git a/src/objects.cc b/src/objects.cc index d426ec02a5..7f8a2be0e9 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -7541,6 +7541,12 @@ Maybe JSObject::PreventExtensions(Handle object, should_throw); } + if (object->map()->has_named_interceptor() || + object->map()->has_indexed_interceptor()) { + RETURN_FAILURE(isolate, should_throw, + NewTypeError(MessageTemplate::kCannotPreventExt)); + } + if (!object->HasFixedTypedArrayElements()) { // If there are fast elements we normalize. Handle dictionary = NormalizeElements(object); @@ -7701,6 +7707,25 @@ Maybe JSObject::PreventExtensionsWithTransition( PrototypeIterator::GetCurrent(iter), should_throw); } + if (object->map()->has_named_interceptor() || + object->map()->has_indexed_interceptor()) { + MessageTemplate::Template message = MessageTemplate::kNone; + switch (attrs) { + case NONE: + message = MessageTemplate::kCannotPreventExt; + break; + + case SEALED: + message = MessageTemplate::kCannotSeal; + break; + + case FROZEN: + message = MessageTemplate::kCannotFreeze; + break; + } + RETURN_FAILURE(isolate, should_throw, NewTypeError(message)); + } + Handle new_element_dictionary; if (!object->HasFixedTypedArrayElements() && !object->HasDictionaryElements() && diff --git a/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden b/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden index acc159e22d..7da5e59a02 100644 --- a/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden +++ b/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden @@ -217,7 +217,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(12), B(LdaConstant), U8(11), B(Star), R(13), @@ -701,7 +701,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(12), B(LdaConstant), U8(11), B(Star), R(13), @@ -1219,7 +1219,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(12), B(LdaConstant), U8(11), B(Star), R(13), @@ -1627,7 +1627,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(11), B(LdaConstant), U8(10), B(Star), R(12), diff --git a/test/cctest/interpreter/bytecode_expectations/ForOf.golden b/test/cctest/interpreter/bytecode_expectations/ForOf.golden index 0ef95c2298..c0363b55da 100644 --- a/test/cctest/interpreter/bytecode_expectations/ForOf.golden +++ b/test/cctest/interpreter/bytecode_expectations/ForOf.golden @@ -85,7 +85,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(12), B(LdaConstant), U8(8), B(Star), R(13), @@ -226,7 +226,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(13), B(LdaConstant), U8(8), B(Star), R(14), @@ -380,7 +380,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(12), B(LdaConstant), U8(8), B(Star), R(13), @@ -524,7 +524,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(11), B(LdaConstant), U8(10), B(Star), R(12), diff --git a/test/cctest/interpreter/bytecode_expectations/Generators.golden b/test/cctest/interpreter/bytecode_expectations/Generators.golden index 1a4cdbcf65..671f38e3cc 100644 --- a/test/cctest/interpreter/bytecode_expectations/Generators.golden +++ b/test/cctest/interpreter/bytecode_expectations/Generators.golden @@ -493,7 +493,7 @@ bytecodes: [ B(TestTypeOf), U8(5), B(JumpIfFalse), U8(4), B(Jump), U8(18), - B(Wide), B(LdaSmi), I16(130), + B(Wide), B(LdaSmi), I16(132), B(Star), R(11), B(LdaConstant), U8(10), B(Star), R(12), diff --git a/test/unittests/BUILD.gn b/test/unittests/BUILD.gn index e879dcb35d..f5f9d18e79 100644 --- a/test/unittests/BUILD.gn +++ b/test/unittests/BUILD.gn @@ -12,6 +12,7 @@ v8_executable("unittests") { "../../testing/gtest-support.h", "api/access-check-unittest.cc", "api/exception-unittest.cc", + "api/interceptor-unittest.cc", "api/isolate-unittest.cc", "api/remote-object-unittest.cc", "api/v8-object-unittest.cc", diff --git a/test/unittests/api/interceptor-unittest.cc b/test/unittests/api/interceptor-unittest.cc new file mode 100644 index 0000000000..2f9f0e459e --- /dev/null +++ b/test/unittests/api/interceptor-unittest.cc @@ -0,0 +1,32 @@ +// Copyright 2017 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "include/v8.h" +#include "test/unittests/test-utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace v8 { +namespace { + +using InterceptorTest = TestWithContext; + +void NamedGetter(Local property, + const PropertyCallbackInfo& info) {} + +TEST_F(InterceptorTest, FreezeApiObjectWithInterceptor) { + TryCatch try_catch(isolate()); + + Local tmpl = FunctionTemplate::New(isolate()); + tmpl->InstanceTemplate()->SetHandler( + NamedPropertyHandlerConfiguration(NamedGetter)); + + Local ctor = tmpl->GetFunction(context()).ToLocalChecked(); + Local obj = ctor->NewInstance(context()).ToLocalChecked(); + ASSERT_TRUE( + obj->SetIntegrityLevel(context(), IntegrityLevel::kFrozen).IsNothing()); + ASSERT_TRUE(try_catch.HasCaught()); +} + +} // namespace +} // namespace v8 diff --git a/test/unittests/unittests.gyp b/test/unittests/unittests.gyp index 2b2d3dec54..f76c559b9e 100644 --- a/test/unittests/unittests.gyp +++ b/test/unittests/unittests.gyp @@ -10,6 +10,7 @@ 'unittests_sources': [ ### gcmole(all) ### 'api/access-check-unittest.cc', 'api/exception-unittest.cc', + 'api/interceptor-unittest.cc', 'api/isolate-unittest.cc', 'api/remote-object-unittest.cc', 'api/v8-object-unittest.cc',