Skip to content

Commit a7980d4

Browse files
paolosevMSFTV8 LUCI CQ
authored andcommitted
[fastcall] Add vector of CFunction overloads to FunctionTemplate
As a first step to support Fast API calls with overloads, adds a new FunctionTemplate constructor that accepts a vector of CFunction*. Bug: v8:11739 Change-Id: I112b1746768f52df52c893a4f1fb799b6bd90856 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2860838 Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Paolo Severini <paolosev@microsoft.com> Cr-Commit-Position: refs/heads/master@{#74481}
1 parent f4a6c62 commit a7980d4

4 files changed

Lines changed: 75 additions & 19 deletions

File tree

include/v8.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6499,6 +6499,15 @@ class V8_EXPORT FunctionTemplate : public Template {
64996499
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
65006500
const CFunction* c_function = nullptr);
65016501

6502+
/** Creates a function template for multiple overloaded fast API calls.*/
6503+
static Local<FunctionTemplate> NewWithCFunctionOverloads(
6504+
Isolate* isolate, FunctionCallback callback = nullptr,
6505+
Local<Value> data = Local<Value>(),
6506+
Local<Signature> signature = Local<Signature>(), int length = 0,
6507+
ConstructorBehavior behavior = ConstructorBehavior::kAllow,
6508+
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
6509+
const std::vector<const CFunction*>& c_function_overloads = {});
6510+
65026511
/**
65036512
* Creates a function template backed/cached by a private property.
65046513
*/
@@ -6530,7 +6539,7 @@ class V8_EXPORT FunctionTemplate : public Template {
65306539
void SetCallHandler(
65316540
FunctionCallback callback, Local<Value> data = Local<Value>(),
65326541
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
6533-
const CFunction* c_function = nullptr);
6542+
const std::vector<const CFunction*>& c_function_overloads = {});
65346543

65356544
/** Set the predefined length property for the FunctionTemplate. */
65366545
void SetLength(int length);

src/api/api.cc

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,7 @@ void FunctionTemplate::SetPrototypeProviderTemplate(
11851185
Utils::OpenHandle(*prototype_provider);
11861186
Utils::ApiCheck(self->GetPrototypeTemplate().IsUndefined(i_isolate),
11871187
"v8::FunctionTemplate::SetPrototypeProviderTemplate",
1188-
"Protoype must be undefiend");
1188+
"Protoype must be undefined");
11891189
Utils::ApiCheck(self->GetParentTemplate().IsUndefined(i_isolate),
11901190
"v8::FunctionTemplate::SetPrototypeProviderTemplate",
11911191
"Prototype provider must be empty");
@@ -1218,7 +1218,7 @@ static Local<FunctionTemplate> FunctionTemplateNew(
12181218
bool do_not_cache,
12191219
v8::Local<Private> cached_property_name = v8::Local<Private>(),
12201220
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
1221-
const CFunction* c_function = nullptr) {
1221+
const std::vector<const CFunction*>& c_function_overloads = {}) {
12221222
i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
12231223
i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
12241224
i::Handle<i::FunctionTemplateInfo> obj =
@@ -1243,7 +1243,7 @@ static Local<FunctionTemplate> FunctionTemplateNew(
12431243
}
12441244
if (callback != nullptr) {
12451245
Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
1246-
c_function);
1246+
c_function_overloads);
12471247
}
12481248
return Utils::ToLocal(obj);
12491249
}
@@ -1257,10 +1257,29 @@ Local<FunctionTemplate> FunctionTemplate::New(
12571257
// function templates when the isolate is created for serialization.
12581258
LOG_API(i_isolate, FunctionTemplate, New);
12591259
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1260-
auto templ = FunctionTemplateNew(i_isolate, callback, data, signature, length,
1261-
behavior, false, Local<Private>(),
1262-
side_effect_type, c_function);
1263-
return templ;
1260+
return FunctionTemplateNew(
1261+
i_isolate, callback, data, signature, length, behavior, false,
1262+
Local<Private>(), side_effect_type,
1263+
c_function ? std::vector<const CFunction*>{c_function}
1264+
: std::vector<const CFunction*>{});
1265+
}
1266+
1267+
Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
1268+
Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
1269+
v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
1270+
SideEffectType side_effect_type,
1271+
const std::vector<const CFunction*>& c_function_overloads) {
1272+
// Multiple overloads not supported yet.
1273+
Utils::ApiCheck(c_function_overloads.size() == 1,
1274+
"v8::FunctionTemplate::NewWithCFunctionOverloads",
1275+
"Function overloads not supported yet.");
1276+
1277+
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1278+
LOG_API(i_isolate, FunctionTemplate, New);
1279+
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
1280+
return FunctionTemplateNew(i_isolate, callback, data, signature, length,
1281+
behavior, false, Local<Private>(),
1282+
side_effect_type, c_function_overloads);
12641283
}
12651284

