Commit b9b8cc9b authored by Raphael Kubo da Costa's avatar Raphael Kubo da Costa Committed by Commit Bot

Expose %ErrorPrototype% as an intrinsic in the public API.

Blink needs %ErrorPrototype% in order to properly set up the inheritance
chain from DOMException, as specified in WebIDL:
https://heycam.github.io/webidl/#es-DOMException-specialness

This patch is similar to commit 5ec1cddc ("Expose %IteratorPrototype% as an
intrinsic in the public API"), with the difference that there was no entry
for %ErrorPrototype% in any of the mappings in contexts.h.

Bug: chromium:556950, chromium:737497
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: Iadc5b2b844f29f6c9640b6a89769d233931366e9
Reviewed-on: https://chromium-review.googlesource.com/559058Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Commit-Queue: Raphael Kubo da Costa (rakuco) <raphael.kubo.da.costa@intel.com>
Cr-Commit-Position: refs/heads/master@{#46464}
parent bfc0bc8f
......@@ -4921,6 +4921,7 @@ class V8_EXPORT External : public Value {
F(ArrayProto_forEach, array_for_each_iterator) \
F(ArrayProto_keys, array_keys_iterator) \
F(ArrayProto_values, array_values_iterator) \
F(ErrorPrototype, initial_error_prototype) \
F(IteratorPrototype, initial_iterator_prototype)
enum Intrinsic {
......
......@@ -1170,6 +1170,7 @@ static void InstallError(Isolate* isolate, Handle<JSObject> global,
SimpleInstallFunction(prototype, factory->toString_string(),
Builtins::kErrorPrototypeToString, 0, true);
isolate->native_context()->set_error_to_string(*to_string_fun);
isolate->native_context()->set_initial_error_prototype(*prototype);
} else {
DCHECK(isolate->native_context()->error_to_string()->IsJSFunction());
......
......@@ -254,6 +254,7 @@ enum ContextLookupFlags {
V(INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX, Map, \
initial_array_iterator_prototype_map) \
V(INITIAL_ARRAY_PROTOTYPE_INDEX, JSObject, initial_array_prototype) \
V(INITIAL_ERROR_PROTOTYPE_INDEX, JSObject, initial_error_prototype) \
V(INITIAL_GENERATOR_PROTOTYPE_INDEX, JSObject, initial_generator_prototype) \
V(INITIAL_ASYNC_GENERATOR_PROTOTYPE_INDEX, JSObject, \
initial_async_generator_prototype) \
......
......@@ -26215,6 +26215,76 @@ TEST(TemplateIteratorPrototypeIntrinsics) {
}
}
TEST(TemplateErrorPrototypeIntrinsics) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
// Object templates.
{
Local<ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate);
object_template->SetIntrinsicDataProperty(v8_str("error_proto"),
v8::kErrorPrototype);
Local<Object> object =
object_template->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("obj"), object).FromJust());
ExpectTrue("obj.error_proto === Error.prototype");
Local<Value> error = v8::Exception::Error(v8_str("error message"));
CHECK(env->Global()->Set(env.local(), v8_str("err"), error).FromJust());
ExpectTrue("obj.error_proto === Object.getPrototypeOf(err)");
}
// Setting %ErrorPrototype% on the function object's prototype template.
{
Local<FunctionTemplate> func_template = v8::FunctionTemplate::New(isolate);
func_template->PrototypeTemplate()->SetIntrinsicDataProperty(
v8_str("error_proto"), v8::kErrorPrototype);
Local<Function> func1 =
func_template->GetFunction(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("func1"), func1).FromJust());
Local<Function> func2 =
func_template->GetFunction(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("func2"), func2).FromJust());
ExpectTrue("func1.prototype.error_proto === Error.prototype");
ExpectTrue("func2.prototype.error_proto === Error.prototype");
ExpectTrue("func1.prototype.error_proto === func2.prototype.error_proto");
Local<Object> instance1 = func1->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()
->Set(env.local(), v8_str("instance1"), instance1)
.FromJust());
ExpectFalse("instance1.hasOwnProperty('error_proto')");
ExpectTrue("'error_proto' in instance1.__proto__");
ExpectTrue("instance1.error_proto === Error.prototype");
}
// Put %ErrorPrototype% in a function object's inheritance chain.
{
Local<FunctionTemplate> parent_template =
v8::FunctionTemplate::New(isolate);
parent_template->RemovePrototype(); // Remove so there is no name clash.
parent_template->SetIntrinsicDataProperty(v8_str("prototype"),
v8::kErrorPrototype);
Local<FunctionTemplate> func_template = v8::FunctionTemplate::New(isolate);
func_template->Inherit(parent_template);
Local<Function> func =
func_template->GetFunction(env.local()).ToLocalChecked();
CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust());
ExpectTrue("func.prototype.__proto__ === Error.prototype");
Local<Object> func_instance =
func->NewInstance(env.local()).ToLocalChecked();
CHECK(env->Global()
->Set(env.local(), v8_str("instance"), func_instance)
.FromJust());
ExpectTrue("instance.__proto__.__proto__.__proto__ === Object.prototype");
// Now let's check if %ErrorPrototype% properties are in the instance.
ExpectTrue("'constructor' in instance");
ExpectTrue("'message' in instance");
ExpectTrue("'name' in instance");
ExpectTrue("'toString' in instance");
}
}
TEST(ObjectTemplateArrayProtoIntrinsics) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment