[api] Implement signature checks using instance types
Rather than depending on slow signature checks, receiver type checks are performed using fast numeric instance type checks. This CL adds a instance type range for embedders to assign values and uses these to perform type checks. Bug: v8:11476 Change-Id: Ie8236ae47ca0ba93ae76a7e690b81aa0a2b0f3e2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2883623 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#76162}
This commit is contained in:
parent
f9627c11b6
commit
7df6678c32
@ -188,6 +188,8 @@ V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject(Address obj);
|
||||
// language mode is strict.
|
||||
V8_EXPORT bool ShouldThrowOnError(v8::internal::Isolate* isolate);
|
||||
|
||||
V8_EXPORT bool CanHaveInternalField(int instance_type);
|
||||
|
||||
/**
|
||||
* This class exports constants and functionality from within v8 that
|
||||
* is necessary to implement inline functions in the v8 api. Don't
|
||||
@ -266,8 +268,9 @@ class Internals {
|
||||
static const int kOddballType = 0x43;
|
||||
static const int kForeignType = 0x46;
|
||||
static const int kJSSpecialApiObjectType = 0x410;
|
||||
static const int kJSApiObjectType = 0x420;
|
||||
static const int kJSObjectType = 0x421;
|
||||
static const int kFirstJSApiObjectType = 0x422;
|
||||
static const int kLastJSApiObjectType = 0x80A;
|
||||
|
||||
static const int kUndefinedOddballKind = 5;
|
||||
static const int kNullOddballKind = 3;
|
||||
|
16
include/v8.h
16
include/v8.h
@ -6544,9 +6544,9 @@ class V8_EXPORT FunctionTemplate : public Template {
|
||||
Local<Signature> signature = Local<Signature>(), int length = 0,
|
||||
ConstructorBehavior behavior = ConstructorBehavior::kAllow,
|
||||
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
|
||||
const CFunction* c_function = nullptr, uint8_t instance_type = 0,
|
||||
uint8_t allowed_receiver_range_start = 0,
|
||||
uint8_t allowed_receiver_range_end = 0);
|
||||
const CFunction* c_function = nullptr, uint16_t instance_type = 0,
|
||||
uint16_t allowed_receiver_instance_type_range_start = 0,
|
||||
uint16_t allowed_receiver_instance_type_range_end = 0);
|
||||
|
||||
/** Creates a function template for multiple overloaded fast API calls.*/
|
||||
static Local<FunctionTemplate> NewWithCFunctionOverloads(
|
||||
@ -11684,10 +11684,8 @@ Local<Value> Object::GetInternalField(int index) {
|
||||
A obj = *reinterpret_cast<A*>(this);
|
||||
// Fast path: If the object is a plain JSObject, which is the common case, we
|
||||
// know where to find the internal fields and can return the value directly.
|
||||
auto instance_type = I::GetInstanceType(obj);
|
||||
if (instance_type == I::kJSObjectType ||
|
||||
instance_type == I::kJSApiObjectType ||
|
||||
instance_type == I::kJSSpecialApiObjectType) {
|
||||
int instance_type = I::GetInstanceType(obj);
|
||||
if (v8::internal::CanHaveInternalField(instance_type)) {
|
||||
int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
|
||||
A value = I::ReadRawField<A>(obj, offset);
|
||||
#ifdef V8_COMPRESS_POINTERS
|
||||
@ -11713,9 +11711,7 @@ void* Object::GetAlignedPointerFromInternalField(int index) {
|
||||
// Fast path: If the object is a plain JSObject, which is the common case, we
|
||||
// know where to find the internal fields and can return the value directly.
|
||||
auto instance_type = I::GetInstanceType(obj);
|
||||
if (V8_LIKELY(instance_type == I::kJSObjectType ||
|
||||
instance_type == I::kJSApiObjectType ||
|
||||
instance_type == I::kJSSpecialApiObjectType)) {
|
||||
if (v8::internal::CanHaveInternalField(instance_type)) {
|
||||
int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
|
||||
#ifdef V8_HEAP_SANDBOX
|
||||
offset += I::kEmbedderDataSlotRawPayloadOffset;
|
||||
|
@ -528,12 +528,14 @@ MaybeHandle<JSFunction> InstantiateFunction(
|
||||
Handle<HeapObject>::cast(parent_prototype));
|
||||
}
|
||||
}
|
||||
InstanceType function_type =
|
||||
(!data->needs_access_check() &&
|
||||
data->GetNamedPropertyHandler().IsUndefined(isolate) &&
|
||||
data->GetIndexedPropertyHandler().IsUndefined(isolate))
|
||||
? JS_API_OBJECT_TYPE
|
||||
: JS_SPECIAL_API_OBJECT_TYPE;
|
||||
InstanceType function_type = JS_SPECIAL_API_OBJECT_TYPE;
|
||||
if (!data->needs_access_check() &&
|
||||
data->GetNamedPropertyHandler().IsUndefined(isolate) &&
|
||||
data->GetIndexedPropertyHandler().IsUndefined(isolate)) {
|
||||
function_type = FLAG_embedder_instance_types && data->HasInstanceType()
|
||||
? static_cast<InstanceType>(data->InstanceType())
|
||||
: JS_API_OBJECT_TYPE;
|
||||
}
|
||||
|
||||
Handle<JSFunction> function = ApiNatives::CreateApiFunction(
|
||||
isolate, native_context, data, prototype, function_type, maybe_name);
|
||||
|
@ -1226,8 +1226,9 @@ static Local<FunctionTemplate> FunctionTemplateNew(
|
||||
v8::Local<Private> cached_property_name = v8::Local<Private>(),
|
||||
SideEffectType side_effect_type = SideEffectType::kHasSideEffect,
|
||||
const MemorySpan<const CFunction>& c_function_overloads = {},
|
||||
uint8_t instance_type = 0, uint8_t allowed_receiver_range_start = 0,
|
||||
uint8_t allowed_receiver_range_end = 0) {
|
||||
uint8_t instance_type = 0,
|
||||
uint8_t allowed_receiver_instance_type_range_start = 0,
|
||||
uint8_t allowed_receiver_instance_type_range_end = 0) {
|
||||
i::Handle<i::Struct> struct_obj = isolate->factory()->NewStruct(
|
||||
i::FUNCTION_TEMPLATE_INFO_TYPE, i::AllocationType::kOld);
|
||||
i::Handle<i::FunctionTemplateInfo> obj =
|
||||
@ -1250,8 +1251,10 @@ static Local<FunctionTemplate> FunctionTemplateNew(
|
||||
: *Utils::OpenHandle(*cached_property_name));
|
||||
if (behavior == ConstructorBehavior::kThrow) raw.set_remove_prototype(true);
|
||||
raw.SetInstanceType(instance_type);
|
||||
raw.set_allowed_receiver_range_start(allowed_receiver_range_start);
|
||||
raw.set_allowed_receiver_range_end(allowed_receiver_range_end);
|
||||
raw.set_allowed_receiver_instance_type_range_start(
|
||||
allowed_receiver_instance_type_range_start);
|
||||
raw.set_allowed_receiver_instance_type_range_end(
|
||||
allowed_receiver_instance_type_range_end);
|
||||
}
|
||||
if (callback != nullptr) {
|
||||
Utils::ToLocal(obj)->SetCallHandler(callback, data, side_effect_type,
|
||||
@ -1264,8 +1267,8 @@ Local<FunctionTemplate> FunctionTemplate::New(
|
||||
Isolate* isolate, FunctionCallback callback, v8::Local<Value> data,
|
||||
v8::Local<Signature> signature, int length, ConstructorBehavior behavior,
|
||||
SideEffectType side_effect_type, const CFunction* c_function,
|
||||
uint8_t instance_type, uint8_t allowed_receiver_range_start,
|
||||
uint8_t allowed_receiver_range_end) {
|
||||
uint16_t instance_type, uint16_t allowed_receiver_instance_type_range_start,
|
||||
uint16_t allowed_receiver_instance_type_range_end) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
// Changes to the environment cannot be captured in the snapshot. Expect no
|
||||
// function templates when the isolate is created for serialization.
|
||||
@ -1276,7 +1279,8 @@ Local<FunctionTemplate> FunctionTemplate::New(
|
||||
Local<Private>(), side_effect_type,
|
||||
c_function ? MemorySpan<const CFunction>{c_function, 1}
|
||||
: MemorySpan<const CFunction>{},
|
||||
instance_type, allowed_receiver_range_start, allowed_receiver_range_end);
|
||||
instance_type, allowed_receiver_instance_type_range_start,
|
||||
allowed_receiver_instance_type_range_end);
|
||||
}
|
||||
|
||||
Local<FunctionTemplate> FunctionTemplate::NewWithCFunctionOverloads(
|
||||
@ -3712,6 +3716,13 @@ bool i::ShouldThrowOnError(i::Isolate* isolate) {
|
||||
i::ShouldThrow::kThrowOnError;
|
||||
}
|
||||
|
||||
bool i::CanHaveInternalField(int instance_type) {
|
||||
return instance_type == i::Internals::kJSObjectType ||
|
||||
instance_type == i::Internals::kJSSpecialApiObjectType ||
|
||||
v8::internal::InstanceTypeChecker::IsJSApiObject(
|
||||
static_cast<v8::internal::InstanceType>(instance_type));
|
||||
}
|
||||
|
||||
void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
|
||||
Utils::ApiCheck(isolate != nullptr && !isolate->IsDead(),
|
||||
|
@ -552,8 +552,20 @@ extern class Filler extends HeapObject generates 'TNode<HeapObject>';
|
||||
// but not their own class definitions:
|
||||
|
||||
// Like JSObject, but created from API function.
|
||||
@apiExposedInstanceTypeValue(0x420)
|
||||
@apiExposedInstanceTypeValue(0x422)
|
||||
@doNotGenerateCast
|
||||
@noVerifier
|
||||
extern class JSApiObject extends JSObject generates 'TNode<JSObject>';
|
||||
|
||||
// TODO(gsathya): This only exists to make JSApiObject instance type into a
|
||||
// range.
|
||||
@apiExposedInstanceTypeValue(0x80A)
|
||||
@doNotGenerateCast
|
||||
@highestInstanceTypeWithinParentClassRange
|
||||
@noVerifier
|
||||
extern class JSLastDummyApiObject extends JSApiObject
|
||||
generates 'TNode<JSObject>';
|
||||
|
||||
// Like JSApiObject, but requires access checks and/or has interceptors.
|
||||
@apiExposedInstanceTypeValue(0x410)
|
||||
extern class JSSpecialApiObject extends JSSpecialObject
|
||||
|
@ -472,7 +472,8 @@ class FastCApiObject {
|
||||
static bool IsValidApiObject(Local<Object> object) {
|
||||
i::Address addr = *reinterpret_cast<i::Address*>(*object);
|
||||
auto instance_type = i::Internals::GetInstanceType(addr);
|
||||
return (instance_type == i::Internals::kJSApiObjectType ||
|
||||
return (base::IsInRange(instance_type, i::Internals::kFirstJSApiObjectType,
|
||||
i::Internals::kLastJSApiObjectType) ||
|
||||
instance_type == i::Internals::kJSSpecialApiObjectType);
|
||||
}
|
||||
static FastCApiObject* UnwrapObject(Local<Object> object) {
|
||||
|
@ -302,6 +302,8 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
||||
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
|
||||
JSFunction::cast(*this).JSFunctionVerify(isolate);
|
||||
break;
|
||||
case JS_LAST_DUMMY_API_OBJECT_TYPE:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,6 +261,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) {
|
||||
case THIN_ONE_BYTE_STRING_TYPE:
|
||||
case UNCACHED_EXTERNAL_STRING_TYPE:
|
||||
case UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE:
|
||||
case JS_LAST_DUMMY_API_OBJECT_TYPE:
|
||||
// TODO(all): Handle these types too.
|
||||
os << "UNKNOWN TYPE " << map().instance_type();
|
||||
UNREACHABLE();
|
||||
|
@ -1394,6 +1394,9 @@ DEFINE_NEG_IMPLICATION(parallel_compile_tasks, finalize_streaming_on_background)
|
||||
DEFINE_BOOL(disable_old_api_accessors, false,
|
||||
"Disable old-style API accessors whose setters trigger through the "
|
||||
"prototype chain")
|
||||
DEFINE_BOOL(
|
||||
embedder_instance_types, false,
|
||||
"enable type checks based on instance types provided by the embedder")
|
||||
|
||||
// bootstrapper.cc
|
||||
DEFINE_BOOL(expose_gc, false, "expose gc extension")
|
||||
|
@ -1812,8 +1812,8 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
|
||||
bool is_clonable_js_type =
|
||||
instance_type == JS_REG_EXP_TYPE || instance_type == JS_OBJECT_TYPE ||
|
||||
instance_type == JS_ERROR_TYPE || instance_type == JS_ARRAY_TYPE ||
|
||||
instance_type == JS_API_OBJECT_TYPE ||
|
||||
instance_type == JS_SPECIAL_API_OBJECT_TYPE;
|
||||
instance_type == JS_SPECIAL_API_OBJECT_TYPE ||
|
||||
InstanceTypeChecker::IsJSApiObject(instance_type);
|
||||
bool is_clonable_wasm_type = false;
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
is_clonable_wasm_type = instance_type == WASM_GLOBAL_OBJECT_TYPE ||
|
||||
|
@ -149,7 +149,8 @@ constexpr InstanceType LAST_STRING_TYPE =
|
||||
|
||||
STATIC_ASSERT((FIRST_NONSTRING_TYPE & kIsNotStringMask) != kStringTag);
|
||||
STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
|
||||
STATIC_ASSERT(JS_API_OBJECT_TYPE == Internals::kJSApiObjectType);
|
||||
STATIC_ASSERT(FIRST_JS_API_OBJECT_TYPE == Internals::kFirstJSApiObjectType);
|
||||
STATIC_ASSERT(LAST_JS_API_OBJECT_TYPE == Internals::kLastJSApiObjectType);
|
||||
STATIC_ASSERT(JS_SPECIAL_API_OBJECT_TYPE == Internals::kJSSpecialApiObjectType);
|
||||
STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
|
||||
STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType);
|
||||
|
@ -2338,6 +2338,11 @@ int JSObject::GetHeaderSize(InstanceType type,
|
||||
return WasmTagObject::kHeaderSize;
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
default: {
|
||||
// Special type check for API Objects because they are in a large variable
|
||||
// instance type range.
|
||||
if (InstanceTypeChecker::IsJSApiObject(type)) {
|
||||
return JSObject::kHeaderSize;
|
||||
}
|
||||
std::stringstream ss;
|
||||
ss << type;
|
||||
FATAL("unexpected instance type: %s\n", ss.str().c_str());
|
||||
@ -5143,18 +5148,18 @@ bool JSObject::IsApiWrapper() {
|
||||
// *_API_* types are generated through templates which can have embedder
|
||||
// fields. The other types have their embedder fields added at compile time.
|
||||
auto instance_type = map().instance_type();
|
||||
return instance_type == JS_API_OBJECT_TYPE ||
|
||||
instance_type == JS_ARRAY_BUFFER_TYPE ||
|
||||
return instance_type == JS_ARRAY_BUFFER_TYPE ||
|
||||
instance_type == JS_DATA_VIEW_TYPE ||
|
||||
instance_type == JS_GLOBAL_OBJECT_TYPE ||
|
||||
instance_type == JS_GLOBAL_PROXY_TYPE ||
|
||||
instance_type == JS_SPECIAL_API_OBJECT_TYPE ||
|
||||
instance_type == JS_TYPED_ARRAY_TYPE;
|
||||
instance_type == JS_TYPED_ARRAY_TYPE ||
|
||||
InstanceTypeChecker::IsJSApiObject(instance_type);
|
||||
}
|
||||
|
||||
bool JSObject::IsDroppableApiWrapper() {
|
||||
auto instance_type = map().instance_type();
|
||||
return instance_type == JS_API_OBJECT_TYPE ||
|
||||
return InstanceTypeChecker::IsJSApiObject(instance_type) ||
|
||||
instance_type == JS_SPECIAL_API_OBJECT_TYPE;
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,10 @@ VisitorId Map::GetVisitorId(Map map) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
if (InstanceTypeChecker::IsJSApiObject(map.instance_type())) {
|
||||
return kVisitJSApiObject;
|
||||
}
|
||||
|
||||
switch (instance_type) {
|
||||
case BYTE_ARRAY_TYPE:
|
||||
return kVisitByteArray;
|
||||
|
@ -270,6 +270,7 @@ class ZoneForwardList;
|
||||
V(FreeSpaceOrFiller) \
|
||||
V(FunctionContext) \
|
||||
V(JSApiObject) \
|
||||
V(JSLastDummyApiObject) \
|
||||
V(JSPromiseConstructor) \
|
||||
V(JSArrayConstructor) \
|
||||
V(JSRegExpConstructor) \
|
||||
|
@ -1006,6 +1006,9 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (InstanceTypeChecker::IsJSApiObject(type)) {
|
||||
return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case EMBEDDER_DATA_ARRAY_TYPE:
|
||||
|
@ -38,10 +38,12 @@ BOOL_ACCESSORS(FunctionTemplateInfo, flag, accept_any_receiver,
|
||||
AcceptAnyReceiverBit::kShift)
|
||||
BOOL_ACCESSORS(FunctionTemplateInfo, flag, published, PublishedBit::kShift)
|
||||
|
||||
BIT_FIELD_ACCESSORS(FunctionTemplateInfo, flag, allowed_receiver_range_start,
|
||||
FunctionTemplateInfo::AllowedReceiverRangeStartBits)
|
||||
BIT_FIELD_ACCESSORS(FunctionTemplateInfo, flag, allowed_receiver_range_end,
|
||||
FunctionTemplateInfo::AllowedReceiverRangeEndBits)
|
||||
BIT_FIELD_ACCESSORS(
|
||||
FunctionTemplateInfo, flag, allowed_receiver_instance_type_range_start,
|
||||
FunctionTemplateInfo::AllowedReceiverInstanceTypeRangeStartBits)
|
||||
BIT_FIELD_ACCESSORS(
|
||||
FunctionTemplateInfo, flag, allowed_receiver_instance_type_range_end,
|
||||
FunctionTemplateInfo::AllowedReceiverInstanceTypeRangeEndBits)
|
||||
|
||||
// static
|
||||
FunctionTemplateRareData FunctionTemplateInfo::EnsureFunctionTemplateRareData(
|
||||
@ -85,10 +87,23 @@ RARE_ACCESSORS(c_function_overloads, CFunctionOverloads, FixedArray,
|
||||
GetReadOnlyRoots(cage_base).empty_fixed_array())
|
||||
#undef RARE_ACCESSORS
|
||||
|
||||
int FunctionTemplateInfo::InstanceType() const { return instance_type(); }
|
||||
int FunctionTemplateInfo::InstanceType() const {
|
||||
int type = instance_type();
|
||||
DCHECK(type == kNoJSApiObjectType ||
|
||||
(type >= Internals::kFirstJSApiObjectType &&
|
||||
type <= Internals::kLastJSApiObjectType));
|
||||
return type;
|
||||
}
|
||||
|
||||
void FunctionTemplateInfo::SetInstanceType(int instance_type) {
|
||||
set_instance_type(instance_type);
|
||||
if (instance_type == 0) {
|
||||
set_instance_type(kNoJSApiObjectType);
|
||||
} else {
|
||||
DCHECK_GT(instance_type, 0);
|
||||
DCHECK_LT(Internals::kFirstJSApiObjectType + instance_type,
|
||||
Internals::kLastJSApiObjectType);
|
||||
set_instance_type(Internals::kFirstJSApiObjectType + instance_type);
|
||||
}
|
||||
}
|
||||
|
||||
bool TemplateInfo::should_cache() const {
|
||||
|
@ -18,6 +18,10 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
bool FunctionTemplateInfo::HasInstanceType() {
|
||||
return instance_type() != kNoJSApiObjectType;
|
||||
}
|
||||
|
||||
Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
|
||||
Isolate* isolate, Handle<FunctionTemplateInfo> info,
|
||||
MaybeHandle<Name> maybe_name) {
|
||||
@ -61,6 +65,17 @@ bool FunctionTemplateInfo::IsTemplateFor(Map map) const {
|
||||
|
||||
// There is a constraint on the object; check.
|
||||
if (!map.IsJSObjectMap()) return false;
|
||||
|
||||
if (FLAG_embedder_instance_types) {
|
||||
DCHECK_IMPLIES(allowed_receiver_instance_type_range_start() == 0,
|
||||
allowed_receiver_instance_type_range_end() == 0);
|
||||
if (base::IsInRange(map.instance_type(),
|
||||
allowed_receiver_instance_type_range_start(),
|
||||
allowed_receiver_instance_type_range_end())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch the constructor function of the object.
|
||||
Object cons_obj = map.GetConstructor();
|
||||
Object type;
|
||||
|
@ -123,8 +123,10 @@ class FunctionTemplateInfo
|
||||
// safely read concurrently.
|
||||
DECL_BOOLEAN_ACCESSORS(published)
|
||||
|
||||
DECL_INT_ACCESSORS(allowed_receiver_range_start)
|
||||
DECL_INT_ACCESSORS(allowed_receiver_range_end)
|
||||
// This specifies the permissable range of instance type of objects that can
|
||||
// be allowed to be used as receivers with the given template.
|
||||
DECL_INT16_ACCESSORS(allowed_receiver_instance_type_range_start)
|
||||
DECL_INT16_ACCESSORS(allowed_receiver_instance_type_range_end)
|
||||
// End flag bits ---------------------
|
||||
|
||||
// Dispatched behavior.
|
||||
@ -157,6 +159,7 @@ class FunctionTemplateInfo
|
||||
inline bool instantiated();
|
||||
|
||||
bool BreakAtEntry();
|
||||
bool HasInstanceType();
|
||||
|
||||
// Helper function for cached accessors.
|
||||
static base::Optional<Name> TryGetCachedPropertyName(Isolate* isolate,
|
||||
@ -174,6 +177,7 @@ class FunctionTemplateInfo
|
||||
DEFINE_TORQUE_GENERATED_FUNCTION_TEMPLATE_INFO_FLAGS()
|
||||
|
||||
private:
|
||||
static constexpr int kNoJSApiObjectType = 0;
|
||||
static inline FunctionTemplateRareData EnsureFunctionTemplateRareData(
|
||||
Isolate* isolate, Handle<FunctionTemplateInfo> function_template_info);
|
||||
|
||||
|
@ -35,8 +35,8 @@ bitfield struct FunctionTemplateInfoFlags extends uint31 {
|
||||
// Allowed receiver ranges are used for instance type checking to check
|
||||
// whether the receiver calling the associated JSFunction is a compatible
|
||||
// receiver.
|
||||
allowed_receiver_range_start: int32: 12 bit;
|
||||
allowed_receiver_range_end: int32: 12 bit;
|
||||
allowed_receiver_instance_type_range_start: int16: 12 bit;
|
||||
allowed_receiver_instance_type_range_end: int16: 12 bit;
|
||||
}
|
||||
|
||||
extern class FunctionTemplateInfo extends TemplateInfo {
|
||||
|
@ -414,7 +414,9 @@ int RegisterThreadedTest::count_ = 0;
|
||||
bool IsValidUnwrapObject(v8::Object* object) {
|
||||
i::Address addr = *reinterpret_cast<i::Address*>(object);
|
||||
auto instance_type = i::Internals::GetInstanceType(addr);
|
||||
return (instance_type == i::Internals::kJSObjectType ||
|
||||
instance_type == i::Internals::kJSApiObjectType ||
|
||||
return (v8::base::IsInRange(instance_type,
|
||||
i::Internals::kFirstJSApiObjectType,
|
||||
i::Internals::kLastJSApiObjectType) ||
|
||||
instance_type == i::Internals::kJSObjectType ||
|
||||
instance_type == i::Internals::kJSSpecialApiObjectType);
|
||||
}
|
||||
|
@ -29251,3 +29251,57 @@ TEST(TestSetSabConstructorEnabledCallback) {
|
||||
sab_constructor_enabled_value = true;
|
||||
CHECK(i_isolate->IsSharedArrayBufferConstructorEnabled(i_context));
|
||||
}
|
||||
|
||||
namespace {
|
||||
void NodeTypeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
args.GetReturnValue().Set(v8::Number::New(isolate, 1));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(EmbedderInstanceTypes) {
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
i::FLAG_embedder_instance_types = true;
|
||||
Local<FunctionTemplate> node = FunctionTemplate::New(isolate);
|
||||
Local<ObjectTemplate> proto_template = node->PrototypeTemplate();
|
||||
Local<FunctionTemplate> nodeType = v8::FunctionTemplate::New(
|
||||
isolate, NodeTypeCallback, Local<Value>(),
|
||||
v8::Signature::New(isolate, node), 0, v8::ConstructorBehavior::kThrow,
|
||||
v8::SideEffectType::kHasSideEffect, nullptr, 0, 1, 3);
|
||||
proto_template->SetAccessorProperty(
|
||||
String::NewFromUtf8Literal(isolate, "nodeType"), nodeType);
|
||||
|
||||
Local<FunctionTemplate> element = FunctionTemplate::New(
|
||||
isolate, nullptr, Local<Value>(), Local<v8::Signature>(), 0,
|
||||
v8::ConstructorBehavior::kAllow, v8::SideEffectType::kHasSideEffect,
|
||||
nullptr, 1);
|
||||
element->Inherit(node);
|
||||
|
||||
Local<FunctionTemplate> html_element = FunctionTemplate::New(
|
||||
isolate, nullptr, Local<Value>(), Local<v8::Signature>(), 0,
|
||||
v8::ConstructorBehavior::kAllow, v8::SideEffectType::kHasSideEffect,
|
||||
nullptr, 2);
|
||||
html_element->Inherit(element);
|
||||
|
||||
Local<FunctionTemplate> div_element = FunctionTemplate::New(
|
||||
isolate, nullptr, Local<Value>(), Local<v8::Signature>(), 0,
|
||||
v8::ConstructorBehavior::kAllow, v8::SideEffectType::kHasSideEffect,
|
||||
nullptr, 3);
|
||||
div_element->Inherit(html_element);
|
||||
|
||||
CHECK(env->Global()
|
||||
->Set(env.local(), v8_str("div"),
|
||||
div_element->GetFunction(env.local())
|
||||
.ToLocalChecked()
|
||||
->NewInstance(env.local())
|
||||
.ToLocalChecked())
|
||||
.FromJust());
|
||||
|
||||
CompileRun("var x = div.nodeType;");
|
||||
|
||||
Local<Value> res =
|
||||
env->Global()->Get(env.local(), v8_str("x")).ToLocalChecked();
|
||||
CHECK_EQ(1, res->ToInt32(env.local()).ToLocalChecked()->Value());
|
||||
}
|
||||
|
@ -156,81 +156,82 @@ INSTANCE_TYPES = {
|
||||
191: "JS_MODULE_NAMESPACE_TYPE",
|
||||
1040: "JS_SPECIAL_API_OBJECT_TYPE",
|
||||
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
|
||||
1042: "JS_ARRAY_ITERATOR_PROTOTYPE_TYPE",
|
||||
1043: "JS_ITERATOR_PROTOTYPE_TYPE",
|
||||
1044: "JS_MAP_ITERATOR_PROTOTYPE_TYPE",
|
||||
1045: "JS_OBJECT_PROTOTYPE_TYPE",
|
||||
1046: "JS_PROMISE_PROTOTYPE_TYPE",
|
||||
1047: "JS_REG_EXP_PROTOTYPE_TYPE",
|
||||
1048: "JS_SET_ITERATOR_PROTOTYPE_TYPE",
|
||||
1049: "JS_SET_PROTOTYPE_TYPE",
|
||||
1050: "JS_STRING_ITERATOR_PROTOTYPE_TYPE",
|
||||
1051: "JS_TYPED_ARRAY_PROTOTYPE_TYPE",
|
||||
1052: "JS_GENERATOR_OBJECT_TYPE",
|
||||
1053: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
|
||||
1054: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
|
||||
1055: "JS_ARGUMENTS_OBJECT_TYPE",
|
||||
1056: "JS_API_OBJECT_TYPE",
|
||||
1058: "JS_BOUND_FUNCTION_TYPE",
|
||||
1059: "JS_FUNCTION_TYPE",
|
||||
1060: "BIGINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1061: "BIGUINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1062: "FLOAT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1063: "FLOAT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1064: "INT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1065: "INT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1066: "INT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1067: "UINT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1068: "UINT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1069: "UINT8_CLAMPED_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1070: "UINT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1071: "JS_ARRAY_CONSTRUCTOR_TYPE",
|
||||
1072: "JS_PROMISE_CONSTRUCTOR_TYPE",
|
||||
1073: "JS_REG_EXP_CONSTRUCTOR_TYPE",
|
||||
1074: "JS_MAP_KEY_ITERATOR_TYPE",
|
||||
1075: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
|
||||
1076: "JS_MAP_VALUE_ITERATOR_TYPE",
|
||||
1077: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
|
||||
1078: "JS_SET_VALUE_ITERATOR_TYPE",
|
||||
1079: "JS_DATA_VIEW_TYPE",
|
||||
1080: "JS_TYPED_ARRAY_TYPE",
|
||||
1081: "JS_MAP_TYPE",
|
||||
1082: "JS_SET_TYPE",
|
||||
1083: "JS_WEAK_MAP_TYPE",
|
||||
1084: "JS_WEAK_SET_TYPE",
|
||||
1085: "JS_ARRAY_TYPE",
|
||||
1086: "JS_ARRAY_BUFFER_TYPE",
|
||||
1087: "JS_ARRAY_ITERATOR_TYPE",
|
||||
1088: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
|
||||
1089: "JS_COLLATOR_TYPE",
|
||||
1090: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
|
||||
1091: "JS_DATE_TYPE",
|
||||
1092: "JS_DATE_TIME_FORMAT_TYPE",
|
||||
1093: "JS_DISPLAY_NAMES_TYPE",
|
||||
1094: "JS_ERROR_TYPE",
|
||||
1095: "JS_FINALIZATION_REGISTRY_TYPE",
|
||||
1096: "JS_LIST_FORMAT_TYPE",
|
||||
1097: "JS_LOCALE_TYPE",
|
||||
1098: "JS_MESSAGE_OBJECT_TYPE",
|
||||
1099: "JS_NUMBER_FORMAT_TYPE",
|
||||
1100: "JS_PLURAL_RULES_TYPE",
|
||||
1101: "JS_PROMISE_TYPE",
|
||||
1102: "JS_REG_EXP_TYPE",
|
||||
1103: "JS_REG_EXP_STRING_ITERATOR_TYPE",
|
||||
1104: "JS_RELATIVE_TIME_FORMAT_TYPE",
|
||||
1105: "JS_SEGMENT_ITERATOR_TYPE",
|
||||
1106: "JS_SEGMENTER_TYPE",
|
||||
1107: "JS_SEGMENTS_TYPE",
|
||||
1108: "JS_STRING_ITERATOR_TYPE",
|
||||
1109: "JS_V8_BREAK_ITERATOR_TYPE",
|
||||
1110: "JS_WEAK_REF_TYPE",
|
||||
1111: "WASM_GLOBAL_OBJECT_TYPE",
|
||||
1112: "WASM_INSTANCE_OBJECT_TYPE",
|
||||
1113: "WASM_MEMORY_OBJECT_TYPE",
|
||||
1114: "WASM_MODULE_OBJECT_TYPE",
|
||||
1115: "WASM_TABLE_OBJECT_TYPE",
|
||||
1116: "WASM_TAG_OBJECT_TYPE",
|
||||
1117: "WASM_VALUE_OBJECT_TYPE",
|
||||
1058: "JS_API_OBJECT_TYPE",
|
||||
2058: "JS_LAST_DUMMY_API_OBJECT_TYPE",
|
||||
2059: "JS_BOUND_FUNCTION_TYPE",
|
||||
2060: "JS_FUNCTION_TYPE",
|
||||
2061: "BIGINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2062: "BIGUINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2063: "FLOAT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2064: "FLOAT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2065: "INT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2066: "INT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2067: "INT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2068: "UINT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2069: "UINT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2070: "UINT8_CLAMPED_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2071: "UINT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2072: "JS_ARRAY_CONSTRUCTOR_TYPE",
|
||||
2073: "JS_PROMISE_CONSTRUCTOR_TYPE",
|
||||
2074: "JS_REG_EXP_CONSTRUCTOR_TYPE",
|
||||
2075: "JS_ARRAY_ITERATOR_PROTOTYPE_TYPE",
|
||||
2076: "JS_ITERATOR_PROTOTYPE_TYPE",
|
||||
2077: "JS_MAP_ITERATOR_PROTOTYPE_TYPE",
|
||||
2078: "JS_OBJECT_PROTOTYPE_TYPE",
|
||||
2079: "JS_PROMISE_PROTOTYPE_TYPE",
|
||||
2080: "JS_REG_EXP_PROTOTYPE_TYPE",
|
||||
2081: "JS_SET_ITERATOR_PROTOTYPE_TYPE",
|
||||
2082: "JS_SET_PROTOTYPE_TYPE",
|
||||
2083: "JS_STRING_ITERATOR_PROTOTYPE_TYPE",
|
||||
2084: "JS_TYPED_ARRAY_PROTOTYPE_TYPE",
|
||||
2085: "JS_MAP_KEY_ITERATOR_TYPE",
|
||||
2086: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
|
||||
2087: "JS_MAP_VALUE_ITERATOR_TYPE",
|
||||
2088: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
|
||||
2089: "JS_SET_VALUE_ITERATOR_TYPE",
|
||||
2090: "JS_GENERATOR_OBJECT_TYPE",
|
||||
2091: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
|
||||
2092: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
|
||||
2093: "JS_DATA_VIEW_TYPE",
|
||||
2094: "JS_TYPED_ARRAY_TYPE",
|
||||
2095: "JS_MAP_TYPE",
|
||||
2096: "JS_SET_TYPE",
|
||||
2097: "JS_WEAK_MAP_TYPE",
|
||||
2098: "JS_WEAK_SET_TYPE",
|
||||
2099: "JS_ARGUMENTS_OBJECT_TYPE",
|
||||
2100: "JS_ARRAY_TYPE",
|
||||
2101: "JS_ARRAY_BUFFER_TYPE",
|
||||
2102: "JS_ARRAY_ITERATOR_TYPE",
|
||||
2103: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
|
||||
2104: "JS_COLLATOR_TYPE",
|
||||
2105: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
|
||||
2106: "JS_DATE_TYPE",
|
||||
2107: "JS_DATE_TIME_FORMAT_TYPE",
|
||||
2108: "JS_DISPLAY_NAMES_TYPE",
|
||||
2109: "JS_ERROR_TYPE",
|
||||
2110: "JS_FINALIZATION_REGISTRY_TYPE",
|
||||
2111: "JS_LIST_FORMAT_TYPE",
|
||||
2112: "JS_LOCALE_TYPE",
|
||||
2113: "JS_MESSAGE_OBJECT_TYPE",
|
||||
2114: "JS_NUMBER_FORMAT_TYPE",
|
||||
2115: "JS_PLURAL_RULES_TYPE",
|
||||
2116: "JS_PROMISE_TYPE",
|
||||
2117: "JS_REG_EXP_TYPE",
|
||||
2118: "JS_REG_EXP_STRING_ITERATOR_TYPE",
|
||||
2119: "JS_RELATIVE_TIME_FORMAT_TYPE",
|
||||
2120: "JS_SEGMENT_ITERATOR_TYPE",
|
||||
2121: "JS_SEGMENTER_TYPE",
|
||||
2122: "JS_SEGMENTS_TYPE",
|
||||
2123: "JS_STRING_ITERATOR_TYPE",
|
||||
2124: "JS_V8_BREAK_ITERATOR_TYPE",
|
||||
2125: "JS_WEAK_REF_TYPE",
|
||||
2126: "WASM_GLOBAL_OBJECT_TYPE",
|
||||
2127: "WASM_INSTANCE_OBJECT_TYPE",
|
||||
2128: "WASM_MEMORY_OBJECT_TYPE",
|
||||
2129: "WASM_MODULE_OBJECT_TYPE",
|
||||
2130: "WASM_TABLE_OBJECT_TYPE",
|
||||
2131: "WASM_TAG_OBJECT_TYPE",
|
||||
2132: "WASM_VALUE_OBJECT_TYPE",
|
||||
}
|
||||
|
||||
# List of known V8 maps.
|
||||
@ -390,7 +391,7 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x05fa9): (82, "StoreHandler2Map"),
|
||||
("read_only_space", 0x05fd1): (82, "StoreHandler3Map"),
|
||||
("map_space", 0x02119): (1057, "ExternalMap"),
|
||||
("map_space", 0x02141): (1098, "JSMessageObjectMap"),
|
||||
("map_space", 0x02141): (2113, "JSMessageObjectMap"),
|
||||
}
|
||||
|
||||
# List of known V8 objects.
|
||||
|
Loading…
Reference in New Issue
Block a user