12661285
Local<FunctionTemplate> FunctionTemplate::NewWithCache(
@@ -1291,10 +1310,10 @@ Local<AccessorSignature> AccessorSignature::New(
12911310
(obj)->setter(*foreign); \
12921311
} while (false)
12931312

1294-
void FunctionTemplate::SetCallHandler(FunctionCallback callback,
1295-
v8::Local<Value> data,
1296-
SideEffectType side_effect_type,
1297-
const CFunction* c_function) {
1313+
void FunctionTemplate::SetCallHandler(
1314+
FunctionCallback callback, v8::Local<Value> data,
1315+
SideEffectType side_effect_type,
1316+
const std::vector<const CFunction*>& c_function_overloads) {
12981317
auto info = Utils::OpenHandle(this);
12991318
EnsureNotPublished(info, "v8::FunctionTemplate::SetCallHandler");
13001319
i::Isolate* isolate = info->GetIsolate();
@@ -1310,13 +1329,20 @@ void FunctionTemplate::SetCallHandler(FunctionCallback callback,
13101329
obj->set_data(*Utils::OpenHandle(*data));
13111330
// Blink passes CFunction's constructed with the default constructor
13121331
// for non-fast calls, so we should check the address too.
1313-
if (c_function != nullptr && c_function->GetAddress()) {
1314-
i::FunctionTemplateInfo::SetCFunction(
1315-
isolate, info,
1316-
i::handle(*FromCData(isolate, c_function->GetAddress()), isolate));
1317-
i::FunctionTemplateInfo::SetCSignature(
1318-
isolate, info,
1319-
i::handle(*FromCData(isolate, c_function->GetTypeInfo()), isolate));
1332+
if (!c_function_overloads.empty()) {
1333+
// Multiple overloads not supported yet.
1334+
Utils::ApiCheck(c_function_overloads.size() == 1,
1335+
"v8::FunctionTemplate::SetCallHandler",
1336+
"Function overloads not supported yet.");
1337+
const CFunction* c_function = c_function_overloads[0];
1338+
if (c_function != nullptr && c_function->GetAddress()) {
1339+
i::FunctionTemplateInfo::SetCFunction(
1340+
isolate, info,
1341+
i::handle(*FromCData(isolate, c_function->GetAddress()), isolate));
1342+
i::FunctionTemplateInfo::SetCSignature(
1343+
isolate, info,
1344+
i::handle(*FromCData(isolate, c_function->GetTypeInfo()), isolate));
1345+
}
13201346
}
13211347
info->set_call_code(*obj, kReleaseStore);
13221348
}

src/d8/d8-test.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
284284
Local<Value>(), signature, 1,
285285
ConstructorBehavior::kThrow,
286286
SideEffectType::kHasSideEffect, &add_all_c_func));
287+
288+
// To test function overloads.
289+
api_obj_ctor->PrototypeTemplate()->Set(
290+
isolate, "overloaded_add_all",
291+
FunctionTemplate::NewWithCFunctionOverloads(
292+
isolate, FastCApiObject::AddAllSlowCallback, Local<Value>(),
293+
signature, 1, ConstructorBehavior::kThrow,
294+
SideEffectType::kHasSideEffect, {&add_all_c_func}));
295+
287296
CFunction add_32bit_int_c_func =
288297
CFunction::Make(FastCApiObject::Add32BitIntFastCallback);
289298
api_obj_ctor->PrototypeTemplate()->Set(

test/mjsunit/compiler/fast-api-calls.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,15 @@ assertEquals(add_32bit_int_result, add_32bit_int_mismatch(false, -42, 45));
178178
assertOptimized(add_32bit_int_mismatch);
179179
assertEquals(1, fast_c_api.fast_call_count());
180180
assertEquals(0, fast_c_api.slow_call_count());
181+
182+
// Test function overloads
183+
function overloaded_add_all(should_fallback = false) {
184+
return fast_c_api.overloaded_add_all(should_fallback,
185+
-42, 45, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER,
186+
max_safe_float * 0.5, Math.PI);
187+
}
188+
189+
%PrepareFunctionForOptimization(overloaded_add_all);
190+
assertEquals(add_all_result, overloaded_add_all());
191+
%OptimizeFunctionOnNextCall(overloaded_add_all);
192+
assertEquals(add_all_result, overloaded_add_all());

0 commit comments

Comments
 (0)