[runtime] Create only one instance of %ThrowTypeError%.

... according to the spec ES#sec-%throwtypeerror%

Bug: v8:4034
Cq-Include-Trybots: master.tryserver.v8:v8_linux_noi18n_rel_ng
Change-Id: Ia4f2d228397edf55447fe3e71402c8fc4589369a
Reviewed-on: https://chromium-review.googlesource.com/563214
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Daniel Ehrenberg <littledan@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46498}
This commit is contained in:
Igor Sheludko 2017-07-10 09:57:09 +02:00 committed by Commit Bot
parent 3b84cbfeb0
commit fa41e3b218
11 changed files with 50 additions and 86 deletions

View File

@ -126,10 +126,9 @@ class Genesis BASE_EMBEDDED {
void CreateRoots();
// Creates the empty function. Used for creating a context from scratch.
Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
// Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Handle<JSFunction> GetRestrictedFunctionPropertiesThrower();
Handle<JSFunction> GetStrictArgumentsPoisonFunction();
Handle<JSFunction> GetThrowTypeErrorIntrinsic(Builtins::Name builtin_name);
// Returns the %ThrowTypeError% intrinsic function.
// See ES#sec-%throwtypeerror% for details.
Handle<JSFunction> GetThrowTypeErrorIntrinsic();
void CreateSloppyModeFunctionMaps(Handle<JSFunction> empty);
void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
@ -249,8 +248,8 @@ class Genesis BASE_EMBEDDED {
Handle<Context> native_context_;
Handle<JSGlobalProxy> global_proxy_;
Handle<JSFunction> strict_poison_function_;
Handle<JSFunction> restricted_function_properties_thrower_;
// %ThrowTypeError%. See ES#sec-%throwtypeerror% for details.
Handle<JSFunction> restricted_properties_thrower_;
BootstrapperActive active_;
friend class Bootstrapper;
@ -546,12 +545,12 @@ void Genesis::CreateSloppyModeFunctionMaps(Handle<JSFunction> empty) {
native_context()->set_sloppy_function_map(*map);
}
// Creates the %ThrowTypeError% function.
Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
Builtins::Name builtin_name) {
Handle<String> name =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("ThrowTypeError"));
Handle<Code> code(isolate()->builtins()->builtin(builtin_name));
Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic() {
if (!restricted_properties_thrower_.is_null()) {
return restricted_properties_thrower_;
}
Handle<String> name(factory()->empty_string());
Handle<Code> code(builtins()->StrictPoisonPillThrower());
Handle<JSFunction> function =
factory()->NewFunctionWithoutPrototype(name, code, STRICT);
function->shared()->DontAdaptArguments();
@ -575,29 +574,10 @@ Handle<JSFunction> Genesis::GetThrowTypeErrorIntrinsic(
DCHECK(false);
}
restricted_properties_thrower_ = function;
return function;
}
// ECMAScript 5th Edition, 13.2.3
Handle<JSFunction> Genesis::GetRestrictedFunctionPropertiesThrower() {
if (restricted_function_properties_thrower_.is_null()) {
restricted_function_properties_thrower_ = GetThrowTypeErrorIntrinsic(
Builtins::kRestrictedFunctionPropertiesThrower);
}
return restricted_function_properties_thrower_;
}
Handle<JSFunction> Genesis::GetStrictArgumentsPoisonFunction() {
if (strict_poison_function_.is_null()) {
strict_poison_function_ = GetThrowTypeErrorIntrinsic(
Builtins::kRestrictedStrictArgumentsPropertiesThrower);
}
return strict_poison_function_;
}
void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
Factory* factory = isolate_->factory();
Handle<Map> map;
@ -885,19 +865,20 @@ void Genesis::CreateJSProxyMaps() {
native_context()->set_proxy_constructor_map(*proxy_constructor_map);
}
static void ReplaceAccessors(Handle<Map> map,
Handle<String> name,
PropertyAttributes attributes,
Handle<AccessorPair> accessor_pair) {
namespace {
void ReplaceAccessors(Handle<Map> map, Handle<String> name,
PropertyAttributes attributes,
Handle<AccessorPair> accessor_pair) {
DescriptorArray* descriptors = map->instance_descriptors();
int idx = descriptors->SearchWithCache(map->GetIsolate(), *name, *map);
Descriptor d = Descriptor::AccessorConstant(name, accessor_pair, attributes);
descriptors->Replace(idx, &d);
}
} // namespace
void Genesis::AddRestrictedFunctionProperties(Handle<JSFunction> empty) {
PropertyAttributes rw_attribs = static_cast<PropertyAttributes>(DONT_ENUM);
Handle<JSFunction> thrower = GetRestrictedFunctionPropertiesThrower();
Handle<JSFunction> thrower = GetThrowTypeErrorIntrinsic();
Handle<AccessorPair> accessors = factory()->NewAccessorPair();
accessors->set_getter(*thrower);
accessors->set_setter(*thrower);
@ -3221,7 +3202,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
// Create the ThrowTypeError function.
Handle<AccessorPair> callee = factory->NewAccessorPair();
Handle<JSFunction> poison = GetStrictArgumentsPoisonFunction();
Handle<JSFunction> poison = GetThrowTypeErrorIntrinsic();
// Install the ThrowTypeError function.
callee->set_getter(*poison);

View File

@ -264,8 +264,7 @@ namespace internal {
/* Special internal builtins */ \
CPP(EmptyFunction) \
CPP(Illegal) \
CPP(RestrictedFunctionPropertiesThrower) \
CPP(RestrictedStrictArgumentsPropertiesThrower) \
CPP(StrictPoisonPillThrower) \
CPP(UnsupportedThrower) \
TFJ(ReturnReceiver, 0) \
\

View File

@ -23,17 +23,7 @@ BUILTIN(UnsupportedThrower) {
NewError(MessageTemplate::kUnsupported));
}
// -----------------------------------------------------------------------------
// Throwers for restricted function properties and strict arguments object
// properties
BUILTIN(RestrictedFunctionPropertiesThrower) {
HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kRestrictedFunctionProperties));
}
BUILTIN(RestrictedStrictArgumentsPropertiesThrower) {
BUILTIN(StrictPoisonPillThrower) {
HandleScope scope(isolate);
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kStrictPoisonPill));

View File

@ -464,9 +464,6 @@ class ErrorUtils : public AllStatic {
T(RegExpNonObject, "% getter called on non-object %") \
T(RegExpNonRegExp, "% getter called on non-RegExp object") \
T(ResolverNotAFunction, "Promise resolver % is not a function") \
T(RestrictedFunctionProperties, \
"'caller' and 'arguments' are restricted function properties and cannot " \
"be accessed in this context.") \
T(ReturnMethodNotCallable, "The iterator's 'return' method is not callable") \
T(SharedArrayBufferTooShort, \
"Derived SharedArrayBuffer constructor created a buffer which was too " \

View File

@ -427,7 +427,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(19),
B(LdaConstant), U8(15),
B(Star), R(20),
@ -742,7 +742,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(17),
B(LdaConstant), U8(25),
B(Star), R(18),
@ -818,7 +818,7 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(Wide), B(LdaSmi), I16(146),
B(Wide), B(LdaSmi), I16(145),
B(Star), R(17),
B(LdaConstant), U8(25),
B(Star), R(18),

View File

@ -156,7 +156,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(20),
B(LdaConstant), U8(15),
B(Star), R(21),
@ -488,7 +488,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(20),
B(LdaConstant), U8(15),
B(Star), R(21),
@ -843,7 +843,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(20),
B(LdaConstant), U8(15),
B(Star), R(21),
@ -1123,7 +1123,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(16),
B(LdaConstant), U8(10),
B(Star), R(17),

View File

@ -85,7 +85,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(11),
B(LdaConstant), U8(8),
B(Star), R(12),
@ -225,7 +225,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(12),
B(LdaConstant), U8(8),
B(Star), R(13),
@ -377,7 +377,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(11),
B(LdaConstant), U8(8),
B(Star), R(12),
@ -520,7 +520,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(10),
B(LdaConstant), U8(10),
B(Star), R(11),

View File

@ -89,7 +89,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(13),
B(LdaConstant), U8(7),
B(Star), R(14),
@ -266,7 +266,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(12),
B(LdaConstant), U8(11),
B(Star), R(13),
@ -419,7 +419,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(11),
B(LdaConstant), U8(9),
B(Star), R(12),
@ -576,7 +576,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(16),
B(LdaConstant), U8(9),
B(Star), R(17),
@ -756,7 +756,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(17),
B(LdaConstant), U8(10),
B(Star), R(18),
@ -965,7 +965,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(16),
B(LdaConstant), U8(14),
B(Star), R(17),
@ -1129,7 +1129,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(20),
B(LdaConstant), U8(7),
B(Star), R(21),
@ -1390,7 +1390,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(21),
B(LdaConstant), U8(11),
B(Star), R(22),

View File

@ -283,7 +283,7 @@ bytecodes: [
B(TestTypeOf), U8(5),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(132),
B(Wide), B(LdaSmi), I16(131),
B(Star), R(15),
B(LdaConstant), U8(15),
B(Star), R(16),

View File

@ -157,9 +157,6 @@
'built-ins/DataView/prototype/setUint8/detached-buffer': [FAIL],
'built-ins/DataView/prototype/setUint8/detached-buffer-before-outofrange-byteoffset': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4034
'built-ins/ThrowTypeError/unique-per-realm-function-proto': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4231
'language/eval-code/direct/var-env-lower-lex-catch-non-strict': [FAIL],

View File

@ -81,16 +81,16 @@ PASS (function (){'use strict'; with(1){};}) threw exception SyntaxError: Strict
PASS (function (){(function (){'use strict'; with(1){};})}) threw exception SyntaxError: Strict mode code may not include a with statement.
PASS (function (){'use strict'; arguments.callee; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function (){'use strict'; arguments.caller; })() is undefined.
PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(){'use strict'; f.caller; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(){'use strict'; f.caller=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.caller; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(){'use strict'; f.caller=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function (arg){'use strict'; arguments.callee; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function (arg){'use strict'; arguments.caller; })() is undefined.
PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(arg){'use strict'; f.caller=5; })() threw exception TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context..
PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS (function f(arg){'use strict'; f.caller=5; })() threw exception TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
PASS "caller" in function(){"use strict"} is true
PASS (function(){"use strict";}).hasOwnProperty("caller") is false
PASS (function(){"use strict";}).__proto__.hasOwnProperty("caller") is true
@ -231,7 +231,7 @@ PASS (function () { try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal;
PASS (function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal; is true
FAIL String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get) should be function () {
[native code]
}. Was function ThrowTypeError() { [native code] }.
}. Was function () { [native code] }.
PASS successfullyParsed is true
TEST COMPLETE