[torque] Generate GC object visitors for Torque classes
In the process: * Augment C++-generated Torque classes with SizeFor methods to calculate size of instances. * Add a new "@generateBodyDescriptor" annotation that causes Torque to generate C++ BodyDescriptors code that can be used to visit objects compatible with existing V8 mechanisms, e.g. GC * Fully automate C++ macro machinery so that adding non-extern Torque class doesn't require any C++ changes, including ensuring generation of instance types and proper boilerplate for validators and printers. * Make handling of @export a true annotation, allowing the modifier to be used on class declarations. * Add functionality such that classes with the @export annotation are available to be used from C++. Field accessors for exported classes are public and factory methods are generated to create instances of the objects from C++. * Change the Torque compiler such that Non-exported classes implicitly have the @generateBodyDescriptor annotation added and causes both verifiers and printers to be generated. * Switch non-extern Torque classes from using existing Struct-based machinery to being first-class classes that support more existing Torque class features. Change-Id: Ic60e60c2c6bd7acd57f949bce086898ad14a3b03 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2007490 Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#66621}
This commit is contained in:
parent
f830171093
commit
4f4d73f225
4
BUILD.gn
4
BUILD.gn
@ -1176,11 +1176,14 @@ template("run_torque") {
|
|||||||
"bit-fields-tq.h",
|
"bit-fields-tq.h",
|
||||||
"builtin-definitions-tq.h",
|
"builtin-definitions-tq.h",
|
||||||
"interface-descriptors-tq.inc",
|
"interface-descriptors-tq.inc",
|
||||||
|
"factory-tq.cc",
|
||||||
|
"factory-tq.inc",
|
||||||
"field-offsets-tq.h",
|
"field-offsets-tq.h",
|
||||||
"class-verifiers-tq.cc",
|
"class-verifiers-tq.cc",
|
||||||
"class-verifiers-tq.h",
|
"class-verifiers-tq.h",
|
||||||
"enum-verifiers-tq.cc",
|
"enum-verifiers-tq.cc",
|
||||||
"objects-printer-tq.cc",
|
"objects-printer-tq.cc",
|
||||||
|
"objects-body-descriptors-tq-inl.h",
|
||||||
"class-definitions-tq.cc",
|
"class-definitions-tq.cc",
|
||||||
"class-definitions-tq-inl.h",
|
"class-definitions-tq-inl.h",
|
||||||
"class-definitions-tq.h",
|
"class-definitions-tq.h",
|
||||||
@ -1302,6 +1305,7 @@ v8_source_set("torque_generated_definitions") {
|
|||||||
"$target_gen_dir/torque-generated/class-definitions-tq.cc",
|
"$target_gen_dir/torque-generated/class-definitions-tq.cc",
|
||||||
"$target_gen_dir/torque-generated/class-verifiers-tq.cc",
|
"$target_gen_dir/torque-generated/class-verifiers-tq.cc",
|
||||||
"$target_gen_dir/torque-generated/class-verifiers-tq.h",
|
"$target_gen_dir/torque-generated/class-verifiers-tq.h",
|
||||||
|
"$target_gen_dir/torque-generated/factory-tq.cc",
|
||||||
"$target_gen_dir/torque-generated/objects-printer-tq.cc",
|
"$target_gen_dir/torque-generated/objects-printer-tq.cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ namespace torque_internal {
|
|||||||
type UninitializedHeapObject extends HeapObject;
|
type UninitializedHeapObject extends HeapObject;
|
||||||
|
|
||||||
extern macro AllocateAllowLOS(intptr): UninitializedHeapObject;
|
extern macro AllocateAllowLOS(intptr): UninitializedHeapObject;
|
||||||
extern macro GetStructMap(constexpr InstanceType): Map;
|
extern macro GetInstanceTypeMap(constexpr InstanceType): Map;
|
||||||
|
|
||||||
macro Allocate(sizeInBytes: intptr, map: Map): UninitializedHeapObject {
|
macro Allocate(sizeInBytes: intptr, map: Map): UninitializedHeapObject {
|
||||||
assert(ValidAllocationSize(sizeInBytes, map));
|
assert(ValidAllocationSize(sizeInBytes, map));
|
||||||
|
@ -1635,9 +1635,10 @@ TNode<Float64T> CodeStubAssembler::LoadHeapNumberValue(
|
|||||||
object, HeapNumber::kValueOffset, MachineType::Float64()));
|
object, HeapNumber::kValueOffset, MachineType::Float64()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<Map> CodeStubAssembler::GetStructMap(InstanceType instance_type) {
|
TNode<Map> CodeStubAssembler::GetInstanceTypeMap(InstanceType instance_type) {
|
||||||
Handle<Map> map_handle(
|
Handle<Map> map_handle(
|
||||||
Map::GetStructMap(ReadOnlyRoots(isolate()), instance_type), isolate());
|
Map::GetInstanceTypeMap(ReadOnlyRoots(isolate()), instance_type),
|
||||||
|
isolate());
|
||||||
return HeapConstant(map_handle);
|
return HeapConstant(map_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
|
|||||||
V(TypedArraySpeciesProtector, typed_array_species_protector, \
|
V(TypedArraySpeciesProtector, typed_array_species_protector, \
|
||||||
TypedArraySpeciesProtector)
|
TypedArraySpeciesProtector)
|
||||||
|
|
||||||
|
#define TORQUE_INTERNAL_CLASS_LIST_CSA_ADAPTER(V, NAME, Name, name) \
|
||||||
|
V(Name##Map, name##_map, Name##Map)
|
||||||
|
|
||||||
#define HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V) \
|
#define HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V) \
|
||||||
V(AccessorInfoMap, accessor_info_map, AccessorInfoMap) \
|
V(AccessorInfoMap, accessor_info_map, AccessorInfoMap) \
|
||||||
V(AccessorPairMap, accessor_pair_map, AccessorPairMap) \
|
V(AccessorPairMap, accessor_pair_map, AccessorPairMap) \
|
||||||
@ -174,7 +177,9 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
|
|||||||
V(UndefinedValue, undefined_value, Undefined) \
|
V(UndefinedValue, undefined_value, Undefined) \
|
||||||
V(uninitialized_symbol, uninitialized_symbol, UninitializedSymbol) \
|
V(uninitialized_symbol, uninitialized_symbol, UninitializedSymbol) \
|
||||||
V(WeakFixedArrayMap, weak_fixed_array_map, WeakFixedArrayMap) \
|
V(WeakFixedArrayMap, weak_fixed_array_map, WeakFixedArrayMap) \
|
||||||
V(zero_string, zero_string, ZeroString)
|
V(zero_string, zero_string, ZeroString) \
|
||||||
|
TORQUE_INTERNAL_CLASS_LIST_GENERATOR(TORQUE_INTERNAL_CLASS_LIST_CSA_ADAPTER, \
|
||||||
|
V)
|
||||||
|
|
||||||
#define HEAP_IMMOVABLE_OBJECT_LIST(V) \
|
#define HEAP_IMMOVABLE_OBJECT_LIST(V) \
|
||||||
HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V) \
|
HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(V) \
|
||||||
@ -1942,7 +1947,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
Label* if_bailout);
|
Label* if_bailout);
|
||||||
TNode<Object> GetConstructor(TNode<Map> map);
|
TNode<Object> GetConstructor(TNode<Map> map);
|
||||||
|
|
||||||
TNode<Map> GetStructMap(InstanceType instance_type);
|
TNode<Map> GetInstanceTypeMap(InstanceType instance_type);
|
||||||
|
|
||||||
TNode<FixedArray> AllocateUninitializedFixedArray(intptr_t capacity) {
|
TNode<FixedArray> AllocateUninitializedFixedArray(intptr_t capacity) {
|
||||||
return UncheckedCast<FixedArray>(AllocateFixedArray(
|
return UncheckedCast<FixedArray>(AllocateFixedArray(
|
||||||
|
@ -77,7 +77,7 @@ class PromiseRejectReactionJobTask;
|
|||||||
class WasmDebugInfo;
|
class WasmDebugInfo;
|
||||||
class Zone;
|
class Zone;
|
||||||
#define MAKE_FORWARD_DECLARATION(V, NAME, Name, name) class Name;
|
#define MAKE_FORWARD_DECLARATION(V, NAME, Name, name) class Name;
|
||||||
TORQUE_STRUCT_LIST_GENERATOR(MAKE_FORWARD_DECLARATION, UNUSED)
|
TORQUE_INTERNAL_CLASS_LIST_GENERATOR(MAKE_FORWARD_DECLARATION, UNUSED)
|
||||||
#undef MAKE_FORWARD_DECLARATION
|
#undef MAKE_FORWARD_DECLARATION
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -369,7 +369,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
|
|||||||
case PROMISE_REJECT_REACTION_JOB_TASK_TYPE:
|
case PROMISE_REJECT_REACTION_JOB_TASK_TYPE:
|
||||||
case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE:
|
case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE:
|
||||||
#define MAKE_TORQUE_CLASS_TYPE(V) case V:
|
#define MAKE_TORQUE_CLASS_TYPE(V) case V:
|
||||||
TORQUE_INTERNAL_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE)
|
TORQUE_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE)
|
||||||
#undef MAKE_TORQUE_CLASS_TYPE
|
#undef MAKE_TORQUE_CLASS_TYPE
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -247,6 +247,7 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
|||||||
// Every class that has its fields defined in a .tq file and corresponds
|
// Every class that has its fields defined in a .tq file and corresponds
|
||||||
// to exactly one InstanceType value is included in the following list.
|
// to exactly one InstanceType value is included in the following list.
|
||||||
TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
|
TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
|
||||||
|
TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
|
||||||
#undef MAKE_TORQUE_CASE
|
#undef MAKE_TORQUE_CASE
|
||||||
|
|
||||||
case ALLOCATION_SITE_TYPE:
|
case ALLOCATION_SITE_TYPE:
|
||||||
|
@ -207,6 +207,7 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
|||||||
// Every class that has its fields defined in a .tq file and corresponds
|
// Every class that has its fields defined in a .tq file and corresponds
|
||||||
// to exactly one InstanceType value is included in the following list.
|
// to exactly one InstanceType value is included in the following list.
|
||||||
TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
|
TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
|
||||||
|
TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
|
||||||
#undef MAKE_TORQUE_CASE
|
#undef MAKE_TORQUE_CASE
|
||||||
|
|
||||||
case ALLOCATION_SITE_TYPE:
|
case ALLOCATION_SITE_TYPE:
|
||||||
|
@ -47,7 +47,7 @@ FactoryBase<OffThreadFactory>::NewHeapNumber<AllocationType::kOld>();
|
|||||||
template <typename Impl>
|
template <typename Impl>
|
||||||
Handle<Struct> FactoryBase<Impl>::NewStruct(InstanceType type,
|
Handle<Struct> FactoryBase<Impl>::NewStruct(InstanceType type,
|
||||||
AllocationType allocation) {
|
AllocationType allocation) {
|
||||||
Map map = Map::GetStructMap(read_only_roots(), type);
|
Map map = Map::GetInstanceTypeMap(read_only_roots(), type);
|
||||||
int size = map.instance_size();
|
int size = map.instance_size();
|
||||||
HeapObject result = AllocateRawWithImmortalMap(size, allocation, map);
|
HeapObject result = AllocateRawWithImmortalMap(size, allocation, map);
|
||||||
Handle<Struct> str = handle(Struct::cast(result), isolate());
|
Handle<Struct> str = handle(Struct::cast(result), isolate());
|
||||||
|
@ -103,6 +103,13 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
|||||||
public:
|
public:
|
||||||
inline ReadOnlyRoots read_only_roots();
|
inline ReadOnlyRoots read_only_roots();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Handle<T> MakeHandle(T obj) {
|
||||||
|
return handle(obj, isolate());
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "torque-generated/factory-tq.inc"
|
||||||
|
|
||||||
Handle<Oddball> NewOddball(Handle<Map> map, const char* to_string,
|
Handle<Oddball> NewOddball(Handle<Map> map, const char* to_string,
|
||||||
Handle<Object> to_number, const char* type_of,
|
Handle<Object> to_number, const char* type_of,
|
||||||
byte kind);
|
byte kind);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "src/objects/oddball.h"
|
#include "src/objects/oddball.h"
|
||||||
#include "src/objects/ordered-hash-table.h"
|
#include "src/objects/ordered-hash-table.h"
|
||||||
#include "src/wasm/wasm-objects.h"
|
#include "src/wasm/wasm-objects.h"
|
||||||
|
#include "torque-generated/objects-body-descriptors-tq-inl.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -43,6 +44,7 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map map,
|
|||||||
return visitor->Visit##TypeName( \
|
return visitor->Visit##TypeName( \
|
||||||
map, ConcreteVisitor::template Cast<TypeName>(object));
|
map, ConcreteVisitor::template Cast<TypeName>(object));
|
||||||
TYPED_VISITOR_ID_LIST(CASE)
|
TYPED_VISITOR_ID_LIST(CASE)
|
||||||
|
TORQUE_VISITOR_ID_LIST(CASE)
|
||||||
#undef CASE
|
#undef CASE
|
||||||
case kVisitShortcutCandidate:
|
case kVisitShortcutCandidate:
|
||||||
return visitor->VisitShortcutCandidate(
|
return visitor->VisitShortcutCandidate(
|
||||||
@ -96,6 +98,7 @@ void HeapVisitor<ResultType, ConcreteVisitor>::VisitMapPointer(
|
|||||||
return static_cast<ResultType>(size); \
|
return static_cast<ResultType>(size); \
|
||||||
}
|
}
|
||||||
TYPED_VISITOR_ID_LIST(VISIT)
|
TYPED_VISITOR_ID_LIST(VISIT)
|
||||||
|
TORQUE_VISITOR_ID_LIST(VISIT)
|
||||||
#undef VISIT
|
#undef VISIT
|
||||||
|
|
||||||
template <typename ResultType, typename ConcreteVisitor>
|
template <typename ResultType, typename ConcreteVisitor>
|
||||||
|
@ -68,6 +68,7 @@ namespace internal {
|
|||||||
|
|
||||||
#define FORWARD_DECLARE(TypeName) class TypeName;
|
#define FORWARD_DECLARE(TypeName) class TypeName;
|
||||||
TYPED_VISITOR_ID_LIST(FORWARD_DECLARE)
|
TYPED_VISITOR_ID_LIST(FORWARD_DECLARE)
|
||||||
|
TORQUE_VISITOR_ID_LIST(FORWARD_DECLARE)
|
||||||
#undef FORWARD_DECLARE
|
#undef FORWARD_DECLARE
|
||||||
|
|
||||||
// The base class for visitors that need to dispatch on object type. The default
|
// The base class for visitors that need to dispatch on object type. The default
|
||||||
@ -103,6 +104,7 @@ class HeapVisitor : public ObjectVisitor {
|
|||||||
#define VISIT(TypeName) \
|
#define VISIT(TypeName) \
|
||||||
V8_INLINE ResultType Visit##TypeName(Map map, TypeName object);
|
V8_INLINE ResultType Visit##TypeName(Map map, TypeName object);
|
||||||
TYPED_VISITOR_ID_LIST(VISIT)
|
TYPED_VISITOR_ID_LIST(VISIT)
|
||||||
|
TORQUE_VISITOR_ID_LIST(VISIT)
|
||||||
#undef VISIT
|
#undef VISIT
|
||||||
V8_INLINE ResultType VisitShortcutCandidate(Map map, ConsString object);
|
V8_INLINE ResultType VisitShortcutCandidate(Map map, ConsString object);
|
||||||
V8_INLINE ResultType VisitDataObject(Map map, HeapObject object);
|
V8_INLINE ResultType VisitDataObject(Map map, HeapObject object);
|
||||||
|
@ -403,6 +403,18 @@ bool Heap::CreateInitialMaps() {
|
|||||||
ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_NAME_DICTIONARY_TYPE,
|
ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_NAME_DICTIONARY_TYPE,
|
||||||
small_ordered_name_dictionary)
|
small_ordered_name_dictionary)
|
||||||
|
|
||||||
|
#define TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR(V, NAME, Name, name) \
|
||||||
|
ALLOCATE_MAP(NAME, Name::kSize, name)
|
||||||
|
TORQUE_INTERNAL_FIXED_CLASS_LIST_GENERATOR(
|
||||||
|
TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR, _);
|
||||||
|
#undef TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR
|
||||||
|
|
||||||
|
#define TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR(V, NAME, Name, name) \
|
||||||
|
ALLOCATE_VARSIZE_MAP(NAME, name)
|
||||||
|
TORQUE_INTERNAL_VARSIZE_CLASS_LIST_GENERATOR(
|
||||||
|
TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR, _);
|
||||||
|
#undef TORQUE_INTERNAL_CLASS_LIST_MAP_ALLOCATOR
|
||||||
|
|
||||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
|
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
|
||||||
|
|
||||||
ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
|
ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "src/roots/roots.h"
|
#include "src/roots/roots.h"
|
||||||
#include "src/utils/ostreams.h"
|
#include "src/utils/ostreams.h"
|
||||||
#include "src/zone/zone-containers.h"
|
#include "src/zone/zone-containers.h"
|
||||||
|
#include "torque-generated/field-offsets-tq.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -74,7 +75,7 @@ void Map::PrintReconfiguration(Isolate* isolate, FILE* file,
|
|||||||
os << "]\n";
|
os << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Map Map::GetStructMap(ReadOnlyRoots roots, InstanceType type) {
|
Map Map::GetInstanceTypeMap(ReadOnlyRoots roots, InstanceType type) {
|
||||||
Map map;
|
Map map;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
#define MAKE_CASE(TYPE, Name, name) \
|
#define MAKE_CASE(TYPE, Name, name) \
|
||||||
@ -82,6 +83,12 @@ Map Map::GetStructMap(ReadOnlyRoots roots, InstanceType type) {
|
|||||||
map = roots.name##_map(); \
|
map = roots.name##_map(); \
|
||||||
break;
|
break;
|
||||||
STRUCT_LIST(MAKE_CASE)
|
STRUCT_LIST(MAKE_CASE)
|
||||||
|
#undef MAKE_CASE
|
||||||
|
#define MAKE_CASE(_, TYPE, Name, name) \
|
||||||
|
case TYPE: \
|
||||||
|
map = roots.name##_map(); \
|
||||||
|
break;
|
||||||
|
TORQUE_INTERNAL_CLASS_LIST_GENERATOR(MAKE_CASE, _)
|
||||||
#undef MAKE_CASE
|
#undef MAKE_CASE
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -360,6 +367,12 @@ VisitorId Map::GetVisitorId(Map map) {
|
|||||||
case SYNTHETIC_MODULE_TYPE:
|
case SYNTHETIC_MODULE_TYPE:
|
||||||
return kVisitSyntheticModule;
|
return kVisitSyntheticModule;
|
||||||
|
|
||||||
|
#define MAKE_TQ_CASE(TYPE, Name) \
|
||||||
|
case TYPE: \
|
||||||
|
return kVisit##Name;
|
||||||
|
TORQUE_BODY_DESCRIPTOR_LIST(MAKE_TQ_CASE)
|
||||||
|
#undef MAKE_TQ_CASE
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,13 @@ enum InstanceType : uint16_t;
|
|||||||
V(WeakArray) \
|
V(WeakArray) \
|
||||||
V(WeakCell)
|
V(WeakCell)
|
||||||
|
|
||||||
|
#define TORQUE_OBJECT_BODY_TO_VISITOR_ID_LIST_ADAPTER(V, TYPE, TypeName) \
|
||||||
|
V(TypeName)
|
||||||
|
|
||||||
|
#define TORQUE_VISITOR_ID_LIST(V) \
|
||||||
|
TORQUE_BODY_DESCRIPTOR_LIST_GENERATOR( \
|
||||||
|
TORQUE_OBJECT_BODY_TO_VISITOR_ID_LIST_ADAPTER, V)
|
||||||
|
|
||||||
// Objects with the same visitor id are processed in the same way by
|
// Objects with the same visitor id are processed in the same way by
|
||||||
// the heap visitors. The visitor ids for data only objects must precede
|
// the heap visitors. The visitor ids for data only objects must precede
|
||||||
// other visitor ids. We rely on kDataOnlyVisitorIdCount for quick check
|
// other visitor ids. We rely on kDataOnlyVisitorIdCount for quick check
|
||||||
@ -92,6 +99,7 @@ enum VisitorId {
|
|||||||
#define VISITOR_ID_ENUM_DECL(id) kVisit##id,
|
#define VISITOR_ID_ENUM_DECL(id) kVisit##id,
|
||||||
DATA_ONLY_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) kDataOnlyVisitorIdCount,
|
DATA_ONLY_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) kDataOnlyVisitorIdCount,
|
||||||
POINTER_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
|
POINTER_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
|
||||||
|
TORQUE_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
|
||||||
#undef VISITOR_ID_ENUM_DECL
|
#undef VISITOR_ID_ENUM_DECL
|
||||||
kVisitorIdCount
|
kVisitorIdCount
|
||||||
};
|
};
|
||||||
@ -794,7 +802,7 @@ class Map : public HeapObject {
|
|||||||
|
|
||||||
inline bool CanTransition() const;
|
inline bool CanTransition() const;
|
||||||
|
|
||||||
static Map GetStructMap(ReadOnlyRoots roots, InstanceType type);
|
static Map GetInstanceTypeMap(ReadOnlyRoots roots, InstanceType type);
|
||||||
|
|
||||||
#define DECL_TESTER(Type, ...) inline bool Is##Type##Map() const;
|
#define DECL_TESTER(Type, ...) inline bool Is##Type##Map() const;
|
||||||
INSTANCE_TYPE_CHECKERS(DECL_TESTER)
|
INSTANCE_TYPE_CHECKERS(DECL_TESTER)
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
#ifndef V8_OBJECTS_OBJECT_LIST_MACROS_H_
|
#ifndef V8_OBJECTS_OBJECT_LIST_MACROS_H_
|
||||||
#define V8_OBJECTS_OBJECT_LIST_MACROS_H_
|
#define V8_OBJECTS_OBJECT_LIST_MACROS_H_
|
||||||
|
|
||||||
|
#include "torque-generated/instance-types-tq.h"
|
||||||
|
|
||||||
|
#define TORQUE_INTERNAL_CLASS_NAMES_ADAPTER(V, NAME, Name, name) V(Name)
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -233,7 +237,8 @@ class ZoneForwardList;
|
|||||||
V(WasmTableObject) \
|
V(WasmTableObject) \
|
||||||
V(WeakFixedArray) \
|
V(WeakFixedArray) \
|
||||||
V(WeakArrayList) \
|
V(WeakArrayList) \
|
||||||
V(WeakCell)
|
V(WeakCell) \
|
||||||
|
TORQUE_INTERNAL_CLASS_LIST_GENERATOR(TORQUE_INTERNAL_CLASS_NAMES_ADAPTER, V)
|
||||||
|
|
||||||
#ifdef V8_INTL_SUPPORT
|
#ifdef V8_INTL_SUPPORT
|
||||||
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
|
#define HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \
|
||||||
|
@ -1100,6 +1100,12 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
|||||||
case SYNTHETIC_MODULE_TYPE:
|
case SYNTHETIC_MODULE_TYPE:
|
||||||
return Op::template apply<SyntheticModule::BodyDescriptor>(p1, p2, p3,
|
return Op::template apply<SyntheticModule::BodyDescriptor>(p1, p2, p3,
|
||||||
p4);
|
p4);
|
||||||
|
#define MAKE_TORQUE_BODY_DESCRIPTOR_APPLY(TYPE, TypeName) \
|
||||||
|
case TYPE: \
|
||||||
|
return Op::template apply<TypeName::BodyDescriptor>(p1, p2, p3, p4);
|
||||||
|
TORQUE_BODY_DESCRIPTOR_LIST(MAKE_TORQUE_BODY_DESCRIPTOR_APPLY)
|
||||||
|
#undef MAKE_TORQUE_BODY_DESCRIPTOR_APPLY
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PrintF("Unknown type: %d\n", type);
|
PrintF("Unknown type: %d\n", type);
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -180,6 +180,10 @@ class SubclassBodyDescriptor final : public BodyDescriptorBase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TORQUE_BODY_DESCRIPTOR_LIST_ADAPTER(V, TYPE, TypeName) V(TYPE, TypeName)
|
||||||
|
#define TORQUE_BODY_DESCRIPTOR_LIST(V) \
|
||||||
|
TORQUE_BODY_DESCRIPTOR_LIST_GENERATOR(TORQUE_BODY_DESCRIPTOR_LIST_ADAPTER, V)
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
|
@ -159,9 +159,7 @@ namespace internal {
|
|||||||
wasm_indirect_function_table) \
|
wasm_indirect_function_table) \
|
||||||
V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data)
|
V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data)
|
||||||
|
|
||||||
#define STRUCT_LIST_GENERATOR(V, _) \
|
#define STRUCT_LIST_GENERATOR(V, _) STRUCT_LIST_GENERATOR_BASE(V, _)
|
||||||
STRUCT_LIST_GENERATOR_BASE(V, _) \
|
|
||||||
TORQUE_STRUCT_LIST_GENERATOR(V, _)
|
|
||||||
|
|
||||||
// Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_LIST entry
|
// Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_LIST entry
|
||||||
#define STRUCT_LIST_ADAPTER(V, NAME, Name, name) V(NAME, Name, name)
|
#define STRUCT_LIST_ADAPTER(V, NAME, Name, name) V(NAME, Name, name)
|
||||||
@ -176,6 +174,15 @@ namespace internal {
|
|||||||
// Produces (Map, struct_name_map, StructNameMap) entries
|
// Produces (Map, struct_name_map, StructNameMap) entries
|
||||||
#define STRUCT_MAPS_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V)
|
#define STRUCT_MAPS_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V)
|
||||||
|
|
||||||
|
// Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_LIST entry
|
||||||
|
#define TORQUE_INTERNAL_CLASS_LIST_MAPS_ADAPTER(V, NAME, Name, name) \
|
||||||
|
V(Map, name##_map, Name##Map)
|
||||||
|
|
||||||
|
// Produces (NAME, Name, name) entries.
|
||||||
|
#define TORQUE_INTERNAL_CLASS_MAPS_LIST(V) \
|
||||||
|
TORQUE_INTERNAL_CLASS_LIST_GENERATOR( \
|
||||||
|
TORQUE_INTERNAL_CLASS_LIST_MAPS_ADAPTER, V)
|
||||||
|
|
||||||
//
|
//
|
||||||
// The following macros define list of allocation size objects and list of
|
// The following macros define list of allocation size objects and list of
|
||||||
// their maps.
|
// their maps.
|
||||||
|
@ -125,6 +125,7 @@
|
|||||||
|
|
||||||
#include "torque-generated/class-definitions-tq-inl.h"
|
#include "torque-generated/class-definitions-tq-inl.h"
|
||||||
#include "torque-generated/internal-class-definitions-tq-inl.h"
|
#include "torque-generated/internal-class-definitions-tq-inl.h"
|
||||||
|
#include "torque-generated/objects-body-descriptors-tq-inl.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -2276,6 +2277,14 @@ int HeapObject::SizeFromMap(Map map) const {
|
|||||||
PreparseData data = PreparseData::unchecked_cast(*this);
|
PreparseData data = PreparseData::unchecked_cast(*this);
|
||||||
return PreparseData::SizeFor(data.data_length(), data.children_length());
|
return PreparseData::SizeFor(data.data_length(), data.children_length());
|
||||||
}
|
}
|
||||||
|
#define MAKE_TORQUE_SIZE_FOR(TYPE, TypeName) \
|
||||||
|
if (instance_type == TYPE) { \
|
||||||
|
TypeName instance = TypeName::unchecked_cast(*this); \
|
||||||
|
return TypeName::SizeFor(instance); \
|
||||||
|
}
|
||||||
|
TORQUE_BODY_DESCRIPTOR_LIST(MAKE_TORQUE_SIZE_FOR)
|
||||||
|
#undef MAKE_TORQUE_SIZE_FOR
|
||||||
|
|
||||||
if (instance_type == CODE_TYPE) {
|
if (instance_type == CODE_TYPE) {
|
||||||
return Code::unchecked_cast(*this).CodeSize();
|
return Code::unchecked_cast(*this).CodeSize();
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,7 @@ class Symbol;
|
|||||||
PUBLIC_SYMBOL_ROOT_LIST(V) \
|
PUBLIC_SYMBOL_ROOT_LIST(V) \
|
||||||
WELL_KNOWN_SYMBOL_ROOT_LIST(V) \
|
WELL_KNOWN_SYMBOL_ROOT_LIST(V) \
|
||||||
STRUCT_MAPS_LIST(V) \
|
STRUCT_MAPS_LIST(V) \
|
||||||
|
TORQUE_INTERNAL_CLASS_MAPS_LIST(V) \
|
||||||
ALLOCATION_SITE_MAPS_LIST(V) \
|
ALLOCATION_SITE_MAPS_LIST(V) \
|
||||||
DATA_HANDLER_MAPS_LIST(V)
|
DATA_HANDLER_MAPS_LIST(V)
|
||||||
|
|
||||||
|
@ -552,8 +552,7 @@ void ImplementationVisitor::GenerateClassDebugReaders(
|
|||||||
std::stringstream class_names;
|
std::stringstream class_names;
|
||||||
|
|
||||||
std::unordered_set<const ClassType*> done;
|
std::unordered_set<const ClassType*> done;
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
GenerateClassDebugReader(*type, h_contents, cc_contents, visitor,
|
GenerateClassDebugReader(*type, h_contents, cc_contents, visitor,
|
||||||
class_names, &done);
|
class_names, &done);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@ static const char* const UNINITIALIZED_ITERATOR_TYPE_STRING =
|
|||||||
"UninitializedIterator";
|
"UninitializedIterator";
|
||||||
static const char* const GENERIC_TYPE_INSTANTIATION_NAMESPACE_STRING =
|
static const char* const GENERIC_TYPE_INSTANTIATION_NAMESPACE_STRING =
|
||||||
"_generic_type_instantiation_namespace";
|
"_generic_type_instantiation_namespace";
|
||||||
|
static const char* const FIXED_ARRAY_BASE_TYPE_STRING = "FixedArrayBase";
|
||||||
|
|
||||||
static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint";
|
static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint";
|
||||||
static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier";
|
static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier";
|
||||||
@ -88,6 +89,9 @@ static const char* const ANNOTATION_INSTANCE_TYPE_VALUE =
|
|||||||
"@apiExposedInstanceTypeValue";
|
"@apiExposedInstanceTypeValue";
|
||||||
static const char* const ANNOTATION_IF = "@if";
|
static const char* const ANNOTATION_IF = "@if";
|
||||||
static const char* const ANNOTATION_IFNOT = "@ifnot";
|
static const char* const ANNOTATION_IFNOT = "@ifnot";
|
||||||
|
static const char* const ANNOTATION_GENERATE_BODY_DESCRIPTOR =
|
||||||
|
"@generateBodyDescriptor";
|
||||||
|
static const char* const ANNOTATION_EXPORT_CPP_CLASS = "@export";
|
||||||
|
|
||||||
inline bool IsConstexprName(const std::string& name) {
|
inline bool IsConstexprName(const std::string& name) {
|
||||||
return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) ==
|
return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) ==
|
||||||
@ -125,6 +129,8 @@ enum class ClassFlag {
|
|||||||
kHighestInstanceTypeWithinParent = 1 << 9,
|
kHighestInstanceTypeWithinParent = 1 << 9,
|
||||||
kLowestInstanceTypeWithinParent = 1 << 10,
|
kLowestInstanceTypeWithinParent = 1 << 10,
|
||||||
kUndefinedLayout = 1 << 11,
|
kUndefinedLayout = 1 << 11,
|
||||||
|
kGenerateBodyDescriptor = 1 << 12,
|
||||||
|
kExport = 1 << 13,
|
||||||
};
|
};
|
||||||
using ClassFlags = base::Flags<ClassFlag>;
|
using ClassFlags = base::Flags<ClassFlag>;
|
||||||
|
|
||||||
|
@ -35,15 +35,6 @@ class GlobalContext : public ContextualClass<GlobalContext> {
|
|||||||
return Get().declarables_;
|
return Get().declarables_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RegisterClass(const TypeAlias* alias) {
|
|
||||||
DCHECK(alias->ParentScope()->IsNamespace());
|
|
||||||
Get().classes_.push_back(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
using GlobalClassList = std::vector<const TypeAlias*>;
|
|
||||||
|
|
||||||
static const GlobalClassList& GetClasses() { return Get().classes_; }
|
|
||||||
|
|
||||||
static void AddCppInclude(std::string include_path) {
|
static void AddCppInclude(std::string include_path) {
|
||||||
Get().cpp_includes_.insert(std::move(include_path));
|
Get().cpp_includes_.insert(std::move(include_path));
|
||||||
}
|
}
|
||||||
@ -84,7 +75,6 @@ class GlobalContext : public ContextualClass<GlobalContext> {
|
|||||||
std::vector<std::unique_ptr<Declarable>> declarables_;
|
std::vector<std::unique_ptr<Declarable>> declarables_;
|
||||||
std::set<std::string> cpp_includes_;
|
std::set<std::string> cpp_includes_;
|
||||||
std::map<SourceId, PerFileStreams> generated_per_file_;
|
std::map<SourceId, PerFileStreams> generated_per_file_;
|
||||||
GlobalClassList classes_;
|
|
||||||
std::map<std::string, size_t> fresh_ids_;
|
std::map<std::string, size_t> fresh_ids_;
|
||||||
|
|
||||||
friend class LanguageServerData;
|
friend class LanguageServerData;
|
||||||
|
@ -1482,7 +1482,7 @@ VisitResult ImplementationVisitor::Visit(NewExpression* expr) {
|
|||||||
VisitResult(TypeOracle::GetConstexprInstanceTypeType(),
|
VisitResult(TypeOracle::GetConstexprInstanceTypeType(),
|
||||||
CapifyStringWithUnderscores(class_type->name()) + "_TYPE"));
|
CapifyStringWithUnderscores(class_type->name()) + "_TYPE"));
|
||||||
object_map = GenerateCall(
|
object_map = GenerateCall(
|
||||||
QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, "GetStructMap"),
|
QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, "GetInstanceTypeMap"),
|
||||||
get_struct_map_arguments, {}, false);
|
get_struct_map_arguments, {}, false);
|
||||||
CurrentSourcePosition::Scope current_pos(expr->pos);
|
CurrentSourcePosition::Scope current_pos(expr->pos);
|
||||||
initializer_results.names.insert(initializer_results.names.begin(),
|
initializer_results.names.insert(initializer_results.names.begin(),
|
||||||
@ -3061,9 +3061,9 @@ class FieldOffsetsGenerator {
|
|||||||
UpdateSection(f);
|
UpdateSection(f);
|
||||||
|
|
||||||
// Emit kHeaderSize before any indexed field.
|
// Emit kHeaderSize before any indexed field.
|
||||||
// TODO(tebbi): Generalize this code to work with multiple indexed fields.
|
if (f.index.has_value() && !header_size_emitted_) {
|
||||||
if (f.index.has_value()) {
|
|
||||||
WriteMarker("kHeaderSize");
|
WriteMarker("kHeaderSize");
|
||||||
|
header_size_emitted_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't know statically how much space an indexed field takes, so report
|
// We don't know statically how much space an indexed field takes, so report
|
||||||
@ -3165,6 +3165,7 @@ class FieldOffsetsGenerator {
|
|||||||
FieldSectionType current_section_ = FieldSectionType::kNoSection;
|
FieldSectionType current_section_ = FieldSectionType::kNoSection;
|
||||||
FieldSections completed_sections_ = FieldSectionType::kNoSection;
|
FieldSections completed_sections_ = FieldSectionType::kNoSection;
|
||||||
bool is_finished_ = false;
|
bool is_finished_ = false;
|
||||||
|
bool header_size_emitted_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator {
|
class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator {
|
||||||
@ -3187,47 +3188,22 @@ class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator {
|
|||||||
std::ostream& out_;
|
std::ostream& out_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
void GenerateClassExport(const ClassType* type, std::ostream& header,
|
||||||
|
std::ostream& inl_header) {
|
||||||
void ImplementationVisitor::GenerateCppForInternalClasses(
|
|
||||||
const std::string& output_directory) {
|
|
||||||
std::stringstream header;
|
|
||||||
std::stringstream inl;
|
|
||||||
std::string base_name = "internal-class-definitions-tq";
|
|
||||||
{
|
|
||||||
IncludeGuardScope header_guard(header, base_name + ".h");
|
|
||||||
header << "#include \"src/objects/objects.h\"\n";
|
|
||||||
header << "#include \"src/objects/struct.h\"\n";
|
|
||||||
header << "#include \"src/objects/js-objects.h\"\n";
|
|
||||||
header << "#include \"src/utils/utils.h\"\n";
|
|
||||||
header << "#include \"torque-generated/class-definitions-tq.h\"\n";
|
|
||||||
IncludeObjectMacrosScope header_macros(header);
|
|
||||||
NamespaceScope header_namespaces(header, {"v8", "internal"});
|
|
||||||
|
|
||||||
IncludeGuardScope inl_guard(inl, base_name + "-inl.h");
|
|
||||||
inl << "#include \"torque-generated/" << base_name << ".h\"\n";
|
|
||||||
inl << "#include \"torque-generated/class-definitions-tq-inl.h\"\n";
|
|
||||||
IncludeObjectMacrosScope inl_macros(inl);
|
|
||||||
NamespaceScope inl_namespaces(inl, {"v8", "internal"});
|
|
||||||
|
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
if (type->IsExtern()) continue;
|
|
||||||
const ClassType* super = type->GetSuperClass();
|
const ClassType* super = type->GetSuperClass();
|
||||||
std::string parent = "TorqueGenerated" + type->name() + "<" +
|
std::string parent = "TorqueGenerated" + type->name() + "<" + type->name() +
|
||||||
type->name() + ", " + super->name() + ">";
|
", " + super->name() + ">";
|
||||||
header << "class " << type->name() << " : public " << parent << " {\n";
|
header << "class " << type->name() << " : public " << parent << " {\n";
|
||||||
header << " public:\n";
|
header << " public:\n";
|
||||||
|
if (type->ShouldGenerateBodyDescriptor()) {
|
||||||
|
header << " class BodyDescriptor;\n";
|
||||||
|
}
|
||||||
header << " TQ_OBJECT_CONSTRUCTORS(" << type->name() << ")\n";
|
header << " TQ_OBJECT_CONSTRUCTORS(" << type->name() << ")\n";
|
||||||
header << "};\n\n";
|
header << "};\n\n";
|
||||||
|
inl_header << "TQ_OBJECT_CONSTRUCTORS_IMPL(" << type->name() << ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
inl << "TQ_OBJECT_CONSTRUCTORS_IMPL(" << type->name() << ")\n";
|
} // namespace
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string dir_basename = output_directory + "/" + base_name;
|
|
||||||
WriteFile(dir_basename + ".h", header.str());
|
|
||||||
WriteFile(dir_basename + "-inl.h", inl.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImplementationVisitor::GenerateClassFieldOffsets(
|
void ImplementationVisitor::GenerateClassFieldOffsets(
|
||||||
const std::string& output_directory) {
|
const std::string& output_directory) {
|
||||||
@ -3236,9 +3212,7 @@ void ImplementationVisitor::GenerateClassFieldOffsets(
|
|||||||
{
|
{
|
||||||
IncludeGuardScope include_guard(header, file_name);
|
IncludeGuardScope include_guard(header, file_name);
|
||||||
|
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
|
|
||||||
// TODO(danno): Remove this once all classes use ClassFieldOffsetGenerator
|
// TODO(danno): Remove this once all classes use ClassFieldOffsetGenerator
|
||||||
// to generate field offsets without the use of macros.
|
// to generate field offsets without the use of macros.
|
||||||
if (!type->GenerateCppClassDefinitions() && !type->HasUndefinedLayout()) {
|
if (!type->GenerateCppClassDefinitions() && !type->HasUndefinedLayout()) {
|
||||||
@ -3251,6 +3225,16 @@ void ImplementationVisitor::GenerateClassFieldOffsets(
|
|||||||
header << "\n";
|
header << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header << "#define TORQUE_BODY_DESCRIPTOR_LIST_GENERATOR(V, _)\\\n";
|
||||||
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
|
if (type->ShouldGenerateBodyDescriptor()) {
|
||||||
|
std::string type_name =
|
||||||
|
CapifyStringWithUnderscores(type->name()) + "_TYPE";
|
||||||
|
header << "V(_, " << type_name << ", " << type->name() << ")\\\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header << "\n";
|
||||||
}
|
}
|
||||||
const std::string output_header_path = output_directory + "/" + file_name;
|
const std::string output_header_path = output_directory + "/" + file_name;
|
||||||
WriteFile(output_header_path, header.str());
|
WriteFile(output_header_path, header.str());
|
||||||
@ -3366,6 +3350,29 @@ class CppClassGenerator {
|
|||||||
std::ostream& impl_;
|
std::ostream& impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
base::Optional<std::vector<Field>> GetOrderedUniqueIndexFields(
|
||||||
|
const ClassType& type) {
|
||||||
|
std::vector<Field> result;
|
||||||
|
std::set<std::string> index_names;
|
||||||
|
for (const Field& field : type.ComputeAllFields()) {
|
||||||
|
if (field.index) {
|
||||||
|
auto name_and_type = ExtractSimpleFieldArraySize(type, *field.index);
|
||||||
|
if (!name_and_type) {
|
||||||
|
return base::nullopt;
|
||||||
|
}
|
||||||
|
index_names.insert(name_and_type->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Field& field : type.ComputeAllFields()) {
|
||||||
|
if (index_names.count(field.name_and_type.name) != 0) {
|
||||||
|
result.push_back(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void CppClassGenerator::GenerateClass() {
|
void CppClassGenerator::GenerateClass() {
|
||||||
hdr_ << template_decl() << "\n";
|
hdr_ << template_decl() << "\n";
|
||||||
hdr_ << "class " << gen_name_ << " : public P {\n";
|
hdr_ << "class " << gen_name_ << " : public P {\n";
|
||||||
@ -3375,10 +3382,16 @@ void CppClassGenerator::GenerateClass() {
|
|||||||
<< " \"Pass in " << super_->name()
|
<< " \"Pass in " << super_->name()
|
||||||
<< " as second template parameter for " << gen_name_ << ".\");\n";
|
<< " as second template parameter for " << gen_name_ << ".\");\n";
|
||||||
hdr_ << " public: \n";
|
hdr_ << " public: \n";
|
||||||
hdr_ << " using Super = P;\n";
|
hdr_ << " using Super = P;\n\n";
|
||||||
|
if (!type_->ShouldExport() && !type_->IsExtern()) {
|
||||||
|
hdr_ << " protected: // not extern or @export\n";
|
||||||
|
}
|
||||||
for (const Field& f : type_->fields()) {
|
for (const Field& f : type_->fields()) {
|
||||||
GenerateFieldAccessor(f);
|
GenerateFieldAccessor(f);
|
||||||
}
|
}
|
||||||
|
if (!type_->ShouldExport() && !type_->IsExtern()) {
|
||||||
|
hdr_ << " public:\n";
|
||||||
|
}
|
||||||
|
|
||||||
GenerateClassCasts();
|
GenerateClassCasts();
|
||||||
|
|
||||||
@ -3410,9 +3423,82 @@ void CppClassGenerator::GenerateClass() {
|
|||||||
g.Finish();
|
g.Finish();
|
||||||
hdr_ << "\n";
|
hdr_ << "\n";
|
||||||
|
|
||||||
|
auto index_fields = GetOrderedUniqueIndexFields(*type_);
|
||||||
|
|
||||||
|
if (!index_fields.has_value()) {
|
||||||
|
hdr_ << " // SizeFor implementations not generated due to complex array "
|
||||||
|
"lengths\n\n";
|
||||||
|
} else if (!type_->IsAbstract() &&
|
||||||
|
!type_->IsSubtypeOf(TypeOracle::GetJSObjectType())) {
|
||||||
|
hdr_ << " V8_INLINE static constexpr int32_t SizeFor(";
|
||||||
|
bool first = true;
|
||||||
|
for (const Field& field : *index_fields) {
|
||||||
|
if (!first) hdr_ << ", ";
|
||||||
|
hdr_ << field.name_and_type.type->HandlifiedCppTypeName() << " "
|
||||||
|
<< field.name_and_type.name;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
hdr_ << ") {\n";
|
||||||
|
if (index_fields->empty()) {
|
||||||
|
hdr_ << " DCHECK(kHeaderSize == kSize && kHeaderSize == "
|
||||||
|
<< *type_->size().SingleValue() << ");\n";
|
||||||
|
}
|
||||||
|
hdr_ << " int32_t size = kHeaderSize;\n";
|
||||||
|
for (const Field& field : type_->ComputeAllFields()) {
|
||||||
|
if (field.index) {
|
||||||
|
auto index_name_and_type =
|
||||||
|
*ExtractSimpleFieldArraySize(*type_, *field.index);
|
||||||
|
size_t field_size = 0;
|
||||||
|
std::tie(field_size, std::ignore) = field.GetFieldSizeInformation();
|
||||||
|
hdr_ << " size += ";
|
||||||
|
auto index_field = std::find_if(
|
||||||
|
index_fields->begin(), index_fields->end(),
|
||||||
|
[&](const Field& field) {
|
||||||
|
return field.name_and_type.name == index_name_and_type.name;
|
||||||
|
});
|
||||||
|
if (index_field->name_and_type.type->IsSubtypeOf(
|
||||||
|
TypeOracle::GetSmiType())) {
|
||||||
|
hdr_ << "Smi::ToInt(" << index_name_and_type.name << ")";
|
||||||
|
} else {
|
||||||
|
hdr_ << index_name_and_type.name;
|
||||||
|
}
|
||||||
|
hdr_ << " * " << field_size << ";\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hdr_ << " return size;\n";
|
||||||
|
hdr_ << " }\n\n";
|
||||||
|
hdr_ << " V8_INLINE static constexpr int32_t SizeFor(D o) {\n";
|
||||||
|
hdr_ << " return SizeFor(";
|
||||||
|
first = true;
|
||||||
|
for (auto field : *index_fields) {
|
||||||
|
if (!first) hdr_ << ", ";
|
||||||
|
// Subclasses of FixedArrayBase need to use the synchronized length
|
||||||
|
// accessor to be consistent (theoretically, FixedArrayBase classes
|
||||||
|
// can concurrently change size e.g. through left-trimming, although
|
||||||
|
// in practice this won't happen for Torque-generated classes) as well as
|
||||||
|
// explicitly convert to a Smi, since the C++-side accessors are
|
||||||
|
// int-based.
|
||||||
|
if (field.aggregate == TypeOracle::GetFixedArrayBaseType() &&
|
||||||
|
field.name_and_type.name == "length") {
|
||||||
|
hdr_ << "Smi::FromInt(o.synchronized_length())";
|
||||||
|
} else {
|
||||||
|
hdr_ << "o." << field.name_and_type.name << "()";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
hdr_ << ");\n }\n";
|
||||||
|
hdr_ << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr_ << " friend class Factory;\n\n";
|
||||||
|
|
||||||
GenerateClassConstructors();
|
GenerateClassConstructors();
|
||||||
|
|
||||||
hdr_ << "};\n\n";
|
hdr_ << "};\n\n";
|
||||||
|
|
||||||
|
if (!type_->IsExtern()) {
|
||||||
|
GenerateClassExport(type_, hdr_, inl_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppClassGenerator::GenerateClassCasts() {
|
void CppClassGenerator::GenerateClassCasts() {
|
||||||
@ -3448,7 +3534,11 @@ void CppClassGenerator::GenerateClassConstructors() {
|
|||||||
// TODO(sigurds): Keep in sync with DECL_ACCESSORS and ACCESSORS macro.
|
// TODO(sigurds): Keep in sync with DECL_ACCESSORS and ACCESSORS macro.
|
||||||
void CppClassGenerator::GenerateFieldAccessor(const Field& f) {
|
void CppClassGenerator::GenerateFieldAccessor(const Field& f) {
|
||||||
const Type* field_type = f.name_and_type.type;
|
const Type* field_type = f.name_and_type.type;
|
||||||
if (field_type == TypeOracle::GetVoidType() || f.index.has_value()) return;
|
if (field_type == TypeOracle::GetVoidType()) return;
|
||||||
|
|
||||||
|
// TODO(danno): Support generation of struct accessors
|
||||||
|
if (f.name_and_type.type->IsStructType()) return;
|
||||||
|
|
||||||
if (!f.name_and_type.type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
if (!f.name_and_type.type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
||||||
return GenerateFieldAccessorForUntagged(f);
|
return GenerateFieldAccessorForUntagged(f);
|
||||||
}
|
}
|
||||||
@ -3460,7 +3550,8 @@ void CppClassGenerator::GenerateFieldAccessor(const Field& f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error("Generation of field accessor for ", type_->name(),
|
Error("Generation of field accessor for ", type_->name(),
|
||||||
":: ", f.name_and_type.name, " : ", *field_type, " is not supported.")
|
"::", f.name_and_type.name, " failed (type ", *field_type,
|
||||||
|
" is not supported).")
|
||||||
.Position(f.pos);
|
.Position(f.pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3479,24 +3570,53 @@ void CppClassGenerator::GenerateFieldAccessorForUntagged(const Field& f) {
|
|||||||
}
|
}
|
||||||
const std::string& name = f.name_and_type.name;
|
const std::string& name = f.name_and_type.name;
|
||||||
const std::string type = constexpr_version->GetGeneratedTypeName();
|
const std::string type = constexpr_version->GetGeneratedTypeName();
|
||||||
const std::string offset = "k" + CamelifyString(name) + "Offset";
|
std::string offset = "k" + CamelifyString(name) + "Offset";
|
||||||
|
|
||||||
// Generate declarations in header.
|
// Generate declarations in header.
|
||||||
|
if (f.index) {
|
||||||
|
hdr_ << " inline " << type << " " << name << "(int i) const;\n";
|
||||||
|
hdr_ << " inline void set_" << name << "(int i, " << type
|
||||||
|
<< " value);\n\n";
|
||||||
|
} else {
|
||||||
hdr_ << " inline " << type << " " << name << "() const;\n";
|
hdr_ << " inline " << type << " " << name << "() const;\n";
|
||||||
hdr_ << " inline void set_" << name << "(" << type << " value);\n\n";
|
hdr_ << " inline void set_" << name << "(" << type << " value);\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Generate implementation in inline header.
|
// Generate implementation in inline header.
|
||||||
inl_ << "template <class D, class P>\n";
|
inl_ << "template <class D, class P>\n";
|
||||||
inl_ << type << " " << gen_name_ << "<D, P>::" << name << "() const {\n";
|
inl_ << type << " " << gen_name_ << "<D, P>::" << name << "(";
|
||||||
|
if (f.index) {
|
||||||
|
inl_ << "int i";
|
||||||
|
}
|
||||||
|
inl_ << ") const {\n";
|
||||||
|
if (f.index) {
|
||||||
|
size_t field_size;
|
||||||
|
std::string size_string;
|
||||||
|
std::tie(field_size, size_string) = f.GetFieldSizeInformation();
|
||||||
|
inl_ << " int offset = " << offset << " + i * " << field_size << ";\n";
|
||||||
|
inl_ << " return this->template ReadField<" << type << ">(offset);\n";
|
||||||
|
} else {
|
||||||
inl_ << " return this->template ReadField<" << type << ">(" << offset
|
inl_ << " return this->template ReadField<" << type << ">(" << offset
|
||||||
<< ");\n";
|
<< ");\n";
|
||||||
|
}
|
||||||
inl_ << "}\n";
|
inl_ << "}\n";
|
||||||
|
|
||||||
inl_ << "template <class D, class P>\n";
|
inl_ << "template <class D, class P>\n";
|
||||||
inl_ << "void " << gen_name_ << "<D, P>::set_" << name << "(" << type
|
inl_ << "void " << gen_name_ << "<D, P>::set_" << name << "(";
|
||||||
<< " value) {\n";
|
if (f.index) {
|
||||||
|
inl_ << "int i, ";
|
||||||
|
}
|
||||||
|
inl_ << type << " value) {\n";
|
||||||
|
if (f.index) {
|
||||||
|
size_t field_size;
|
||||||
|
std::string size_string;
|
||||||
|
std::tie(field_size, size_string) = f.GetFieldSizeInformation();
|
||||||
|
inl_ << " int offset = " << offset << " + i * " << field_size << ";\n";
|
||||||
|
inl_ << " this->template WriteField<" << type << ">(offset, value);\n";
|
||||||
|
} else {
|
||||||
inl_ << " this->template WriteField<" << type << ">(" << offset
|
inl_ << " this->template WriteField<" << type << ">(" << offset
|
||||||
<< ", value);\n";
|
<< ", value);\n";
|
||||||
|
}
|
||||||
inl_ << "}\n\n";
|
inl_ << "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3507,20 +3627,43 @@ void CppClassGenerator::GenerateFieldAccessorForSmi(const Field& f) {
|
|||||||
const std::string offset = "k" + CamelifyString(name) + "Offset";
|
const std::string offset = "k" + CamelifyString(name) + "Offset";
|
||||||
|
|
||||||
// Generate declarations in header.
|
// Generate declarations in header.
|
||||||
|
if (f.index) {
|
||||||
|
hdr_ << " inline " << type << " " << name << "(int i) const;\n";
|
||||||
|
hdr_ << " inline void set_" << name << "(int i, " << type
|
||||||
|
<< " value);\n\n";
|
||||||
|
}
|
||||||
hdr_ << " inline " << type << " " << name << "() const;\n";
|
hdr_ << " inline " << type << " " << name << "() const;\n";
|
||||||
hdr_ << " inline void set_" << name << "(" << type << " value);\n\n";
|
hdr_ << " inline void set_" << name << "(" << type << " value);\n\n";
|
||||||
|
|
||||||
// Generate implementation in inline header.
|
// Generate implementation in inline header.
|
||||||
inl_ << "template <class D, class P>\n";
|
inl_ << "template <class D, class P>\n";
|
||||||
inl_ << type << " " << gen_name_ << "<D, P>::" << name << "() const {\n";
|
inl_ << type << " " << gen_name_ << "<D, P>::" << name << "(";
|
||||||
|
if (f.index) {
|
||||||
|
inl_ << "int i";
|
||||||
|
}
|
||||||
|
inl_ << ") const {\n";
|
||||||
|
if (f.index) {
|
||||||
|
inl_ << " int offset = " << offset << " + i * kTaggedSize;\n";
|
||||||
|
inl_ << " return this->template ReadField<Smi>(offset);\n";
|
||||||
|
inl_ << "}\n";
|
||||||
|
} else {
|
||||||
inl_ << " return TaggedField<Smi, " << offset << ">::load(*this);\n";
|
inl_ << " return TaggedField<Smi, " << offset << ">::load(*this);\n";
|
||||||
inl_ << "}\n";
|
inl_ << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
inl_ << "template <class D, class P>\n";
|
inl_ << "template <class D, class P>\n";
|
||||||
inl_ << "void " << gen_name_ << "<D, P>::set_" << name << "(" << type
|
inl_ << "void " << gen_name_ << "<D, P>::set_" << name << "(";
|
||||||
<< " value) {\n";
|
if (f.index) {
|
||||||
|
inl_ << "int i, ";
|
||||||
|
}
|
||||||
|
inl_ << type << " value) {\n";
|
||||||
inl_ << " DCHECK(value.IsSmi());\n";
|
inl_ << " DCHECK(value.IsSmi());\n";
|
||||||
|
if (f.index) {
|
||||||
|
inl_ << " int offset = " << offset << " + i * kTaggedSize;\n";
|
||||||
|
inl_ << " WRITE_FIELD(*this, offset, value);\n";
|
||||||
|
} else {
|
||||||
inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n";
|
inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n";
|
||||||
|
}
|
||||||
inl_ << "}\n\n";
|
inl_ << "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3538,11 +3681,13 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) {
|
|||||||
if (!class_type && field_type != TypeOracle::GetObjectType()) {
|
if (!class_type && field_type != TypeOracle::GetObjectType()) {
|
||||||
hdr_ << " // Torque type: " << field_type->ToString() << "\n";
|
hdr_ << " // Torque type: " << field_type->ToString() << "\n";
|
||||||
}
|
}
|
||||||
hdr_ << " inline " << type << " " << name << "() const;\n";
|
|
||||||
hdr_ << " inline " << type << " " << name
|
hdr_ << " inline " << type << " " << name << "(" << (f.index ? "int i" : "")
|
||||||
<< "(const Isolate* isolate) const;\n";
|
<< ") const;\n";
|
||||||
hdr_ << " inline void set_" << name << "(" << type
|
hdr_ << " inline " << type << " " << name << "(const Isolate* isolates"
|
||||||
<< " value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);\n\n";
|
<< (f.index ? ", int i" : "") << ") const;\n";
|
||||||
|
hdr_ << " inline void set_" << name << "(" << (f.index ? "int i, " : "")
|
||||||
|
<< type << " value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);\n\n";
|
||||||
|
|
||||||
std::string type_check;
|
std::string type_check;
|
||||||
for (const RuntimeType& runtime_type : field_type->GetRuntimeTypes()) {
|
for (const RuntimeType& runtime_type : field_type->GetRuntimeTypes()) {
|
||||||
@ -3552,36 +3697,89 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) {
|
|||||||
|
|
||||||
// Generate implementation in inline header.
|
// Generate implementation in inline header.
|
||||||
inl_ << "template <class D, class P>\n";
|
inl_ << "template <class D, class P>\n";
|
||||||
inl_ << type << " " << gen_name_ << "<D, P>::" << name << "() const {\n";
|
inl_ << type << " " << gen_name_ << "<D, P>::" << name << "("
|
||||||
|
<< (f.index ? "int i" : "") << ") const {\n";
|
||||||
inl_ << " const Isolate* isolate = GetIsolateForPtrCompr(*this);\n";
|
inl_ << " const Isolate* isolate = GetIsolateForPtrCompr(*this);\n";
|
||||||
inl_ << " return " << gen_name_ << "::" << name << "(isolate);\n";
|
inl_ << " return " << gen_name_ << "::" << name << "(isolate"
|
||||||
|
<< (f.index ? ", i" : "") << ");\n";
|
||||||
inl_ << "}\n";
|
inl_ << "}\n";
|
||||||
|
|
||||||
inl_ << "template <class D, class P>\n";
|
inl_ << "template <class D, class P>\n";
|
||||||
inl_ << type << " " << gen_name_ << "<D, P>::" << name
|
inl_ << type << " " << gen_name_ << "<D, P>::" << name
|
||||||
<< "(const Isolate* isolate) const {\n";
|
<< "(const Isolate* isolate" << (f.index ? ", int i" : "")
|
||||||
|
<< ") const {\n";
|
||||||
|
|
||||||
if (class_type) {
|
if (class_type) {
|
||||||
|
if (f.index) {
|
||||||
|
inl_ << " int offset = " << offset << " + i * kTaggedSize;\n";
|
||||||
|
inl_ << " return " << type
|
||||||
|
<< "::cast(RELAXED_READ_FIELD(*this, offset));\n";
|
||||||
|
} else {
|
||||||
inl_ << " return TaggedField<" << type << ", " << offset
|
inl_ << " return TaggedField<" << type << ", " << offset
|
||||||
<< ">::load(isolate, *this);\n";
|
<< ">::load(isolate, *this);\n";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO(tebbi): load value as HeapObject when possible
|
// TODO(tebbi): load value as HeapObject when possible
|
||||||
|
if (f.index) {
|
||||||
|
inl_ << " int offset = " << offset << " + i * kTaggedSize;\n";
|
||||||
|
inl_ << " Object value = Object::cast(RELAXED_READ_FIELD(*this, "
|
||||||
|
"offset));\n";
|
||||||
|
} else {
|
||||||
inl_ << " Object value = TaggedField<Object, " << offset
|
inl_ << " Object value = TaggedField<Object, " << offset
|
||||||
<< ">::load(isolate, *this);\n";
|
<< ">::load(isolate, *this);\n";
|
||||||
|
}
|
||||||
inl_ << " DCHECK(" << type_check << ");\n";
|
inl_ << " DCHECK(" << type_check << ");\n";
|
||||||
inl_ << " return value;\n";
|
inl_ << " return value;\n";
|
||||||
}
|
}
|
||||||
inl_ << "}\n";
|
inl_ << "}\n";
|
||||||
|
|
||||||
inl_ << "template <class D, class P>\n";
|
inl_ << "template <class D, class P>\n";
|
||||||
inl_ << "void " << gen_name_ << "<D, P>::set_" << name << "(" << type
|
inl_ << "void " << gen_name_ << "<D, P>::set_" << name << "(";
|
||||||
<< " value, WriteBarrierMode mode) {\n";
|
if (f.index) {
|
||||||
|
inl_ << "int i, ";
|
||||||
|
}
|
||||||
|
inl_ << type << " value, WriteBarrierMode mode) {\n";
|
||||||
inl_ << " SLOW_DCHECK(" << type_check << ");\n";
|
inl_ << " SLOW_DCHECK(" << type_check << ");\n";
|
||||||
|
if (f.index) {
|
||||||
|
inl_ << " int offset = " << offset << " + i * kTaggedSize;\n";
|
||||||
|
inl_ << " WRITE_FIELD(*this, offset, value);\n";
|
||||||
|
} else {
|
||||||
inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n";
|
inl_ << " WRITE_FIELD(*this, " << offset << ", value);\n";
|
||||||
|
}
|
||||||
inl_ << " CONDITIONAL_WRITE_BARRIER(*this, " << offset
|
inl_ << " CONDITIONAL_WRITE_BARRIER(*this, " << offset
|
||||||
<< ", value, mode);\n";
|
<< ", value, mode);\n";
|
||||||
inl_ << "}\n\n";
|
inl_ << "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmitClassDefinitionHeadersIncludes(const std::string& basename,
|
||||||
|
std::stringstream& header,
|
||||||
|
std::stringstream& inline_header) {
|
||||||
|
header << "#include \"src/objects/fixed-array.h\"\n";
|
||||||
|
header << "#include \"src/objects/objects.h\"\n";
|
||||||
|
header << "#include \"src/objects/smi.h\"\n";
|
||||||
|
header << "#include \"torque-generated/field-offsets-tq.h\"\n";
|
||||||
|
header << "#include <type_traits>\n\n";
|
||||||
|
|
||||||
|
inline_header << "#include \"torque-generated/class-definitions-tq.h\"\n";
|
||||||
|
inline_header << "#include "
|
||||||
|
"\"torque-generated/objects-body-descriptors-tq-inl.h\"\n\n";
|
||||||
|
inline_header << "#include \"src/objects/js-promise.h\"\n";
|
||||||
|
inline_header << "#include \"src/objects/js-weak-refs.h\"\n";
|
||||||
|
inline_header << "#include \"src/objects/module.h\"\n";
|
||||||
|
inline_header << "#include \"src/objects/objects-inl.h\"\n";
|
||||||
|
inline_header << "#include \"src/objects/script.h\"\n";
|
||||||
|
inline_header << "#include \"src/objects/shared-function-info.h\"\n";
|
||||||
|
inline_header << "#include \"src/objects/tagged-field.h\"\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitClassDefinitionHeadersForwardDeclarations(std::stringstream& header) {
|
||||||
|
// Generate forward declarations for every class.
|
||||||
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
|
header << "class " << type->GetGeneratedTNodeTypeName() << ";\n";
|
||||||
|
}
|
||||||
|
header << "using BuiltinPtr = Smi;\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
void GenerateStructLayoutDescription(std::ostream& header,
|
void GenerateStructLayoutDescription(std::ostream& header,
|
||||||
const StructType* type) {
|
const StructType* type) {
|
||||||
header << "struct TorqueGenerated" << CamelifyString(type->name())
|
header << "struct TorqueGenerated" << CamelifyString(type->name())
|
||||||
@ -3599,32 +3797,70 @@ void GenerateStructLayoutDescription(std::ostream& header,
|
|||||||
|
|
||||||
void ImplementationVisitor::GenerateClassDefinitions(
|
void ImplementationVisitor::GenerateClassDefinitions(
|
||||||
const std::string& output_directory) {
|
const std::string& output_directory) {
|
||||||
std::stringstream header;
|
std::stringstream external_header;
|
||||||
std::stringstream inline_header;
|
std::stringstream inline_external_header;
|
||||||
|
std::stringstream internal_header;
|
||||||
|
std::stringstream inline_internal_header;
|
||||||
std::stringstream implementation;
|
std::stringstream implementation;
|
||||||
|
std::stringstream factory_header;
|
||||||
|
std::stringstream factory_impl;
|
||||||
std::string basename = "class-definitions-tq";
|
std::string basename = "class-definitions-tq";
|
||||||
|
std::string internal_basename = "internal-" + basename;
|
||||||
std::string file_basename = output_directory + "/" + basename;
|
std::string file_basename = output_directory + "/" + basename;
|
||||||
|
std::string internal_file_basename =
|
||||||
|
output_directory + "/" + internal_basename;
|
||||||
|
std::string factory_basename = "factory-tq";
|
||||||
|
std::string factory_file_basename = output_directory + "/" + factory_basename;
|
||||||
|
|
||||||
{
|
{
|
||||||
IncludeGuardScope header_guard(header, basename + ".h");
|
IncludeGuardScope header_guard(external_header, basename + ".h");
|
||||||
header << "#include \"src/objects/objects.h\"\n";
|
|
||||||
header << "#include \"src/objects/smi.h\"\n";
|
|
||||||
header << "#include \"torque-generated/field-offsets-tq.h\"\n";
|
|
||||||
header << "#include <type_traits>\n\n";
|
|
||||||
IncludeObjectMacrosScope header_macros(header);
|
|
||||||
NamespaceScope header_namespaces(header, {"v8", "internal"});
|
|
||||||
header << "using BuiltinPtr = Smi;\n\n";
|
|
||||||
|
|
||||||
IncludeGuardScope inline_header_guard(inline_header, basename + "-inl.h");
|
IncludeGuardScope inline_header_guard(inline_external_header,
|
||||||
inline_header << "#include \"torque-generated/class-definitions-tq.h\"\n\n";
|
basename + "-inl.h");
|
||||||
inline_header << "#include \"src/objects/js-promise.h\"\n";
|
|
||||||
inline_header << "#include \"src/objects/js-weak-refs.h\"\n";
|
IncludeGuardScope internal_header_guard(internal_header,
|
||||||
inline_header << "#include \"src/objects/module.h\"\n";
|
internal_basename + ".h");
|
||||||
inline_header << "#include \"src/objects/objects-inl.h\"\n";
|
|
||||||
inline_header << "#include \"src/objects/script.h\"\n";
|
IncludeGuardScope internal_inline_header_guard(
|
||||||
inline_header << "#include \"src/objects/shared-function-info.h\"\n\n";
|
inline_internal_header, internal_basename + "-inl.h");
|
||||||
IncludeObjectMacrosScope inline_header_macros(inline_header);
|
|
||||||
NamespaceScope inline_header_namespaces(inline_header, {"v8", "internal"});
|
external_header
|
||||||
|
<< "#include \"torque-generated/internal-class-definitions-tq.h\"\n";
|
||||||
|
|
||||||
|
EmitClassDefinitionHeadersIncludes(basename, external_header,
|
||||||
|
inline_external_header);
|
||||||
|
|
||||||
|
EmitClassDefinitionHeadersIncludes(internal_basename, internal_header,
|
||||||
|
inline_internal_header);
|
||||||
|
|
||||||
|
IncludeObjectMacrosScope header_macros(external_header);
|
||||||
|
IncludeObjectMacrosScope inline_header_macros(inline_external_header);
|
||||||
|
|
||||||
|
IncludeObjectMacrosScope internal_header_macros(internal_header);
|
||||||
|
IncludeObjectMacrosScope internal_inline_header_macros(
|
||||||
|
inline_internal_header);
|
||||||
|
|
||||||
|
NamespaceScope header_namespaces(external_header, {"v8", "internal"});
|
||||||
|
NamespaceScope inline_header_namespaces(inline_external_header,
|
||||||
|
{"v8", "internal"});
|
||||||
|
NamespaceScope internal_header_namespaces(internal_header,
|
||||||
|
{"v8", "internal"});
|
||||||
|
NamespaceScope internal_inline_header_namespaces(inline_internal_header,
|
||||||
|
{"v8", "internal"});
|
||||||
|
|
||||||
|
EmitClassDefinitionHeadersForwardDeclarations(external_header);
|
||||||
|
EmitClassDefinitionHeadersForwardDeclarations(internal_header);
|
||||||
|
|
||||||
|
factory_impl << "#include \"src/heap/factory.h\"\n";
|
||||||
|
factory_impl << "#include \"src/heap/factory-inl.h\"\n";
|
||||||
|
factory_impl << "#include \"src/heap/heap.h\"\n";
|
||||||
|
factory_impl << "#include \"src/heap/heap-inl.h\"\n";
|
||||||
|
factory_impl << "#include \"src/execution/isolate.h\"\n\n";
|
||||||
|
factory_impl
|
||||||
|
<< "#include "
|
||||||
|
"\"torque-generated/internal-class-definitions-tq-inl.h\"\n\n";
|
||||||
|
NamespaceScope factory_impl_namespaces(factory_impl, {"v8", "internal"});
|
||||||
|
factory_impl << "\n";
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
<< "#include \"torque-generated/class-definitions-tq.h\"\n\n";
|
<< "#include \"torque-generated/class-definitions-tq.h\"\n\n";
|
||||||
@ -3652,16 +3888,16 @@ void ImplementationVisitor::GenerateClassDefinitions(
|
|||||||
NamespaceScope implementation_namespaces(implementation,
|
NamespaceScope implementation_namespaces(implementation,
|
||||||
{"v8", "internal"});
|
{"v8", "internal"});
|
||||||
|
|
||||||
// Generate forward declarations for every class.
|
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
header << "class " << type->GetGeneratedTNodeTypeName() << ";\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_set<const StructType*> structs_used_in_classes;
|
std::unordered_set<const StructType*> structs_used_in_classes;
|
||||||
|
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
std::stringstream& header = (type->IsExtern() || type->ShouldExport())
|
||||||
|
? external_header
|
||||||
|
: internal_header;
|
||||||
|
std::stringstream& inline_header =
|
||||||
|
(type->IsExtern() || type->ShouldExport()) ? inline_external_header
|
||||||
|
: inline_internal_header;
|
||||||
|
|
||||||
if (type->GenerateCppClassDefinitions()) {
|
if (type->GenerateCppClassDefinitions()) {
|
||||||
CppClassGenerator g(type, header, inline_header, implementation);
|
CppClassGenerator g(type, header, inline_header, implementation);
|
||||||
g.GenerateClass();
|
g.GenerateClass();
|
||||||
@ -3673,17 +3909,92 @@ void ImplementationVisitor::GenerateClassDefinitions(
|
|||||||
structs_used_in_classes.insert(field_as_struct);
|
structs_used_in_classes.insert(field_as_struct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (type->ShouldExport()) {
|
||||||
|
factory_header << type->HandlifiedCppTypeName() << " New"
|
||||||
|
<< type->name() << "(";
|
||||||
|
factory_impl << type->HandlifiedCppTypeName() << " Factory::New"
|
||||||
|
<< type->name() << "(";
|
||||||
|
|
||||||
|
for (const Field& f : type->ComputeAllFields()) {
|
||||||
|
if (f.name_and_type.name == "map") continue;
|
||||||
|
if (!f.index) {
|
||||||
|
std::string type_string =
|
||||||
|
f.name_and_type.type->HandlifiedCppTypeName();
|
||||||
|
factory_header << type_string << " " << f.name_and_type.name
|
||||||
|
<< ", ";
|
||||||
|
factory_impl << type_string << " " << f.name_and_type.name << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
factory_header << "AllocationType allocation_type);\n";
|
||||||
|
factory_impl << "AllocationType allocation_type) {\n";
|
||||||
|
|
||||||
|
factory_impl << " int size = ";
|
||||||
|
const ClassType* super = type->GetSuperClass();
|
||||||
|
std::string gen_name = "TorqueGenerated" + type->name();
|
||||||
|
std::string gen_name_T =
|
||||||
|
gen_name + "<" + type->name() + ", " + super->name() + ">";
|
||||||
|
factory_impl << gen_name_T << "::SizeFor(";
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
auto index_fields = GetOrderedUniqueIndexFields(*type);
|
||||||
|
CHECK(index_fields.has_value());
|
||||||
|
for (auto index_field : *index_fields) {
|
||||||
|
if (!first) {
|
||||||
|
factory_impl << ", ";
|
||||||
|
}
|
||||||
|
factory_impl << index_field.name_and_type.name;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory_impl << ");\n";
|
||||||
|
factory_impl << " ReadOnlyRoots roots(isolate());\n";
|
||||||
|
factory_impl << " HeapObject result =\n";
|
||||||
|
factory_impl << " "
|
||||||
|
"isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>"
|
||||||
|
"(size, allocation_type);\n";
|
||||||
|
factory_impl << " result.set_map_after_allocation(roots."
|
||||||
|
<< SnakeifyString(type->name())
|
||||||
|
<< "_map(), SKIP_WRITE_BARRIER);\n";
|
||||||
|
factory_impl << " " << type->HandlifiedCppTypeName()
|
||||||
|
<< " result_handle(" << type->name()
|
||||||
|
<< "::cast(result), isolate());\n";
|
||||||
|
|
||||||
|
for (const Field& f : type->ComputeAllFields()) {
|
||||||
|
if (f.name_and_type.name == "map") continue;
|
||||||
|
if (!f.index) {
|
||||||
|
factory_impl << " result_handle->set_"
|
||||||
|
<< SnakeifyString(f.name_and_type.name) << "(";
|
||||||
|
if (f.name_and_type.type->IsSubtypeOf(
|
||||||
|
TypeOracle::GetTaggedType()) &&
|
||||||
|
!f.name_and_type.type->IsSubtypeOf(TypeOracle::GetSmiType())) {
|
||||||
|
factory_impl << "*" << f.name_and_type.name
|
||||||
|
<< ", SKIP_WRITE_BARRIER";
|
||||||
|
} else {
|
||||||
|
factory_impl << f.name_and_type.name;
|
||||||
|
}
|
||||||
|
factory_impl << ");\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
factory_impl << " return result_handle;\n";
|
||||||
|
factory_impl << "}\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const StructType* type : structs_used_in_classes) {
|
for (const StructType* type : structs_used_in_classes) {
|
||||||
if (type != TypeOracle::GetFloat64OrHoleType()) {
|
if (type != TypeOracle::GetFloat64OrHoleType()) {
|
||||||
GenerateStructLayoutDescription(header, type);
|
GenerateStructLayoutDescription(external_header, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WriteFile(file_basename + ".h", header.str());
|
WriteFile(file_basename + ".h", external_header.str());
|
||||||
WriteFile(file_basename + "-inl.h", inline_header.str());
|
WriteFile(file_basename + "-inl.h", inline_external_header.str());
|
||||||
WriteFile(file_basename + ".cc", implementation.str());
|
WriteFile(file_basename + ".cc", implementation.str());
|
||||||
|
WriteFile(internal_file_basename + ".h", internal_header.str());
|
||||||
|
WriteFile(internal_file_basename + "-inl.h", inline_internal_header.str());
|
||||||
|
WriteFile(factory_file_basename + ".inc", factory_header.str());
|
||||||
|
WriteFile(factory_file_basename + ".cc", factory_impl.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -3700,10 +4011,19 @@ void GeneratePrintDefinitionsForClass(std::ostream& impl, const ClassType* type,
|
|||||||
for (const AggregateType* aggregate_type : hierarchy) {
|
for (const AggregateType* aggregate_type : hierarchy) {
|
||||||
for (const Field& f : aggregate_type->fields()) {
|
for (const Field& f : aggregate_type->fields()) {
|
||||||
if (f.name_and_type.name == "map") continue;
|
if (f.name_and_type.name == "map") continue;
|
||||||
|
if (!f.index.has_value()) {
|
||||||
|
if ((aggregate_type == TypeOracle::GetFixedArrayBaseType() &&
|
||||||
|
f.name_and_type.name == "length") ||
|
||||||
|
!f.name_and_type.type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
|
||||||
|
impl << " os << \"\\n - " << f.name_and_type.name << ": \" << "
|
||||||
|
<< "this->" << f.name_and_type.name << "();\n";
|
||||||
|
} else {
|
||||||
impl << " os << \"\\n - " << f.name_and_type.name << ": \" << "
|
impl << " os << \"\\n - " << f.name_and_type.name << ": \" << "
|
||||||
<< "Brief(this->" << f.name_and_type.name << "());\n";
|
<< "Brief(this->" << f.name_and_type.name << "());\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl << " os << \"\\n\";\n";
|
impl << " os << \"\\n\";\n";
|
||||||
impl << "}\n\n";
|
impl << "}\n\n";
|
||||||
}
|
}
|
||||||
@ -3725,8 +4045,7 @@ void ImplementationVisitor::GeneratePrintDefinitions(
|
|||||||
|
|
||||||
NamespaceScope impl_namespaces(impl, {"v8", "internal"});
|
NamespaceScope impl_namespaces(impl, {"v8", "internal"});
|
||||||
|
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
if (!type->ShouldGeneratePrint()) continue;
|
if (!type->ShouldGeneratePrint()) continue;
|
||||||
|
|
||||||
if (type->GenerateCppClassDefinitions()) {
|
if (type->GenerateCppClassDefinitions()) {
|
||||||
@ -3748,6 +4067,142 @@ void ImplementationVisitor::GeneratePrintDefinitions(
|
|||||||
WriteFile(output_directory + "/" + file_name, new_contents);
|
WriteFile(output_directory + "/" + file_name, new_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImplementationVisitor::GenerateBodyDescriptors(
|
||||||
|
const std::string& output_directory) {
|
||||||
|
std::string file_name = "objects-body-descriptors-tq-inl";
|
||||||
|
std::stringstream h_contents;
|
||||||
|
{
|
||||||
|
IncludeGuardScope include_guard(h_contents, file_name + ".h");
|
||||||
|
|
||||||
|
h_contents << "\n#include \"src/objects/objects-body-descriptors.h\"\n";
|
||||||
|
h_contents << "\n#include \"torque-generated/class-definitions-tq.h\"\n";
|
||||||
|
h_contents
|
||||||
|
<< "\n#include \"torque-generated/internal-class-definitions-tq.h\"\n";
|
||||||
|
h_contents << "\n#include "
|
||||||
|
"\"torque-generated/internal-class-definitions-tq-inl.h\"\n";
|
||||||
|
|
||||||
|
NamespaceScope h_namespaces(h_contents, {"v8", "internal"});
|
||||||
|
|
||||||
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
|
std::string name = type->name();
|
||||||
|
if (!type->ShouldGenerateBodyDescriptor()) continue;
|
||||||
|
|
||||||
|
const ClassType* super_class = type->GetSuperClass();
|
||||||
|
std::string super_name = super_class->name();
|
||||||
|
h_contents << "class " << name
|
||||||
|
<< "::BodyDescriptor final : public BodyDescriptorBase {\n";
|
||||||
|
|
||||||
|
h_contents << " public:\n";
|
||||||
|
|
||||||
|
h_contents << " static bool IsValidSlot(Map map, HeapObject obj, int "
|
||||||
|
"offset) {\n";
|
||||||
|
|
||||||
|
if (super_class == TypeOracle::GetHeapObjectType() ||
|
||||||
|
super_class == TypeOracle::GetFixedArrayBaseType()) {
|
||||||
|
h_contents << " if (offset < " << super_name
|
||||||
|
<< "::kHeaderSize) return true;\n";
|
||||||
|
} else {
|
||||||
|
h_contents << " if (" << super_name
|
||||||
|
<< "::BodyDescriptor::IsValidSlot(map, obj, offset)) return "
|
||||||
|
"true;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
h_contents << " return offset >= " << name
|
||||||
|
<< "::kStartOfStrongFieldsOffset"
|
||||||
|
<< " && offset < " << name << ""
|
||||||
|
<< "::kEndOfStrongFieldsOffset;\n";
|
||||||
|
h_contents << " }\n\n";
|
||||||
|
|
||||||
|
h_contents << " template <typename ObjectVisitor>\n";
|
||||||
|
h_contents << " static inline void IterateBody(Map map, HeapObject obj, "
|
||||||
|
"int object_size, ObjectVisitor* v) {\n";
|
||||||
|
|
||||||
|
// There may be MaybeObjects embedded in the strong pointer section, which
|
||||||
|
// are not suppored.
|
||||||
|
for (auto& f : type->fields()) {
|
||||||
|
for (const Type* t : LowerType(f.name_and_type.type)) {
|
||||||
|
if (t->IsSubtypeOf(TypeOracle::GetTaggedType()) &&
|
||||||
|
!t->IsSubtypeOf(TypeOracle::GetObjectType())) {
|
||||||
|
Error("Cannot generate body descriptor for field ",
|
||||||
|
f.name_and_type.name, " of class ", name, " because ", *t,
|
||||||
|
" can contain tagged weak pointers.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (super_class != TypeOracle::GetHeapObjectType() &&
|
||||||
|
super_class != TypeOracle::GetFixedArrayBaseType()) {
|
||||||
|
h_contents
|
||||||
|
<< " " << super_name
|
||||||
|
<< "::BodyDescriptor::IterateBody(map, obj, object_size, v);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
h_contents << " if (" << name
|
||||||
|
<< "::kStartOfStrongFieldsOffset != " << name
|
||||||
|
<< "::kEndOfStrongFieldsOffset) {\n";
|
||||||
|
h_contents << " IteratePointers(obj, " << name
|
||||||
|
<< "::kStartOfStrongFieldsOffset, " << name
|
||||||
|
<< "::kEndOfStrongFieldsOffset, v);\n";
|
||||||
|
h_contents << " }\n";
|
||||||
|
|
||||||
|
h_contents << " if (" << name
|
||||||
|
<< "::kStartOfWeakFieldsOffset != " << name
|
||||||
|
<< "::kEndOfWeakFieldsOffset) {\n";
|
||||||
|
h_contents << " IterateCustomWeakPointers(obj, " << name
|
||||||
|
<< "::kStartOfWeakFieldsOffset, " << name
|
||||||
|
<< "::kEndOfWeakFieldsOffset, v);\n";
|
||||||
|
h_contents << " }\n";
|
||||||
|
|
||||||
|
// Since all of the index fields are at the end of the object and must
|
||||||
|
// only be Tagged values, emit only a single IteratePointers from the
|
||||||
|
// beginning of the first indexed field to the end of the object.
|
||||||
|
bool first_index_seen = false;
|
||||||
|
for (const Field& field : type->ComputeAllFields()) {
|
||||||
|
if (field.index && !first_index_seen) {
|
||||||
|
std::string indexed_field_name =
|
||||||
|
CamelifyString(field.name_and_type.name);
|
||||||
|
if (field.name_and_type.type->IsSubtypeOf(
|
||||||
|
TypeOracle::GetObjectType())) {
|
||||||
|
h_contents << " BodyDescriptorBase::IteratePointers(obj, "
|
||||||
|
<< name << "::k" << indexed_field_name << "Offset, "
|
||||||
|
<< name << "::SizeFor(" << name << "::cast(obj)), v);\n";
|
||||||
|
} else {
|
||||||
|
Error(
|
||||||
|
"generating body descriptors for indexed fields not subtype of "
|
||||||
|
"Object isn't (yet) supported");
|
||||||
|
}
|
||||||
|
first_index_seen = true;
|
||||||
|
}
|
||||||
|
if (first_index_seen) {
|
||||||
|
for (const Type* t : LowerType(field.name_and_type.type)) {
|
||||||
|
if (!t->IsSubtypeOf(TypeOracle::GetObjectType())) {
|
||||||
|
Error("cannot generate class body descriptor for \"",
|
||||||
|
type->name(),
|
||||||
|
"\", all fields of including and after the first indexed "
|
||||||
|
"member must no comprised only of subtypes of Object "
|
||||||
|
"(field \"",
|
||||||
|
field.name_and_type.name, "\" is not)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h_contents << " }\n\n";
|
||||||
|
|
||||||
|
h_contents
|
||||||
|
<< " static inline int SizeOf(Map map, HeapObject raw_object) {\n";
|
||||||
|
h_contents << " " << name << " object = " << name
|
||||||
|
<< "::cast(raw_object);\n";
|
||||||
|
h_contents << " return " << name << "::SizeFor(object);\n";
|
||||||
|
h_contents << " }\n\n";
|
||||||
|
|
||||||
|
h_contents << "};\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteFile(output_directory + "/" + file_name + ".h", h_contents.str());
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Generate verification code for a single piece of class data, which might be
|
// Generate verification code for a single piece of class data, which might be
|
||||||
@ -3909,8 +4364,7 @@ void ImplementationVisitor::GenerateClassVerifiers(
|
|||||||
|
|
||||||
// Generate forward declarations to avoid including any headers.
|
// Generate forward declarations to avoid including any headers.
|
||||||
h_contents << "class Isolate;\n";
|
h_contents << "class Isolate;\n";
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
if (!type->ShouldGenerateVerify()) continue;
|
if (!type->ShouldGenerateVerify()) continue;
|
||||||
h_contents << "class " << type->name() << ";\n";
|
h_contents << "class " << type->name() << ";\n";
|
||||||
}
|
}
|
||||||
@ -3920,8 +4374,7 @@ void ImplementationVisitor::GenerateClassVerifiers(
|
|||||||
h_contents << "class " << verifier_class << "{\n";
|
h_contents << "class " << verifier_class << "{\n";
|
||||||
h_contents << " public:\n";
|
h_contents << " public:\n";
|
||||||
|
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
std::string name = type->name();
|
std::string name = type->name();
|
||||||
if (!type->ShouldGenerateVerify()) continue;
|
if (!type->ShouldGenerateVerify()) continue;
|
||||||
|
|
||||||
|
@ -388,13 +388,13 @@ class ImplementationVisitor {
|
|||||||
void GenerateBitFields(const std::string& output_directory);
|
void GenerateBitFields(const std::string& output_directory);
|
||||||
void GeneratePrintDefinitions(const std::string& output_directory);
|
void GeneratePrintDefinitions(const std::string& output_directory);
|
||||||
void GenerateClassDefinitions(const std::string& output_directory);
|
void GenerateClassDefinitions(const std::string& output_directory);
|
||||||
|
void GenerateBodyDescriptors(const std::string& output_directory);
|
||||||
void GenerateInstanceTypes(const std::string& output_directory);
|
void GenerateInstanceTypes(const std::string& output_directory);
|
||||||
void GenerateClassVerifiers(const std::string& output_directory);
|
void GenerateClassVerifiers(const std::string& output_directory);
|
||||||
void GenerateEnumVerifiers(const std::string& output_directory);
|
void GenerateEnumVerifiers(const std::string& output_directory);
|
||||||
void GenerateClassDebugReaders(const std::string& output_directory);
|
void GenerateClassDebugReaders(const std::string& output_directory);
|
||||||
void GenerateExportedMacrosAssembler(const std::string& output_directory);
|
void GenerateExportedMacrosAssembler(const std::string& output_directory);
|
||||||
void GenerateCSATypes(const std::string& output_directory);
|
void GenerateCSATypes(const std::string& output_directory);
|
||||||
void GenerateCppForInternalClasses(const std::string& output_directory);
|
|
||||||
|
|
||||||
VisitResult Visit(Expression* expr);
|
VisitResult Visit(Expression* expr);
|
||||||
const Type* Visit(Statement* stmt);
|
const Type* Visit(Statement* stmt);
|
||||||
|
@ -289,6 +289,8 @@ std::unique_ptr<InstanceTypeTree> AssignInstanceTypes() {
|
|||||||
// - fully_defined_single_instance_types: This list is pairs of class name and
|
// - fully_defined_single_instance_types: This list is pairs of class name and
|
||||||
// instance type, for classes which have defined layouts and a single
|
// instance type, for classes which have defined layouts and a single
|
||||||
// corresponding instance type.
|
// corresponding instance type.
|
||||||
|
// - fully_defined_multiple_instance_types: This list is pairs of class name and
|
||||||
|
// instance type, for classes which have defined layouts and subclasses.
|
||||||
// - only_declared_single_instance_types: This list is pairs of class name and
|
// - only_declared_single_instance_types: This list is pairs of class name and
|
||||||
// instance type, for classes which have a single corresponding instance type
|
// instance type, for classes which have a single corresponding instance type
|
||||||
// and do not have layout definitions in Torque.
|
// and do not have layout definitions in Torque.
|
||||||
@ -302,6 +304,7 @@ std::unique_ptr<InstanceTypeTree> AssignInstanceTypes() {
|
|||||||
void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
|
void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
|
||||||
std::ostream& values,
|
std::ostream& values,
|
||||||
std::ostream& fully_defined_single_instance_types,
|
std::ostream& fully_defined_single_instance_types,
|
||||||
|
std::ostream& fully_defined_multiple_instance_types,
|
||||||
std::ostream& only_declared_single_instance_types,
|
std::ostream& only_declared_single_instance_types,
|
||||||
std::ostream& fully_defined_range_instance_types,
|
std::ostream& fully_defined_range_instance_types,
|
||||||
std::ostream& only_declared_range_instance_types,
|
std::ostream& only_declared_range_instance_types,
|
||||||
@ -331,6 +334,7 @@ void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
|
|||||||
for (auto& child : root->children) {
|
for (auto& child : root->children) {
|
||||||
PrintInstanceTypes(
|
PrintInstanceTypes(
|
||||||
child.get(), definitions, values, fully_defined_single_instance_types,
|
child.get(), definitions, values, fully_defined_single_instance_types,
|
||||||
|
fully_defined_multiple_instance_types,
|
||||||
only_declared_single_instance_types, fully_defined_range_instance_types,
|
only_declared_single_instance_types, fully_defined_range_instance_types,
|
||||||
only_declared_range_instance_types, inner_indent);
|
only_declared_range_instance_types, inner_indent);
|
||||||
}
|
}
|
||||||
@ -351,6 +355,11 @@ void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
|
|||||||
: fully_defined_range_instance_types;
|
: fully_defined_range_instance_types;
|
||||||
range_instance_types << " V(" << root->type->name() << ", FIRST_"
|
range_instance_types << " V(" << root->type->name() << ", FIRST_"
|
||||||
<< type_name << ", LAST_" << type_name << ") \\\n";
|
<< type_name << ", LAST_" << type_name << ") \\\n";
|
||||||
|
if (!root->type->IsExtern() && !root->type->IsAbstract() &&
|
||||||
|
!root->type->HasUndefinedLayout()) {
|
||||||
|
fully_defined_multiple_instance_types << " V(" << root->type->name()
|
||||||
|
<< ", " << type_name << ") \\\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,12 +379,14 @@ void ImplementationVisitor::GenerateInstanceTypes(
|
|||||||
std::unique_ptr<InstanceTypeTree> instance_types = AssignInstanceTypes();
|
std::unique_ptr<InstanceTypeTree> instance_types = AssignInstanceTypes();
|
||||||
std::stringstream values_list;
|
std::stringstream values_list;
|
||||||
std::stringstream fully_defined_single_instance_types;
|
std::stringstream fully_defined_single_instance_types;
|
||||||
|
std::stringstream fully_defined_multiple_instance_types;
|
||||||
std::stringstream only_declared_single_instance_types;
|
std::stringstream only_declared_single_instance_types;
|
||||||
std::stringstream fully_defined_range_instance_types;
|
std::stringstream fully_defined_range_instance_types;
|
||||||
std::stringstream only_declared_range_instance_types;
|
std::stringstream only_declared_range_instance_types;
|
||||||
if (instance_types != nullptr) {
|
if (instance_types != nullptr) {
|
||||||
PrintInstanceTypes(instance_types.get(), header, values_list,
|
PrintInstanceTypes(instance_types.get(), header, values_list,
|
||||||
fully_defined_single_instance_types,
|
fully_defined_single_instance_types,
|
||||||
|
fully_defined_multiple_instance_types,
|
||||||
only_declared_single_instance_types,
|
only_declared_single_instance_types,
|
||||||
fully_defined_range_instance_types,
|
fully_defined_range_instance_types,
|
||||||
only_declared_range_instance_types, " ");
|
only_declared_range_instance_types, " ");
|
||||||
@ -394,6 +405,12 @@ void ImplementationVisitor::GenerateInstanceTypes(
|
|||||||
header << fully_defined_single_instance_types.str();
|
header << fully_defined_single_instance_types.str();
|
||||||
header << "\n";
|
header << "\n";
|
||||||
|
|
||||||
|
header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have\n";
|
||||||
|
header << "// full Torque definitions and subclasses.\n";
|
||||||
|
header << "#define TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(V) \\\n";
|
||||||
|
header << fully_defined_multiple_instance_types.str();
|
||||||
|
header << "\n";
|
||||||
|
|
||||||
header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that are\n";
|
header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that are\n";
|
||||||
header << "// declared but not defined in Torque. These classes may\n";
|
header << "// declared but not defined in Torque. These classes may\n";
|
||||||
header << "// correspond with actual C++ classes, but they are not\n";
|
header << "// correspond with actual C++ classes, but they are not\n";
|
||||||
@ -416,10 +433,9 @@ void ImplementationVisitor::GenerateInstanceTypes(
|
|||||||
header << only_declared_range_instance_types.str();
|
header << only_declared_range_instance_types.str();
|
||||||
header << "\n";
|
header << "\n";
|
||||||
|
|
||||||
header << "// Instance types for Torque-internal classes.\n";
|
header << "// Instance types for non-extern Torque classes.\n";
|
||||||
header << "#define TORQUE_INTERNAL_INSTANCE_TYPES(V) \\\n";
|
header << "#define TORQUE_INSTANCE_TYPES(V) \\\n";
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
if (type->IsExtern()) continue;
|
if (type->IsExtern()) continue;
|
||||||
std::string type_name =
|
std::string type_name =
|
||||||
CapifyStringWithUnderscores(type->name()) + "_TYPE";
|
CapifyStringWithUnderscores(type->name()) + "_TYPE";
|
||||||
@ -427,11 +443,11 @@ void ImplementationVisitor::GenerateInstanceTypes(
|
|||||||
}
|
}
|
||||||
header << "\n";
|
header << "\n";
|
||||||
|
|
||||||
header << "// Struct list entries for Torque-internal classes.\n";
|
header << "// Map list macros for non-extern Torque classes.\n";
|
||||||
header << "#define TORQUE_STRUCT_LIST_GENERATOR(V, _) \\\n";
|
header << "#define TORQUE_INTERNAL_VARSIZE_CLASS_LIST_GENERATOR(V, _) \\\n";
|
||||||
for (const TypeAlias* alias : GlobalContext::GetClasses()) {
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
const ClassType* type = ClassType::DynamicCast(alias->type());
|
|
||||||
if (type->IsExtern()) continue;
|
if (type->IsExtern()) continue;
|
||||||
|
if (!type->HasIndexedField()) continue;
|
||||||
std::string type_name =
|
std::string type_name =
|
||||||
CapifyStringWithUnderscores(type->name()) + "_TYPE";
|
CapifyStringWithUnderscores(type->name()) + "_TYPE";
|
||||||
std::string variable_name = SnakeifyString(type->name());
|
std::string variable_name = SnakeifyString(type->name());
|
||||||
@ -439,6 +455,21 @@ void ImplementationVisitor::GenerateInstanceTypes(
|
|||||||
<< variable_name << ") \\\n";
|
<< variable_name << ") \\\n";
|
||||||
}
|
}
|
||||||
header << "\n";
|
header << "\n";
|
||||||
|
header << "#define TORQUE_INTERNAL_FIXED_CLASS_LIST_GENERATOR(V, _) \\\n";
|
||||||
|
for (const ClassType* type : TypeOracle::GetClasses()) {
|
||||||
|
if (type->IsExtern()) continue;
|
||||||
|
if (type->HasIndexedField()) continue;
|
||||||
|
std::string type_name =
|
||||||
|
CapifyStringWithUnderscores(type->name()) + "_TYPE";
|
||||||
|
std::string variable_name = SnakeifyString(type->name());
|
||||||
|
header << " V(_, " << type_name << ", " << type->name() << ", "
|
||||||
|
<< variable_name << ") \\\n";
|
||||||
|
}
|
||||||
|
header << "\n";
|
||||||
|
header << "#define TORQUE_INTERNAL_CLASS_LIST_GENERATOR(V, _) \\\n";
|
||||||
|
header << " TORQUE_INTERNAL_VARSIZE_CLASS_LIST_GENERATOR(V, _) \\\n";
|
||||||
|
header << " TORQUE_INTERNAL_FIXED_CLASS_LIST_GENERATOR(V, _)\n";
|
||||||
|
header << "\n";
|
||||||
}
|
}
|
||||||
std::string output_header_path = output_directory + "/" + file_name;
|
std::string output_header_path = output_directory + "/" + file_name;
|
||||||
WriteFile(output_header_path, header.str());
|
WriteFile(output_header_path, header.str());
|
||||||
|
@ -88,10 +88,10 @@ void CompileCurrentAst(TorqueCompilerOptions options) {
|
|||||||
implementation_visitor.GenerateClassVerifiers(output_directory);
|
implementation_visitor.GenerateClassVerifiers(output_directory);
|
||||||
implementation_visitor.GenerateClassDebugReaders(output_directory);
|
implementation_visitor.GenerateClassDebugReaders(output_directory);
|
||||||
implementation_visitor.GenerateEnumVerifiers(output_directory);
|
implementation_visitor.GenerateEnumVerifiers(output_directory);
|
||||||
|
implementation_visitor.GenerateBodyDescriptors(output_directory);
|
||||||
implementation_visitor.GenerateExportedMacrosAssembler(output_directory);
|
implementation_visitor.GenerateExportedMacrosAssembler(output_directory);
|
||||||
implementation_visitor.GenerateCSATypes(output_directory);
|
implementation_visitor.GenerateCSATypes(output_directory);
|
||||||
implementation_visitor.GenerateInstanceTypes(output_directory);
|
implementation_visitor.GenerateInstanceTypes(output_directory);
|
||||||
implementation_visitor.GenerateCppForInternalClasses(output_directory);
|
|
||||||
|
|
||||||
implementation_visitor.EndCSAFiles();
|
implementation_visitor.EndCSAFiles();
|
||||||
implementation_visitor.GenerateImplementation(output_directory);
|
implementation_visitor.GenerateImplementation(output_directory);
|
||||||
|
@ -549,9 +549,24 @@ base::Optional<ParseResult> MakeIntrinsicDeclaration(
|
|||||||
return ParseResult{result};
|
return ParseResult{result};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
bool HasExportAnnotation(ParseResultIterator* child_results,
|
||||||
|
const char* declaration) {
|
||||||
|
auto annotations = child_results->NextAs<std::vector<Annotation>>();
|
||||||
|
if (annotations.size()) {
|
||||||
|
if (annotations.size() > 1 || annotations[0].name->value != "@export") {
|
||||||
|
Error(declaration,
|
||||||
|
" declarations only support a single @export annotation");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
base::Optional<ParseResult> MakeTorqueMacroDeclaration(
|
base::Optional<ParseResult> MakeTorqueMacroDeclaration(
|
||||||
ParseResultIterator* child_results) {
|
ParseResultIterator* child_results) {
|
||||||
auto export_to_csa = child_results->NextAs<bool>();
|
bool export_to_csa = HasExportAnnotation(child_results, "macro");
|
||||||
auto transitioning = child_results->NextAs<bool>();
|
auto transitioning = child_results->NextAs<bool>();
|
||||||
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
|
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
|
||||||
auto name = child_results->NextAs<Identifier*>();
|
auto name = child_results->NextAs<Identifier*>();
|
||||||
@ -835,7 +850,8 @@ base::Optional<ParseResult> MakeClassDeclaration(
|
|||||||
child_results,
|
child_results,
|
||||||
{ANNOTATION_GENERATE_PRINT, ANNOTATION_NO_VERIFIER, ANNOTATION_ABSTRACT,
|
{ANNOTATION_GENERATE_PRINT, ANNOTATION_NO_VERIFIER, ANNOTATION_ABSTRACT,
|
||||||
ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT,
|
ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT,
|
||||||
ANNOTATION_GENERATE_CPP_CLASS,
|
ANNOTATION_GENERATE_CPP_CLASS, ANNOTATION_GENERATE_BODY_DESCRIPTOR,
|
||||||
|
ANNOTATION_EXPORT_CPP_CLASS,
|
||||||
ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT,
|
ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT,
|
||||||
ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT},
|
ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT},
|
||||||
{ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE,
|
{ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE,
|
||||||
@ -854,6 +870,12 @@ base::Optional<ParseResult> MakeClassDeclaration(
|
|||||||
if (annotations.Contains(ANNOTATION_GENERATE_CPP_CLASS)) {
|
if (annotations.Contains(ANNOTATION_GENERATE_CPP_CLASS)) {
|
||||||
flags |= ClassFlag::kGenerateCppClassDefinitions;
|
flags |= ClassFlag::kGenerateCppClassDefinitions;
|
||||||
}
|
}
|
||||||
|
if (annotations.Contains(ANNOTATION_GENERATE_BODY_DESCRIPTOR)) {
|
||||||
|
flags |= ClassFlag::kGenerateBodyDescriptor;
|
||||||
|
}
|
||||||
|
if (annotations.Contains(ANNOTATION_EXPORT_CPP_CLASS)) {
|
||||||
|
flags |= ClassFlag::kExport;
|
||||||
|
}
|
||||||
if (annotations.Contains(ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT)) {
|
if (annotations.Contains(ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT)) {
|
||||||
flags |= ClassFlag::kHighestInstanceTypeWithinParent;
|
flags |= ClassFlag::kHighestInstanceTypeWithinParent;
|
||||||
}
|
}
|
||||||
@ -945,7 +967,8 @@ base::Optional<ParseResult> MakeSpecializationDeclaration(
|
|||||||
|
|
||||||
base::Optional<ParseResult> MakeStructDeclaration(
|
base::Optional<ParseResult> MakeStructDeclaration(
|
||||||
ParseResultIterator* child_results) {
|
ParseResultIterator* child_results) {
|
||||||
bool is_export = child_results->NextAs<bool>();
|
bool is_export = HasExportAnnotation(child_results, "Struct");
|
||||||
|
|
||||||
StructFlags flags = StructFlag::kNone;
|
StructFlags flags = StructFlag::kNone;
|
||||||
if (is_export) flags |= StructFlag::kExport;
|
if (is_export) flags |= StructFlag::kExport;
|
||||||
|
|
||||||
@ -2322,7 +2345,7 @@ struct TorqueGrammar : Grammar {
|
|||||||
Sequence({Token("generates"), &externalString})),
|
Sequence({Token("generates"), &externalString})),
|
||||||
&optionalClassBody},
|
&optionalClassBody},
|
||||||
AsSingletonVector<Declaration*, MakeClassDeclaration>()),
|
AsSingletonVector<Declaration*, MakeClassDeclaration>()),
|
||||||
Rule({CheckIf(Token("@export")), Token("struct"), &name,
|
Rule({annotations, Token("struct"), &name,
|
||||||
TryOrDefault<GenericParameters>(&genericParameters), Token("{"),
|
TryOrDefault<GenericParameters>(&genericParameters), Token("{"),
|
||||||
List<Declaration*>(&method),
|
List<Declaration*>(&method),
|
||||||
List<StructFieldExpression>(&structField), Token("}")},
|
List<StructFieldExpression>(&structField), Token("}")},
|
||||||
@ -2363,7 +2386,7 @@ struct TorqueGrammar : Grammar {
|
|||||||
Rule({Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
|
Rule({Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
|
||||||
&name, &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
|
&name, &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
|
||||||
AsSingletonVector<Declaration*, MakeExternalRuntime>()),
|
AsSingletonVector<Declaration*, MakeExternalRuntime>()),
|
||||||
Rule({CheckIf(Token("@export")), CheckIf(Token("transitioning")),
|
Rule({annotations, CheckIf(Token("transitioning")),
|
||||||
Optional<std::string>(
|
Optional<std::string>(
|
||||||
Sequence({Token("operator"), &externalString})),
|
Sequence({Token("operator"), &externalString})),
|
||||||
Token("macro"), &name,
|
Token("macro"), &name,
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "src/torque/type-oracle.h"
|
#include "src/torque/type-oracle.h"
|
||||||
#include "src/torque/type-visitor.h"
|
#include "src/torque/type-visitor.h"
|
||||||
|
#include "src/torque/types.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -68,6 +69,17 @@ Namespace* TypeOracle::CreateGenericTypeInstantiationNamespace() {
|
|||||||
return Get().generic_type_instantiation_namespaces_.back().get();
|
return Get().generic_type_instantiation_namespaces_.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::vector<const ClassType*> TypeOracle::GetClasses() {
|
||||||
|
std::vector<const ClassType*> result;
|
||||||
|
for (const std::unique_ptr<AggregateType>& t : Get().aggregate_types_) {
|
||||||
|
if (auto* class_type = ClassType::DynamicCast(t.get())) {
|
||||||
|
result.push_back(class_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace torque
|
} // namespace torque
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -293,6 +293,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
|
|||||||
return Get().GetBuiltinType(UNINITIALIZED_ITERATOR_TYPE_STRING);
|
return Get().GetBuiltinType(UNINITIALIZED_ITERATOR_TYPE_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const Type* GetFixedArrayBaseType() {
|
||||||
|
return Get().GetBuiltinType(FIXED_ARRAY_BASE_TYPE_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
static base::Optional<const Type*> ImplicitlyConvertableFrom(
|
static base::Optional<const Type*> ImplicitlyConvertableFrom(
|
||||||
const Type* to, const Type* from) {
|
const Type* to, const Type* from) {
|
||||||
while (from != nullptr) {
|
while (from != nullptr) {
|
||||||
@ -315,6 +319,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
|
|||||||
static const std::vector<std::unique_ptr<BitFieldStructType>>&
|
static const std::vector<std::unique_ptr<BitFieldStructType>>&
|
||||||
GetBitFieldStructTypes();
|
GetBitFieldStructTypes();
|
||||||
|
|
||||||
|
// By construction, this list of all classes is topologically sorted w.r.t.
|
||||||
|
// inheritance.
|
||||||
|
static std::vector<const ClassType*> GetClasses();
|
||||||
|
|
||||||
static void FinalizeAggregateTypes();
|
static void FinalizeAggregateTypes();
|
||||||
|
|
||||||
static size_t FreshTypeId() { return Get().next_type_id_++; }
|
static size_t FreshTypeId() { return Get().next_type_id_++; }
|
||||||
|
@ -244,41 +244,21 @@ const StructType* TypeVisitor::ComputeType(
|
|||||||
|
|
||||||
const ClassType* TypeVisitor::ComputeType(
|
const ClassType* TypeVisitor::ComputeType(
|
||||||
ClassDeclaration* decl, MaybeSpecializationKey specialized_from) {
|
ClassDeclaration* decl, MaybeSpecializationKey specialized_from) {
|
||||||
ClassType* new_class;
|
|
||||||
// TODO(sigurds): Remove this hack by introducing a declarable for classes.
|
// TODO(sigurds): Remove this hack by introducing a declarable for classes.
|
||||||
const TypeAlias* alias =
|
const TypeAlias* alias =
|
||||||
Declarations::LookupTypeAlias(QualifiedName(decl->name->value));
|
Declarations::LookupTypeAlias(QualifiedName(decl->name->value));
|
||||||
GlobalContext::RegisterClass(alias);
|
|
||||||
DCHECK_EQ(*alias->delayed_, decl);
|
DCHECK_EQ(*alias->delayed_, decl);
|
||||||
bool is_shape = decl->flags & ClassFlag::kIsShape;
|
ClassFlags flags = decl->flags;
|
||||||
if (is_shape && !(decl->flags & ClassFlag::kExtern)) {
|
bool is_shape = flags & ClassFlag::kIsShape;
|
||||||
|
std::string generates = decl->name->value;
|
||||||
|
const Type* super_type = TypeVisitor::ComputeType(*decl->super);
|
||||||
|
if (is_shape) {
|
||||||
|
if (!(flags & ClassFlag::kExtern)) {
|
||||||
ReportError("Shapes must be extern, add \"extern\" to the declaration.");
|
ReportError("Shapes must be extern, add \"extern\" to the declaration.");
|
||||||
}
|
}
|
||||||
if (is_shape && decl->flags & ClassFlag::kUndefinedLayout) {
|
if (flags & ClassFlag::kUndefinedLayout) {
|
||||||
ReportError("Shapes need to define their layout.");
|
ReportError("Shapes need to define their layout.");
|
||||||
}
|
}
|
||||||
if (decl->flags & ClassFlag::kExtern) {
|
|
||||||
if (!decl->super) {
|
|
||||||
ReportError("Extern class must extend another type.");
|
|
||||||
}
|
|
||||||
const Type* super_type = TypeVisitor::ComputeType(*decl->super);
|
|
||||||
if (super_type != TypeOracle::GetStrongTaggedType()) {
|
|
||||||
const ClassType* super_class = ClassType::DynamicCast(super_type);
|
|
||||||
if (!super_class) {
|
|
||||||
ReportError(
|
|
||||||
"class \"", decl->name->value,
|
|
||||||
"\" must extend either StrongTagged or an already declared class");
|
|
||||||
}
|
|
||||||
if (super_class->HasUndefinedLayout() &&
|
|
||||||
!(decl->flags & ClassFlag::kUndefinedLayout)) {
|
|
||||||
Error("Class \"", decl->name->value,
|
|
||||||
"\" defines its layout but extends a class which does not")
|
|
||||||
.Position(decl->pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string generates = decl->name->value;
|
|
||||||
if (is_shape) {
|
|
||||||
const ClassType* super_class = ClassType::DynamicCast(super_type);
|
const ClassType* super_class = ClassType::DynamicCast(super_type);
|
||||||
if (!super_class ||
|
if (!super_class ||
|
||||||
!super_class->IsSubtypeOf(TypeOracle::GetJSObjectType())) {
|
!super_class->IsSubtypeOf(TypeOracle::GetJSObjectType())) {
|
||||||
@ -290,35 +270,57 @@ const ClassType* TypeVisitor::ComputeType(
|
|||||||
// support for type-checks on the C++ side.
|
// support for type-checks on the C++ side.
|
||||||
generates = super_class->name();
|
generates = super_class->name();
|
||||||
}
|
}
|
||||||
|
if (!decl->super) {
|
||||||
|
ReportError("Extern class must extend another type.");
|
||||||
|
}
|
||||||
|
if (super_type != TypeOracle::GetStrongTaggedType()) {
|
||||||
|
const ClassType* super_class = ClassType::DynamicCast(super_type);
|
||||||
|
if (!super_class) {
|
||||||
|
ReportError(
|
||||||
|
"class \"", decl->name->value,
|
||||||
|
"\" must extend either StrongTagged or an already declared class");
|
||||||
|
}
|
||||||
|
if (super_class->HasUndefinedLayout() &&
|
||||||
|
!(flags & ClassFlag::kUndefinedLayout)) {
|
||||||
|
Error("Class \"", decl->name->value,
|
||||||
|
"\" defines its layout but extends a class which does not")
|
||||||
|
.Position(decl->pos);
|
||||||
|
}
|
||||||
|
if ((flags & ClassFlag::kExport) &&
|
||||||
|
!(super_class->ShouldExport() || super_class->IsExtern())) {
|
||||||
|
Error("cannot export class ", decl->name,
|
||||||
|
" because superclass is neither @export or extern");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((flags & ClassFlag::kGenerateBodyDescriptor ||
|
||||||
|
flags & ClassFlag::kExport) &&
|
||||||
|
flags & ClassFlag::kUndefinedLayout) {
|
||||||
|
Error("Class \"", decl->name->value,
|
||||||
|
"\" requires a layout but doesn't have one");
|
||||||
|
}
|
||||||
|
if (flags & ClassFlag::kExtern) {
|
||||||
if (decl->generates) {
|
if (decl->generates) {
|
||||||
bool enforce_tnode_type = true;
|
bool enforce_tnode_type = true;
|
||||||
generates = ComputeGeneratesType(decl->generates, enforce_tnode_type);
|
generates = ComputeGeneratesType(decl->generates, enforce_tnode_type);
|
||||||
}
|
}
|
||||||
|
if (flags & ClassFlag::kExport) {
|
||||||
new_class = TypeOracle::GetClassType(super_type, decl->name->value,
|
Error("cannot export a class that is marked extern");
|
||||||
decl->flags, generates, decl, alias);
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!decl->super) {
|
|
||||||
ReportError("Intern class ", decl->name->value,
|
|
||||||
" must extend class Struct.");
|
|
||||||
}
|
|
||||||
const Type* super_type = TypeVisitor::ComputeType(*decl->super);
|
|
||||||
const ClassType* super_class = ClassType::DynamicCast(super_type);
|
|
||||||
const Type* struct_type =
|
|
||||||
Declarations::LookupGlobalType(QualifiedName("Struct"));
|
|
||||||
if (!super_class || super_class != struct_type) {
|
|
||||||
ReportError("Intern class ", decl->name->value,
|
|
||||||
" must extend class Struct.");
|
|
||||||
}
|
|
||||||
if (decl->generates) {
|
if (decl->generates) {
|
||||||
ReportError("Only extern classes can specify a generated type.");
|
ReportError("Only extern classes can specify a generated type.");
|
||||||
}
|
}
|
||||||
new_class = TypeOracle::GetClassType(
|
if (super_type != TypeOracle::GetStrongTaggedType()) {
|
||||||
super_type, decl->name->value,
|
if (flags & ClassFlag::kUndefinedLayout) {
|
||||||
decl->flags | ClassFlag::kGeneratePrint | ClassFlag::kGenerateVerify,
|
Error("non-external classes must have defined layouts");
|
||||||
decl->name->value, decl, alias);
|
|
||||||
}
|
}
|
||||||
return new_class;
|
}
|
||||||
|
flags = flags | ClassFlag::kGeneratePrint | ClassFlag::kGenerateVerify |
|
||||||
|
ClassFlag::kGenerateBodyDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypeOracle::GetClassType(super_type, decl->name->value, flags,
|
||||||
|
generates, decl, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
|
const Type* TypeVisitor::ComputeType(TypeExpression* type_expression) {
|
||||||
@ -406,17 +408,6 @@ void TypeVisitor::VisitClassFieldsAndMethods(
|
|||||||
ReportError("in-object properties cannot be weak");
|
ReportError("in-object properties cannot be weak");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(class_declaration->flags & ClassFlag::kExtern)) {
|
|
||||||
if (!field_type->IsSubtypeOf(TypeOracle::GetObjectType())) {
|
|
||||||
ReportError(
|
|
||||||
"non-extern classes only support subtypes of type Object, but "
|
|
||||||
"found type ",
|
|
||||||
*field_type);
|
|
||||||
}
|
|
||||||
if (field_expression.weak) {
|
|
||||||
ReportError("non-extern classes do not support weak fields");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
base::Optional<Expression*> array_length = field_expression.index;
|
base::Optional<Expression*> array_length = field_expression.index;
|
||||||
const Field& field = class_type->RegisterField(
|
const Field& field = class_type->RegisterField(
|
||||||
{field_expression.name_and_type.name->pos,
|
{field_expression.name_and_type.name->pos,
|
||||||
|
@ -67,6 +67,20 @@ std::string Type::SimpleName() const {
|
|||||||
return *aliases_.begin();
|
return *aliases_.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(danno): HandlifiedCppTypeName should be used universally in Torque
|
||||||
|
// where the C++ type of a Torque object is required.
|
||||||
|
std::string Type::HandlifiedCppTypeName() const {
|
||||||
|
if (IsSubtypeOf(TypeOracle::GetTaggedType()) &&
|
||||||
|
!IsSubtypeOf(TypeOracle::GetSmiType())) {
|
||||||
|
base::Optional<const ClassType*> class_type = ClassSupertype();
|
||||||
|
std::string type =
|
||||||
|
class_type ? (*class_type)->GetGeneratedTNodeTypeName() : "Object";
|
||||||
|
return "Handle<" + type + ">";
|
||||||
|
} else {
|
||||||
|
return ConstexprVersion()->GetGeneratedTypeName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Type::IsSubtypeOf(const Type* supertype) const {
|
bool Type::IsSubtypeOf(const Type* supertype) const {
|
||||||
if (supertype->IsTopType()) return true;
|
if (supertype->IsTopType()) return true;
|
||||||
if (IsNever()) return true;
|
if (IsNever()) return true;
|
||||||
@ -517,24 +531,43 @@ void ClassType::GenerateAccessors() {
|
|||||||
// For each field, construct AST snippets that implement a CSA accessor
|
// For each field, construct AST snippets that implement a CSA accessor
|
||||||
// function. The implementation iterator will turn the snippets into code.
|
// function. The implementation iterator will turn the snippets into code.
|
||||||
for (auto& field : fields_) {
|
for (auto& field : fields_) {
|
||||||
if (field.index || field.name_and_type.type == TypeOracle::GetVoidType()) {
|
if (field.name_and_type.type == TypeOracle::GetVoidType()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CurrentSourcePosition::Scope position_activator(field.pos);
|
CurrentSourcePosition::Scope position_activator(field.pos);
|
||||||
|
|
||||||
IdentifierExpression* parameter =
|
IdentifierExpression* parameter =
|
||||||
MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"}));
|
MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"o"}));
|
||||||
|
IdentifierExpression* index =
|
||||||
|
MakeNode<IdentifierExpression>(MakeNode<Identifier>(std::string{"i"}));
|
||||||
|
|
||||||
// Load accessor
|
// Load accessor
|
||||||
std::string camel_field_name = CamelifyString(field.name_and_type.name);
|
std::string camel_field_name = CamelifyString(field.name_and_type.name);
|
||||||
std::string load_macro_name = "Load" + this->name() + camel_field_name;
|
std::string load_macro_name = "Load" + this->name() + camel_field_name;
|
||||||
|
|
||||||
|
// For now, only generate indexed accessors for simple types
|
||||||
|
if (field.index.has_value() && field.name_and_type.type->IsStructType()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Signature load_signature;
|
Signature load_signature;
|
||||||
load_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
|
load_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
|
||||||
load_signature.parameter_types.types.push_back(this);
|
load_signature.parameter_types.types.push_back(this);
|
||||||
|
if (field.index) {
|
||||||
|
load_signature.parameter_names.push_back(MakeNode<Identifier>("i"));
|
||||||
|
load_signature.parameter_types.types.push_back(
|
||||||
|
TypeOracle::GetIntPtrType());
|
||||||
|
}
|
||||||
load_signature.parameter_types.var_args = false;
|
load_signature.parameter_types.var_args = false;
|
||||||
load_signature.return_type = field.name_and_type.type;
|
load_signature.return_type = field.name_and_type.type;
|
||||||
Statement* load_body =
|
|
||||||
MakeNode<ReturnStatement>(MakeNode<FieldAccessExpression>(
|
Expression* load_expression = MakeNode<FieldAccessExpression>(
|
||||||
parameter, MakeNode<Identifier>(field.name_and_type.name)));
|
parameter, MakeNode<Identifier>(field.name_and_type.name));
|
||||||
|
if (field.index) {
|
||||||
|
load_expression =
|
||||||
|
MakeNode<ElementAccessExpression>(load_expression, index);
|
||||||
|
}
|
||||||
|
Statement* load_body = MakeNode<ReturnStatement>(load_expression);
|
||||||
Declarations::DeclareMacro(load_macro_name, true, base::nullopt,
|
Declarations::DeclareMacro(load_macro_name, true, base::nullopt,
|
||||||
load_signature, load_body, base::nullopt);
|
load_signature, load_body, base::nullopt);
|
||||||
|
|
||||||
@ -544,17 +577,25 @@ void ClassType::GenerateAccessors() {
|
|||||||
std::string store_macro_name = "Store" + this->name() + camel_field_name;
|
std::string store_macro_name = "Store" + this->name() + camel_field_name;
|
||||||
Signature store_signature;
|
Signature store_signature;
|
||||||
store_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
|
store_signature.parameter_names.push_back(MakeNode<Identifier>("o"));
|
||||||
store_signature.parameter_names.push_back(MakeNode<Identifier>("v"));
|
|
||||||
store_signature.parameter_types.types.push_back(this);
|
store_signature.parameter_types.types.push_back(this);
|
||||||
|
if (field.index) {
|
||||||
|
store_signature.parameter_names.push_back(MakeNode<Identifier>("i"));
|
||||||
|
store_signature.parameter_types.types.push_back(
|
||||||
|
TypeOracle::GetIntPtrType());
|
||||||
|
}
|
||||||
|
store_signature.parameter_names.push_back(MakeNode<Identifier>("v"));
|
||||||
store_signature.parameter_types.types.push_back(field.name_and_type.type);
|
store_signature.parameter_types.types.push_back(field.name_and_type.type);
|
||||||
store_signature.parameter_types.var_args = false;
|
store_signature.parameter_types.var_args = false;
|
||||||
// TODO(danno): Store macros probably should return their value argument
|
// TODO(danno): Store macros probably should return their value argument
|
||||||
store_signature.return_type = TypeOracle::GetVoidType();
|
store_signature.return_type = TypeOracle::GetVoidType();
|
||||||
Statement* store_body =
|
Expression* store_expression = MakeNode<FieldAccessExpression>(
|
||||||
MakeNode<ExpressionStatement>(MakeNode<AssignmentExpression>(
|
parameter, MakeNode<Identifier>(field.name_and_type.name));
|
||||||
MakeNode<FieldAccessExpression>(
|
if (field.index) {
|
||||||
parameter, MakeNode<Identifier>(field.name_and_type.name)),
|
store_expression =
|
||||||
value));
|
MakeNode<ElementAccessExpression>(store_expression, index);
|
||||||
|
}
|
||||||
|
Statement* store_body = MakeNode<ExpressionStatement>(
|
||||||
|
MakeNode<AssignmentExpression>(store_expression, value));
|
||||||
Declarations::DeclareMacro(store_macro_name, true, base::nullopt,
|
Declarations::DeclareMacro(store_macro_name, true, base::nullopt,
|
||||||
store_signature, store_body, base::nullopt,
|
store_signature, store_body, base::nullopt,
|
||||||
false);
|
false);
|
||||||
|
@ -113,6 +113,8 @@ class V8_EXPORT_PRIVATE Type : public TypeBase {
|
|||||||
// Used for naming generated code.
|
// Used for naming generated code.
|
||||||
virtual std::string SimpleName() const;
|
virtual std::string SimpleName() const;
|
||||||
|
|
||||||
|
std::string HandlifiedCppTypeName() const;
|
||||||
|
|
||||||
const Type* parent() const { return parent_; }
|
const Type* parent() const { return parent_; }
|
||||||
bool IsVoid() const { return IsAbstractName(VOID_TYPE_STRING); }
|
bool IsVoid() const { return IsAbstractName(VOID_TYPE_STRING); }
|
||||||
bool IsNever() const { return IsAbstractName(NEVER_TYPE_STRING); }
|
bool IsNever() const { return IsAbstractName(NEVER_TYPE_STRING); }
|
||||||
@ -611,12 +613,15 @@ class ClassType final : public AggregateType {
|
|||||||
std::string GetGeneratedTNodeTypeNameImpl() const override;
|
std::string GetGeneratedTNodeTypeNameImpl() const override;
|
||||||
bool IsExtern() const { return flags_ & ClassFlag::kExtern; }
|
bool IsExtern() const { return flags_ & ClassFlag::kExtern; }
|
||||||
bool ShouldGeneratePrint() const {
|
bool ShouldGeneratePrint() const {
|
||||||
return (flags_ & ClassFlag::kGeneratePrint || !IsExtern()) &&
|
return !IsExtern() ||
|
||||||
!HasUndefinedLayout();
|
((flags_ & ClassFlag::kGeneratePrint) && !HasUndefinedLayout());
|
||||||
}
|
}
|
||||||
bool ShouldGenerateVerify() const {
|
bool ShouldGenerateVerify() const {
|
||||||
return (flags_ & ClassFlag::kGenerateVerify || !IsExtern()) &&
|
return !IsExtern() || ((flags_ & ClassFlag::kGenerateVerify) &&
|
||||||
!HasUndefinedLayout() && !IsShape();
|
(!HasUndefinedLayout() && !IsShape()));
|
||||||
|
}
|
||||||
|
bool ShouldGenerateBodyDescriptor() const {
|
||||||
|
return flags_ & ClassFlag::kGenerateBodyDescriptor || !IsExtern();
|
||||||
}
|
}
|
||||||
bool IsTransient() const override { return flags_ & ClassFlag::kTransient; }
|
bool IsTransient() const override { return flags_ & ClassFlag::kTransient; }
|
||||||
bool IsAbstract() const { return flags_ & ClassFlag::kAbstract; }
|
bool IsAbstract() const { return flags_ & ClassFlag::kAbstract; }
|
||||||
@ -624,8 +629,10 @@ class ClassType final : public AggregateType {
|
|||||||
return flags_ & ClassFlag::kHasSameInstanceTypeAsParent;
|
return flags_ & ClassFlag::kHasSameInstanceTypeAsParent;
|
||||||
}
|
}
|
||||||
bool GenerateCppClassDefinitions() const {
|
bool GenerateCppClassDefinitions() const {
|
||||||
return flags_ & ClassFlag::kGenerateCppClassDefinitions || !IsExtern();
|
return flags_ & ClassFlag::kGenerateCppClassDefinitions || !IsExtern() ||
|
||||||
|
ShouldGenerateBodyDescriptor();
|
||||||
}
|
}
|
||||||
|
bool ShouldExport() const { return flags_ & ClassFlag::kExport; }
|
||||||
bool IsShape() const { return flags_ & ClassFlag::kIsShape; }
|
bool IsShape() const { return flags_ & ClassFlag::kIsShape; }
|
||||||
bool HasStaticSize() const;
|
bool HasStaticSize() const;
|
||||||
bool HasIndexedField() const override;
|
bool HasIndexedField() const override;
|
||||||
|
@ -736,6 +736,35 @@ TEST(TestTestParentFrameArguments) {
|
|||||||
asm_tester.GenerateCode();
|
asm_tester.GenerateCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestFullyGeneratedClassFromCpp) {
|
||||||
|
CcTest::InitializeVM();
|
||||||
|
Isolate* isolate(CcTest::i_isolate());
|
||||||
|
i::HandleScope scope(isolate);
|
||||||
|
CodeAssemblerTester asm_tester(isolate, 1);
|
||||||
|
TestTorqueAssembler m(asm_tester.state());
|
||||||
|
{ m.Return(m.TestFullyGeneratedClassFromCpp()); }
|
||||||
|
FunctionTester ft(asm_tester.GenerateCode(), 0);
|
||||||
|
Handle<ExportedSubClass> result =
|
||||||
|
Handle<ExportedSubClass>::cast(ft.Call().ToHandleChecked());
|
||||||
|
CHECK_EQ(result->c_field(), 7);
|
||||||
|
CHECK_EQ(result->d_field(), 8);
|
||||||
|
CHECK_EQ(Smi::ToInt(result->e_field()), 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestFullyGeneratedClassWithElements) {
|
||||||
|
CcTest::InitializeVM();
|
||||||
|
Isolate* isolate(CcTest::i_isolate());
|
||||||
|
i::HandleScope scope(isolate);
|
||||||
|
CodeAssemblerTester asm_tester(isolate, 1);
|
||||||
|
TestTorqueAssembler m(asm_tester.state());
|
||||||
|
{
|
||||||
|
m.TestFullyGeneratedClassWithElements();
|
||||||
|
m.Return(m.UndefinedConstant());
|
||||||
|
}
|
||||||
|
FunctionTester ft(asm_tester.GenerateCode(), 0);
|
||||||
|
ft.Call();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -767,7 +767,7 @@ namespace test {
|
|||||||
check(a.b.GetX() == 2);
|
check(a.b.GetX() == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
class InternalClass extends Struct {
|
class InternalClass extends HeapObject {
|
||||||
macro Flip() labels NotASmi {
|
macro Flip() labels NotASmi {
|
||||||
const tmp = Cast<Smi>(this.b) otherwise NotASmi;
|
const tmp = Cast<Smi>(this.b) otherwise NotASmi;
|
||||||
this.b = this.a;
|
this.b = this.a;
|
||||||
@ -833,7 +833,7 @@ namespace test {
|
|||||||
return new FixedArray{map: kFixedArrayMap, length: 5, objects: ...i};
|
return new FixedArray{map: kFixedArrayMap, length: 5, objects: ...i};
|
||||||
}
|
}
|
||||||
|
|
||||||
class SmiPair extends Struct {
|
class SmiPair extends HeapObject {
|
||||||
macro GetA():&Smi {
|
macro GetA():&Smi {
|
||||||
return & this.a;
|
return & this.a;
|
||||||
}
|
}
|
||||||
@ -920,7 +920,7 @@ namespace test {
|
|||||||
StaticAssert(1 + 2 == 3);
|
StaticAssert(1 + 2 == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SmiBox extends Struct {
|
class SmiBox extends HeapObject {
|
||||||
value: Smi;
|
value: Smi;
|
||||||
unrelated: Smi;
|
unrelated: Smi;
|
||||||
}
|
}
|
||||||
@ -1120,4 +1120,108 @@ namespace test {
|
|||||||
check(val3.d == 99);
|
check(val3.d == 99);
|
||||||
check(val3.e == 1234);
|
check(val3.e == 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@export
|
||||||
|
class ExportedSubClass extends ExportedSubClassBase {
|
||||||
|
c_field: int32;
|
||||||
|
d_field: int32;
|
||||||
|
e_field: Smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
@export
|
||||||
|
class ExportedSubClassBase extends HeapObject {
|
||||||
|
a: HeapObject;
|
||||||
|
b: HeapObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
class InternalClassWithSmiElements extends FixedArrayBase {
|
||||||
|
data: Smi;
|
||||||
|
object: Oddball;
|
||||||
|
entries[length]: Smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InternalClassStructElement {
|
||||||
|
a: Smi;
|
||||||
|
b: Smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
class InternalClassWithStructElements extends HeapObject {
|
||||||
|
dummy1: int32;
|
||||||
|
dummy2: int32;
|
||||||
|
count: Smi;
|
||||||
|
data: Smi;
|
||||||
|
object: Object;
|
||||||
|
entries[count]: Smi;
|
||||||
|
more_entries[count]: InternalClassStructElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SmiGeneratorIterator {
|
||||||
|
macro Next(): Smi labels _NoMore {
|
||||||
|
return this.value++;
|
||||||
|
}
|
||||||
|
value: Smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InternalClassStructElementGeneratorIterator {
|
||||||
|
macro Next(): InternalClassStructElement labels _NoMore {
|
||||||
|
return InternalClassStructElement{a: this.value++, b: this.value++};
|
||||||
|
}
|
||||||
|
value: Smi;
|
||||||
|
}
|
||||||
|
|
||||||
|
@export
|
||||||
|
macro TestFullyGeneratedClassWithElements() {
|
||||||
|
// Test creation, initialization and access of a fully generated class with
|
||||||
|
// simple (Smi) elements
|
||||||
|
const length: Smi = Convert<Smi>(3);
|
||||||
|
const object1 = new InternalClassWithSmiElements{
|
||||||
|
length,
|
||||||
|
data: 0,
|
||||||
|
object: Undefined,
|
||||||
|
entries: ...SmiGeneratorIterator {
|
||||||
|
value: 11
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assert(object1.length == 3);
|
||||||
|
assert(object1.data == 0);
|
||||||
|
assert(object1.object == Undefined);
|
||||||
|
assert(object1.entries[0] == 11);
|
||||||
|
assert(object1.entries[1] == 12);
|
||||||
|
assert(object1.entries[2] == 13);
|
||||||
|
|
||||||
|
// Test creation, initialization and access of a fully generated class
|
||||||
|
// with elements that are a struct.
|
||||||
|
const object2 = new InternalClassWithStructElements{
|
||||||
|
dummy1: 44,
|
||||||
|
dummy2: 45,
|
||||||
|
count: length,
|
||||||
|
data: 55,
|
||||||
|
object: Undefined,
|
||||||
|
entries: ...SmiGeneratorIterator{value: 3},
|
||||||
|
more_entries: ...InternalClassStructElementGeneratorIterator {
|
||||||
|
value: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(object2.dummy1 == 44);
|
||||||
|
assert(object2.dummy2 == 45);
|
||||||
|
assert(object2.count == 3);
|
||||||
|
assert(object2.data == 55);
|
||||||
|
assert(object2.object == Undefined);
|
||||||
|
assert(object2.entries[0] == 3);
|
||||||
|
assert(object2.entries[1] == 4);
|
||||||
|
assert(object2.entries[2] == 5);
|
||||||
|
assert(object2.more_entries[0].a == 1);
|
||||||
|
assert(object2.more_entries[0].b == 2);
|
||||||
|
assert(object2.more_entries[1].a == 3);
|
||||||
|
assert(object2.more_entries[1].b == 4);
|
||||||
|
assert(object2.more_entries[2].a == 5);
|
||||||
|
assert(object2.more_entries[2].b == 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
@export
|
||||||
|
macro TestFullyGeneratedClassFromCpp(): ExportedSubClass {
|
||||||
|
return new
|
||||||
|
ExportedSubClass{a: Null, b: Null, c_field: 7, d_field: 8, e_field: 9};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
2
third_party/v8/builtins/array-sort.tq
vendored
2
third_party/v8/builtins/array-sort.tq
vendored
@ -14,7 +14,7 @@
|
|||||||
// https://github.com/python/cpython/blob/master/Objects/listsort.txt
|
// https://github.com/python/cpython/blob/master/Objects/listsort.txt
|
||||||
|
|
||||||
namespace array {
|
namespace array {
|
||||||
class SortState extends Struct {
|
class SortState extends HeapObject {
|
||||||
macro Compare(implicit context: Context)(x: JSAny, y: JSAny): Number {
|
macro Compare(implicit context: Context)(x: JSAny, y: JSAny): Number {
|
||||||
const sortCompare: CompareBuiltinFn = this.sortComparePtr;
|
const sortCompare: CompareBuiltinFn = this.sortComparePtr;
|
||||||
return sortCompare(context, this.userCmpFn, x, y);
|
return sortCompare(context, this.userCmpFn, x, y);
|
||||||
|
@ -69,6 +69,7 @@ v8_component("v8_debug_helper") {
|
|||||||
sources = [
|
sources = [
|
||||||
"$target_gen_dir/../../torque-generated/class-debug-readers-tq.cc",
|
"$target_gen_dir/../../torque-generated/class-debug-readers-tq.cc",
|
||||||
"$target_gen_dir/../../torque-generated/class-debug-readers-tq.h",
|
"$target_gen_dir/../../torque-generated/class-debug-readers-tq.h",
|
||||||
|
"$target_gen_dir/../../torque-generated/instance-types-tq.h",
|
||||||
"$target_gen_dir/heap-constants-gen.cc",
|
"$target_gen_dir/heap-constants-gen.cc",
|
||||||
"debug-helper-internal.cc",
|
"debug-helper-internal.cc",
|
||||||
"debug-helper-internal.h",
|
"debug-helper-internal.h",
|
||||||
|
@ -104,6 +104,7 @@ TypedObject GetTypedObjectByInstanceType(uintptr_t address,
|
|||||||
case i::INSTANCE_TYPE: \
|
case i::INSTANCE_TYPE: \
|
||||||
return {type_source, std::make_unique<Tq##ClassName>(address)};
|
return {type_source, std::make_unique<Tq##ClassName>(address)};
|
||||||
TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(INSTANCE_TYPE_CASE)
|
TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(INSTANCE_TYPE_CASE)
|
||||||
|
TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(INSTANCE_TYPE_CASE)
|
||||||
#undef INSTANCE_TYPE_CASE
|
#undef INSTANCE_TYPE_CASE
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -29,8 +29,8 @@ INSTANCE_TYPES = {
|
|||||||
65: "BIG_INT_BASE_TYPE",
|
65: "BIG_INT_BASE_TYPE",
|
||||||
66: "HEAP_NUMBER_TYPE",
|
66: "HEAP_NUMBER_TYPE",
|
||||||
67: "ODDBALL_TYPE",
|
67: "ODDBALL_TYPE",
|
||||||
68: "SOURCE_TEXT_MODULE_TYPE",
|
68: "EXPORTED_SUB_CLASS_BASE_TYPE",
|
||||||
69: "SYNTHETIC_MODULE_TYPE",
|
69: "EXPORTED_SUB_CLASS_TYPE",
|
||||||
70: "FOREIGN_TYPE",
|
70: "FOREIGN_TYPE",
|
||||||
71: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
|
71: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
|
||||||
72: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
|
72: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
|
||||||
@ -60,84 +60,88 @@ INSTANCE_TYPES = {
|
|||||||
96: "FEEDBACK_CELL_TYPE",
|
96: "FEEDBACK_CELL_TYPE",
|
||||||
97: "FUNCTION_TEMPLATE_RARE_DATA_TYPE",
|
97: "FUNCTION_TEMPLATE_RARE_DATA_TYPE",
|
||||||
98: "INTERCEPTOR_INFO_TYPE",
|
98: "INTERCEPTOR_INFO_TYPE",
|
||||||
99: "INTERNAL_CLASS_TYPE",
|
99: "INTERPRETER_DATA_TYPE",
|
||||||
100: "INTERPRETER_DATA_TYPE",
|
100: "PROMISE_CAPABILITY_TYPE",
|
||||||
101: "PROMISE_CAPABILITY_TYPE",
|
101: "PROMISE_REACTION_TYPE",
|
||||||
102: "PROMISE_REACTION_TYPE",
|
102: "PROPERTY_DESCRIPTOR_OBJECT_TYPE",
|
||||||
103: "PROPERTY_DESCRIPTOR_OBJECT_TYPE",
|
103: "PROTOTYPE_INFO_TYPE",
|
||||||
104: "PROTOTYPE_INFO_TYPE",
|
104: "SCRIPT_TYPE",
|
||||||
105: "SCRIPT_TYPE",
|
105: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE",
|
||||||
106: "SMI_BOX_TYPE",
|
106: "STACK_FRAME_INFO_TYPE",
|
||||||
107: "SMI_PAIR_TYPE",
|
107: "STACK_TRACE_FRAME_TYPE",
|
||||||
108: "SORT_STATE_TYPE",
|
108: "TEMPLATE_OBJECT_DESCRIPTION_TYPE",
|
||||||
109: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE",
|
109: "TUPLE2_TYPE",
|
||||||
110: "STACK_FRAME_INFO_TYPE",
|
110: "WASM_CAPI_FUNCTION_DATA_TYPE",
|
||||||
111: "STACK_TRACE_FRAME_TYPE",
|
111: "WASM_DEBUG_INFO_TYPE",
|
||||||
112: "TEMPLATE_OBJECT_DESCRIPTION_TYPE",
|
112: "WASM_EXCEPTION_TAG_TYPE",
|
||||||
113: "TUPLE2_TYPE",
|
113: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
|
||||||
114: "WASM_CAPI_FUNCTION_DATA_TYPE",
|
114: "WASM_INDIRECT_FUNCTION_TABLE_TYPE",
|
||||||
115: "WASM_DEBUG_INFO_TYPE",
|
115: "WASM_JS_FUNCTION_DATA_TYPE",
|
||||||
116: "WASM_EXCEPTION_TAG_TYPE",
|
116: "FIXED_ARRAY_TYPE",
|
||||||
117: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
|
117: "HASH_TABLE_TYPE",
|
||||||
118: "WASM_INDIRECT_FUNCTION_TABLE_TYPE",
|
118: "EPHEMERON_HASH_TABLE_TYPE",
|
||||||
119: "WASM_JS_FUNCTION_DATA_TYPE",
|
119: "GLOBAL_DICTIONARY_TYPE",
|
||||||
120: "FIXED_ARRAY_TYPE",
|
120: "NAME_DICTIONARY_TYPE",
|
||||||
121: "HASH_TABLE_TYPE",
|
121: "NUMBER_DICTIONARY_TYPE",
|
||||||
122: "EPHEMERON_HASH_TABLE_TYPE",
|
122: "ORDERED_HASH_MAP_TYPE",
|
||||||
123: "GLOBAL_DICTIONARY_TYPE",
|
123: "ORDERED_HASH_SET_TYPE",
|
||||||
124: "NAME_DICTIONARY_TYPE",
|
124: "ORDERED_NAME_DICTIONARY_TYPE",
|
||||||
125: "NUMBER_DICTIONARY_TYPE",
|
125: "SIMPLE_NUMBER_DICTIONARY_TYPE",
|
||||||
126: "ORDERED_HASH_MAP_TYPE",
|
126: "STRING_TABLE_TYPE",
|
||||||
127: "ORDERED_HASH_SET_TYPE",
|
127: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE",
|
||||||
128: "ORDERED_NAME_DICTIONARY_TYPE",
|
128: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE",
|
||||||
129: "SIMPLE_NUMBER_DICTIONARY_TYPE",
|
129: "SCOPE_INFO_TYPE",
|
||||||
130: "STRING_TABLE_TYPE",
|
130: "SCRIPT_CONTEXT_TABLE_TYPE",
|
||||||
131: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE",
|
131: "BYTE_ARRAY_TYPE",
|
||||||
132: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE",
|
132: "BYTECODE_ARRAY_TYPE",
|
||||||
133: "SCOPE_INFO_TYPE",
|
133: "FIXED_DOUBLE_ARRAY_TYPE",
|
||||||
134: "SCRIPT_CONTEXT_TABLE_TYPE",
|
134: "INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE",
|
||||||
135: "BYTE_ARRAY_TYPE",
|
135: "AWAIT_CONTEXT_TYPE",
|
||||||
136: "BYTECODE_ARRAY_TYPE",
|
136: "BLOCK_CONTEXT_TYPE",
|
||||||
137: "FIXED_DOUBLE_ARRAY_TYPE",
|
137: "CATCH_CONTEXT_TYPE",
|
||||||
138: "AWAIT_CONTEXT_TYPE",
|
138: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
||||||
139: "BLOCK_CONTEXT_TYPE",
|
139: "EVAL_CONTEXT_TYPE",
|
||||||
140: "CATCH_CONTEXT_TYPE",
|
140: "FUNCTION_CONTEXT_TYPE",
|
||||||
141: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
141: "MODULE_CONTEXT_TYPE",
|
||||||
142: "EVAL_CONTEXT_TYPE",
|
142: "NATIVE_CONTEXT_TYPE",
|
||||||
143: "FUNCTION_CONTEXT_TYPE",
|
143: "SCRIPT_CONTEXT_TYPE",
|
||||||
144: "MODULE_CONTEXT_TYPE",
|
144: "WITH_CONTEXT_TYPE",
|
||||||
145: "NATIVE_CONTEXT_TYPE",
|
145: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||||
146: "SCRIPT_CONTEXT_TYPE",
|
146: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||||
147: "WITH_CONTEXT_TYPE",
|
147: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
||||||
148: "SMALL_ORDERED_HASH_MAP_TYPE",
|
148: "SOURCE_TEXT_MODULE_TYPE",
|
||||||
149: "SMALL_ORDERED_HASH_SET_TYPE",
|
149: "SYNTHETIC_MODULE_TYPE",
|
||||||
150: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
150: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
||||||
151: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
151: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
||||||
152: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
152: "WEAK_FIXED_ARRAY_TYPE",
|
||||||
153: "WEAK_FIXED_ARRAY_TYPE",
|
153: "TRANSITION_ARRAY_TYPE",
|
||||||
154: "TRANSITION_ARRAY_TYPE",
|
154: "CELL_TYPE",
|
||||||
155: "CELL_TYPE",
|
155: "CODE_TYPE",
|
||||||
156: "CODE_TYPE",
|
156: "CODE_DATA_CONTAINER_TYPE",
|
||||||
157: "CODE_DATA_CONTAINER_TYPE",
|
157: "COVERAGE_INFO_TYPE",
|
||||||
158: "COVERAGE_INFO_TYPE",
|
158: "DESCRIPTOR_ARRAY_TYPE",
|
||||||
159: "DESCRIPTOR_ARRAY_TYPE",
|
159: "EMBEDDER_DATA_ARRAY_TYPE",
|
||||||
160: "EMBEDDER_DATA_ARRAY_TYPE",
|
160: "FEEDBACK_METADATA_TYPE",
|
||||||
161: "FEEDBACK_METADATA_TYPE",
|
161: "FEEDBACK_VECTOR_TYPE",
|
||||||
162: "FEEDBACK_VECTOR_TYPE",
|
162: "FILLER_TYPE",
|
||||||
163: "FILLER_TYPE",
|
163: "FREE_SPACE_TYPE",
|
||||||
164: "FREE_SPACE_TYPE",
|
164: "INTERNAL_CLASS_TYPE",
|
||||||
165: "MAP_TYPE",
|
165: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE",
|
||||||
166: "PREPARSE_DATA_TYPE",
|
166: "MAP_TYPE",
|
||||||
167: "PROPERTY_ARRAY_TYPE",
|
167: "PREPARSE_DATA_TYPE",
|
||||||
168: "PROPERTY_CELL_TYPE",
|
168: "PROPERTY_ARRAY_TYPE",
|
||||||
169: "SHARED_FUNCTION_INFO_TYPE",
|
169: "PROPERTY_CELL_TYPE",
|
||||||
170: "WEAK_ARRAY_LIST_TYPE",
|
170: "SHARED_FUNCTION_INFO_TYPE",
|
||||||
171: "WEAK_CELL_TYPE",
|
171: "SMI_BOX_TYPE",
|
||||||
172: "JS_PROXY_TYPE",
|
172: "SMI_PAIR_TYPE",
|
||||||
|
173: "SORT_STATE_TYPE",
|
||||||
|
174: "WEAK_ARRAY_LIST_TYPE",
|
||||||
|
175: "WEAK_CELL_TYPE",
|
||||||
|
176: "JS_PROXY_TYPE",
|
||||||
1057: "JS_OBJECT_TYPE",
|
1057: "JS_OBJECT_TYPE",
|
||||||
173: "JS_GLOBAL_OBJECT_TYPE",
|
177: "JS_GLOBAL_OBJECT_TYPE",
|
||||||
174: "JS_GLOBAL_PROXY_TYPE",
|
178: "JS_GLOBAL_PROXY_TYPE",
|
||||||
175: "JS_MODULE_NAMESPACE_TYPE",
|
179: "JS_MODULE_NAMESPACE_TYPE",
|
||||||
1040: "JS_SPECIAL_API_OBJECT_TYPE",
|
1040: "JS_SPECIAL_API_OBJECT_TYPE",
|
||||||
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
|
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
|
||||||
1042: "JS_MAP_KEY_ITERATOR_TYPE",
|
1042: "JS_MAP_KEY_ITERATOR_TYPE",
|
||||||
@ -194,78 +198,78 @@ INSTANCE_TYPES = {
|
|||||||
|
|
||||||
# List of known V8 maps.
|
# List of known V8 maps.
|
||||||
KNOWN_MAPS = {
|
KNOWN_MAPS = {
|
||||||
("read_only_space", 0x00121): (164, "FreeSpaceMap"),
|
("read_only_space", 0x00121): (163, "FreeSpaceMap"),
|
||||||
("read_only_space", 0x00149): (165, "MetaMap"),
|
("read_only_space", 0x00149): (166, "MetaMap"),
|
||||||
("read_only_space", 0x0018d): (67, "NullMap"),
|
("read_only_space", 0x0018d): (67, "NullMap"),
|
||||||
("read_only_space", 0x001c5): (159, "DescriptorArrayMap"),
|
("read_only_space", 0x001c5): (158, "DescriptorArrayMap"),
|
||||||
("read_only_space", 0x001f5): (153, "WeakFixedArrayMap"),
|
("read_only_space", 0x001f5): (152, "WeakFixedArrayMap"),
|
||||||
("read_only_space", 0x0021d): (163, "OnePointerFillerMap"),
|
("read_only_space", 0x0021d): (162, "OnePointerFillerMap"),
|
||||||
("read_only_space", 0x00245): (163, "TwoPointerFillerMap"),
|
("read_only_space", 0x00245): (162, "TwoPointerFillerMap"),
|
||||||
("read_only_space", 0x00289): (67, "UninitializedMap"),
|
("read_only_space", 0x00289): (67, "UninitializedMap"),
|
||||||
("read_only_space", 0x002cd): (8, "OneByteInternalizedStringMap"),
|
("read_only_space", 0x002cd): (8, "OneByteInternalizedStringMap"),
|
||||||
("read_only_space", 0x00329): (67, "UndefinedMap"),
|
("read_only_space", 0x00329): (67, "UndefinedMap"),
|
||||||
("read_only_space", 0x0035d): (66, "HeapNumberMap"),
|
("read_only_space", 0x0035d): (66, "HeapNumberMap"),
|
||||||
("read_only_space", 0x003a1): (67, "TheHoleMap"),
|
("read_only_space", 0x003a1): (67, "TheHoleMap"),
|
||||||
("read_only_space", 0x00401): (67, "BooleanMap"),
|
("read_only_space", 0x00401): (67, "BooleanMap"),
|
||||||
("read_only_space", 0x00489): (135, "ByteArrayMap"),
|
("read_only_space", 0x00489): (131, "ByteArrayMap"),
|
||||||
("read_only_space", 0x004b1): (120, "FixedArrayMap"),
|
("read_only_space", 0x004b1): (116, "FixedArrayMap"),
|
||||||
("read_only_space", 0x004d9): (120, "FixedCOWArrayMap"),
|
("read_only_space", 0x004d9): (116, "FixedCOWArrayMap"),
|
||||||
("read_only_space", 0x00501): (121, "HashTableMap"),
|
("read_only_space", 0x00501): (117, "HashTableMap"),
|
||||||
("read_only_space", 0x00529): (64, "SymbolMap"),
|
("read_only_space", 0x00529): (64, "SymbolMap"),
|
||||||
("read_only_space", 0x00551): (40, "OneByteStringMap"),
|
("read_only_space", 0x00551): (40, "OneByteStringMap"),
|
||||||
("read_only_space", 0x00579): (133, "ScopeInfoMap"),
|
("read_only_space", 0x00579): (129, "ScopeInfoMap"),
|
||||||
("read_only_space", 0x005a1): (169, "SharedFunctionInfoMap"),
|
("read_only_space", 0x005a1): (170, "SharedFunctionInfoMap"),
|
||||||
("read_only_space", 0x005c9): (156, "CodeMap"),
|
("read_only_space", 0x005c9): (155, "CodeMap"),
|
||||||
("read_only_space", 0x005f1): (155, "CellMap"),
|
("read_only_space", 0x005f1): (154, "CellMap"),
|
||||||
("read_only_space", 0x00619): (168, "GlobalPropertyCellMap"),
|
("read_only_space", 0x00619): (169, "GlobalPropertyCellMap"),
|
||||||
("read_only_space", 0x00641): (70, "ForeignMap"),
|
("read_only_space", 0x00641): (70, "ForeignMap"),
|
||||||
("read_only_space", 0x00669): (154, "TransitionArrayMap"),
|
("read_only_space", 0x00669): (153, "TransitionArrayMap"),
|
||||||
("read_only_space", 0x00691): (45, "ThinOneByteStringMap"),
|
("read_only_space", 0x00691): (45, "ThinOneByteStringMap"),
|
||||||
("read_only_space", 0x006b9): (162, "FeedbackVectorMap"),
|
("read_only_space", 0x006b9): (161, "FeedbackVectorMap"),
|
||||||
("read_only_space", 0x0070d): (67, "ArgumentsMarkerMap"),
|
("read_only_space", 0x0070d): (67, "ArgumentsMarkerMap"),
|
||||||
("read_only_space", 0x0076d): (67, "ExceptionMap"),
|
("read_only_space", 0x0076d): (67, "ExceptionMap"),
|
||||||
("read_only_space", 0x007c9): (67, "TerminationExceptionMap"),
|
("read_only_space", 0x007c9): (67, "TerminationExceptionMap"),
|
||||||
("read_only_space", 0x00831): (67, "OptimizedOutMap"),
|
("read_only_space", 0x00831): (67, "OptimizedOutMap"),
|
||||||
("read_only_space", 0x00891): (67, "StaleRegisterMap"),
|
("read_only_space", 0x00891): (67, "StaleRegisterMap"),
|
||||||
("read_only_space", 0x008d5): (134, "ScriptContextTableMap"),
|
("read_only_space", 0x008d5): (130, "ScriptContextTableMap"),
|
||||||
("read_only_space", 0x008fd): (131, "ClosureFeedbackCellArrayMap"),
|
("read_only_space", 0x008fd): (127, "ClosureFeedbackCellArrayMap"),
|
||||||
("read_only_space", 0x00925): (161, "FeedbackMetadataArrayMap"),
|
("read_only_space", 0x00925): (160, "FeedbackMetadataArrayMap"),
|
||||||
("read_only_space", 0x0094d): (120, "ArrayListMap"),
|
("read_only_space", 0x0094d): (116, "ArrayListMap"),
|
||||||
("read_only_space", 0x00975): (65, "BigIntMap"),
|
("read_only_space", 0x00975): (65, "BigIntMap"),
|
||||||
("read_only_space", 0x0099d): (132, "ObjectBoilerplateDescriptionMap"),
|
("read_only_space", 0x0099d): (128, "ObjectBoilerplateDescriptionMap"),
|
||||||
("read_only_space", 0x009c5): (136, "BytecodeArrayMap"),
|
("read_only_space", 0x009c5): (132, "BytecodeArrayMap"),
|
||||||
("read_only_space", 0x009ed): (157, "CodeDataContainerMap"),
|
("read_only_space", 0x009ed): (156, "CodeDataContainerMap"),
|
||||||
("read_only_space", 0x00a15): (158, "CoverageInfoMap"),
|
("read_only_space", 0x00a15): (157, "CoverageInfoMap"),
|
||||||
("read_only_space", 0x00a3d): (137, "FixedDoubleArrayMap"),
|
("read_only_space", 0x00a3d): (133, "FixedDoubleArrayMap"),
|
||||||
("read_only_space", 0x00a65): (123, "GlobalDictionaryMap"),
|
("read_only_space", 0x00a65): (119, "GlobalDictionaryMap"),
|
||||||
("read_only_space", 0x00a8d): (96, "ManyClosuresCellMap"),
|
("read_only_space", 0x00a8d): (96, "ManyClosuresCellMap"),
|
||||||
("read_only_space", 0x00ab5): (120, "ModuleInfoMap"),
|
("read_only_space", 0x00ab5): (116, "ModuleInfoMap"),
|
||||||
("read_only_space", 0x00add): (124, "NameDictionaryMap"),
|
("read_only_space", 0x00add): (120, "NameDictionaryMap"),
|
||||||
("read_only_space", 0x00b05): (96, "NoClosuresCellMap"),
|
("read_only_space", 0x00b05): (96, "NoClosuresCellMap"),
|
||||||
("read_only_space", 0x00b2d): (125, "NumberDictionaryMap"),
|
("read_only_space", 0x00b2d): (121, "NumberDictionaryMap"),
|
||||||
("read_only_space", 0x00b55): (96, "OneClosureCellMap"),
|
("read_only_space", 0x00b55): (96, "OneClosureCellMap"),
|
||||||
("read_only_space", 0x00b7d): (126, "OrderedHashMapMap"),
|
("read_only_space", 0x00b7d): (122, "OrderedHashMapMap"),
|
||||||
("read_only_space", 0x00ba5): (127, "OrderedHashSetMap"),
|
("read_only_space", 0x00ba5): (123, "OrderedHashSetMap"),
|
||||||
("read_only_space", 0x00bcd): (128, "OrderedNameDictionaryMap"),
|
("read_only_space", 0x00bcd): (124, "OrderedNameDictionaryMap"),
|
||||||
("read_only_space", 0x00bf5): (166, "PreparseDataMap"),
|
("read_only_space", 0x00bf5): (167, "PreparseDataMap"),
|
||||||
("read_only_space", 0x00c1d): (167, "PropertyArrayMap"),
|
("read_only_space", 0x00c1d): (168, "PropertyArrayMap"),
|
||||||
("read_only_space", 0x00c45): (92, "SideEffectCallHandlerInfoMap"),
|
("read_only_space", 0x00c45): (92, "SideEffectCallHandlerInfoMap"),
|
||||||
("read_only_space", 0x00c6d): (92, "SideEffectFreeCallHandlerInfoMap"),
|
("read_only_space", 0x00c6d): (92, "SideEffectFreeCallHandlerInfoMap"),
|
||||||
("read_only_space", 0x00c95): (92, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
("read_only_space", 0x00c95): (92, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||||
("read_only_space", 0x00cbd): (129, "SimpleNumberDictionaryMap"),
|
("read_only_space", 0x00cbd): (125, "SimpleNumberDictionaryMap"),
|
||||||
("read_only_space", 0x00ce5): (120, "SloppyArgumentsElementsMap"),
|
("read_only_space", 0x00ce5): (116, "SloppyArgumentsElementsMap"),
|
||||||
("read_only_space", 0x00d0d): (148, "SmallOrderedHashMapMap"),
|
("read_only_space", 0x00d0d): (145, "SmallOrderedHashMapMap"),
|
||||||
("read_only_space", 0x00d35): (149, "SmallOrderedHashSetMap"),
|
("read_only_space", 0x00d35): (146, "SmallOrderedHashSetMap"),
|
||||||
("read_only_space", 0x00d5d): (150, "SmallOrderedNameDictionaryMap"),
|
("read_only_space", 0x00d5d): (147, "SmallOrderedNameDictionaryMap"),
|
||||||
("read_only_space", 0x00d85): (68, "SourceTextModuleMap"),
|
("read_only_space", 0x00d85): (148, "SourceTextModuleMap"),
|
||||||
("read_only_space", 0x00dad): (130, "StringTableMap"),
|
("read_only_space", 0x00dad): (126, "StringTableMap"),
|
||||||
("read_only_space", 0x00dd5): (69, "SyntheticModuleMap"),
|
("read_only_space", 0x00dd5): (149, "SyntheticModuleMap"),
|
||||||
("read_only_space", 0x00dfd): (152, "UncompiledDataWithoutPreparseDataMap"),
|
("read_only_space", 0x00dfd): (151, "UncompiledDataWithoutPreparseDataMap"),
|
||||||
("read_only_space", 0x00e25): (151, "UncompiledDataWithPreparseDataMap"),
|
("read_only_space", 0x00e25): (150, "UncompiledDataWithPreparseDataMap"),
|
||||||
("read_only_space", 0x00e4d): (170, "WeakArrayListMap"),
|
("read_only_space", 0x00e4d): (174, "WeakArrayListMap"),
|
||||||
("read_only_space", 0x00e75): (122, "EphemeronHashTableMap"),
|
("read_only_space", 0x00e75): (118, "EphemeronHashTableMap"),
|
||||||
("read_only_space", 0x00e9d): (160, "EmbedderDataArrayMap"),
|
("read_only_space", 0x00e9d): (159, "EmbedderDataArrayMap"),
|
||||||
("read_only_space", 0x00ec5): (171, "WeakCellMap"),
|
("read_only_space", 0x00ec5): (175, "WeakCellMap"),
|
||||||
("read_only_space", 0x00eed): (32, "StringMap"),
|
("read_only_space", 0x00eed): (32, "StringMap"),
|
||||||
("read_only_space", 0x00f15): (41, "ConsOneByteStringMap"),
|
("read_only_space", 0x00f15): (41, "ConsOneByteStringMap"),
|
||||||
("read_only_space", 0x00f3d): (33, "ConsStringMap"),
|
("read_only_space", 0x00f3d): (33, "ConsStringMap"),
|
||||||
@ -305,36 +309,40 @@ KNOWN_MAPS = {
|
|||||||
("read_only_space", 0x0357d): (93, "ClassPositionsMap"),
|
("read_only_space", 0x0357d): (93, "ClassPositionsMap"),
|
||||||
("read_only_space", 0x035a5): (94, "DebugInfoMap"),
|
("read_only_space", 0x035a5): (94, "DebugInfoMap"),
|
||||||
("read_only_space", 0x035cd): (97, "FunctionTemplateRareDataMap"),
|
("read_only_space", 0x035cd): (97, "FunctionTemplateRareDataMap"),
|
||||||
("read_only_space", 0x035f5): (100, "InterpreterDataMap"),
|
("read_only_space", 0x035f5): (99, "InterpreterDataMap"),
|
||||||
("read_only_space", 0x0361d): (101, "PromiseCapabilityMap"),
|
("read_only_space", 0x0361d): (100, "PromiseCapabilityMap"),
|
||||||
("read_only_space", 0x03645): (102, "PromiseReactionMap"),
|
("read_only_space", 0x03645): (101, "PromiseReactionMap"),
|
||||||
("read_only_space", 0x0366d): (103, "PropertyDescriptorObjectMap"),
|
("read_only_space", 0x0366d): (102, "PropertyDescriptorObjectMap"),
|
||||||
("read_only_space", 0x03695): (104, "PrototypeInfoMap"),
|
("read_only_space", 0x03695): (103, "PrototypeInfoMap"),
|
||||||
("read_only_space", 0x036bd): (105, "ScriptMap"),
|
("read_only_space", 0x036bd): (104, "ScriptMap"),
|
||||||
("read_only_space", 0x036e5): (109, "SourceTextModuleInfoEntryMap"),
|
("read_only_space", 0x036e5): (105, "SourceTextModuleInfoEntryMap"),
|
||||||
("read_only_space", 0x0370d): (110, "StackFrameInfoMap"),
|
("read_only_space", 0x0370d): (106, "StackFrameInfoMap"),
|
||||||
("read_only_space", 0x03735): (111, "StackTraceFrameMap"),
|
("read_only_space", 0x03735): (107, "StackTraceFrameMap"),
|
||||||
("read_only_space", 0x0375d): (112, "TemplateObjectDescriptionMap"),
|
("read_only_space", 0x0375d): (108, "TemplateObjectDescriptionMap"),
|
||||||
("read_only_space", 0x03785): (113, "Tuple2Map"),
|
("read_only_space", 0x03785): (109, "Tuple2Map"),
|
||||||
("read_only_space", 0x037ad): (114, "WasmCapiFunctionDataMap"),
|
("read_only_space", 0x037ad): (110, "WasmCapiFunctionDataMap"),
|
||||||
("read_only_space", 0x037d5): (115, "WasmDebugInfoMap"),
|
("read_only_space", 0x037d5): (111, "WasmDebugInfoMap"),
|
||||||
("read_only_space", 0x037fd): (116, "WasmExceptionTagMap"),
|
("read_only_space", 0x037fd): (112, "WasmExceptionTagMap"),
|
||||||
("read_only_space", 0x03825): (117, "WasmExportedFunctionDataMap"),
|
("read_only_space", 0x03825): (113, "WasmExportedFunctionDataMap"),
|
||||||
("read_only_space", 0x0384d): (118, "WasmIndirectFunctionTableMap"),
|
("read_only_space", 0x0384d): (114, "WasmIndirectFunctionTableMap"),
|
||||||
("read_only_space", 0x03875): (119, "WasmJSFunctionDataMap"),
|
("read_only_space", 0x03875): (115, "WasmJSFunctionDataMap"),
|
||||||
("read_only_space", 0x0389d): (99, "InternalClassMap"),
|
("read_only_space", 0x0389d): (134, "InternalClassWithSmiElementsMap"),
|
||||||
("read_only_space", 0x038c5): (107, "SmiPairMap"),
|
("read_only_space", 0x038c5): (165, "InternalClassWithStructElementsMap"),
|
||||||
("read_only_space", 0x038ed): (106, "SmiBoxMap"),
|
("read_only_space", 0x038ed): (164, "InternalClassMap"),
|
||||||
("read_only_space", 0x03915): (108, "SortStateMap"),
|
("read_only_space", 0x03915): (172, "SmiPairMap"),
|
||||||
("read_only_space", 0x0393d): (85, "AllocationSiteWithWeakNextMap"),
|
("read_only_space", 0x0393d): (171, "SmiBoxMap"),
|
||||||
("read_only_space", 0x03965): (85, "AllocationSiteWithoutWeakNextMap"),
|
("read_only_space", 0x03965): (68, "ExportedSubClassBaseMap"),
|
||||||
("read_only_space", 0x0398d): (76, "LoadHandler1Map"),
|
("read_only_space", 0x0398d): (69, "ExportedSubClassMap"),
|
||||||
("read_only_space", 0x039b5): (76, "LoadHandler2Map"),
|
("read_only_space", 0x039b5): (173, "SortStateMap"),
|
||||||
("read_only_space", 0x039dd): (76, "LoadHandler3Map"),
|
("read_only_space", 0x039dd): (85, "AllocationSiteWithWeakNextMap"),
|
||||||
("read_only_space", 0x03a05): (77, "StoreHandler0Map"),
|
("read_only_space", 0x03a05): (85, "AllocationSiteWithoutWeakNextMap"),
|
||||||
("read_only_space", 0x03a2d): (77, "StoreHandler1Map"),
|
("read_only_space", 0x03a2d): (76, "LoadHandler1Map"),
|
||||||
("read_only_space", 0x03a55): (77, "StoreHandler2Map"),
|
("read_only_space", 0x03a55): (76, "LoadHandler2Map"),
|
||||||
("read_only_space", 0x03a7d): (77, "StoreHandler3Map"),
|
("read_only_space", 0x03a7d): (76, "LoadHandler3Map"),
|
||||||
|
("read_only_space", 0x03aa5): (77, "StoreHandler0Map"),
|
||||||
|
("read_only_space", 0x03acd): (77, "StoreHandler1Map"),
|
||||||
|
("read_only_space", 0x03af5): (77, "StoreHandler2Map"),
|
||||||
|
("read_only_space", 0x03b1d): (77, "StoreHandler3Map"),
|
||||||
("map_space", 0x00121): (1057, "ExternalMap"),
|
("map_space", 0x00121): (1057, "ExternalMap"),
|
||||||
("map_space", 0x00149): (1073, "JSMessageObjectMap"),
|
("map_space", 0x00149): (1073, "JSMessageObjectMap"),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user