[fastcall] Allow receiver to be passed as Object

This CL enhances the fast C API in a way to allow passing the receiver
to the fast callback as Local<Object> instead of Local<Value>. It also
fixes documentation comments.

Bug: chromium:1052746
Change-Id: I424aa83023c2e6633b9df08ee040bf170db32b3d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2887510
Commit-Queue: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74519}
This commit is contained in:
Maya Lekova 2021-05-12 10:54:52 +02:00 committed by V8 LUCI CQ
parent ea9164ef4d
commit 57afcaf4f5
4 changed files with 36 additions and 42 deletions

View File

@ -70,8 +70,7 @@
* return GetInternalField<CustomEmbedderType,
* kV8EmbedderWrapperObjectIndex>(wrapper);
* }
* static void FastMethod(v8::Value* receiver_obj, int param) {
* v8::Object* v8_object = v8::Object::Cast(receiver_obj);
* static void FastMethod(v8::Local<v8::Object> receiver_obj, int param) {
* CustomEmbedderType* receiver = static_cast<CustomEmbedderType*>(
* receiver_obj->GetAlignedPointerFromInternalField(
* kV8EmbedderWrapperObjectIndex));
@ -210,7 +209,7 @@ class CTypeInfo {
kFloat64,
kV8Value,
kApiObject, // This will be deprecated once all users have
// migrated from v8::ApiObject to v8::Value*.
// migrated from v8::ApiObject to v8::Local<v8::Value>.
};
// kCallbackOptionsType is not part of the Type enum
@ -315,7 +314,7 @@ class V8_EXPORT CFunction {
};
};
struct V8_DEPRECATE_SOON("Use v8::Value* instead.") ApiObject {
struct V8_DEPRECATE_SOON("Use v8::Local<v8::Value> instead.") ApiObject {
uintptr_t address;
};
@ -415,20 +414,22 @@ struct TypeInfoHelper {
static constexpr CTypeInfo::Type Type() { return CTypeInfo::Type::Enum; } \
};
#define BASIC_C_TYPES(V) \
V(void, kVoid) \
V(bool, kBool) \
V(int32_t, kInt32) \
V(uint32_t, kUint32) \
V(int64_t, kInt64) \
V(uint64_t, kUint64) \
V(float, kFloat32) \
V(double, kFloat64) \
V(ApiObject, kApiObject) \
V(v8::Local<v8::Value>, kV8Value)
#define BASIC_C_TYPES(V) \
V(void, kVoid) \
V(bool, kBool) \
V(int32_t, kInt32) \
V(uint32_t, kUint32) \
V(int64_t, kInt64) \
V(uint64_t, kUint64) \
V(float, kFloat32) \
V(double, kFloat64) \
V(ApiObject, kApiObject) \
V(v8::Local<v8::Value>, kV8Value) \
V(v8::Local<v8::Object>, kV8Value)
// ApiObject was a temporary solution to wrap the pointer to the v8::Value.
// Please use v8::Value* in new code, as ApiObject will be deprecated soon.
// Please use v8::Local<v8::Value> in new code for the arguments and
// v8::Local<v8::Object> for the receiver, as ApiObject will be deprecated.
BASIC_C_TYPES(SPECIALIZE_GET_TYPE_INFO_HELPER_FOR)

View File

@ -37,13 +37,12 @@ namespace {
class FastCApiObject {
public:
static double AddAllFastCallback(Local<Value> receiver, bool should_fallback,
static double AddAllFastCallback(Local<Object> receiver, bool should_fallback,
int32_t arg_i32, uint32_t arg_u32,
int64_t arg_i64, uint64_t arg_u64,
float arg_f32, double arg_f64,
FastApiCallbackOptions& options) {
CHECK(receiver->IsObject());
FastCApiObject* self = UnwrapObject(receiver.As<Object>());
FastCApiObject* self = UnwrapObject(receiver);
CHECK_SELF_OR_FALLBACK(0);
self->fast_call_count_++;
@ -92,12 +91,11 @@ class FastCApiObject {
args.GetReturnValue().Set(Number::New(isolate, sum));
}
static int Add32BitIntFastCallback(v8::Local<v8::Value> receiver,
static int Add32BitIntFastCallback(v8::Local<v8::Object> receiver,
bool should_fallback, int32_t arg_i32,
uint32_t arg_u32,
FastApiCallbackOptions& options) {
CHECK(receiver->IsObject());
FastCApiObject* self = UnwrapObject(receiver.As<Object>());
FastCApiObject* self = UnwrapObject(receiver);
CHECK_SELF_OR_FALLBACK(0);
self->fast_call_count_++;
@ -128,12 +126,11 @@ class FastCApiObject {
args.GetReturnValue().Set(Number::New(isolate, sum));
}
static bool IsFastCApiObjectFastCallback(v8::Local<v8::Value> receiver,
static bool IsFastCApiObjectFastCallback(v8::Local<v8::Object> receiver,
bool should_fallback,
v8::Local<v8::Value> arg,
FastApiCallbackOptions& options) {
CHECK(receiver->IsObject());
FastCApiObject* self = UnwrapObject(receiver.As<Object>());
FastCApiObject* self = UnwrapObject(receiver);
CHECK_SELF_OR_FALLBACK(false);
self->fast_call_count_++;

View File

@ -27680,7 +27680,7 @@ namespace {
template <typename Value, typename Impl, typename Ret>
struct BasicApiChecker {
static Ret FastCallback(v8::Local<v8::Value> receiver, Value argument,
static Ret FastCallback(v8::Local<v8::Object> receiver, Value argument,
v8::FastApiCallbackOptions& options) {
// TODO(mslekova): Refactor the data checking.
v8::Value* data = &(options.data);
@ -27688,7 +27688,7 @@ struct BasicApiChecker {
CHECK_EQ(v8::Number::Cast(data)->Value(), 42.0);
return Impl::FastCallback(receiver, argument, options);
}
static Ret FastCallbackNoFallback(v8::Local<v8::Value> receiver,
static Ret FastCallbackNoFallback(v8::Local<v8::Object> receiver,
Value argument) {
v8::FastApiCallbackOptions options = {false, {0}};
return Impl::FastCallback(receiver, argument, options);
@ -27730,9 +27730,9 @@ struct ApiNumberChecker : BasicApiChecker<T, ApiNumberChecker<T>, void> {
write_to_fallback_(write_to_fallback),
args_count_(args_count) {}
static void FastCallback(v8::Local<v8::Value> receiver, T argument,
static void FastCallback(v8::Local<v8::Object> receiver, T argument,
v8::FastApiCallbackOptions& options) {
v8::Object* receiver_obj = v8::Object::Cast(*receiver);
v8::Object* receiver_obj = *receiver;
if (!IsValidUnwrapObject(receiver_obj)) {
options.fallback = 1;
return;
@ -27781,12 +27781,11 @@ struct ApiNumberChecker : BasicApiChecker<T, ApiNumberChecker<T>, void> {
struct UnexpectedObjectChecker
: BasicApiChecker<v8::Local<v8::Value>, UnexpectedObjectChecker, void> {
static void FastCallback(v8::Local<v8::Value> receiver,
static void FastCallback(v8::Local<v8::Object> receiver,
v8::Local<v8::Value> argument,
v8::FastApiCallbackOptions& options) {
v8::Object* receiver_obj = v8::Object::Cast(*receiver);
UnexpectedObjectChecker* receiver_ptr =
GetInternalField<UnexpectedObjectChecker>(receiver_obj);
GetInternalField<UnexpectedObjectChecker>(*receiver);
receiver_ptr->SetCallFast();
if (argument->IsObject()) {
v8::Object* argument_obj = v8::Object::Cast(*argument);
@ -27815,12 +27814,11 @@ struct ApiObjectChecker
ApiObjectChecker(v8::FunctionTemplate* ctor, int data)
: ctor_(ctor), initial_data_(data) {}
static void FastCallback(v8::Local<v8::Value> receiver,
static void FastCallback(v8::Local<v8::Object> receiver,
v8::Local<v8::Value> argument,
v8::FastApiCallbackOptions& options) {
v8::Object* receiver_obj = v8::Object::Cast(*receiver);
ApiObjectChecker* receiver_ptr =
GetInternalField<ApiObjectChecker>(receiver_obj);
GetInternalField<ApiObjectChecker>(*receiver);
receiver_ptr->SetCallFast();
v8::Object* argument_obj = v8::Object::Cast(*argument);
@ -28003,11 +28001,10 @@ void CheckApiObjectArg() {
template <typename T>
struct ReturnValueChecker : BasicApiChecker<T, ReturnValueChecker<T>, T> {
static T FastCallback(v8::Local<v8::Value> receiver, T arg,
static T FastCallback(v8::Local<v8::Object> receiver, T arg,
v8::FastApiCallbackOptions& options) {
v8::Object* receiver_obj = v8::Object::Cast(*receiver);
ReturnValueChecker<T>* receiver_ptr =
GetInternalField<ReturnValueChecker<T>>(receiver_obj);
GetInternalField<ReturnValueChecker<T>>(*receiver);
receiver_ptr->SetCallFast();
return arg;
}

View File

@ -4071,17 +4071,16 @@ UNINITIALIZED_TEST(DetailedSourcePositionAPI_Inlining) {
namespace {
struct FastApiReceiver {
static void FastCallback(v8::Local<v8::Value> receiver, int argument,
static void FastCallback(v8::Local<v8::Object> receiver, int argument,
v8::FastApiCallbackOptions& options) {
// TODO(mslekova): The fallback is not used by the test. Replace this
// with a CHECK.
v8::Object* receiver_obj = v8::Object::Cast(*receiver);
if (!IsValidUnwrapObject(receiver_obj)) {
if (!IsValidUnwrapObject(*receiver)) {
options.fallback = 1;
return;
}
FastApiReceiver* receiver_ptr =
GetInternalField<FastApiReceiver>(receiver_obj);
GetInternalField<FastApiReceiver>(*receiver);
receiver_ptr->result_ |= ApiCheckerResult::kFastCalled;