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

Unified Diff: src/api-natives.cc

Issue 1972613002: Support subclassing API functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/api-natives.h ('k') | src/builtins.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/api-natives.cc
diff --git a/src/api-natives.cc b/src/api-natives.cc
index 4d3dc4d5401d9ddf75b687456887dcec111b7d02..fcd19ccadad7b364599d830ac72f90c0a40c5ace 100644
--- a/src/api-natives.cc
+++ b/src/api-natives.cc
@@ -17,6 +17,7 @@ namespace {
MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
Handle<ObjectTemplateInfo> data,
+ Handle<JSReceiver> new_target,
bool is_hidden_prototype);
MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
@@ -31,7 +32,7 @@ MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data,
Handle<FunctionTemplateInfo>::cast(data), name);
} else if (data->IsObjectTemplateInfo()) {
return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data),
- false);
+ Handle<JSReceiver>(), false);
} else {
return data;
}
@@ -288,11 +289,25 @@ void UncacheTemplateInstantiation(Isolate* isolate, uint32_t serial_number) {
MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
Handle<ObjectTemplateInfo> info,
+ Handle<JSReceiver> new_target,
bool is_hidden_prototype) {
- // Fast path.
- Handle<JSObject> result;
+ Handle<JSFunction> constructor;
uint32_t serial_number =
static_cast<uint32_t>(Smi::cast(info->serial_number())->value());
+ if (!new_target.is_null()) {
+ if (new_target->IsJSFunction() &&
+ JSFunction::cast(*new_target)->shared()->function_data() ==
+ info->constructor() &&
+ JSFunction::cast(*new_target)->context()->native_context() ==
+ isolate->context()->native_context()) {
+ constructor = Handle<JSFunction>::cast(new_target);
+ } else {
+ // Disable caching for subclass instantiation.
+ serial_number = 0;
+ }
+ }
+ // Fast path.
+ Handle<JSObject> result;
if (serial_number) {
// Probe cache.
auto cache = isolate->template_instantiations_cache();
@@ -305,20 +320,27 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
}
// Enter a new scope. Recursion could otherwise create a lot of handles.
HandleScope scope(isolate);
- auto constructor = handle(info->constructor(), isolate);
- Handle<JSFunction> cons;
- if (constructor->IsUndefined()) {
- cons = isolate->object_function();
- } else {
- auto cons_templ = Handle<FunctionTemplateInfo>::cast(constructor);
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, cons, InstantiateFunction(isolate, cons_templ), JSFunction);
+
+ if (constructor.is_null()) {
+ Handle<Object> cons(info->constructor(), isolate);
+ if (cons->IsUndefined()) {
+ constructor = isolate->object_function();
+ } else {
+ auto cons_templ = Handle<FunctionTemplateInfo>::cast(cons);
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, constructor,
+ InstantiateFunction(isolate, cons_templ),
+ JSObject);
+ }
+
+ if (new_target.is_null()) new_target = constructor;
}
- auto object = isolate->factory()->NewJSObject(cons);
+
+ Handle<JSObject> object;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, object,
+ JSObject::New(constructor, new_target), JSObject);
ASSIGN_RETURN_ON_EXCEPTION(
isolate, result,
- ConfigureInstance(isolate, object, info, is_hidden_prototype),
- JSFunction);
+ ConfigureInstance(isolate, object, info, is_hidden_prototype), JSObject);
// TODO(dcarney): is this necessary?
JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject");
@@ -356,7 +378,7 @@ MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
isolate, prototype,
InstantiateObject(isolate,
Handle<ObjectTemplateInfo>::cast(prototype_templ),
- data->hidden_prototype()),
+ Handle<JSReceiver>(), data->hidden_prototype()),
JSFunction);
}
auto parent = handle(data->parent_template(), isolate);
@@ -448,12 +470,11 @@ MaybeHandle<JSFunction> ApiNatives::InstantiateFunction(
return ::v8::internal::InstantiateFunction(isolate, data);
}
-
MaybeHandle<JSObject> ApiNatives::InstantiateObject(
- Handle<ObjectTemplateInfo> data) {
+ Handle<ObjectTemplateInfo> data, Handle<JSReceiver> new_target) {
Isolate* isolate = data->GetIsolate();
InvokeScope invoke_scope(isolate);
- return ::v8::internal::InstantiateObject(isolate, data, false);
+ return ::v8::internal::InstantiateObject(isolate, data, new_target, false);
}
« no previous file with comments | « src/api-natives.h ('k') | src/builtins.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698